从Xamarin读取NFC标签

3

我刚接触Xamarin跨平台应用程序开发,现在我正在尝试在我的Android应用程序上实现外部NFC标签读取。

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

我在MainActivity.cs中有这个实现,但它不起作用,因为似乎我无法获取意图:

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);
        }
    }
}

你能帮助我吗?

1个回答

2
你正在为ActionNdefDiscovered意图注册前台调度。但是,此意图过滤器还需要特定的数据类型(存在于标签上并已注册为意图)。如果这是你想要的,你需要将该数据类型(MIME类型或URI)添加到意图过滤器(变量tagDetected)中。
相反地,如果你只想监听所有标签,你应该使用ActionTagDiscovered意图。实际上,你可以从对EnableForegroundDispatch的调用中完全跳过意图过滤器。
_nfcAdapter.EnableForegroundDispatch(this, pendingIntent, null, null);

@Micheal Roland 谢谢!现在,通过将_tagDetected_设置为 ActionNdefDiscovered,我获得了一个新的意图,但我还不能读取标签内容... 我认为在 OnNewIntent(Intent intent) 的第一个 if 条件 中出了问题。你能再帮我一次吗? - user8334240
更好的做法是,只有当应用程序正在运行而不是在启动时才进入if条件语句中。 - user8334240
@FabioPaccosi “Something goes wrong”并不是一个有用的问题描述。我的回答解决了你最初的问题吗?如果是,请提出一个单独的新问题。如果不是,请使用更多细节更新您现有的问题。具体来说,当您的应用程序在前台运行时它是否正常工作(这就是您在问题中展示的代码的作用...)。当您的应用程序启动时它也应该工作(那可能是一个的问题)?然后您还需要显示您的清单意图过滤器以及您实际放在标签上的数据。 - Michael Roland
1
@MichealRoland 你说得对,如果我无法解决我的问题,我会开一个新的请求。感谢您的建议。 - user8334240
非常感谢,这真的救了我的一天。@MichaelRoland - touhid udoy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接