Можно ли запустить приложение при сканировании NFC-метки?


У меня есть NFC-метка. Я хочу написать приложение для Android, которое автоматически запускается и получает данные от NFC, когда NFC-метка сканируется с помощью телефона.

Это должно работать при условии, что устройство имеет NFC включен и что нет никаких других приложений, работающих на телефоне. Я нашел несколько приложений, которые могут запускать другое приложение, но мое приложение должно работать без такого дополнительного приложения, работающего в фоновом режиме.

Есть ли способ решить эту проблему? это задание?

2 5

2 ответа:

Чтобы приложение (фактически activity) запустилось после сканирования тега, необходимо добавить соответствующий фильтр намерений в манифест приложения.

Если вы хотите запустить приложение только для любого тега, вы можете использовать фильтр намерений 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>
Этот фильтр намерений требует дополнительного файла ресурсов 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 подразумевает либо NfcA, либо NfcB,
  • MifareClassic подразумевает NfcA,
  • MifareUltralight подразумевает NfcA, и
  • Ndef / NdefFormatable подразумевают либо то, либо другое NfcA, NfcB, NfcF, или NfcV.

Вышеуказанный фильтр намерений будет срабатывать, если нет другого приложения, которое имеет более подходящий фильтр намерений. Лучшим совпадением будет совпадение типа данных, используемого в теге. Так, например, если ваш тег содержит URL-адрес (инкапсулированный в сообщение NDEF), приложение, запускающее URL-адреса, получит приоритет над вашим приложением. Если вы знаете типы данных, используемые в тегах, вы также можете добавить фильтр для этих типов данных. Например, для сопоставления любого URL-адреса" http:// "и" https:// " можно использовать:

<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-типом "приложение/донгов.ком.пример", вы могли бы использовать:

<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>

Вы даже можете объединить несколько фильтров намерений для одного действия:

<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-filter>
    <action android:name="android.nfc.action.TAG_DISCOVERED" />
    <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

Однако обычно вы не используете этот фильтр намерений в манифесте. Он предназначен только для резервного копирования и будет срабатывать только в том случае, если нет другого приложения, запускающего технологию или данные отсканированного тега. Таким образом, нет необходимости добавлять этот intent-фильтр вашего уже триггера для вышеупомянутого TECH_DISCOVERED intent filter.

Добавьте следующий тег intent-filter к вашему основному тегу activity в файле AndroidManifest.xml.

<!-- main activity -->
<activity ...>
    ...
    <intent-filter>
        <action android-name="android.nfc.action.TAG_DISCOVERED" />
        <category android-name="android.nfc.category.DEFAULT" />
    </intent-filter>
    ...
</activity>
Теперь, когда вы нажмете NFC-метку на свой телефон, ваше приложение будет вызвано и запущено.