Как запустить операцию с 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()) работает в этой ситуации. Смотрите мой другой ответ здесь.

Другие вопросы по тегам