0

I'm running into a very odd issue in my Xamarin Forms app. I am trying to take a picture in my app, then use OCR to read the text, but I'm struggling to get permissions to be granted for WRITE_EXTERNAL_STORAGE. I now have to declare WRITE_EXTERNAL_STORAGE twice in my AndroidManifest in order for the app to allow me to request storage permissions or to access storage, once as a self-closing tag and once with explicit tag:

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

If either is removed (leaving just one version of WRITE_EXTERNAL_STORAGE), I get the following exception when trying to request permissions for external storage or when trying to capture a picture: "You need to declare using the permission: android.permission.WRITE_EXTERNAL_STORAGE in your AndroidManifest.xml"

This ONLY affects WRITE_EXTERNAL_STORAGE...all other declared permissions (using self-closing tags) in the manifest work appropriately. It's just the write storage permission that needs this "hack."

This issue occurs on emulated devices (debug mode) AND on physical devices (via Play Store alpha track) when only one instance of the permission is listed. When debugging with both lines in the manifest, the app is able to obtain permissions to storage successfully and I can take the picture as expected. The Play Store will not accept submissions with duplicate lines in the manifest, so I am unable to submit to the store using this "hack."

This is a full copy of my AndroidManifest (without PII), including the duplicate lines I have to include in order for storage permissions to be granted successfully when debugging:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="myapp" android:versionName="3.2.2" android:installLocation="auto" android:versionCode="59">
    <application android:theme="@android:style/Theme.Material.Light" android:icon="@drawable/Icon120" android:label="MyApp">
        <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"></meta-data>
        </provider>
    </application>
    <uses-feature android:name="android.hardware.camera" android:required="true" />
    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29" />
    <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-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
</manifest>

I also have the following line in my AssemblyInfo.cs file:

[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]

When I try to request permissions via Xamarin.Essentials or to access the camera to tke a picture via Xamarin.Essentials or CrossMedia, the app blows up with the above exception, claiming I am missing the WRITE_EXTERNAL_STORAGE permission, despite it being in the manifest once (either self-closed or with explicit tag). Any of these lines executing will result in the exception and all lines work when both entries for WRITE_EXTERNAL_STORAGE are present:

var permissionStatus = await Xamarin.Essentials.Permissions.RequestAsync<Xamarin.Essentials.Permissions.StorageWrite>();
var photo = await Xamarin.Essentials.MediaPicker.CapturePhotoAsync(new Xamarin.Essentials.MediaPickerOptions { Title = DateTime.Now.ToString("G") + ".jpg" });
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions { Name = DateTime.Now.ToString("G") + ".jpg" });

I have tried updating all of my NuGet packages and am now on the latest versions of frameworks for the app (Xamarin Forms v5 and Xamarin.Essentials 1.6.1) but this issue still persists. I also tried completely deleting the manifest and restarting from scratch, but the same "hack" is still needed.

Has anyone run into this or have any idea of how this can be fixed?

Thank you in advance!

lfrahm
  • 21
  • 2
  • [VS2019 16.9 removes automatic addition of this](https://github.com/xamarin/xamarin-android/commit/113ffccfcd144aa03f6ab288d1c82756e8da0463) – magicandre1981 Feb 01 '21 at 15:01
  • @magicandre1981 unfortunately, this is for write permission instead of read. I did try removing the write from the manifest just in case it would work for write as well, but the same exception about missing write permissions still occurs – lfrahm Feb 01 '21 at 16:10
  • Is this happening in android 10 devices only or all devices? – Anand Feb 01 '21 at 18:15
  • You can check with this link. I am not sure wether your issue is related with this. Have a look https://stackoverflow.com/questions/57449242/android-q-10-ask-permission-to-get-access-all-storage-scoped-storage – Anand Feb 01 '21 at 18:16
  • @Anand this is happening with all Android devices, though most of them are indeed using Android10. I tried that linked article, but it appears the issue persists – lfrahm Feb 02 '21 at 14:28
  • @lfrahm Can you test your project at other android version, not android 10, to see whether there are difference. – Cherry Bu - MSFT Feb 04 '21 at 07:20

1 Answers1

2

To anyone who has this issue, the solution was to remove all references to and uninstall the NuGet package for HockeySDK.Xamarin. As soon as I removed everything related to this, the issue resolved itself and I no longer had the problem with the manifest

lfrahm
  • 21
  • 2