android - 从 Xamarin 读取 NFC 标签

标签 android xamarin tags nfc intentfilter

我是 Xamarin 跨平台应用开发的新手,我正在尝试在我的应用的 Android 版本上实现外部 NFC 标签读取。

当扫描标签时,我希望我的应用程序打开并读取标签内的文本,最后根据读取的内容执行一些特定的操作。

我在 MainActivity.cs 上有这个实现,但它不起作用,因为我似乎无法理解 Intent :

using Android.Content;
using System;
using System.Text;
using System.Diagnostics;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Xamarin.Forms;
using Android.Content.Res;
using FFImageLoading.Forms.Platform;
using Plugin.Permissions;
using Plugin.Permissions.Abstractions;
using Plugin.CurrentActivity;
using Android.Nfc;
using Android.Nfc.Tech;
using Poz1.NFCForms.Abstract;
using Poz1.NFCForms.Droid;

namespace Kibelis.Droid
{
    [Activity(Label = "Kibelis", Icon = "@drawable/icon", Theme = "@style/MainTheme", LaunchMode = LaunchMode.SingleTop, MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {

        private NfcAdapter _nfcAdapter;


        public object NFCUtil { get; private set; }


        protected override void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;
            CachedImageRenderer.Init(true);
            base.OnCreate(savedInstanceState);
            CrossCurrentActivity.Current.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);


            _nfcAdapter = NfcAdapter.GetDefaultAdapter(this);
            System.Diagnostics.Debug.WriteLine("CREATE");


            // is attached.
            LoadApplication(new App());
        }

        protected override void OnResume()
        {
            base.OnResume();

            if (_nfcAdapter == null)
            {
                System.Diagnostics.Debug.WriteLine("NFC UNAVIABLE");
            }
            else
            {
                var tagDetected = new IntentFilter(NfcAdapter.ActionNdefDiscovered);
                var filters = new[] { tagDetected };

                var intent = new Intent(this, this.GetType()).AddFlags(ActivityFlags.SingleTop);

                var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);

                _nfcAdapter.EnableForegroundDispatch(this, pendingIntent, filters, null);

                System.Diagnostics.Debug.WriteLine("FOREGRAUND DISPATCH");
            }
        }


        protected override void OnPause()
        {
            base.OnPause();
        }

        protected override void OnNewIntent(Intent intent)
        {
            base.OnNewIntent(intent);

            System.Diagnostics.Debug.WriteLine("NEW INTENT");

            if (intent.Extras.IsEmpty)
            {
                System.Diagnostics.Debug.WriteLine("empty");
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("Not empty");
            }

            //For start reading
            if (intent.Action == NfcAdapter.ActionTagDiscovered || intent.Action == NfcAdapter.ActionNdefDiscovered || intent.Action == NfcAdapter.ActionAdapterStateChanged
                || intent.Action == NfcAdapter.ActionTransactionDetected || intent.Action == NfcAdapter.ExtraNdefMessages || intent.Action == NfcAdapter.ExtraNdefMessages)
            {
                System.Diagnostics.Debug.WriteLine("DISCOVERD");
                var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
                if (tag != null)
                {
                    System.Diagnostics.Debug.WriteLine("TAG");
                    // First get all the NdefMessage
                    var rawMessages = intent.GetParcelableArrayExtra(NfcAdapter.ExtraNdefMessages);
                    if (rawMessages != null)
                    {
                        var msg = (NdefMessage)rawMessages[0];
                        System.Diagnostics.Debug.WriteLine("MESSAGE");
                        // Get NdefRecord which contains the actual data
                        var record = msg.GetRecords()[0];
                        if (record != null)
                        {
                            if (record.Tnf == NdefRecord.TnfWellKnown)
                            { 
                                // Get the transfered data
                                var data = Encoding.ASCII.GetString(record.GetPayload());
                                System.Diagnostics.Debug.WriteLine("RECORD");
                            }
                        }
                    }
                }
            }
        }

        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
        {
            PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}

你能帮帮我吗?

最佳答案

您正在为 ActionNdefDiscovered Intent 注册前台调度。但是,此 Intent 过滤器还需要特定的数据类型(出现在标签上并为 Intent 注册)。如果这是您想要的,您需要将该数据类型(MIME 类型或 URI)添加到 Intent 过滤器(变量 tagDetected)。

相反,如果您只想监听所有标签,则需要使用 ActionTagDiscovered Intent 。事实上,您可以简单地跳过对 EnableForegroundDispatch 的调用中的所有 intnent 过滤器:

_nfcAdapter.EnableForegroundDispatch(this, pendingIntent, null, null);

关于android - 从 Xamarin 读取 NFC 标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53333274/

相关文章:

java - Android java http Xml 转换为 Json Caused by : java. lang.NoSuchMethodError: No direct method <init>(Ljava/io/Reader;)

svn - 如何在Jenkins中自动标记生产版本?

jquery - jQueryUI ajax 选项卡示例不起作用

java - 使用 c :out tag 访问 session 中 1 个 java bean 的属性

java - 如何确保多个模型对象实例之间的一致性

java - 保存SQL数据库条目的创建日期

android - 在 Kotlin 中使用 Android 数据绑定(bind)初始化 RecyclerView 会引发错误。我究竟做错了什么?

c# - 是否可以将一个颜色资源指向 Xamarin.Forms 中的另一个颜色资源?

xamarin - SignalR 不自动重新连接

Xamarin.Forms 曲棍球应用程序错误 CrashManager.Register