Android Question Help: FLAG_IMMUTABLE or FLAG_MUTABLE

Zeev Goldstein

Well-Known Member
Licensed User
Longtime User
hi,

i get this error message when running on phone with android 13
on version 9 it works
i set targetsdk to 31
when reduce it to 30 it works on the new phone

my B4A version is 12

searching the forum i found some other posts on that topic and they were referred to use NB6 - here i got lost
i couldn't find any sample that works as all are either partial or used for services which i don't

i don't want to use sdk less than 31 as this is the recommendation now...

anyone can help ?
thanks
 
Solution
Last try - see if attached is working for "31". Have changed the Java code to be as follows:

B4X:
    NFCUtils(final Activity pActivity) {
        mActivity = pActivity;
        mNfcAdapter = NfcAdapter.getDefaultAdapter(mActivity);
        if (Build.VERSION.SDK_INT < 31) {
            mPendingIntent = PendingIntent.getActivity(mActivity, 0,
                    new Intent(mActivity, mActivity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        } else {
       
            mPendingIntent = PendingIntent.getActivity(mActivity, 0,
                    new Intent(mActivity, mActivity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 67108864);
        }  
    }

@agraham , please comment if I have it...
More information needed as to what the error is. Post the log.
here it is...

Error occurred on line: 182 (Main)
java.lang.IllegalArgumentException: arkom.CardReader.android: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
at android.app.PendingIntent.checkFlags(PendingIntent.java:408)
at android.app.PendingIntent.getActivityAsUser(PendingIntent.java:491)
at android.app.PendingIntent.getActivity(PendingIntent.java:477)
at android.app.PendingIntent.getActivity(PendingIntent.java:441)
at io.github.tapcard.android.NFCUtils.<init>(NFCUtils.java:87)
at io.github.tapcard.android.NFCCardReader.<init>(NFCCardReader.java:32)
at tapcardwrapper.tapcardWrapper.Initialize(tapcardWrapper.java:83)
at arkom.CardReader.android.main$ResumableSub_Activity_Create.resume(main.java:668)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:146)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:193)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:267)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:139)
at anywheresoftware.b4a.BA$2.run(BA.java:387)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8741)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
** Activity (main) Pause, UserClosed = true **
 
Upvote 0
Doesn't look like anything to do with NB6. Whatever arkom.CardReader is it looks like it needs an update.
update what?
it is on B4A 12
sdk 31
a simple app (most taken from Johan's TapCard sample - his code as is)
even his original code (link will follow) shows this error

i'm lost as this is going to be a very critical part of my project...

this is Johan's great great example and project

just run it with targetsdk = 31
 
Upvote 0
arkom.CardReader as I just said - whatever it is. Presumably it is part of a library or something if the original example also throws this error. Android now requires an additional flag for PendingIntents.
oh, thanks

what permission i need?
in manifest?
in code?
both?
 
Upvote 0
I've poked around in the
what permission i need?
You don't. As I have said twice above some library needs updating to add an extra flag.

I've poked around inside Tapcard.jar and the constructor for the call to PendingIntent.getActivity(...) in the NFCUtils class constructor needs needs FLAG_IMMUTABLE specifying to run on SDK31 and higher. I've no idea where Tapcard.jar comes from but whoever wrote it needs to modify it.
 
Upvote 0
I've poked around in the

You don't. As I have said twice above some library needs updating to add an extra flag.

I've poked around inside Tapcard.jar and the constructor for the call to PendingIntent.getActivity(...) in the NFCUtils class constructor needs needs FLAG_IMMUTABLE specifying to run on SDK31 and higher. I've no idea where Tapcard.jar comes from but whoever wrote it needs to modify it.
ok
can you tell which libraries?
or where do i get these updates?
i just updated to b4a 12.20 - i'm not sure it did update any libs as it was quite small anf went very fast...
 
Upvote 0
can you tell which libraries?
For God's sake I've just told you above exactly what is needed. Tapcard.jar needs modifying as I said. I think Johan Schoeman probably wrote it as it include the B4A wrapper class. He needs to modiy it.
 
Upvote 0
For God's sake I've just told you above exactly what is needed. Tapcard.jar needs modifying as I said. I think Johan Schoeman probably wrote it as it include the B4A wrapper class. He needs to modiy it.
thanks, i missed it, i'll try to contact him and ask...
by setting sdk to 30 all works perfectly - so my next "dumb" question is - what if i go with sdk 30?
will it be blocked by google?

and if i may i have another question on another topic -
file.makedir on external storage doesn't seems to work

Code:
File.MakeDir(File.DirRootExternal,"/Zeev")

i got the permission
on older phone it works
on new/updated phones it just ignore it - no error generated

i need to create a shared folder to share it with another app i have
i see so many other apps do that and create their on folder to keep their stuff
 
Upvote 0
For God's sake I've just told you above exactly what is needed. Tapcard.jar needs modifying as I said. I think Johan Schoeman probably wrote it as it include the B4A wrapper class. He needs to modiy it.
Zeev, you can try with the attached lib files (jar and xml). No idea if it will solve your problem. Have changed the constructor to be as follows:

Code:
    NFCUtils(final Activity pActivity) {
       
        int flags = Intent.FLAG_ACTIVITY_SINGLE_TOP;
       
        if (Build.VERSION.SDK_INT >= 31)
            flags |= 67108864; //FLAG_IMMUTABLE
       
        mActivity = pActivity;
        mNfcAdapter = NfcAdapter.getDefaultAdapter(mActivity);
        mPendingIntent = PendingIntent.getActivity(mActivity, 0,
                new Intent(mActivity, mActivity.getClass()).addFlags(flags), 0);
    }
 

Attachments

Upvote 0
Zeev, you can try with the attached lib files (jar and xml). No idea if it will solve your problem. Have changed the constructor to be as follows:

Code:
    NFCUtils(final Activity pActivity) {
      
        int flags = Intent.FLAG_ACTIVITY_SINGLE_TOP;
      
        if (Build.VERSION.SDK_INT >= 31)
            flags |= 67108864; //FLAG_IMMUTABLE
      
        mActivity = pActivity;
        mNfcAdapter = NfcAdapter.getDefaultAdapter(mActivity);
        mPendingIntent = PendingIntent.getActivity(mActivity, 0,
                new Intent(mActivity, mActivity.getClass()).addFlags(flags), 0);
    }
thank you Johan
i will go over the sample and hope it solves the issue
will of course revert and update
(hope you're well)
 
Upvote 0
Zeev, you can try with the attached lib files (jar and xml). No idea if it will solve your problem. Have changed the constructor to be as follows:

Code:
    NFCUtils(final Activity pActivity) {
      
        int flags = Intent.FLAG_ACTIVITY_SINGLE_TOP;
      
        if (Build.VERSION.SDK_INT >= 31)
            flags |= 67108864; //FLAG_IMMUTABLE
      
        mActivity = pActivity;
        mNfcAdapter = NfcAdapter.getDefaultAdapter(mActivity);
        mPendingIntent = PendingIntent.getActivity(mActivity, 0,
                new Intent(mActivity, mActivity.getClass()).addFlags(flags), 0);
    }
Update 2
Seems there's a problem
I changed the sdk to 31 as I want it to be on Google store
I run the app from my main app as intent

On previous libs & sdk 30 it all worked perfectly, now with new libs and sdk 31 the app loads and crashes

I will change sdk back to 30 and check
 
Upvote 0
Update 2
Seems there's a problem
I changed the sdk to 31 as I want it to be on Google store
I run the app from my main app as intent

On previous libs & sdk 30 it all worked perfectly, now with new libs and sdk 31 the app loads and crashes

I will change sdk back to 30 and check
What is the "crash" message in the B4A log?
 
Upvote 0
ok, final update with findings

on sdk 30 all is perfect - checked on android 9 - 13

on sdk 31 on older versions like 9 - works fine
on android 13 it crached on the following line

Code:
    tapcard.Initialize("ips")

the log for the error is: (all other logs you showed are ok)

Error occurred on line: 267 (Main)
java.lang.IllegalArgumentException: arkom.nfc: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
at android.app.PendingIntent.checkFlags(PendingIntent.java:408)
at android.app.PendingIntent.getActivityAsUser(PendingIntent.java:491)
at android.app.PendingIntent.getActivity(PendingIntent.java:477)
at android.app.PendingIntent.getActivity(PendingIntent.java:441)
at io.github.tapcard.android.NFCUtils.<init>(NFCUtils.java:105)
at io.github.tapcard.android.NFCCardReader.<init>(NFCCardReader.java:32)
at tapcardwrapper.tapcardWrapper.Initialize(tapcardWrapper.java:83)
at arkom.nfc.main$ResumableSub_Activity_Create.resume(main.java:673)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:275)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:150)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
at anywheresoftware.b4a.keywords.Common$15.run(Common.java:1804)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8741)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:571)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
 
Upvote 0
here are two more things

on older android the expiry comes where year is 4 digits like 10/2025
on android 13 it come 2 digits like 10/25
that's not really an issue as is is solved in code simply by checking the year element so it can be ignored

one strange thing - with the new libs the returning of scanned data looks much faster - there is no delay time at all
also good (!)

so i think the only issue is sdk 31 with android 13 (obviously)
at this point i returned to sdk 30 and holding my breath... :)
 
Upvote 0
Back
Top