Как запустить активность с NFC, а затем разрешить сканирование разных тегов в одной и той же активности?

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

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


person Sergio    schedule 14.04.2015    source источник


Ответы (1)


Получение свежего намерения от диспетчера переднего плана NFC

В onResume() вы получаете намерение с помощью getIntent(). Если вы не перезапишете это намерение с помощью setIntent(), getIntent() вернет намерение, которое изначально запустило ваше действие.

Свежее намерение от системы диспетчеризации переднего плана NFC доставляется в вашу активность через метод onNewIntent(). Поэтому вы можете сделать что-то вроде этого:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    doTagOperations(intent);
}

Второе событие NFC запускает новый экземпляр действия.

Я не совсем уверен в этом, но я мог бы попробовать поэкспериментировать с установкой lauchMode для вашей деятельности. См. этот ответ на вопрос Чтение тегов NFC. Вы также можете попробовать, работает ли в этой ситуации альтернативный подход к использованию системы диспетчеризации переднего плана (с использованием createPendingResult() и onActivityResult()). См. другой мой ответ здесь.

person Michael Roland    schedule 14.04.2015