Xamarin Essentials Permissions failing to grant permission

Viewed 7479

I'm currently writing a Xamarin Forms app which requires use of the camera, in the code below I am requesting the permission using the Xamarin Essentials Permissions which comes back as "Granted"; immediately following that I am requesting use of the camera to take a photo, which throws the following error.

ex = {Plugin.Media.Abstractions.MediaPermissionException: Camera permission(s) are required.

The permission code

public static async Task<bool> GetPermission<TPermission>() where TPermission : BasePermission, new()
    {
        var hasPermission = await Permissions.CheckStatusAsync<TPermission>();

        if (hasPermission == PermissionStatus.Granted)
            return true;
        else if (hasPermission == PermissionStatus.Disabled)
            return false;

        var result = await Permissions.RequestAsync<TPermission>();
        if (result != PermissionStatus.Granted)
            return false;

        return true;
    }

The photo manager code

if(!await PermissionHelpers.GetPermission<Permissions.Camera>())
        {
            await new ErrorAlert().Show("App can't take a picture without permission to use the camera");
            return string.Empty;
        }

        var photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
        {
            PhotoSize = PhotoSize.Small,
            SaveToAlbum = false
        });

As previously said, the GetPermission method returns true, but still the error is thrown.

I'm currently running this on Android. My AndroidManifest.xml has these permission in it.

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

I have now made a sample project to showcase my issue GitHub Repo for the issue

4 Answers

don't forget

Android

protected override void OnCreate(Bundle savedInstanceState) {
    //...
    base.OnCreate(savedInstanceState);
    Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
    //...

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
    Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

    base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

Documentation

First of all, I notice you use Xam.Plugin.Media, this plugin need WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE and android.permission.CAMERA in Android, You should request these permission at runtime.

You can use following code in the MainActivity

  public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);

        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());

        if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) != (int)Permission.Granted)
        {
            RequestPermissions(new string[] { Manifest.Permission.Camera, Manifest.Permission.WriteExternalStorage, Manifest.Permission.ReadExternalStorage }, 0);
        }

    } 

Here is running gif.

enter image description here

Update

If you use this CrossMedia, you need grant Storage and Camera permission.Please open your PhotoManager.cs Add the request storage code like following code.

     public class PhotoManager
{
    public async Task<string> TakeNewPhoto()
    {
        try
        {
            if (!CrossMedia.IsSupported || !CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
            {
                return string.Empty;
            }

            if (!await PermissionHelpers.GetPermission<Permissions.Camera>())
            {
                return string.Empty;
            }
            //=====================================add above line==================================================

            if (!await PermissionHelpers.GetPermission<Permissions.StorageWrite>())
            {
                return string.Empty;
            }

            var photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
            {
                PhotoSize = PhotoSize.Small,
                SaveToAlbum = false
            });

            if (photo != null)
            {
                return "photo taken successfully";
            }

            return string.Empty;
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
    }
}

Here is your issueProjects' running GIF.

enter image description here

thank you for all of your time gone into helping me to resolve this issue. It turned out that if you are using Xamarin essentials version 1.5.0 you need to install the CurrentActivity NuGet plugin to your android project.

Or, a better solution is update to 1.5.1 which resolves the issue entirely.

You must add permissions for camera to your Android Manifest file!

In Visual Studio right click your android project.

Go to Options -> Build -> Android Application and tick the box in required permissions that says camera.

NB: If you are going to be recording you may also want to enable microphone and audio permissions.

You must also add:

<uses-feature android:name="android.hardware.camera" />

To your android manifest.

Related