在 Windows Phone 和 Android 上有额外数据的跨平台启动记录

Cross platform launch records with extra data on Windows Phone and Android

是否可以创建跨平台 NDEF 消息以在 Android Windows Phone 上启动应用程序将附加数据传递给应用程序?

我想做什么:

我在 Android 和 Windows Phone 上安装了一个应用程序。应该可以使用 NFC 标签启动应用程序,我需要将来自标签(任何字符串)的额外数据传递到我的应用程序。

为了使用 NFC 标签启动应用程序,我创建了一个 Windows Phone LaunchApp 记录和一个 Android 应用程序记录 (AAR) 并将它们存储在标签上。

Windows Phone 需要 LaunchApp 记录成为 NDEF 消息中的第一个 NDEF 记录。所以NDEF报文的顺序是:

  1. Windows Phone LaunchApp 记录
  2. Android申请记录

要传递额外的数据,我可以在 Windows Phone LaunchApp 记录中放置一些参数,这样就可以正常工作。但是不可能向 Android 应用程序记录添加一些额外的数据。

我试图将第三个 NDEF 记录添加到消息中,其中包含 Android 的额外数据。我创建了一个外部记录并将过滤器添加到我的清单中。

<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="/myapp.com:customtype"/>
</intent-filter>

问题在于 NDEF 消息的顺序:

Windows Phone 记录必须是消息中的第一个记录,但附加记录也必须是第一个在 Android 上接收意图的记录。

NDEF 消息:

  1. 外部和 LaunchApp 记录
  2. Android申请记录

如果我有以下记录序列,我会在 Android 上收到额外的数据并且应用程序会启动,但是我无法在 Windows Phone 上打开应用程序,因为记录是第二个

  1. 外部记录
  2. Windows Phone LaunchApp
  3. Android申请记录

这个问题有什么解决办法吗?我错过了什么吗?

这里的问题如下:

  • Windows 要求 LaunchApp 记录是标签上 NDEF 消息的第一条记录。
  • Android 只会将发现的 NDEF message/NFC 标记对象传递给应用程序,前提是该应用程序具有针对 NDEF 消息的第一条记录的 Intent 过滤器。
  • LaunchApp 记录不是有效的 NDEF 记录(因为其类型名称格式指示绝对 URI 记录但其类型 ("windows.com/LaunchApp") 不是 有效的绝对URI).

因此,您无法轻易地将记录(LaunchApp 记录)与 Android 上的意图过滤器相匹配(URI 意图过滤器按照顺序方案匹配 -> 主机 -> 路径,但因为有没有方案,您无法匹配 host/path).

诀窍是使用一个意图过滤器来匹配任何具有空方案的 URI:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="" />
</intent-filter>

现在,如果您的 NDEF 消息是

LaunchApp record | [optional other records] | Android Application record

您的 Android 应用程序将被调用,NDEF message/tag 对象将在 NDEF_DISCOVERED 意图中传递给具有上述意图过滤器的 activity。

不幸的是,对于包含没有方案的相对 URI/any URI 并且不包含另一个应用程序的 AAR 的任何其他标签,也会触发该 intent 过滤器。


更新

创建我的测试 LaunchApp 记录标签的代码:

final Ndef ndefTag = Ndef.get(tag);

if (ndefTag != null) {
    try {
        ndefTag.connect();
        ndefTag.writeNdefMessage(new NdefMessage(new NdefRecord[] {
                    new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI,
                                   "windows.com/LaunchApp".getBytes("US-ASCII"),
                                   null,
                                   "la:uz".getBytes("US-ASCII")),
                    NdefRecord.createApplicationRecord("at.mroland.launchrecordtest")
        }));
    } catch (Exception e) {
    } finally {
        try {
            ndefTag.close();
        } catch (Exception ee) {
        }
    }
}

接收应用的清单:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="at.mroland.launchrecordtest"
          android:versionCode="1"
          android:versionName="1.0">
    <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.NFC" />
    <uses-feature android:name="android.hardware.nfc" android:required="true" />
    <application android:label="@string/app_name"
                 android:icon="@drawable/ic_launcher">
        <activity android:name=".LaunchRecordTest"
                  android:label="LaunchRecordTest">
            <intent-filter>
                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="" />
            </intent-filter>
        </activity>
    </application>
</manifest>

onCreate() 中,我使用 getIntent() 检索意图。