Android NFC передает один параметр при запуске приложения

Я хотел бы запустить приложение, используя тег NFC. Я получил эту часть, работающую с использованием записи приложения для Android (AAR), как описано в разделе Запуск приложения Android из NFC-тега с дополнительными данными или с помощью NDEF_DISCOVERED / TECH_DISCOVERED Фильтры намерений. Но как передать данные из тега NFC (например, некоторый текст) в мою деятельность после ее запуска через событие NFC?

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

Более того, кажется, что эти механизмы позволяют приложению читать тег после его запуска тегом. Другими словами, я обеспокоен тем, что, если кто-то нажмет на тег позже, когда приложение уже открыто, этот тег будет прочитан снова (что я не хочу).

Во-вторых, как мне создать такое сообщение NDEF?

1 ответ

Решение

Android автоматически прочитает сообщение NDEF тега NFC и обработает его, чтобы

  • начать зарегистрированную деятельность на основе первой записи NDEF, и
  • запускать приложения на основе записей приложений Android (AAR) в любом месте сообщения NDEF.

Чтобы начать свою деятельность и заставить Android передавать предварительно прочитанное сообщение NDEF, вы можете использовать NDEF_DISCOVERED фильтр намерений:

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

Затем из вашей деятельности вы можете обработать это сообщение 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

        }
    }
}

Обратите внимание, что onResume() запускается всякий раз, когда ваша деятельность становится основной деятельностью. Следовательно, он может быть запущен несколько раз для одного и того же тега. Поэтому вы можете использовать другой метод жизненного цикла или принять некоторые меры предосторожности, чтобы не анализировать сообщение несколько раз.

Если вы хотите отбросить все дальнейшие события NFC, как только ваша активность будет открыта, вы можете следовать подходу, который я описал в ответ на приложение Android, чтобы включить NFC только для одной операции. Следовательно, вы должны зарегистрироваться для отправки на передний план (которая дает приоритет вашей активности при получении событий 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
    }
}

Наконец, чтобы создать сообщение NDEF для вашего тега NFC, вы должны сделать что-то вроде этого:

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")
)
Другие вопросы по тегам