NFC broadcastreceiver problem

狂风中的少年 提交于 2019-12-04 15:51:09

问题


I want my app to listen to nfc tags only when is activated. For this I tried to register an nfc listener as following, without any success.

IntentFilter filter = new IntentFilter("android.nfc.action.TECH_DISCOVERED"); 
registerReceiver(nfcTagListener, filter); 

BroadcastReceiver nfcTagListener = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) { 
            String action = intent.getAction(); 

            if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) { 
                Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  
                Log.d("nfc", "" + tag.getId());     
            }
        }
    };

I tried as well to declare the intent in my manifest following the apidemos and works perfectly, it launches my activity and gets the nfc tag id. But this is not what I want, I want to detect the tag id only when I am inside that activity. I am thinking it might be related to the following line included in the api demos. But I dont know how to do that programatically

      <meta-data android:name="android.nfc.action.TECH_DISCOVERED"
            android:resource="@xml/filter_nfc"> 

Any hint?

Thanks!


回答1:


Try to use Foreground Dispatch System.

To enable it, on the activity's onCreate method, you should prepare some stuffs:

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
                getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

after that, create the IntentFilters (in my example, all actions are handled using Intent Filters):

    IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
    try {
        ndef.addDataType("*/*");
    } catch (MalformedMimeTypeException e) {
        throw new RuntimeException("fail", e);
    }

    IntentFilter tech = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
    try {
        tech.addDataType("*/*");
    } catch (MalformedMimeTypeException e) {
        throw new RuntimeException("fail", e);
    }

    IntentFilter[] intentFiltersArray = new IntentFilter[] { tag, ndef, tech };

after that, you'll need a String array to contain supported technologies:

    String[][] techList = new String[][] { new String[] { NfcA.class.getName(),
            NfcB.class.getName(), NfcF.class.getName(),
            NfcV.class.getName(), IsoDep.class.getName(),
            MifareClassic.class.getName(),
            MifareUltralight.class.getName(), Ndef.class.getName() } };

in the onResume method, you should enable the foreground dispatch method:

NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techList);

and disable in onPause:

@Override
protected void onPause() {
    super.onPause();
    nfcAdapter.disableForegroundDispatch(this);
}

By this way, you have successfully initialized the needed mechanism. To handle a received Intent you should override the onNewIntent(Intent intent) method.

@Override
public void onNewIntent(Intent intent) {
    String action = intent.getAction();

    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
        // reag TagTechnology object...
    } else if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
        // read NDEF message...
    } else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {

    }
}

Note: if you want to handle the intents by only foreground dispatching, do not enable Intent Dispatch System in your manifest file, just give the right permissions to your application there.

I hope that helps.




回答2:


If you do not want to use foreground mode, your can always programmatically enable or disable intent filters.

The NDEF Tools for Android project has working sample using foreground mode, also detects

  1. NFC device support
  2. NFC enabled / disabled on activity launch, or later changed
  3. NFC push enabled / disabled on activity launch, or later changed


来源:https://stackoverflow.com/questions/5685946/nfc-broadcastreceiver-problem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!