首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NFC - Xamarin - C#上的IntentFilter

NFC - Xamarin - C#上的IntentFilter
EN

Stack Overflow用户
提问于 2015-10-29 19:29:23
回答 2查看 2.4K关注 0票数 4

上下文是:Framework4.5,Xamarin.Android v5.0

我想使用NFC技术为我的应用程序用户实现快捷方式。我希望用户扫描NFC标签,这样他们只需为预定义的方案赋值即可。

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

代码语言:javascript
复制
    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中:

代码语言:javascript
复制
<uses-feature android:name="android.hardware.nfc" android:required="true" />

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

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

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

代码语言:javascript
复制
    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];
                }
            }
        }
    }

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

EN

回答 2

Stack Overflow用户

发布于 2015-11-07 18:21:47

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

代码语言:javascript
复制
[IntentFilter(new[] { NfcAdapter.ActionNdefDiscovered },
      Categories = new[] { Intent.CategoryDefault },
      DataScheme = "vnd.android.nfc",
      DataPathPrefix = "letypetype",
      DataHost = "ext")]

是否与您使用以下命令创建的外部记录不匹配

代码语言:javascript
复制
NdefRecord external = NdefRecord.CreateExternal(
            applicationPackageName(),
            "letypetype",
            Encoding.ASCII.GetBytes("param"));

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

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

代码语言:javascript
复制
[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权限:

代码语言:javascript
复制
<uses-permission android:name="android.permission.NFC" />
票数 1
EN

Stack Overflow用户

发布于 2015-10-30 15:12:58

如果我很好地理解了这个问题(如果不是,请纠正我),问题是从标签读取数据?尝试通过EnableForegroundDispatchOnNewIntent进行第一次简单阅读,然后根据需要进行定制。

代码语言:javascript
复制
private NfcAdapter mNfcAdapter;

在活动OnCreate中

代码语言:javascript
复制
  mNfcAdapter = NfcAdapter.GetDefaultAdapter(this);

在活动OnResume中

代码语言:javascript
复制
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);
    }

并重写

代码语言:javascript
复制
    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中使用

代码语言:javascript
复制
if (mNfcAdapter != null) mNfcAdapter.DisableForegroundDispatch(this);

和OnDestroy

代码语言:javascript
复制
if (mNfcAdapter != null)
    {
      mNfcAdapter.Dispose();
      mNfcAdapter = null;
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33413007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档