【问题标题】:IntentFilter on NFC - Xamarin - C#NFC 上的 IntentFilter - Xamarin - C#
【发布时间】:2016-01-29 12:32:24
【问题描述】:

上下文是:Framework 4.5,Xamarin.Android v5.0

我想使用 NFC 技术为我的应用程序用户实现快捷方式。我希望用户扫描 NFC 标签,因此他们只需为预定义的方案输入一个值。

我在我的 NFC 消息中添加了一些参数,当我在我的 NFC 标签上写消息时我会这样做:

    var tag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
    var ndef = Ndef.Get(tag);
            NdefRecord external = NdefRecord.CreateExternal(applicationPackageName(), "letypetype", Encoding.ASCII.GetBytes("param"));
            NdefRecord appRecord = NdefRecord.CreateApplicationRecord(applicationPackageName());
            NdefMessage ndefMessage = new NdefMessage(external, appRecord);
    if (ndef != null)
    {
        ndef.Connect();
        ndef.WriteNdefMessage(ndefMessage);
    }

然后,我想在我的应用程序上使用它,所以我把它放在 AndroidManifest.xml 这个:

<uses-feature android:name="android.hardware.nfc" android:required="true" />

在我的主要活动中,我有以下意图过滤器:

     [IntentFilter(new[] { NfcAdapter.ActionNdefDiscovered },
      Categories = new[] { Intent.CategoryDefault },
      DataScheme = "vnd.android.nfc", DataPathPrefix = "letypetype",
     DataHost = "ext")]
        public class Activity1 : Activity
       { ...

我尝试使用覆盖方法 OnResume 处理此活动中的参数:

    protected override void OnResume()
    {
        base.OnResume();
        if (NfcAdapter.ActionNdefDiscovered.Equals(this.Intent.Action))
        {
            IParcelable[] rawMsgs = this.Intent.GetParcelableArrayExtra(NfcAdapter.ExtraNdefMessages);
            if (rawMsgs != null)
            {
                NdefMessage[] msgs = new NdefMessage[rawMsgs.Length];
                for (int i = 0; i < rawMsgs.Length; i++)
                {
                    msgs[i] = (NdefMessage)rawMsgs[i];
                }
            }
        }
    }

但是没有办法找回它。 所以我很确定我做错了什么,但我不知道是什么。

【问题讨论】:

  • 你试过我的解决方案了吗?
  • 对不起,我星期五休息了。所以是的,我已经尝试过你的代码,我还将这一行添加到我的 AndroidManifest.xml 中: 是的,标签启动了应用程序,在我之后尝试访问我的标签上的额外信息。但是仍然没有额外的标签可以访问...所以问题可能来自我的消息的创建...我不知道...
  • 问题解决了吗?标记对您有帮助的答案或发布您自己的答案以帮助遇到同样问题的人。

标签: android xamarin nfc intentfilter android-applicationrecord


【解决方案1】:

您面临的问题是您对外部记录的错误意图过滤器的结果。目前在您的情况下发生的是意图过滤器

[IntentFilter(new[] { NfcAdapter.ActionNdefDiscovered },
      Categories = new[] { Intent.CategoryDefault },
      DataScheme = "vnd.android.nfc",
      DataPathPrefix = "letypetype",
      DataHost = "ext")]

与您使用

创建的外部记录匹配
NdefRecord external = NdefRecord.CreateExternal(
            applicationPackageName(),
            "letypetype",
            Encoding.ASCII.GetBytes("param"));

相反,您的活动是由于 Android 应用程序记录 (AAR) 而启动的。由于没有匹配的 NFC 意图过滤器,Android 不知道您的 Activity 支持 NFC,因此不会将标签(及其 NDEF 消息)传递给您的 Activity。

为了在您的活动中接收 NDEF 消息/标签句柄,您需要更新意图过滤器以匹配外部记录。如果应用程序的包名称是“com.example”,那么您的意图过滤器需要如下所示:

[IntentFilter(new[] { NfcAdapter.ActionNdefDiscovered },
      Categories = new[] { Intent.CategoryDefault },
      DataScheme = "vnd.android.nfc",
      DataPathPrefix = "/com.example:letypetype",
      DataHost = "ext")]

请注意,域字段和前导斜杠需要包含在 DataPathPrefix 属性中。

另请注意(虽然这通常有效)根据 NFC 论坛的外部类型规范,Java/Android 包名称不是有效的域名。相反,您应该使用真实域名(例如“example.com”)。

最后:不要忘记在清单中请求 NFC 权限:

<uses-permission android:name="android.permission.NFC" />

【讨论】:

    【解决方案2】:

    如果我很好理解这个问题(如果没有更正我),问题是从标签中读取数据吗?尝试通过EnableForegroundDispatchOnNewIntent 进行第一次简单阅读,然后根据您的需要进行定制。

    private NfcAdapter mNfcAdapter;
    

    在 Activity OnCreate 中

      mNfcAdapter = NfcAdapter.GetDefaultAdapter(this);
    

    在 Activity OnResume 中

    if (mNfcAdapter != null)
        {
          var tagDetected = new IntentFilter(NfcAdapter.ActionTagDiscovered);//or try other Action type
          var filters = new[] { tagDetected };
          var intent = new Intent(this, GetType()).AddFlags(ActivityFlags.SingleTop);
          var pendingIntent = PendingIntent.GetActivity(this, 0, intent, 0);
          mNfcAdapter.EnableForegroundDispatch(this, pendingIntent, filters, null);
        }
    

    然后重写

        protected override void OnNewIntent(Intent intent)
    {
      object obj = intent.GetParcelableExtra(NfcAdapter.ExtraTag);
      if (obj != null && obj is Tag)
      {
        Tag t = (Tag)obj;
        byte[] id = t.GetId();
        string[] techList = t.GetTechList();
        int con = t.DescribeContents();
        string objName = t.ToString();
      }
    }
    

    不要忘记在 OnPause 中

    if (mNfcAdapter != null) mNfcAdapter.DisableForegroundDispatch(this);
    

    和 OnDestroy

    if (mNfcAdapter != null)
        {
          mNfcAdapter.Dispose();
          mNfcAdapter = null;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-08
      • 1970-01-01
      • 1970-01-01
      • 2019-04-19
      • 2017-07-27
      • 2019-11-14
      • 2020-06-21
      • 1970-01-01
      相关资源
      最近更新 更多