Android NFC 在启动应用程序时传递单个参数

标签 android tags nfc ndef android-applicationrecord

我想启动一个使用 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 中,您可以处理该 ND​​EF 消息:

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/

相关文章:

android - 切换 textColor 不起作用

css - 拆分 Twitter Bootstrap 标签

iphone - 如何用 viewWithTag 隐藏 UILabel?

java - 读取和写入 NFC

java - 如何使用数字获取货币对象

android - MediaPlayer 无法解析方法创建

css - 如何根据图像更改文章的大小?

java - NFC (Android Studio) - 如何通过单击按钮启用/禁用 NFC

android - 读取 NFC 标签上的 "payload"数据?

android - 集成 Localytics - 项目编号