Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Requesting Permission has been failed on Android 14 #56

Open
endless-runner-007 opened this issue Dec 19, 2023 · 13 comments
Open

Requesting Permission has been failed on Android 14 #56

endless-runner-007 opened this issue Dec 19, 2023 · 13 comments

Comments

@endless-runner-007
Copy link

On Android 14, There are 2 problems

  1. Receiver_Export issue

image

this error occurs on the following code line, UsbSerialForAndroid/Extensions/UsbManagerExtensions.cs
context.RegisterReceiver(usbPermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION));

I changed it to following

if (Build.VERSION.SdkInt >= BuildVersionCodes.Tiramisu)
context.RegisterReceiver(usbPermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION), (ActivityFlags)ReceiverFlags.Exported);
else
context.RegisterReceiver(usbPermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION));

  1. PendingIntent parma issue

image

this error occurs on the following code line
PendingIntentFlags pendingIntentFlags = Build.VERSION.SdkInt >= BuildVersionCodes.S ? PendingIntentFlags.Mutable : 0;

I changed it Immutable. But I can't get the permission.

@S-CODE-pl
Copy link

I have the same issue, anyone find solution?

@memsom
Copy link

memsom commented Jun 4, 2024

I have the code fixed here: https://github.com/memsom/UsbSerialForAndroid I would submit a pull request, but I also removed the legacy .Net runtimes, so it might not be exactly what you want. The changes needed are here: https://github.com/memsom/UsbSerialForAndroid/blob/a00c01134c125c00b1e24a3aa23f7cb5252ef8f3/UsbSerialForAndroid/Extensions/UsbManagerExtensions.cs#L43

@memsom
Copy link

memsom commented Jun 5, 2024

You actually also need to export the Receiver too -

https://github.com/memsom/UsbSerialForAndroid/blob/6bb07e570506d3487e6f754ee869464def961874/UsbSerialForAndroid/Extensions/UsbManagerExtensions.cs#L33

So the full fix would be:

 public static Task<bool> RequestPermissionAsync(this UsbManager manager, UsbDevice device, Context context)
        {
            var completionSource = new TaskCompletionSource<bool>();

            var usbPermissionReceiver = new UsbPermissionReceiver(completionSource);

            if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
            {
#pragma warning disable CA1416
                //this is checking that it is API 26 or greater, bu the compiler doesn't see it that way. So we have to add in a pragma
                context.RegisterReceiver(usbPermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION), ReceiverFlags.Exported);
#pragma warning restore CA1416
            }
            else
            {
                context.RegisterReceiver(usbPermissionReceiver, new IntentFilter(ACTION_USB_PERMISSION));
            }


            // Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
#if NET6_0_OR_GREATER
            PendingIntentFlags pendingIntentFlags = Build.VERSION.SdkInt >= BuildVersionCodes.S ? PendingIntentFlags.Mutable : 0;
#else
            PendingIntentFlags pendingIntentFlags = Build.VERSION.SdkInt >= (BuildVersionCodes)31 ? (PendingIntentFlags).33554432 : 0;
#endif
            var intent = new Intent(ACTION_USB_PERMISSION);
            // we need this for Android 34+ as apparently, security. If you follow Google's docs,
            // you will spend a lot of time fighting with the API not actually replying with any
            // useful data... because Immutable Intents *can;t* be changed, so the API is basically
            // hobbled.
            if (Build.VERSION.SdkInt >= BuildVersionCodes.UpsideDownCake)
            {
                intent.SetPackage(context.PackageName);
            }

            var pendingIntent = PendingIntent.GetBroadcast(context, 0, intent, pendingIntentFlags);

            manager.RequestPermission(device, pendingIntent);

            return completionSource.Task;
        }

If you do not do those two things in Android 14, it basically just doesn't work.

Edit: I used ReceiverFlags.Exported, but you might be able to use the ReceiverFlags.NotExported, I'm not an Android API expert and so I don;t know what the difference is and haven't experimented outside of this type of "fix" in previously working code.

This is my own personal opinion, but the stuff they have changed recently seems to have made everything less easy to do simple things and have made everything more locked down in a "not good" type of way from a developers point of view. (External file system access, I see you there in the corner... grrr.)

@memsom
Copy link

memsom commented Jun 5, 2024

Okay - I tried it in the test app, and not exporting the BroadcastReceiver doesn't seem to make any difference there.

Apparently, it should be automatically exported if you have an intent list, but then to be honest the attributes in Xamarin projects are very vague as to what they generate in the actual AndroidManifest.xml, so I have started to avoid them. They do not seem to add in the extra stuff Android 14 seems to require.

There was another weird bug in the Hex dumping code. Every now and again it was throwing with an index out of bounds. I fixed it by hiding the exception, but I see a # in dumped hex every now and again, and that is the char I replaced the thrown exception with. So it is for sure happening regularly for me under .Net8.

@anotherlab
Copy link
Owner

@memsom Each release by Google is another rachet of the security screw. Which makes projects like this a moving target.

I'm sorry, but we are only looking at code changes that have been submitted as pull requests.

@memsom
Copy link

memsom commented Jun 10, 2024

@anotherlab Okay, I can do you a PR. My main issue is that you are using really old runtimes and I simply don't have them installed anymore. If I submit a PR that removes the stuff that is out of support also, would that be acceptable? Or would you want 2 separate PRs?

@anotherlab
Copy link
Owner

@memsom By old runtimes, do you mean Xamarin Android (as opposed to Microsoft Android)?

@memsom
Copy link

memsom commented Jun 15, 2024

@memsom By old runtimes, do you mean Xamarin Android (as opposed to Microsoft Android)?

I can have a look and see, but probably. We now have a fork of the code working on Android 14 with both FTDI and CDC drivers, so with these changes it should be possible to continue using the code for the foreseeable future as-is. The fixes I posted are what was needed to fix it for Android 14. I will get you a PR, but it isn't a super high priority at the moment. It would probably be quicker for you to do the fix yourself - if you want to support MAUI, this is needed with DotNet 8.0, which targets API level 34.

Edit: I don't mean to sound like I don;t care, I do. I just don't have the free time at the moment. Porting Xamarin Forms to MAUI is not as straight forward as Microsoft claims so I'm very busy in my day job currently, and I would need to do the PR on my own time, despite me not actually needing this for any personal projects..

Xamarin Android is now legacy and is out of support, and so continuing to support it from here has diminishing returns.

@memsom
Copy link

memsom commented Jul 11, 2024

Forgive me, but I looked and I don't see any commits against this issue. Is this really complete? Closing this issue seems extremely premature if not. Closing the issue will not magically make Android 14 work. The fix is a dozen lines of changes. But this library is useless without those fixes.

@anotherlab anotherlab reopened this Jul 11, 2024
@anotherlab
Copy link
Owner

@memsom This issue should not have been closed and I re-opened it.

I am looking at your suggested changes and will create a PR, hopefully this weekend (this is not my day job).

@memsom
Copy link

memsom commented Jul 11, 2024

I am looking at your suggested changes and will create a PR, hopefully this weekend (this is not my day job).

If it helps I can probably package up our current changes and put them in my copy of the repo. (I don't remember if we changed anything else or not since I forked the code.) It should then just be a case of you working out what needs to be added to make it compile for the older platforms you support. A good compare tool should make light work of it.

I'm sorry I haven't been able to help more. We'd really like to see a nuget that supports the Microsoft Android target compatible with Maui, so I might circle back on that later if you have no time. At the moment we have the code in our Maui repository, but I'd rather it was an external dependency.

@andrea-993
Copy link

Thanks for your fix memsom
i made it work but add to apply a small change to your code:
PendingIntentFlags pendingIntentFlags = Build.VERSION.SdkInt >= (BuildVersionCodes)31 ? (PendingIntentFlags).33554432 : 0;
into this:
PendingIntentFlags pendingIntentFlags = Build.VERSION.SdkInt >= (BuildVersionCodes)31 ? (PendingIntentFlags)33554432 : 0;

I removed the dot otherwise it would get interpreted as double and then converted to int and becomes 0 instead of 33554432
did you get a different result?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants