Skip to content Skip to sidebar Skip to footer

Unable To Trigger Intent On Nfc Read Using With Locktaskmode

I'm trying to read NFC tags in my Android Application, the NFC tags are simple card with plain text on it, after looking at Android documentation and looking some other guides i've

Solution 1:

Update:

Based on the comment that the App is in LockTaskMode this might change the systems ability to re-launch Apps to deliver an intent to it (I have no experience of LockTaskMode)

I suggest that you don't use the old NFC API's that have to use launching or re-launching Apps when you are in the restrictive LockTaskMode.

I suggest that you try the newer and much better enableReaderMode NFC API to read cards. https://developer.android.com/reference/android/nfc/NfcAdapter#enableReaderMode(android.app.Activity,%20android.nfc.NfcAdapter.ReaderCallback,%20int,%20android.os.Bundle)

This enableReaderMode NFC API causes a callback in your App that starts a new thread to handle the incoming NFC data, there is no launch or re-launching of you App and therefore might not have a problem with LockTaskMode.

example of enableReaderMode API use.

publicclassMainActivityextendsAppCompatActivityimplementsNfcAdapter.ReaderCallback{

private NfcAdapter mNfcAdapter;

@OverrideprotectedvoidonResume() {
        super.onResume();
        enableNfc();
    }

    privatevoidenableNfc(){
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if(mNfcAdapter!= null && mNfcAdapter.isEnabled()) {
            // READER_PRESENCE_CHECK_DELAY is a work around for a Bug in some NFC implementations.Bundleoptions=newBundle();
            options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 250);

            // Ask for all type of cards to be sent to the App as they all might contain NDEF data
            mNfcAdapter.enableReaderMode(this,
                    this,
                    NfcAdapter.FLAG_READER_NFC_A |
                            NfcAdapter.FLAG_READER_NFC_B |
                            NfcAdapter.FLAG_READER_NFC_F |
                            NfcAdapter.FLAG_READER_NFC_V |
                            NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS,
                    options);
        } else {
            NfcMessage();
        }
    }

    @OverrideprotectedvoidonPause() {
        super.onPause();
        if(mNfcAdapter!= null)
            mNfcAdapter.disableReaderMode(this);
    }


// This gets run in a new thread on Tag detection// Thus cannot directly interact with the UI ThreadpublicvoidonTagDiscovered(Tag tag) {

// Get the Tag as an NDEF tag TechnologyNdefmNdef= Ndef.get(tag);

        // only process if there is NDEF data on the cardif (mNdef != null) {
             NdefMessagemNdefMessage= mNdef.getCachedNdefMessage();

             // Now process the Ndef message
             ....

             // If success of reading the correct Ndef message// Make a notification sound (as we disabled PLATFORM_SOUNDS when enabling reader Mode)// As getting a confirmation sound too early causes bad user behaviour especial when trying to write to cards
        }

        // Ignore other Tag types.

}


....

Original I'll leave the original answer here as it shows here the working of the System NFC App which with enableForegroundDispatch directly delivers the an intent with the NFC data in it to your App by re-launching it and Pausing and Resuming it which fires the onNewIntent It also explains if you have not enableForegroundDispatch then the system NFC App passes the NFC intent to the Android OS which causes it to find an App that can handle this type of Intent, which it does by looking at all the App's manifest files for Intent filter to match.

So the Manifest Intent filters will cause Android to launch your App if a matching Tag is scanned by the system.

onNewIntent is for

the activity is re-launched while at the top of the activity stack instead of a new instance of the activity being started, onNewIntent() will be called on the existing instance with the Intent that was used to re-launch it.

From https://developer.android.com/reference/android/app/Activity#onNewIntent(android.content.Intent)

So in this scenario where your App is not running it cannot be re-launched thus the Intent has to be captured in onCreate Instead.

So in onCreate put something like

Intentintent= getIntent();

        // Check to see if the App was started because of the Intent filter in the manifest, if yes read the data from the Intentif (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
          readFromIntent(intent);
        }

Now if you want to cover receiving NFC data while the App is running you need to use enableForegroundDispatch and onNewIntent

https://developer.android.com/guide/topics/connectivity/nfc/advanced-nfc#foreground-dispatch

Which can be done creating a Intent Filter in onResume and enabling foreground dispatch (foreground dispatch should be disabled when your app is not in the foreground i.e in onPause as shown).

e.g. something like

private NfcAdapter adapter;

publicvoidonResume() {
    super.onResume();
    pendingIntent = PendingIntent.getActivity(this, 0, newIntent(this,
            getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    IntentFilterndef=newIntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
    try {
        // Only look for plain text mime type
        ndef.addDataType("text/plain");
    }
    catch (MalformedMimeTypeException e) {
        thrownewRuntimeException("fail", e);
    }
    intentFiltersArray = newIntentFilter[] {ndef, };


    adapter = NfcAdapter.getDefaultAdapter(this);
    adapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, null);
}

@OverridepublicvoidonPause() {
    super.onPause();
    adapter.disableForegroundDispatch(this);

}

Post a Comment for "Unable To Trigger Intent On Nfc Read Using With Locktaskmode"