Почему всегда TECH_DISCOVERED или TAG_DISCOVERED, но не NDEF_DISCOVERED?

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

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    adapter = NfcAdapter.getDefaultAdapter(this);
    nfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP),  0);
    nfcFilter = new IntentFilter[]{
                new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED),
                new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED),
                new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
            };
    techList = new String[][]{{Ndef.class.getName()}};
}

@Override
public void onResume(){
    super.onResume();

    if (adapter != null){
        adapter.enableForegroundDispatch(this, nfcPendingIntent, nfcFilter, techList);
        if (!adapter.isEnabled()){
            Toast.makeText(this, "please enable your nfc", Toast.LENGTH_SHORT).show();
        }
    } else {
        Toast.makeText(this, "your device do not have nfc.", Toast.LENGTH_SHORT).show();
    }
}

@Override
public void onPause(){
    super.onPause();
    if (adapter != null){
        adapter.disableForegroundDispatch(this);
    }
}

@Override
protected void onNewIntent(Intent intent){
    String TAG = "onNewIntent";
    super.onNewIntent(intent);

    Log.d(TAG, "action: "+intent.getAction());
    //Log.d(TAG, "type: "+intent.getType());
    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())){
        Parcelable[] rawMsg = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        if (rawMsg != null){
            for (int i=0; i<rawMsg.length; i++){
                NdefMessage msg = (NdefMessage)rawMsg[i];
                NdefRecord[] records = msg.getRecords();
                for (int j=0; j<records.length; j++){
                    Log.d(TAG, records[j].toMimeType()+"");
                    byte [] payload = records[j].getPayload();
                    if (payload != null && payload.length > 0){
                        Log.d(TAG, new String(payload, 1, payload.length-1));
                    }
                }
            }
        }
    } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())){

    } else if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
        Parcelable[] rawMsg = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        if (rawMsg != null){
            for (int i=0; i<rawMsg.length; i++){
                NdefMessage msg = (NdefMessage)rawMsg[i];
                NdefRecord[] records = msg.getRecords();
                for (int j=0; j<records.length; j++){
                    Log.d(TAG, records[j].toMimeType()+"");
                    byte [] payload = records[j].getPayload();
                    if (payload != null && payload.length > 0){
                        Log.d(TAG, new String(payload, 1, payload.length-1)+"("+j+")");
                    }
                }
            }
        }
    }
}

Здесь возникает два вопроса:

  1. Результат говорит диспетчеру переднего плана только перехватывать TECH_DISCOVERED(с techList) и TAG_DISCOVERED(без techList), но пропустить NDEF_DISCOVERED.

  2. Когда я покидаю приложение и сканирую тег NFC, он автоматически приводит меня на веб-сайт (я записываю URL в качестве записи). Как это говорит эта запись состоит из действия, чтобы открыть браузер или сделать звонок?

1 ответ

NDEF_DISCOVERED Фильтр намерений обычно (кажется, что некоторые исключения существуют) будет совпадать, только если у него есть связанный тип данных, который соответствует сообщению NDEF в теге. Так, например, спецификация типа данных */* будет соответствовать любому типу MIME:

IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
    ndef.addDataType("*/*");
} catch (MalformedMimeTypeException e) {}
nfcFilter = new IntentFilter[]{
        ndef,
        new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED),
        new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED)
};

Точно так же, если вы хотите запускать только для определенного URL http://www.example.com/, вы можете использовать:

IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
ndef.addDataScheme("http");
ndef.addDataAuthority("www.example.com", null);

Обратите внимание, что - с системой диспетчеризации переднего плана - вы обычно регистрируете только самый общий фильтр намерений, которому хотите соответствовать. Таким образом, если ваш фильтр намерений отправки переднего плана уже содержит действие TAG_DISCOVERED, нет необходимости добавлять какие-либо более конкретные фильтры (например, TECH_DISCOVERED или же NDEF_DISCOVERED), поскольку ваша деятельность уже получит любой обнаруженный тег. То же самое относится и к TECH_DISCOVERED в комбинации с Ndef технология тэгов: она уже содержит любой тэг NDEF_DISCOVERED, Тем не менее, обратите внимание, что TAG_DISCOVERED Фильтр намерений является особенным в том смысле, что он означает "поймать все" при использовании с диспетчеризацией переднего плана, в то время как он означает "только резервный" (т. е. совпадать, только если нет лучшего совпадения с любым другим приложением) при использовании в фильтрах намерений на основе манифеста,

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