maui: .NET MAUI does not work with Android 13 Android.permission.write_external_storage
Description
My App was working and able to take pictures on Android 12 and .NET 6 but as soon as I upgraded to Android 13 and .NET 7, it stopped working. When I call this method:
FileResult photo = await MediaPicker.Default.CapturePhotoAsync();
I get this error: Microsoft.Maui.ApplicationModel.PermissionException: ‘StorageWrite permission was not granted: Denied’.
I do have these declarations in the AndroidManifest.xml file:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
Steps to Reproduce
- Create a new .NET MAUI App with the default template (not empty template).
- Replace the code in the OnCounterClicked method with the code below.
- Connect your device to your PC (my device is Google Pixel Pro 6).
- Run (Debug) the app on the local Android 13 device.
- Click the Counter button
- Notice the error
Link to public reproduction project repository
https://github.com/FatCodeMonkey/MAUIPhoto
Version with bug
6.0.486 (current)
Last version that worked well
6.0.424
Affected platforms
Android
Affected platform versions
Android 13
Did you find any workaround?
No
Relevant log output
0xFFFFFFFFFFFFFFFF in Android.Runtime.JNIEnv.monodroid_debugger_unhandled_exception C#
0x1A in Android.Runtime.JNINativeWrapper._unhandled_exception at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:12,5 C#
0x1D in Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:23,26 C#
0x17 in System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw C#
0x6 in System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0 C#
0xC in Android.App.SyncContext. at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.App/SyncContext.cs:36,19 C#
0xE in Java.Lang.Thread.RunnableImplementor.Run at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Java.Lang/Thread.cs:36,6 C#
0x8 in Java.Lang.IRunnableInvoker.n_Run at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net6.0/android-33/mcw/Java.Lang.IRunnable.cs:84,4 C#
0x8 in Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PP_V at /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:22,5 C#
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 16
- Comments: 75 (29 by maintainers)
What baffles me, is that .net MAUI was released with an initial target Android API of 33. But the underlying code does not support Android API 33!
Starting from Android 13, if your application target SDK is specified to 33 or above, the READ_EXTERNAL_STORAGE permission will be completely useless, and applying for it will have no effect.
Correspondingly, Google has added three runtime permissions: READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, and READ_MEDIA_AUDIO, which are used to manage the photos, videos and audio files of the phone respectively. That is to say, in the past, you only needed to apply for a READ_EXTERNAL_STORAGE permission. This is no longer possible. You have to apply for it on demand, so that users can learn more precisely which media permissions your app has applied for.
It is the same for notifications!
I pulled the Android permissions code, and updated it to support API 33. Hopefully they will realize that making the “Essentials” an actual part of the MAUI core, requires a higher level of attention to external API changes.
@PureWeen @UkeHa
Ok, I managed to find it, and it has to do with a really unexpected twist in how certain values in the android manifest are applied.
I followed this thread, and applied appropriate changes to the manifest, such as the relevant parts of this comment and this comment.
Therefore my android manifest ended up with these two lines (other lines omitted):
This seems correct. I want to build with support for API 21 - 32, and on all those API versions WRITE_EXTERNAL_STORAGE exists, is required, and is requested. If I ever upgrade to building for API 33, WRITE_EXTERNAL_STORAGE should not be requested for that API 33 version, because it doesn’t exist in API 33.
In this case I set
android:targetSdkVersion="32", and I get the warning that it compiles with API 33 after all. Apparently this means that theuses-permissionis omitted, because we’re at API 33. If I remove theandroid:maxSdkVersionattribute from theuses-permissionline, I still build API 33 according to the warning, but now suddenlyuses-permissiondoes work correctly, even though that permission doesn’t even exist in API 33.I’m baffled, yet happy that our release-blocker can be bypassed this way.
And here is the code
Here is a snippet that I use to open the device gallery and/or select a ringtone…
I do not see how I can circumvent the issue either. Everyone around me has devices with the latest Android installed which I can’t run my .net maui app on. The app can’t work without media picker (MediaPicker control), but it seems to rely on WRITE_EXTERNAL_STORAGE only, which is not in the list of android permissions anymore. It does not care about new api 33 permissions like READ_MEDIA_IMAGES, it wants WRITE_EXTERNAL_STORAGE and does not run camera without it. Am I stuck till the issue is fixed in new ver of .net maui core, or there is some temp. workaround for that?
I have added that before it didn’t work for some reason. When I removed the READ_MEDIA permissions its not working. Thanks for the help. Yes I was trying to capture images on Android 13. That was my first time asking a question on GitHub and looks like ill be doing it more now. Happy to join the MAUI community.
You haven’t yet told us what you’re trying to do. What exactly is not working? Are you trying to take a picture on Android 13? Then reread this thread, because that’s discussed quite extensively. You can remove the
READ_MEDIApermissions, since taking pictures is not about reading, but writing. Then you’ll need:Although you may use a different
minSdkVersion.Keep in mind that this is not necessary because of Android, but because of a bug in MAUI. Once #12766 is merged and a new MAUI version is released, it’s no longer necessary.
Thank you. I had tried this before and it didn’t work for some reason, but I tried it now and it works. This is the best solution.
@symbiogenesis, again, if you don’t need to target sdk33 just target 32 and it’ll work just fine. Still a bug that needs to be fixed.
@YMichurin Yes, no issues there, since devices running higher versions know how to deal with older ones.
@mattleibow @rachelkang
Congratulations on the new release pack and thanks!
@Stedy59 Could you share your modifications while we wait for the MAUI team to fix this ? (right now as a workaround I fixed the target android sdk to 30 in the android manifest).
Anyone knows why this is still not working? Here’s my dotnet SDK and MAUI versions:
The easiest way in my opinion is using the .NET CLI. Personally I prefer this as it works in almost all environments, also in CI environments such as Github Actions. The .NET CLI is normally installed with the .NET SDK which you probably have installed already.
See this
dotnet workload installmanualOn Wed, 22 Mar 2023, 17:26 FM1973, @.***> wrote:
Looks like we backported the fix to net7.0 branches here: https://github.com/dotnet/maui/pull/12914
This will be available in the next .NET 7.0 servicing release of .NET MAUI (Service Release 4) which should be available within the next few weeks.
I don’t get why you would have to change the target framework. The workaround applies to the
MediaPicker.CaptureAsyncbug, and involves a downgrade of the Android SDK, from API 33 which is supported in .NET 7.0+ to SDK 32 which is supported in .NET 6.0+.My thought are:
Please explain where I went wrong, and I might be able to help you find a working solution.
Waiting for the Solution Still.
This is how my AndroidManifest.xml looks like and its still not working any ideas?
I do see those too, note that the third error seems to be a re-parse of the second one, where the
Codeis parsed separately from theDescriptionby Visual Studio. I’m just seeing the two unique warnings.Actually, I’m now seeing 3 warnings in the error list
I still have that warning in my code right now, and it is the only one. Thinking again, I think it is possible that I only verified it using the emulator, and took the device photos with an ipad.
I recently had tried switching to the Xamarin.MediaGallery nuget package (with MAUI support) because of a different ios camera bug regarding device orientation data not getting saved in the EXIF metadata. It seemed to have some recent work done for Android 13 compatibility as well, so it seemed promising.
That completely didn’t work for me at all, so I tried switching back to MAUI essentials plus a workaround, and that seems to have fixed ios. But the Android version isn’t even launching now on a real device with a published app in Release mode. So I cannot really verify anything about this right now, except to say that it is working perfect in the emulator for Android SDK 33
I just ignored the XA4211 warning. It worked. I took photos successfully on Android 13, both with the real device and the emulator.
I think your PR is still very helpful, and I hope you continue to clean up that horrible code.
The iOS code is possibly even worse. The photos don’t respect the device orientation, and it is using obsolete APIs with lots of TODOs and pragmas in the code.
How do you get that to work? If I do that I get:
@espenrl The compilation still happens with API 33 and the MediaPicker.Capture methods won’t work.
Because the warning mentions $(TargetFrameworkVersion), I tried adding a
TargetFrameworkVersionoption with value 32 to the build, but that didn’t change a thing.I tried this, and followed the readme file, with both the stable and preview release, but it just pops up a dialog saying “Can’t connect to the camera” in the Android 13 Emulator with SDK level 33.
Are you on .NET6 like the sample? Is there some other trick to it?
Same here. I had to set the targetSdkVersion to 32 to use Notifications. A lot of people already user Android 13. It would be nice to have the new permissions implemented in Maui.