扫描 NFC 标签时是否可以启动应用程序?

Is it possible to launch an app when an NFC tag is scanned?

我有一个 NFC 标签。我想编写一个 Android 应用程序,它在使用 phone.

扫描 NFC 标签时自动启动并从 NFC 获取数据

假设设备已打开 NFC 并且 phone 上没有其他应用程序 运行,这应该可以工作。我找到了一些可以启动另一个应用程序的应用程序,但我的应用程序应该可以在后台没有这样的附加应用程序的情况下工作 运行。

有什么办法可以解决这个任务吗?

将以下 intent-filter 添加到 AndroidManifest.xml 文件中的主要 activity 标记。

<!-- main activity -->
<activity ...>
    ...
    <intent-filter>
        <action android-name="android.nfc.action.TAG_DISCOVERED" />
        <category android-name="android.nfc.category.DEFAULT" />
    </intent-filter>
    ...
</activity>

现在,当您将 NFC 标签轻触 phone 时,您的应用程序将被调用并且 运行。

为了让您的应用程序(实际上是 activity)在扫描标签时启动,您需要在应用程序清单中添加适当的 Intent 过滤器。

如果您只想为任何标签启动您的应用程序,TECH_DISCOVERED 意图过滤器就是您想要使用的:

<activity ...>
    <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" />
</activity>

此 Intent 过滤器需要一个额外的 XML 资源文件来定义您的应用程序应侦听的标记技术(请注意 <meta-data ... /> 标记 之外意图过滤器)。可用技术是命名空间 android.nfc.tech.* 中的技术,目前:

  • android.nfc.tech.IsoDep
  • android.nfc.tech.MifareClassic
  • android.nfc.tech.MifareUltralight
  • android.nfc.tech.Ndef
  • android.nfc.tech.NdefFormatable
  • android.nfc.tech.NfcA
  • android.nfc.tech.NfcB
  • android.nfc.tech.NfcBarcode
  • android.nfc.tech.NfcF
  • android.nfc.tech.NfcV

要发现任何标签,您可以像这样创建一个 XML 文件(将文件创建为 xml/nfc_tech_filter.xml):

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <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.NfcBarcode</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcF</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcV</tech>
    </tech-list>
</resources>

请注意,您不一定需要将其他技术包括在内

  • IsoDep 表示 NfcANfcB,
  • MifareClassic 表示 NfcA,
  • MifareUltralight 意味着 NfcA
  • Ndef / NdefFormatable 表示 NfcANfcBNfcFNfcV.

如果没有其他应用具有更好匹配的 Intent 过滤器,则会触发上述 Intent 过滤器。更好的匹配是与标签上使用的数据类型的匹配。因此,例如,如果您的标签包含 URL(封装在 NDEF 消息中),则在 URL 上触发的应用将优先于您的应用。如果您知道标签上使用的数据类型,您还可以为这些数据类型添加过滤器。例如,要匹配任何 "http://" 和 "https://" URL,您可以使用:

<activity ...>
    <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>
</activity>

同样,如果您的标签包含 MIME 类型 "application/vnd.com.example",您可以使用:

<activity ...>
    <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="application/vnd.com.example" />
    </intent-filter>
</activity>

您甚至可以将多个 Intent 过滤器合并为一个 activity:

<activity ...>
    <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.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.NDEF_DISCOVERED" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="application/vnd.com.example" />
    </intent-filter>
</activity>

最后,还有一个与 NFC 相关的 intent 过滤器:

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

但是,您通常不会在清单中使用此 Intent 过滤器。它仅作为后备,并且只有在没有其他应用程序触发该技术或扫描标签的数据时才会被触发。因此,无需添加您已经触发上述 TECH_DISCOVERED 意图过滤器的意图过滤器。