具有前台调度功能的 NFC Action_Tech_Discovered 无法捕获 Mifare 1k 卡
NFC Action_Tech_Discovered with foreground dispatch won't catch Mifare 1k card
我正在使用 Xamarin 在 C# 中编写代码,并尝试通过 NFC 扫描 MIFARE Classic 1K 卡。
m1card_test 的 intent-filter 工作正常。但是我不想select哪个Activity我要开始。所以我正在尝试使用前台调度。
这是我的部分代码 (C#):
OnCreate
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);
恢复
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";
}
}
}
TECH_DISCOVERED
意图过滤器没有与之关联的数据类型(MIME 类型)。因此,您需要删除行
ndefDetected.AddDataType("*/*");
此外,我不太确定 typeof(Android.Nfc.Tech.MifareClassic).FullName
是否解析为标签技术的正确名称(完整的 Java class 名称)。因此,您应该对该字符串进行硬编码(就像您在 tech-filter XML 文件中所做的那样):
techLists = new string[][] { new string[] {
"android.nfc.tech.NfcA",
"android.nfc.tech.MifareClassic"
}};
最后,由于 MifareClassic 标签技术总是暗示 NfcA,您可以安全地将技术过滤器减少到
techLists = new string[][] { new string[] {
"android.nfc.tech.MifareClassic"
}};
我正在使用 Xamarin 在 C# 中编写代码,并尝试通过 NFC 扫描 MIFARE Classic 1K 卡。
m1card_test 的 intent-filter 工作正常。但是我不想select哪个Activity我要开始。所以我正在尝试使用前台调度。
这是我的部分代码 (C#):
OnCreate
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);
恢复
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";
}
}
}
TECH_DISCOVERED
意图过滤器没有与之关联的数据类型(MIME 类型)。因此,您需要删除行
ndefDetected.AddDataType("*/*");
此外,我不太确定 typeof(Android.Nfc.Tech.MifareClassic).FullName
是否解析为标签技术的正确名称(完整的 Java class 名称)。因此,您应该对该字符串进行硬编码(就像您在 tech-filter XML 文件中所做的那样):
techLists = new string[][] { new string[] {
"android.nfc.tech.NfcA",
"android.nfc.tech.MifareClassic"
}};
最后,由于 MifareClassic 标签技术总是暗示 NfcA,您可以安全地将技术过滤器减少到
techLists = new string[][] { new string[] {
"android.nfc.tech.MifareClassic"
}};