Фильтры намерений, которые вы зарегистрировали в манифесте приложения, не имеют особого смысла.
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
.