我想启动一个使用 NFC 标签的应用程序。如 Start Android application from NFC-tag with extra data 中所述,我使用 android 应用程序记录 (AAR) 使该部分工作。 或使用 NDEF_DISCOVERED
/TECH_DISCOVERED
Intent 过滤器。但是,如何在通过 NFC 事件启动 Activity 时将数据从 NFC 标签(例如一些文本)传递到 Activity?
我已通读 NFC Basics ,但据我所知,它似乎想要实现一种读取标签的机制,当我真的不想在标签打开应用程序后重新读取标签,而是我只想传递数据同时。
此外,这些机制似乎允许应用程序在标签启动后读取标签。换句话说,我担心如果有人稍后在应用程序已经打开时点击该标签,该标签将被再次读取(这是我不想要的)。
其次,如何创建这样的 NDEF 消息?
最佳答案
Android 会自动读取 NFC 标签的 NDEF 消息并进行处理,以便
- 根据第一个 NDEF 记录开始注册 Activity ,并且
- 根据 NDEF 消息中任意位置的 Android 应用程序记录 (AAR) 启动应用。
为了启动您的 Activity 并让 Android 传递预读 NDEF 消息,您可以使用 NDEF_DISCOVERED
Intent 过滤器:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="vnd.android.nfc"
android:host="ext"
android:pathPrefix="/example.com:mycustomtype"/>
</intent-filter>
然后在您的 Activity 中,您可以处理该 NDEF 消息:
public void onResume() {
super.onResume();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
NdefMessage[] msgs = null;
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; ++i) {
msgs[i] = (NdefMessage)rawMsgs[i];
}
}
if ((msgs != null) && (msgs.length > 0)) {
NdefRecord[] records = msgs[0].getRecords();
NdefRecord firstRecord = records[0];
byte[] payloadData = firstRecord.getPayload();
// do something with the payload (data passed through your NDEF record)
// or process remaining NDEF message
}
}
}
请注意,只要您的 Activity 成为前台 Activity ,就会运行 onResume()
。因此,它可能会针对同一个标签运行多次。因此,您可以使用其他生命周期方法或采取一些预防措施,以免多次解析消息。
如果您想删除所有进一步的 NFC 事件,一旦您的 Activity 打开,您可以按照我在回复 Android app enable NFC only for one Activity 时描述的方法进行操作.因此,您将注册前台调度(这使您的 Activity 优先接收 NFC 事件,然后您可以简单地删除这些事件。
public void onResume() {
super.onResume();
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
}
public void onPause() {
super.onPause();
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.disableForegroundDispatch(this);
}
public void onNewIntent(Intent intent) {
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
// drop NFC events
}
}
最后,要为您的 NFC 标签创建 NDEF 消息,您可以执行如下操作:
byte[] payload = ... // generate your data payload
NdefMessage msg = new NdefMessage(
NdefRecord.createExternal("example.com", "mycustomtype", payload)
)
如果你想确保只有你的应用程序是通过这个标签启动的(或者如果你的应用程序没有安装 Play Store 是打开的),你也可以添加一个 AAR:
NdefMessage msg = new NdefMessage(
NdefRecord.createExternal("example.com", "mycustomtype", payload),
NdefRecord.createApplicationRecord("com.example.your.app.package")
)
关于Android NFC 在启动应用程序时传递单个参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30837403/