Отображать тостовое сообщение при обнаружении метки NFC - PullRequest
0 голосов
/ 09 мая 2018

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

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity)

    val nfcAdapter = NfcAdapter.getDefaultAdapter(this)

}

override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)

    Toast.makeText(applicationContext, "NFC Tag Detected", Toast.LENGTH_LONG).show()

}

И в моем манифесте у меня есть это:

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

Я тестирую это на Samsung Galaxy S6 и S7. Когда я соединяю их во время выполнения действия на одном из них, я хочу видеть всплывающее сообщение, но пока ничего не отображается. Мне не нужно читать тег, мне все равно, какой это тип тега, мне нужно только знать, что обнаружен тег.

1 Ответ

0 голосов
/ 18 мая 2018

Фильтры намерений, которые вы зарегистрировали в манифесте приложения, не имеют особого смысла.

  • android.nfc.action.TAG_DISCOVERED (при использовании в манифесте) - это всего лишь резервный механизм для отлова любых тегов NFC, которые не обрабатываются другими приложениями.
  • android.nfc.action.NDEF_DISCOVERED также требуется спецификация типа данных для фактического перехвата тегов NFC, которые содержат специфических записей NDEF. Ни один тег не будет соответствовать без него.
  • android.nfc.action.TECH_DISCOVERED также нужна технология, чтобы поймать определенные технологии тегов. Ни один тег не будет соответствовать без него.

Более того, вы, вероятно, захотите поместить каждое намеренное действие в отдельный <intent-filter>, чтобы лучше контролировать категории, типы данных и т. Д.

Однако, так как вы заинтересованы только в получении событий обнаружения NFC, когда ваша деятельность находится на переднем плане, у вас есть лучшие и (несколько) более надежные варианты обнаружения тегов: система диспетчеризации на переднем плане и API режима считывателя.

Вы хотите выбрать один из них:

  • Если вы работаете на Android 4.4+ и заинтересованы только в обнаружении других тегов (и устройств no peer-to-peer). Я настоятельно рекомендую вам использовать API режима чтения, поскольку он дает вам намного лучший контроль над тем, какие теги вы хотите обнаружить и как эти теги должны обрабатываться. Кроме того, если вы хотите иметь возможность обнаруживать и говорить с приложением HCE на другом устройстве Android, единственным вариантом является API режима чтения.
  • Если вы также хотите поддерживать устройства до Android 4.4 или если вы также хотите получать данные от одноранговых устройств (например, через Android Beam), вам необходимо придерживаться системы диспетчеризации переднего плана.

Система диспетчеризации переднего плана

Вы можете зарегистрировать свою активность для получения намерений NFC в течение onResume():

@Override
public void onResume() {
    super.onResume();

    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
}

Это, вероятно, что-то вроде этого в Kotlin (хотя и не проверено):

fun onResume() {
    super.onResume()
    val pendingIntent = PendingIntent.getActivity(this, 0, Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0)
    val nfcAdapter = NfcAdapter.getDefaultAdapter(this)
    nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null)
}

Обязательно отмените регистрацию снова во время onPause():

@Override
public void onPause() {
    super.onPause();
    NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    nfcAdapter.disableForegroundDispatch(this);
}

Котлин:

fun onPause() {
    super.onPause()
    val nfcAdapter = NfcAdapter.getDefaultAdapter(this)
    nfcAdapter.disableForegroundDispatch(this)
}

Затем вы будете получать события NFC с намерениями TAG_DISCOVERED через onNewIntent():

@Override
public void onNewIntent(Intent intent) {
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
        // TODO: process intent
    }
}

Котлин:

fun onNewIntent(intent: Intent) {
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
        // TODO: process intent
    }
}

API режима чтения

С помощью API режима чтения вы регистрируете свою активность для получения обратных вызовов NFC (здесь не используются намерения!) В течение onStart():

@Override
public void onStart() {
    super.onStart();

    NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    nfcAdapter.enableReaderMode(this, new NfcAdapter.ReaderCallback() {
        @Override
        public void onTagDiscovered(Tag tag) {
            // TODO: use NFC tag
        }
    }, NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_NFC_B | NfcAdapter.FLAG_READER_NFC_F | NfcAdapter.FLAG_READER_NFC_V | NfcAdapter.FLAG_READER_NFC_BARCODE, null);
}

Котлин:

fun onStart() {
    super.onStart()
    val nfcAdapter = NfcAdapter.getDefaultAdapter(this)
    nfcAdapter.enableReaderMode(this, object : NfcAdapter.ReaderCallback() {
        fun onTagDiscovered(tag: Tag) {
            // TODO: use NFC tag
        }
    }, NfcAdapter.FLAG_READER_NFC_A or NfcAdapter.FLAG_READER_NFC_B or NfcAdapter.FLAG_READER_NFC_F or NfcAdapter.FLAG_READER_NFC_V or NfcAdapter.FLAG_READER_NFC_BARCODE, null)
}

Вы также должны отменить регистрацию во время onStop():

@Override
public void onStop() {
    super.onStop();
    NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    nfcAdapter.disableReaderMode(this);
}

Котлин:

fun onStop() {
    super.onStop()
    val nfcAdapter = NfcAdapter.getDefaultAdapter(this)
    nfcAdapter.disableReaderMode(this)
}

Вы получаете обнаруженные дескрипторы тегов с помощью метода обратного вызова onTagDiscovered(Tag tag), описанного выше. Вместо этого вы, конечно, могли бы также реализовать интерфейс NfcAdapter.ReaderCallback в своем классе активности и передать this вместо анонимного класса методу enableReaderMode.

...