【问题标题】:Read NFC tag from Xamarin从 Xamarin 读取 NFC 标签
【发布时间】:2019-04-19 08:55:05
【问题描述】:

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

你能帮帮我吗?

【问题讨论】:

    标签: android xamarin tags nfc intentfilter


    【解决方案1】:

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

    相反,如果您只想监听所有标签,则需要使用ActionTagDiscovered 意图。实际上,您可以简单地从调用EnableForegroundDispatch 时一起跳过意图过滤器:

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

    【讨论】:

    • @Micheal Roland 谢谢!现在,通过将 tagDetected 设置为 ActionNdefDiscovered,我有了新的意图,但我还无法读取标签内容...我认为第一个 if 条件出现了问题 关于 OnNewIntent(意图意图)。你能再帮我一次吗?
    • 更好的是,代码只在应用程序同时运行而不是启动时进入if条件
    • @FabioPaccosi “出了点问题”并不是对问题的真正有用描述。我的回答解决了您最初的问题吗?如果是,请提出一个新的问题。如果不是,请更新您现有的问题并提供更多详细信息。具体来说,当您的应用程序处于前台时,它现在是否正常工作(这就是您在问题中显示的代码是关于......)。当您的应用程序启动时它是否也可以工作(那可能是一个问题)?然后,您还需要显示您的清单意图过滤器以及您实际放置在标签上的数据。
    • @MichealRoland 你说得对,如果我不能解决我的问题,我会打开一个新请求。感谢您的建议。
    • 非常感谢,它拯救了我的一天。 @MichaelRoland
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-24
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多