chariotsolutions / phonegap-nfc

PhoneGap NFC Plugin
MIT License
703 stars 547 forks source link

Android 12 - Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent #465

Open SachinAgarwal1337 opened 2 years ago

SachinAgarwal1337 commented 2 years ago

The plugin works perfectly in all devices except for Andorid 12. I get following error

 Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent

I see the problem is in createPendingIntent Method

 private void createPendingIntent() {
        if (pendingIntent == null) {
            Activity activity = getActivity();
            Intent intent = new Intent(activity, activity.getClass());
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0); // Problem in the last param here
        }
    }

Would like to know if I am doing something wrong? or is this needs to be fixed

P.S I use this plugin for only reading NFC tags

ghost commented 1 year ago

I can confirm this issue, the plugin is not usable on Android 12. Please fix!

escully27 commented 1 year ago

Can confirm the same issue. Disabling plugin for now but will check into work arounds.

escully27 commented 1 year ago

I fixed it by editing "NfcPlugin.java" under the Android file to have this code:

` private void createPendingIntent() {

if (pendingIntent == null) {

        Activity activity = getActivity();
        Intent intent = new Intent(activity, activity.getClass());

        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            pendingIntent = PendingIntent.getActivity(activity, 0, intent, PendingIntent.FLAG_IMMUTABLE);
        } else {
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0);
        }
    }

}`
escully27 commented 1 year ago

I also made a fork here: https://github.com/escully27/phonegap-nfc-android-12

dilo99 commented 1 year ago

ok, but on line 486 of NfcPlugin.java there's an error: instead of '(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)' i should be 'f (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) ' or it will not compile. please fix it or i create another fork for it, but it seems useless to me thanks

dilo99 commented 1 year ago

i fixed this on my fork: https://github.com/dilo99/phonegap-nfc

escully27 commented 1 year ago

OK thanks. Let me know if helpful I can change mine otherwise probably best to do a PR for yours

dilo99 commented 1 year ago

@escully27 > OK thanks. Let me know if helpful I can change mine otherwise probably best to do a PR for yours

ok i created a PR, I don't know how useful it is, there are another 15 waiting for more than two years ...

ReneDyhr commented 1 year ago

How does this work for you guys? I've tried adding the fix but it won't work. The Java code does register, but the action returns null and therefor never sends it back to Cordova.

escully27 commented 1 year ago

You have to update the repo you’re using and reinstall it, changing the Java code will be overwritten whenever it’s built and run again.

On Wed, Aug 10, 2022 at 7:59 AM René Dyhr @.***> wrote:

How does this work for you guys? I've tried adding the fix but it won't work. The Java code does register, but the action returns null and therefor never sends it back to Cordova.

— Reply to this email directly, view it on GitHub https://github.com/chariotsolutions/phonegap-nfc/issues/465#issuecomment-1210640044, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACUZFS4BNDPCJERB7LZVEDLVYORUBANCNFSM5PDP4R2Q . You are receiving this because you were mentioned.Message ID: @.***>

ReneDyhr commented 1 year ago

You have to update the repo you’re using and reinstall it, changing the Java code will be overwritten whenever it’s built and run again.

That I'm aware of and have of course made sure it's not being overwritten again. And that I can also see in the app. Before the app won't load on Android 12 to now it will load, but the String action = intent.getAction(); from the parseMessage function now returns null. This results in the Cordova app not getting the response and therefor never reacts on the NFC scanning

escully27 commented 1 year ago

Can you post the full code surrounding the .getAction line that's returning null?

ReneDyhr commented 1 year ago

Can you post the full code surrounding the .getAction line that's returning null?

Of course! To start with, you can see the createPendingIntent that I changed to the code provided from the PR.

private void createPendingIntent() {
    if (pendingIntent == null) {
        Activity activity = getActivity();
        Intent intent = new Intent(activity, activity.getClass());
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            pendingIntent = PendingIntent.getActivity(activity, 0, intent, PendingIntent.FLAG_IMMUTABLE);
        } else {
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            pendingIntent = PendingIntent.getActivity(activity, 0, intent, 0);
        }
    }
}

And then the parseMessage function until it stops.

void parseMessage() {
        cordova.getThreadPool().execute(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "parseMessage " + getIntent());
                Intent intent = getIntent();
                String action = intent.getAction();
                Log.d(TAG, "action " + action);
                if (action == null) {
                    return;
                }

Before the createPendingIntent fix, the action returned a string: android.nfc.action.TAG_DISCOVERED After the fix, it now returns null and get into the if and stops.

ReneDyhr commented 1 year ago

Addition to my last reply, I have the logs from NfcPlugin while it works and when it's broken. Seems like the intent is changed and therefor wont work properly.

This is when it works.

NfcPlugin: onPause Intent {  }
NfcPlugin: stopNfc
NfcPlugin: onNewIntent Intent { act=android.nfc.action.TAG_DISCOVERED flg=0x34000000 mp=com.cleanmanager.application/.MainActivity (has extras) }
NfcPlugin: parseMessage Intent { act=android.nfc.action.TAG_DISCOVERED flg=0x34000000 cmp=com.cleanmanager.application/.MainActivity (has extras) }
NfcPlugin: action android.nfc.action.TAG_DISCOVERED

And after the fix:

NfcPlugin: onPause Intent {  }
NfcPlugin: stopNfc
NfcPlugin: onNewIntent Intent { flg=0x34000000 cmp=com.cleanmanager.application/.MainActivity }
NfcPlugin: parseMessage Intent { flg=0x34000000 cmp=com.cleanmanager.application/.MainActivity }
NfcPlugin: action null

Could it be because I'm using cordova-android@9.1.0? (UPDATE: Have tried both @10.0.0 and @11.0.0)

ReneDyhr commented 1 year ago

I do think I found my issue. For my case it seems like I need to use FLAG_MUTABLE instead of FLAG_IMUTABLE.

Though since our app is backwards compatible with older Android versions, we had to hardcode the value for the flag, since FLAG_MUTABLE isn't available in our stack.

Pynka commented 1 year ago

For all Capacitor developers: Capawesome has recently announced an up-to-date Capacitor NFC plugin. Maybe worth a try. My client unfortunately still hangs on Cordova.

Nickholas commented 1 year ago

I have the same problem after upgrade my solution to Android 32 but i works good before (Android 30)

Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent

Is it possible to resolve by my own? Other solution will be return to previous version but Google Play doesnt allow 30 anymore.

I have tried to change the line 486 by my self and seems to work fine but i am not sure if it will works for all devices:

\android\capacitor-cordova-android-plugins\src\main\java\com\chariotsolutions\nfc\plugin\NfcPlugin.java

Paradox7208 commented 1 year ago

@Nickholas If you are still having issues with API 32, please refer to my comment on a similar issue. I hope it works for you.

https://github.com/chariotsolutions/phonegap-nfc/issues/476#issuecomment-1226614717

Nickholas commented 1 year ago

I solved changing the line 486 of the folder called NfcPlugin.java that you can find in the ·..android\capacitor-cordova-android-plugins\src\main\java\com\chariotsolutions\nfc\plugin" directory.

pendingIntent = PendingIntent.getActivity(activity, 0, intent, PendingIntent.FLAG_IMMUTABLE);

alioucisse7 commented 1 year ago

I do think I found my issue. For my case it seems like I need to use FLAG_MUTABLE instead of FLAG_IMUTABLE.

Though since our app is backwards compatible with older Android versions, we had to hardcode the value for the flag, since FLAG_MUTABLE isn't available in our stack.

I do think I found my issue. For my case it seems like I need to use FLAG_MUTABLE instead of FLAG_IMUTABLE.

Though since our app is backwards compatible with older Android versions, we had to hardcode the value for the flag, since FLAG_MUTABLE isn't available in our stack.

hi, any update for a solution ?

csaar95 commented 1 year ago

Ist this plugin still under maintenance as there hasn't been any activity for nearly 2 years? There is an open merge request, which obviously fixing this problem, no response either. We depend on this bugfix and can't publish our application for Android 12+ devices.

Do you recommend any other NFC plugin?

Related issue: https://github.com/ionic-team/capacitor/issues/5392

pilz97 commented 1 year ago

@escully27 and @ath0mas thx for your forks.

But i get an build error: image

Does your build work?

Paradox7208 commented 1 year ago

@pilz97 do you have the build tools for Android API 30/31 installed? When I made my code change, I didn't have to include any additional import references than what were already in the solution.

ath0mas commented 1 year ago

@pilz97 Indeed in my fork I went a bit too quick on removing the check on android.os.Build.VERSION.SDK_INT and now did a bit more debug on it:

pilz97 commented 1 year ago

@Paradox7208 @ath0mas thx for your answers i still was on cordova-android 9.x now i upgraded to 11.0.0 and it works. Thanks for your help!