我的应用在前台和后台都使用NFC读取功能。为了获取用户信息,我在活动中使用CountDownTimer(120 * 1000, 5 * 1000)方法,并使用onTick(long l)方法每5秒检查一次NFC状态。有时(据我的客户说,在Android 4.2.2上发生过,但我没有遇到过),NfcAdapter.getDefaultAdapter(BaseActivity.this)会返回null,但后台和前台的NFC读取仍然可以正常工作!关闭和开启并不能解决问题,只有重新安装才能帮助解决。
通过清单文件进行后台读取:
<activity
android:name=".activity.NfcReaderActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
</activity>
通过意图读取 FG:
IntentFilter ndef = new IntentFilter();
ndef.addAction(NfcAdapter.ACTION_TECH_DISCOVERED);
ndef.addCategory(Intent.CATEGORY_DEFAULT);
try {
ndef.addDataType("*/*");
} catch (IntentFilter.MalformedMimeTypeException e) {
throw new RuntimeException("fail", e);
}
mNfcAdapter = NfcAdapter.getDefaultAdapter(this.mActivity);
mNfcPendingIntent = PendingIntent.getActivity(
this.mActivity, 0,
new Intent(this.mActivity, this.mActivity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
0
);
mNfcFilters = new IntentFilter[] {
ndef
};
mNfcTechLists = new String[][] { new String[] {
// White solid cards
NfcA.class.getName()
} };
if (mNfcAdapter != null) {
mNfcAdapter.enableForegroundDispatch(
mActivity,
mNfcPendingIntent,
mNfcFilters,
mNfcTechLists
);
}
看起来NfcAdapter被卡住或冻结了。有人有相同的经历吗?问题可能出在哪里?
经过一些测试,我有了新的观察结果。这只在重启后发生。我以为我的应用程序启动了两次,并且存在一些线程死锁,但事实并非如此。如果我在onCreate方法中调用CountDownTimer(带有一些延迟(3秒或更多)),这样做就可以使getDefaultAdapter不为空。如果启动延迟太低(2秒或更少),我会在日志中找到此消息:“E / NFC:无法检索NFC服务”,然后getDefaultAdapter返回null,直到我重新安装我的应用程序。
因此,在执行CountDownTimer之前设置短暂延迟(也许Timer.schedule(...,delay,interval)会更好)是一种临时解决方案。但如果有人知道什么是最佳解决方案,请告诉我。
NfcAdapter.getDefaultAdapter(this)
返回 null 的?你在应用程序的哪个位置调用了上述代码?当你调用该代码时,mActivity
是前台活动吗?你请求了 NFC 权限吗? - Michael Rolandif (mNfcAdapter != null) { mNfcAdapter.enableForegroundDispatch [...]
部分是在mNfcAdapter = NfcAdapter.getDefaultAdapter(this.mActivity);
之后立即调用的,还是它们来自不同的方法?你的活动是否在其中某个时刻被重新创建了? - Michael Roland