首页 > 解决方案 > 在外部 sd 卡上创建目录。(写访问错误)

问题描述

我按照本教程:https ://www.youtube.com/watch?v=Uzpy3qdYXmE获得使用路径写入和读取外部 SD 卡的权限:/storage/XXXX-XXXX/。但是,即使代码似乎很乐意给我权限,但在写入 SD 卡时(例如创建目录时),我仍然会收到拒绝访问错误。

这发生在 Android 7.0(自定义 rom)上。

只是为了让事情变得更加困难,目录的创建发生在一个应该跨平台运行的单独制作的库中。我使用编译符号为特定平台编译库。

该应用程序本身是一个 WebView 应用程序,它通过由库启动的 websocket 服务器与库中的代码进行交互。

我最初的想法是在 MainActivity 中请求所有需要的权限,就是这样。但显然我错过了一些东西。

这是错误消息:

System.UnauthorizedAccessException: Access to the path "/storage/09F6-DC14/Test" is denied.
at System.IO.Directory.CreateDirectoriesInternal (System.String path) [0x0004b] in <fd78fee11d3a4b2b99a184d3a0faf63e>:0 
at System.IO.Directory.CreateDirectory (System.String path) [0x00075] in <fd78fee11d3a4b2b99a184d3a0faf63e>:0 
at Library.Handlers.DirectoryHandler.CreateDirectory (System.String path, System.String name) [0x000db] in

这是我的清单文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"     package="TestApp.TestApp" android:versionCode="1"     android:versionName="0.0.1 Preview Version -WIP"     android:installLocation="preferExternal">
    <uses-sdk android:targetSdkVersion="24" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <application android:label="TestApp" android:hardwareAccelerated="true"></application>
</manifest>

这是 AssemblyInfo.cs:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Android.App;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("TestApp")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TestApp")]
[assembly: AssemblyCopyright("Copyright ©  2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]


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

这是请求权限的代码(从上述教程中使用的代码更改):

MainActivity.cs:

    readonly string[] PermissionsGroupExternalStorage=
    {
                //TODO add more permissions
                Manifest.Permission.ReadExternalStorage,
                Manifest.Permission.WriteExternalStorage
    };


    async Task GetPermissionsAsync()
    {
        const string permissionRead = Manifest.Permission.ReadExternalStorage;
        const string permissionWrite = Manifest.Permission.WriteExternalStorage;

        if  ((CheckSelfPermission(permissionRead) == (int)Android.Content.PM.Permission.Granted) && (CheckSelfPermission(permissionWrite) == (int)Android.Content.PM.Permission.Granted))
        {
            //TODO change the message to show the permissions name
            Toast.MakeText(this, "Storage permissions granted.", ToastLength.Short).Show();
            return;
        } else 
        {

            Toast.MakeText(this, "Storage permissions not granted.", ToastLength.Short).Show();
            //set alert for executing the task
            AlertDialog.Builder alert = new AlertDialog.Builder(this);
            alert.SetTitle("Storage Permissions Needed");
            alert.SetMessage("The application need special permissions to read and write to (external) storage devices to continue");
            alert.SetPositiveButton("Request Permissions", (senderAlert, args) =>
            {
                RequestPermissions(PermissionsGroupExternalStorage, RequestLocationId);
            });

            alert.SetNegativeButton("Cancel", (senderAlert, args) =>
            {
                Toast.MakeText(this, "Cancelled!", ToastLength.Short).Show();
            });

            Dialog dialog = alert.Create();
            dialog.Show();


        }

        RequestPermissions(PermissionsGroupExternalStorage, RequestLocationId);

        return;
    }

然后我只是尝试使用以下代码创建一个目录(在跨平台(ish)库中):

我的库中的 DirectoryHandler 类:

Directory.CreateDirectory("/storage/09F6-DC14/Test")

显然可以对代码进行改进,但我想让它首先工作......

吐司返回“授予存储权限”,所以我相信我确实设置了正确的权限,这就是阻止我解决这个问题的原因,如果这不是由于权限......还有什么可以阻止我访问我的外部贮存?

每次我尝试从/向外部存储设备写入/读取时,我是否真的需要请求许可?这样做似乎有点骇人听闻。

标签: c#androidxamarinandroid-external-storage

解决方案


推荐阅读