4

I'm trying to make my application open a specific fragment then process the tag data in that fragment. It's working when the app is running on foreground but when I discover the TAG when it's on background it seems to lose it's extra data.

The application is put on foreground when I read the TAG, the onNewIntent is called with the intent action being android.nfc.action.TAG_DISCOVERED. But there is no intent.EXTRA_TAG as when I detect it from foreground directly... What am I doing wrong?

Here is the NFC specific part of my code:

Once upon the time in my activity...

@Override
public void onNewIntent(Intent intent) {
    Log.e(TAG, "RETRIVE HERE" + selectedFragment.getTagText() );
    if (selectedFragment instanceof FragmentNfc) {
        Log.e(TAG, "RETRIVE HERE");
        FragmentNfc my = (FragmentNfc) selectedFragment;
        my.processNFC(intent);
    }
}

public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
    final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
    intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

    final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);
    adapter.enableForegroundDispatch(activity, pendingIntent, null, null);
}

public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) {
    adapter.disableForegroundDispatch(activity);
}

Once upon the time in my fragment...(The for loop is never entered when I detect the TAG from background)

public void processNFC(Intent intent) {
    Log.e(TAG, "Process NFC");
    String hexdump = "";
    String action = intent.getAction();
    Log.e(TAG, "ACTION: " + action);
    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        String[] techList = tag.getTechList();
        String searchedTech = Ndef.class.getName();
        for (String tech : techList) {
            Log.e(TAG, "TECH: " + tech);
            if (searchedTech.equals(tech)) {
                byte[] tagId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID);
                for (int i = 0; i < tagId.length; i++) {
                    String x = Integer.toHexString(((int) tagId[i] & 0xff));
                    if (x.length() == 1) {
                        x = '0' + x;
                    }
                    hexdump += x;
                    if (i < 6) {
                        hexdump += ":";
                    }
                }
                onNfcReceive(hexdump);
            }
        }
    }
}

Once upon the time in the Manifest...

   <activity
        android:name=".activityv2.ActivityHome"
        android:label="Security Agent"
        android:launchMode="singleInstance"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.nfc.action.TECH_DISCOVERED" />
        </intent-filter>

        <meta-data
            android:name="android.nfc.action.TECH_DISCOVERED"
            android:resource="@xml/nfc_tag_filter" />
    </activity>
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
Jaythaking
  • 2,200
  • 4
  • 25
  • 67

1 Answers1

1

Since you registered the intent filter for action android.nfc.action.TECH_DISCOVERED in your manifest, the method onNewIntent() will receive a TECH_DISCOVERED intent and not a TAG_DISCOVERED intent. Consequently, the condition of the if-branch

if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)) {

will evaluate to false and you will never enter than branch.

You could instead check for both TAG_DISCOVERED and TECH_DISCOVERED:

if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action) ||
    NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • I added this to the manifest finally, but your solutions also work ... : – Jaythaking Jun 07 '16 at 15:10
  • 1
    @Jaythaking If you add a `TAG_DISCOVERED` intent filter to the manifest, keep in mind that `TAG_DISCOVERED` does not have the same meaning (catch-all) as when used in the foreground dispatch system. Instead, when `TAG_DISCOVERED` is used in the manifest it is only a fall-back mechanism (i.e. catch those tags that no other app wanted). See http://stackoverflow.com/a/26398314/2425802 – Michael Roland Jun 07 '16 at 15:21
  • True that... Then why is TAG_DISCOVERED catched when the app is on FOREGROUND? Even when I didn't add that one in the manifest, it was the action set in the intent. I want it to be always TECH_DISCOVERED – Jaythaking Jun 07 '16 at 15:24
  • That's because you registered the foreground dispatch system for that intent filter (by specifying null as the intent filter argument). `TAG_DISCOVERED` does have the catch-all meaning with the foreground dispatch. If you want to receive `TECH_DISCOVERED` from the foreground dispatch system you have to set the intent filters in the call to `enableForegroundDispatch()` accordingly. – Michael Roland Jun 07 '16 at 15:30
  • Why do we need `TAG_DISCOVERED`? – IgorGanapolsky Jul 10 '20 at 20:30