Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Sunday, March 22, 2020 9:56 AM
Hi all,
I'm trying to enumerate through all files located in "/storage/emulated/0/DCIM" and "/storage/emulated/0/Pictures". However I'm getting an Access Denied exception when trying to enumerate through them.
I've added the READEXTERNALSTORAGE and WRITEEXTERNALSTORAGE permissions and used the Xamarin.Essentials permissions to ask the user at runtime to give access. The app info shows that the app has indeed access to storage.
Does anyone know why I'm still getting this exception?
Xamarin Forms: 4.4.0.991757 Target Android API: 29, minimum 28. (Going to use the app at home)
Thank you in advance.
All replies (14)
Sunday, March 22, 2020 11:07 AM
maybe you need runtime permissions
Sunday, March 22, 2020 11:08 AM
Thank you but no, I've already asked for permissions on runtime. Hence the line "... and used the Xamarin.Essentials permissions to ask the user at runtime to give access.".
Monday, March 23, 2020 1:51 AM
What's the full log of this error? If it is convenient for you ,could you please post a basic demo or some code snippet so that we can test on our side?
Wednesday, March 25, 2020 10:18 AM
I can't seem to post a reply. "Has to be approved", but doesn't seem to get approved... I've sent you a message.
Thursday, March 26, 2020 3:30 AM
Is your app based on xamarin form, right? I will test myself.
Thursday, March 26, 2020 5:33 AM
Hi In your device, you must activate setting / application / Myapplication/permissions/storage.
Thursday, March 26, 2020 8:53 AM
@jezh said: Is your app based on xamarin form, right? I will test myself.
Yes, Xamarin Forms.
@readn said: Hi In your device, you must activate setting / application / Myapplication/permissions/storage.
As I already said, storage is granted in app settings. But thanks anyways.
Friday, March 27, 2020 8:31 AM
I created a demo to achieve this function,and use PermissionsPlugin
to request permission.It works properly. The main code is as follows, you can check it.
interface IFileReadWrite
public interface IFileReadWrite
{
List<string> getFile();
}
class FileHelper(android)
public class FileHelper: IFileReadWrite
{
public List<string> getFile()
{
string dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures).AbsolutePath;
string[] files = Directory.GetFiles(dir);
return new List<string>(files);
}
}
MainPage.xaml.cs
private async void BtnGetFile_Clicked(object sender, EventArgs e)
{
var status = PermissionStatus.Unknown;
status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);
btnGetFile.IsEnabled = false;
await DisplayAlert("Pre - Results", status.ToString(), "OK");
if (status != PermissionStatus.Granted)
{
status = await Utils.CheckPermissions(Permission.Storage);
}
await DisplayAlert("Results", status.ToString(), "OK");
btnGetFile.IsEnabled = true;
List<string> files = DependencyService.Get<IFileReadWrite>().getFile();
if (files!=null && files.Count>0) {
System.Diagnostics.Debug.WriteLine("***result files " + files.Count);
foreach (string item in files) {
lblFileTexts.Text = item +" /n";
}
}
}
The result is:
Note: You can follow the PermissionsPlugin to add permission. And there is a sample withe this link. It should be helpful for you.
Friday, March 27, 2020 10:48 AM
Thank you for your demo. Your code is almost the same as what I sent you. You're using Plugin.Permissions but it actually uses Xamarin.Essentials to ask for permissions.
However, I copied over your code (and used Plugin.Permissions) and it still throws the exception when trying to access the file system. Tried it on my physical device and emulator. Both Android 10. Xamarin Forms 4.4.0.991265.
Could you send me your project to test it out myself? Maybe you're on a lower API or Forms version than me?
Friday, March 27, 2020 11:06 AM
@StephanBisschop Hi friend, I have put the demo into the attachement, you can check it.
Friday, March 27, 2020 12:52 PM
It seems to not work when the Android project is set to compile for Android 10. Even with your working project. The Alerts return granted but after that the exception gets thrown again.
Could you try it at your end?
Tuesday, March 31, 2020 9:57 AM
Yes, it is just the case as you said. When we check document getExternalStoragePublicDirectory, we will see
So, when an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible to apps.
Tuesday, May 12, 2020 3:23 PM
Stacktrace: System.UnauthorizedAccessException: 'Access to the path '/storage/emulated/0' is denied.'
03-23 10:42:00.923 D/Mono ( 9121): DllImport attempting to load: '/system/lib64/liblog.so'. 03-23 10:42:00.924 D/Mono ( 9121): DllImport loaded library '/system/lib64/liblog.so'. 03-23 10:42:00.925 D/Mono ( 9121): DllImport searching in: '/system/lib64/liblog.so' ('/system/lib64/liblog.so'). 03-23 10:42:00.925 D/Mono ( 9121): Searching for '**androidlogprint'. 03-23 10:42:00.925 D/Mono ( 9121): Probing '**androidlogprint'. 03-23 10:42:00.925 D/Mono ( 9121): Found as 'androidlogprint'. 03-23 10:42:00.929 I/MonoDroid( 9121): UNHANDLED EXCEPTION: 03-23 10:42:00.933 I/MonoDroid( 9121): System.UnauthorizedAccessException: Access to the path '/storage/emulated/0' is denied. > System.IO.IOException: Permission denied 03-23 10:42:00.933 I/MonoDroid( 9121): End of inner exception stack trace 03-23 10:42:00.933 I/MonoDroid( 9121): at System.IO.Enumeration.FileSystemEnumerator1[TResult].CreateDirectoryHandle (System.String path, System.Boolean ignoreNotFound) [0x0002a] in /Users/builder/jenkins/workspace/archive-mono/2019-10/android/release/external/corefx/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs:89 03-23 10:42:00.933 I/MonoDroid( 9121): at System.IO.Enumeration.FileSystemEnumerator
1[TResult]..ctor (System.String directory, System.IO.EnumerationOptions options) [0x00048] in /Users/builder/jenkins/workspace/archive-mono/2019-10/android/release/external/corefx/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerator.Unix.cs:49 03-23 10:42:00.933 I/MonoDroid( 9121): at System.IO.Enumeration.FileSystemEnumerable1+DelegateEnumerator[TResult]..ctor (System.IO.Enumeration.FileSystemEnumerable
1[TResult] enumerable) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2019-10/android/release/external/corefx/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerable.cs:57 03-23 10:42:00.933 I/MonoDroid( 9121): at System.IO.Enumeration.FileSystemEnumerable1[TResult]..ctor (System.String directory, System.IO.Enumeration.FileSystemEnumerable
1+FindTransform[TResult] transform, System.IO.EnumerationOptions options) [0x00042] in /Users/builder/jenkins/workspace/archive-mono/2019-10/android/release/external/corefx/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerable.cs:29 03-23 10:42:00.933 I/MonoDroid( 9121): at System.IO.Enumeration.FileSystemEnumerableFactory.UserFiles (System.String directory, System.String expression, System.IO.EnumerationOptions options) [0x00014] in /Users/builder/jenkins/workspace/archive-mono/2019-10/android/release/external/corefx/src/System.IO.FileSystem/src/System/IO/Enumeration/FileSystemEnumerableFactory.cs:90 03-23 10:42:00.933 I/MonoDroid( 9121): at System.IO.Directory.InternalEnumeratePaths (System.String path, System.String searchPattern, System.IO.SearchTarget searchTarget, System.IO.EnumerationOptions options) [0x0003c] in /Users/builder/jenkins/workspace/archive-mono/2019-10/android/release/external/corefx/src/System.IO.FileSystem/src/System/IO/Directory.cs:178 03-23 10:42:00.933 I/MonoDroid( 9121): at System.IO.Directory.GetFiles (System.String path, System.String searchPattern, System.IO.EnumerationOptions enumerationOptions) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2019-10/android/release/external/corefx/src/System.IO.FileSystem/src/System/IO/Directory.cs:140 03-23 10:42:00.933 I/MonoDroid( 9121): at System.IO.Directory.GetFiles (System.String path, System.String searchPattern) [0x00000] in /Users/builder/jenkins/workspace/archive-mono/2019-10/android/release/external/corefx/src/System.IO.FileSystem/src/System/IO/Directory.cs:134 03-23 10:42:00.933 I/MonoDroid( 9121): at BisschopFotos.App.Droid.Services.FileSystem+<>cDisplayClass1
0.b0 () [0x00007] in D:\Stephan\Documents\Projects\BisschopFotos\BisschopFotos\BisschopFotos.App\BisschopFotos.App.Android\Services\FileSystem.cs:30 03-23 10:42:00.933 I/MonoDroid( 9121): at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in :0 03-23 10:42:00.933 I/MonoDroid( 9121): at Java.Lang.IRunnableInvoker.nRun (System.IntPtr jnienv, System.IntPtr nativethis) [0x00009] in :0 03-23 10:42:00.933 I/MonoDroid( 9121): at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.62(intptr,intptr) 03-23 10:42:00.942 W/sschopfotos.ap( 9121): JNI RegisterNativeMethods: attempt to register 0 native methods for android.runtime.JavaProxyThrowable 03-23 10:42:00.945 D/Mono ( 9121): DllImport searching in: '_Internal' ('(null)'). 03-23 10:42:00.945 D/Mono ( 9121): Searching for 'javainteropjnienvthrow'. 03-23 10:42:00.945 D/Mono ( 9121): Probing 'javainteropjnienvthrow'. 03-23 10:42:00.945 D/Mono ( 9121): Found as 'javainteropjnienvthrow'. System.UnauthorizedAccessException: 'Access to the path '/storage/emulated/0' is denied.'
03-23 10:42:02.108 E/mono ( 9121): 03-23 10:42:02.108 E/mono ( 9121): Unhandled Exception: 03-23 10:42:02.108 E/mono ( 9121): System.UnauthorizedAccessException: Access to the path '/storage/emulated/0' is denied. > System.IO.IOException: Permission denied 03-23 10:42:02.108 E/mono ( 9121): End of inner exception stack trace 03-23 10:42:02.108 E/mono ( 9121): at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.62(intptr,intptr) 03-23 10:42:02.108 E/mono ( 9121): at (wrapper native-to-managed) Android.Runtime.DynamicMethodNameCounter.62(intptr,intptr) 03-23 10:42:02.108 E/mono-rt ( 9121): [ERROR] FATAL UNHANDLED EXCEPTION: System.UnauthorizedAccessException: Access to the path '/storage/emulated/0' is denied. > System.IO.IOException: Permission denied 03-23 10:42:02.108 E/mono-rt ( 9121): End of inner exception stack trace 03-23 10:42:02.108 E/mono-rt ( 9121): at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.62(intptr,intptr) 03-23 10:42:02.108 E/mono-rt ( 9121): at (wrapper native-to-managed) Android.Runtime.DynamicMethodNameCounter.62(intptr,intptr)
Code snippet in Xamarin.Android project. (implements IFileSystem)
public IEnumerable GetFiles() { //var filePath = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures); //var canRead = filePath.CanRead(); // This returns false var files = new [] { "" }; var path = "/storage/emulated/0/Pictures"; //Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures).AboslutePath; files = Directory.GetFiles(path); //This line throws the exception
return files; }
Code snippet in Xamarin.Forms project
Device.BeginInvokeOnMainThread(async () => { await Permissions.RequestAsync().ConfigureAwait(false); await Permissions.RequestAsync().ConfigureAwait(false);
if (await Permissions.CheckStatusAsync().ConfigureAwait(false) != PermissionStatus.Granted && await Permissions.CheckStatusAsync().ConfigureAwait(false) != PermissionStatus.Granted) { throw new Exception("No rights to storage"); // The permissions are granted, so this does not get triggered } var files = DependencyService.Get().GetFiles(); });
(Code markdown didn't seem to like my code, so put it in quote markdown)
Thanks!
Monday, January 18, 2021 4:01 PM
Is there a solution for this mess? VS 2019 16.8.4 requires Xamarin Forms Apps to Target Android 10 an the android workaround (android:requestLegacyExternalStorage="true") does not work for /storage/emulated/0