Как запустить операцию с NFC, а затем разрешить сканирование разных тегов на одной и той же активности?
У меня есть базовое приложение для Android, и мне нужно реализовать возможность прокрутки NFC для запуска определенного действия. Я добился этого, написав запись приложения для Android. Затем мне нужно для дальнейших ударов использовать ту же активность, а не запускать новые.
Запись приложения Android запускает активность, как и ожидалось. Затем я запускаю создание Pending Intent и в OnResume устанавливаю диспетчеризацию переднего плана.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_plant);
// initialize NFC
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
}
@Override
protected void onResume() {
Log.d(TAG, "onResume");
super.onResume();
enableForegroundMode();
doTagOperations(getIntent());
}
public void enableForegroundMode() {
Log.d(TAG, "enableForegroundMode");
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED); // filter for all
IntentFilter[] writeTagFilters = new IntentFilter[] {tagDetected};
nfcAdapter.enableForegroundDispatch(this, nfcPendingIntent, writeTagFilters, null);
}
Затем у меня есть метод, который помечает связанные действия. Это выглядит следующим образом:
private void doTagOperations(Intent intent) {
Log.i(TAG, intent.getAction());
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
TextView textView = (TextView) findViewById(R.id.title);
textView.setText("Hello NFC!");
Parcelable[] messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
Log.d(TAG, "Found " + messages.length + " NDEF messages"); // is almost always just one
vibrate(); // signal found messages :-)
// parse to records
for (int i = 0; i < messages.length; i++) {
try {
List<Record> records = new Message((NdefMessage)messages[i]);
Log.d(TAG, "Found " + records.size() + " records in message " + i);
for(int k = 0; k < records.size(); k++) {
Log.d(TAG, " Record #" + k + " is of class " + records.get(k).getClass().getSimpleName());
Record record = records.get(k);
if(records.get(k).getClass().getSimpleName().equals("TextRecord")) {
String plant = new String(records.get(k).getNdefRecord().getPayload());
Log.i(TAG, plant);
textView.setText(plant);
}
if(record instanceof AndroidApplicationRecord) {
AndroidApplicationRecord aar = (AndroidApplicationRecord)record;
Log.d(TAG, "Package is " + aar.getDomain() + " " + aar.getType());
}
}
} catch (Exception e) {
Log.e(TAG, "Problem parsing message", e);
}
}
}
} else {
// ignore
}
}
Моя проблема в том, что система ведет себя странным образом. Вы можете запустить действие с тегом, но второй удар запустит новое действие. Дальнейшие свайпы затем будут использовать существующую активность, но намерение всегда будет выглядеть одинаково. Я пытаюсь прочитать текстовую запись из тега, и это должно измениться в зависимости от тега, который я провела, но это не так. Это как если бы метод, с помощью которого я собираю Intent, всегда выбирает один и тот же, независимо от того, какой тег был проведен.
1 ответ
Получение свежего намерения от переднего плана NFC
В onResume()
вы получаете намерение с getIntent()
, Если вы не перезапишите это намерение setIntent()
, getIntent()
вернет намерение, которое изначально начало вашей деятельности.
Новое намерение от системы диспетчеризации NFC передается вашей деятельности через onNewIntent()
метод. Поэтому вы могли бы сделать что-то вроде этого:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
doTagOperations(intent);
}
Второе событие NFC запускает новый экземпляр действия
Я не совсем уверен в этом, но я могу попробовать поэкспериментировать с настройкой lauchMode для вашей активности. Посмотрите этот ответ на вопрос Чтение тегов NFC. Вы также можете попробовать, если альтернативный подход к использованию системы диспетчеризации переднего плана (с использованием createPendingResult()
а также onActivityResult()
) работает в этой ситуации. Смотрите мой другой ответ здесь.