我正在处理Android NFC设备,只是尝试读取标签并从活动中接收信息。标签属于MifareUltralight
类型。只需在Android docs中阅读该案例,我首先必须注册Intent以在清单文件中启动我的Activity,然后我将能够从中接收NFC Intent。这就是我的清单文件的样子:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mycompany.android">
<uses-feature android:name="android.hardware.nfc" android:required="false" />
<uses-permission android:name="android.permission.NFC" />
<application
android:allowBackup="true"
android:label="Test">
<activity
android:name="com.mycompany.android.activities.NfcTestActivity"
android:launchMode="singleTop"
android:label="Test">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
我将nfc功能设置为不需要,因为这对我的应用程序不起作用。关于NFC技术过滤器,这是我的nfc_tech_filter.xml文件:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.IsoDep</tech>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.NfcB</tech>
<tech>android.nfc.tech.NfcF</tech>
<tech>android.nfc.tech.NfcV</tech>
<tech>android.nfc.tech.Ndef</tech>
<tech>android.nfc.tech.NdefFormatable</tech>
<tech>android.nfc.tech.MifareClassic</tech>
<tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
</resources>
嗯,配置完成后,似乎我的NfcTestActivity
应该能够接收NFC意图。这就是我实现它的方式:
public class NfcTestActivity extends Activity {
final String TAG = NfcTestActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "IntentAction (onCreate): " + getIntent().getAction());
NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
NfcAdapter adapter = manager.getDefaultAdapter();
if (adapter != null && adapter.isEnabled()) {
Log.i(TAG, "NFC adapter is enabled");
} else {
Log.i(TAG, "NFC adapter is disabled");
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.i(TAG, "IntentAction (onNewIntent): " + getIntent().getAction());
}
@Override
public void onResume() {
super.onResume();
Log.i(TAG, "IntentAction (onResume): " + getIntent().getAction());
}
}
当我启动应用程序时,我得到以下日志:
05-28 10:41:52.044 31182-31182/com.mycompany.android I/NfcTestActivity? IntentAction (onCreate): android.intent.action.MAIN
05-28 10:41:52.054 31182-31182/com.mycompany.android I/NfcTestActivity? NFC adapter is enabled
05-28 10:41:52.054 31182-31182/com.mycompany.android I/NfcTestActivity? IntentAction (onResume): android.intent.action.MAIN
稍后,我读了我的标签,显示了这个日志:
05-28 10:41:59.661 31182-31182/com.mycompany.android I/NfcTestActivity? IntentAction (onResume): android.intent.action.MAIN
这意味着在读取标记时会调用Activity#onResume
方法,正如文档所述,但是,我在这里得到的是android.intent.action.MAIN
而不是NFC ACTION_NDEF_DISCOVERED
, ACTION_TECH_DISCOVERED
或ACTION_TAG_DISCOVERED
)。
此外,作为线索,当我从我的活动声明中删除此代码片段时,我在阅读标记时没有显示onResume
日志:
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>
所以似乎TAG_DISCOVERED
动作是以某种方式定义的,而不是其他动作,但是我无法从活动中正确地捕捉它。
有人知道吗?
答案 0 :(得分:2)
经过一番头脑风暴,我意识到默认android.nfc.action.TAG_DISCOVERED
代替android.nfc.action.NDEF_DISCOVERED
为我做了工作:
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
当我的标签类型被TAG_DISCOVERED
覆盖时,我仍然不知道为什么我应该使用TECH_DISCOVERED
,这是最好使用的。无论如何,这是我后来用来获取标签ID的代码:
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "onResume: action-"+getIntent().getAction());
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(getIntent().getAction())) {
Tag tag = getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG);
String tagId = bytesToHexString(tag.getId());
Log.i(TAG, "NFC tag: " + tagId);
}
}
另见:
答案 1 :(得分:1)
首先,您的nfc_tech_filter.xml不正确。过滤器
<tech-list>
<tech>android.nfc.tech.IsoDep</tech>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.NfcB</tech>
<tech>android.nfc.tech.NfcF</tech>
<tech>android.nfc.tech.NfcV</tech>
<tech>android.nfc.tech.Ndef</tech>
<tech>android.nfc.tech.NdefFormatable</tech>
<tech>android.nfc.tech.MifareClassic</tech>
<tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
表示您要匹配IsoDep
和 NfcA
和 NfcB
和 NfcF
和 ...但是,NfcX
标记技术相互排斥(Ndef
和NdefFormatable
),所以过滤器不匹配任何标签。你真正想要的是这样的:
<tech-list>
<tech>android.nfc.tech.NfcA</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcB</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcF</tech>
</tech-list>
<tech-list>
<tech>android.nfc.tech.NfcV</tech>
</tech-list>
哪个匹配任何标记技术。或者,如果您只想匹配MifareUltralight
,则可以使用:
<tech-list>
<tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
使用TAG_DISCOVERED意图过滤器通常不是一个好主意。它仅仅意味着后备以及与第一个Android NFC API的向后兼容性。
当您希望在应用处于前台时接收NFC意图时,通常最好注册foreground dispatch system,而不是依赖应用程序清单中的意图过滤器。这将确保您的活动收到活动,并且即使其他应用也有针对这些活动的意图过滤器,也不会显示活动选择器。