Android: фильтр намерений для NDEF_DISCOVERED открывает приложение в окне nfc вместо запуска приложения

#java #android #android-intent #nfc

#java #Android #android-намерение #nfc

Вопрос:

Я реализовал этот пример: https://developer.android.com/guide/topics/connectivity/nfc/nfc#p2p

 package com.example.android.beam;

import android.app.Activity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.TextView;
import android.widget.Toast;
import java.nio.charset.Charset;


public class Beam extends Activity implements CreateNdefMessageCallback {
    NfcAdapter nfcAdapter;
    TextView textView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView textView = (TextView) findViewById(R.id.textView);
        // Check for available NFC Adapter
        nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (nfcAdapter == null) {
            Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
            finish();
            return;
        }
        // Register callback
        nfcAdapter.setNdefPushMessageCallback(this, this);
    }

    @Override
    public NdefMessage createNdefMessage(NfcEvent event) {
        String text = ("Beam me up, Android!nn"  
                "Beam Time: "   System.currentTimeMillis());
        NdefMessage msg = new NdefMessage(
                new NdefRecord[] { createMime(
                        "application/vnd.com.example.android.beam", text.getBytes())
         /**
          * The Android Application Record (AAR) is commented out. When a device
          * receives a push with an AAR in it, the application specified in the AAR
          * is guaranteed to run. The AAR overrides the tag dispatch system.
          * You can add it back in to guarantee that this
          * activity starts when receiving a beamed message. For now, this code
          * uses the tag dispatch system.
          */
          //,NdefRecord.createApplicationRecord("com.example.android.beam")
        });
        return msg;
    }

    @Override
    public void onResume() {
        super.onResume();
        // Check to see that the Activity started due to an Android Beam
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
            processIntent(getIntent());
        }
    }

    @Override
    public void onNewIntent(Intent intent) {
        // onResume gets called after this to handle the intent
        setIntent(intent);
    }

    /**
     * Parses the NDEF Message from the intent and prints to the TextView
     */
    void processIntent(Intent intent) {
        textView = (TextView) findViewById(R.id.textView);
        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
                NfcAdapter.EXTRA_NDEF_MESSAGES);
        // only one message sent during the beam
        NdefMessage msg = (NdefMessage) rawMsgs[0];
        // record 0 contains the MIME type, record 1 is the AAR, if present
        textView.setText(new String(msg.getRecords()[0].getPayload()));
    }
}
 

в моем приложении и добавил этот фильтр намерений в манифест

 <intent-filter>
      <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
      <category android:name="android.intent.category.DEFAULT"/>
      <data android:mimeType="text/plain"/>
</intent-filter>
 

Когда я теперь передаю на одно из двух устройств, intent выполняет код в processIntent(), но внутри программы с именем NFC, а не в моем запущенном приложении. Итак, как я могу получить намерение для выполнения в запущенном приложении и не открывать приложение NFC?

Ответ №1:

У вас есть несоответствующие типы mime между сообщением, которое вы создаете, которое имеет тип mime application/vnd.com.example.android.beam , и типом mime в манифесте text/plain , который вы попросили систему запустить ваше приложение, если оно увидит.

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

Это связано с тем, что onNewIntent вызывается только при повторном запуске приложения, а ваше приложение не запускается повторно.

Обычная практика заключается в том, что фильтр манифеста запускает ваше приложение с Intent помощью, вам нужно обработать это при запуске приложения (обычно в onCreate ).
onNewIntent используется только тогда, когда ваше приложение уже запущено и используется enableForegroundDispatch для того, чтобы заставить систему отправлять NFC Intent -коды вашему запущенному приложению вместо того, чтобы пытаться запустить новый экземпляр вашего приложения.

Итак, в вашем коде в конце onCreate добавьте строку

 processIntent(getIntent());