【问题标题】:NFC Action_Tech_Discovered with foreground dispatch won't catch Mifare 1k cardNFC Action_Tech_Discovered 与前台调度不会捕获 Mifare 1k 卡
【发布时间】:2016-07-25 17:20:02
【问题描述】:

我正在使用 Xamarin 使用 C# 进行编码,并尝试通过 NFC 扫描 MIFARE Classic 1K 卡。

m1card_test 的意图过滤器工作正常。但我不想选择要开始的活动。所以我正在尝试使用前台调度。

这是我的代码(C#)的一部分:

  • 创建时

    Intent Myintent = new Intent(this, GetType());
    Myintent.AddFlags(ActivityFlags.SingleTop);
    mPendingIntent = PendingIntent.GetActivity(this, 0, Myintent, 0);
    
    ndefDetected = new IntentFilter(NfcAdapter.ActionTechDiscovered);
    ndefDetected.AddDataType("*/*");
    
    intentF = new IntentFilter[] { ndefDetected };
    techLists = new string[][] {new string[] {
        typeof(Android.Nfc.Tech.NfcA).FullName,
        typeof(Android.Nfc.Tech.MifareClassic).FullName}
    };
    
  • 暂停

    NfcManager manager = (NfcManager)GetSystemService(NfcService);
    manager.DefaultAdapter.DisableForegroundDispatch(this);
    
  • OnResume

    NfcManager manager = (NfcManager)GetSystemService(NfcService);
    manager.DefaultAdapter.EnableForegroundDispatch(this,mPendingIntent,intentF,techLists);
    

不幸的是,前台调度不起作用(即它没有拾取标签)。

如果我把对EnableForegroundDispatch()的电话改为

manager.DefaultAdapter.EnableForegroundDispatch(this,mPendingIntent,null,null);

前台调度工作正常。但它会拾取所有标签,而不仅仅是 MIFARE Classic,我得到一个意图 Action_Tag_Discovered 而不是 Action_Tech_Discovered。

如何在前台调度系统中使用 Action_Tech_Discovered?

我错过了什么吗?


tech_list.xml:

<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
  <tech-list>
    <tech>android.nfc.tech.NfcA</tech>
    <tech>android.nfc.tech.MifareClassic</tech>
  </tech-list>  
</resources>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="m1card_test.m1card_test" android:versionCode="1" android:versionName="1.0">
  <uses-sdk android:minSdkVersion="16" />
  <application android:label="m1card_test"></application>
  <uses-permission android:name="android.permission.NFC" />
</manifest>

我的 C# 代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Nfc;

namespace m1card_test
{
    [Activity(Label = "m1_read",  Icon = "@drawable/icon", LaunchMode = Android.Content.PM.LaunchMode.SingleTask)]
    [IntentFilter(
    new[] {NfcAdapter.ActionTechDiscovered}, 
    Categories = new[] {Intent.CategoryDefault,})]
    [MetaData("android.nfc.action.TECH_DISCOVERED", Resource = "@xml/tech_list")]

    public class m1_read : Activity
    {
        TextView mTV;
        PendingIntent mPendingIntent;
        IntentFilter ndefDetected;
        IntentFilter[] intentF;
        String[][] techLists;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            SetContentView(Resource.Layout.m1_read);

            Intent Myintent = new Intent(this, GetType());
            Myintent.AddFlags(ActivityFlags.SingleTop);
            mPendingIntent = PendingIntent.GetActivity(this, 0, Myintent, 0);

            ndefDetected = new IntentFilter(NfcAdapter.ActionTechDiscovered);
            ndefDetected.AddDataType("*/*");

            intentF = new IntentFilter[] { ndefDetected };
            techLists = new string[][] {new string[] {
                typeof(Android.Nfc.Tech.NfcA).FullName,
                typeof(Android.Nfc.Tech.MifareClassic).FullName}
            };

            Button button = FindViewById<Button>(Resource.Id.Back_Button);
            mTV = FindViewById<TextView>(Resource.Id.textview);
            button.Click += delegate
            {
                Intent main_intent = new Intent(this, typeof(MainActivity));
                this.StartActivity(main_intent);
                Finish();
            };

        }
        protected override void OnPause()
        {
            base.OnPause();
            NfcManager manager = (NfcManager)GetSystemService(NfcService);
            manager.DefaultAdapter.DisableForegroundDispatch(this);
        }

        protected override void OnResume()
        {
            base.OnResume();
            NfcManager manager = (NfcManager)GetSystemService(NfcService);
            manager.DefaultAdapter.EnableForegroundDispatch(this, mPendingIntent,intentF,techLists);
        }

        protected override void OnNewIntent(Intent intent)
        {
            base.OnNewIntent(intent);
            mTV.Text = "OnNewIntent";
        }
    }
}

【问题讨论】:

    标签: c# android xamarin nfc intentfilter


    【解决方案1】:

    TECH_DISCOVERED 意图过滤器没有与之关联的数据类型(MIME 类型)。因此,您需要删除该行

    ndefDetected.AddDataType("*/*");
    

    此外,我不太确定typeof(Android.Nfc.Tech.MifareClassic).FullName 是否解析为标签技术的正确名称(完整的Java 类名)。因此,您可能应该对该字符串进行硬编码(就像在 tech-filter XML 文件中所做的那样):

    techLists = new string[][] { new string[] {
        "android.nfc.tech.NfcA",
        "android.nfc.tech.MifareClassic"
    }};
    

    最后,由于 MifareClassic 标签技术总是暗示着 NfcA,您可以放心地将 tech-filter 减少到只是

    techLists = new string[][] { new string[] {
        "android.nfc.tech.MifareClassic"
    }};
    

    【讨论】:

    • 首先感谢您的编辑。在我删除数据类型并使用硬代码后,它可以工作了!我是新手,非常感谢您的再次容忍和帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    • 2021-09-08
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    相关资源
    最近更新 更多