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

[BUG] READ_EXTERNAL_STORAGE permission on Android 13 #998

Closed
2 tasks done
zZHorizonZz opened this issue Feb 15, 2023 · 10 comments
Closed
2 tasks done

[BUG] READ_EXTERNAL_STORAGE permission on Android 13 #998

zZHorizonZz opened this issue Feb 15, 2023 · 10 comments
Labels
bug Something isn't working unverified

Comments

@zZHorizonZz
Copy link

zZHorizonZz commented Feb 15, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Did you read the "Reporting a bug" section on Contributing file?

Current Behavior

The newly added feature FolderPicker is not working properly on Android 13. As of Android 13 (Api 33), it is no longer possible to use READ_EXTERNAL_STORAGE.
The new permissions are:

  • Images and photos: READ_MEDIA_IMAGES
  • Videos: READ_MEDIA_VIDEO
  • Audio files: READ_MEDIA_AUDIO

As can be seen here Android 13 Behavior Changes,

Expected Behavior

We could just probably check if API is smaller than API 33 and then use READ_EXTERNAL_STORAGE otherwise request READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO, or from my testing we don't need to request permission at all since if we want to request folder to which we don't we have permission this permission will be automatically requested via folder picker.

Steps To Reproduce

Try to run the FilePicker on a device with Android 13 (API 33).

Link to public reproduction project repository

We can just use Sample from https://github.com/CommunityToolkit/Maui/tree/main/samples/CommunityToolkit.Maui.Sample itself.

Environment

- .NET MAUI CommunityToolkit: 4.0.0
- OS: Windows 10 Enterprise Build 19044.2486
- .NET MAUI: 7.0.59 Service Release 3

Anything else?

No response

@zZHorizonZz zZHorizonZz added bug Something isn't working unverified labels Feb 15, 2023
@brminnick
Copy link
Collaborator

This is a known issue in .NET MAUI. The team has fixed it in an upcoming release: dotnet/maui#11275

@brminnick brminnick closed this as not planned Won't fix, can't repro, duplicate, stale Feb 15, 2023
@Christerad
Copy link

When is The Upcoming Release ?

@zZHorizonZz
Copy link
Author

When is The Upcoming Release ?

I think they are usually every month.

@zZHorizonZz
Copy link
Author

Hi, since I was waiting for the fix I just tested on 32 and then I kinda forgot about that, but now since you reminded it to me I have done some digging and found out that it still doesn't work. But I was able to create the workaround:

#if ANDROID
    public async Task<bool> RequestPermissionAsync()
    {
        var activity = Platform.CurrentActivity ?? throw new NullReferenceException("Current activity is null");

        if (ContextCompat.CheckSelfPermission(activity, Manifest.Permission.ReadExternalStorage) == Permission.Granted)
        {
            return true;
        }

        if (ActivityCompat.ShouldShowRequestPermissionRationale(activity, Manifest.Permission.ReadExternalStorage))
        {
            await Toast.Make("Please grant access to external storage", ToastDuration.Short, 12).Show();
        }

        ActivityCompat.RequestPermissions(activity, new[] { Manifest.Permission.ReadExternalStorage }, 1);

        return false;
    }
#endif

And you can use it:

#if ANDROID

            await RequestPermissionAsync();
#endif

            var folder = await mFolderPicker.PickAsync(cancelToken);
            folder.EnsureSuccess();

You also need to make sure to import the android imports:

#if ANDROID
using Android;
using Android.Content.PM;
using AndroidX.Core.App;
using AndroidX.Core.Content;
#endif

@zZHorizonZz
Copy link
Author

zZHorizonZz commented May 2, 2023

@brminnick Could you reopen this issue since this still doesn't seem like it's fixed and also your comment is linked to write related issue and not read issue.

@VladislavAntonyuk
Copy link
Collaborator

@zZHorizonZz it is not an issue of CommunityToolkit. It's better to open the issue in .NET MAUI repo on Permissions.RequestAsync API

@MichaelStett
Copy link

Thank you for this workaround! @zZHorizonZz :)

@cworth33
Copy link

Special thanks to @zZHorizonZz for the workaround

I was having similar issues with the FileSaver.
With knowledge of the above workaround I made similar adjustments to get FileSaver to work with API 33.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
	<application android:allowBackup="true" android:icon="@mipmap/appicon" android:supportsRtl="true"></application>
	<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
	<uses-permission android:name="android.permission.INTERNET" />
	<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
	<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
	<queries>
		<intent>
			<action android:name="android.intent.action.SENDTO" />
			<data android:scheme="mailto" />
		</intent>
	</queries>
</manifest>

Content Page or Content View code behind

#if ANDROID
using Android;
using Android.Content.PM;
using AndroidX.Core.App;
using AndroidX.Core.Content;
#endif

Using the FileSaver in your page or view

            // this will run for Android 33 and greater
            if (DeviceInfo.Platform == DevicePlatform.Android && OperatingSystem.IsAndroidVersionAtLeast(33))
            {
#if ANDROID
                var activity = Platform.CurrentActivity ?? throw new NullReferenceException("Current activity is null");
                if (ContextCompat.CheckSelfPermission(activity, Manifest.Permission.ReadExternalStorage) != Permission.Granted)
                {
                    ActivityCompat.RequestPermissions(activity, new[] { Manifest.Permission.ReadExternalStorage }, 1);
                }
#endif
            }

            var fileSaverResult = await FileSaver.Default.SaveAsync(attachment.AttachmentName, stream, cancellationToken);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working unverified
Projects
None yet
Development

No branches or pull requests

7 participants
@brminnick @cworth33 @MichaelStett @VladislavAntonyuk @zZHorizonZz @Christerad and others