Android 写入下载文件夹时出错打开失败的EPERM操作不允许

Android 写入下载文件夹时出错打开失败的EPERM操作不允许,android,xamarin.android,Android,Xamarin.android,我正在写一个Xamarin.Android应用程序,但是用原生Android回答就足够了。我正在尝试将pdf文件(以字节[]形式下载)保存到下载文件夹中。这是我的密码: File path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads); var file = new File(path, "myfile.pdf");

我正在写一个Xamarin.Android应用程序,但是用原生Android回答就足够了。我正在尝试将pdf文件(以字节[]形式下载)保存到下载文件夹中。这是我的密码:

File path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads);
var file = new File(path, "myfile.pdf");

using (var output = new FileOutputStream(file))
{
    try
    {
        await output.WriteAsync(theByteArray);
    }
    catch (Exception ex)
    {
                
    }
}
我得到一个错误:

/存储/模拟/0/下载/myfile.pdf:打开失败:EPERM(操作 (不允许)

我在AndroidManifest.xml中检查了WriteExternalStorage,从Android 6.0(API级别23)开始,Android设备需要运行时权限

如果需要存储权限,可以使用下面的代码进行请求

public class Activity1 : Activity
{
    public string TAG
    {
        get
        {
            return "Activity1";
        }
    }
    static readonly int REQUEST_STORAGES = 1;
    static string[] PERMISSIONS_STORAGES = {
        Manifest.Permission.ReadExternalStorage,
        Manifest.Permission.WriteExternalStorage
    };

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);

        // Create your application here

        SetContentView(Resource.Layout.layout2);
        var request_permission = FindViewById<Button>(Resource.Id.btn_request_permission);
        var save = FindViewById<Button>(Resource.Id.btn_save);
        layout = FindViewById(Resource.Id.layout2);

        request_permission.Click += delegate
        {
            Log.Info(TAG, "Show Storage button pressed. Checking permissions.");

            // Verify that all required contact permissions have been granted.
            if (ActivityCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) != (int)Permission.Granted
                || ActivityCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) != (int)Permission.Granted)
            {
                // Contacts permissions have not been granted.
                Log.Info(TAG, "Storage permissions has NOT been granted. Requesting permissions.");
                RequestContactsPermissions();
            }
            else
            {
                // Contact permissions have been granted. Show the contacts fragment.
                Log.Info(TAG, "Storage permissions have already been granted.");

            }
        };

        save.Click += async delegate
        {

            if (ActivityCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) == (int)Permission.Granted
               || ActivityCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) == (int)Permission.Granted)
            {
                var path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads);
                var file = new File(path, "myfile.pdf");
                var theByteArray = new byte[] { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };

                using (var output = new FileOutputStream(file))
                {
                    try
                    {
                        await output.WriteAsync(theByteArray);
                    }
                    catch (Exception ex)
                    {

                    }
                }

            }

        };


    }
    /**
* Root of the layout of this Activity.
*/
    View layout;
    void RequestContactsPermissions()
    {
        if (ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.ReadContacts)
            || ActivityCompat.ShouldShowRequestPermissionRationale(this, Manifest.Permission.WriteContacts))
        {

            // Provide an additional rationale to the user if the permission was not granted
            // and the user would benefit from additional context for the use of the permission.
            // For example, if the request has been denied previously.
            Log.Info(TAG, "Displaying contacts permission rationale to provide additional context.");

            // Display a SnackBar with an explanation and a button to trigger the request.
            Snackbar.Make(layout, "Storage Permission is needed",
                Snackbar.LengthIndefinite).SetAction("OK", new Action<View>(delegate (View obj)
                {
                    ActivityCompat.RequestPermissions(this, PERMISSIONS_STORAGES, REQUEST_STORAGES);
                })).Show();
        }
        else
        {
            //  permissions have not been granted yet. Request them directly.
            ActivityCompat.RequestPermissions(this, PERMISSIONS_STORAGES, REQUEST_STORAGES);
        }
    }
    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
    {
        if (requestCode == REQUEST_STORAGES)
        {
            // Received permission result for  permission.
            Log.Info(TAG, "Received response for Storage permission request.");

            // Check if the only required permission has been granted
            if ((grantResults.Length == 1) && (grantResults[0] == Permission.Granted))
            {
                Log.Info(TAG, "Storage permission has now been granted.");
            }
            else
            {
                Log.Info(TAG, "Storage permission was NOT granted.");
            }
        }
        else
        {
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
公共类活动1:活动
{
公共字符串标签
{
得到
{
返回“活动1”;
}
}
静态只读int请求存储=1;
静态字符串[]权限\存储={
Manifest.Permission.ReadExternalStorage,
Manifest.Permission.WriteExternalStorage
};
创建时受保护的覆盖无效(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
//在此处创建应用程序
SetContentView(Resource.Layout.layout2);
var request\u permission=findviewbyd(Resource.Id.btn\u request\u permission);
var save=findviewbyd(Resource.Id.btn\u save);
布局=FindViewById(Resource.Id.layout2);
请求权限。单击+=委派
{
Log.Info(标记“显示已按下的存储按钮。检查权限”);
//验证是否已授予所有必需的联系人权限。
if(ActivityCompat.CheckSelfPermission(this,Manifest.Permission.ReadExternalStorage)!=(int)Permission.grated
||ActivityCompat.CheckSelfPermission(此,Manifest.Permission.WriteExternalStorage)!=(int)权限。已授予)
{
//尚未授予联系人权限。
Log.Info(标记“尚未授予存储权限。正在请求权限”);
RequestContactsPermissions();
}
其他的
{
//已授予联系人权限。显示联系人片段。
Log.Info(标记“已授予存储权限”);
}
};
保存。单击+=异步委托
{
if(ActivityCompat.CheckSelfPermission(this,Manifest.Permission.ReadExternalStorage)==(int)Permission.grated
||ActivityCompat.CheckSelfPermission(此,Manifest.Permission.WriteExternalStorage)==(int)权限。已授予)
{
var path=Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads);
var file=新文件(路径为“myfile.pdf”);
var theByteArray=新字节[]{0x20,0x20,0x20,0x20,0x20,0x20,0x20};
使用(var输出=新文件输出流(文件))
{
尝试
{
等待输出。WriteAsync(theByteArray);
}
捕获(例外情况除外)
{
}
}
}
};
}
/**
*此活动布局的根目录。
*/
视图布局;
void requestsPermissions()
{
if(ActivityCompat.shouldshowRequestPermissionRegulation)(这是Manifest.Permission.ReadContacts)
||ActivityCompat.shouldShowRequestPermissionRegulation(这是Manifest.Permission.WriteContacts))
{
//如果未授予权限,则向用户提供其他理由
//用户将从使用权限的附加上下文中受益。
//例如,如果请求先前已被拒绝。
Info(标记“显示联系人权限理由以提供附加上下文”);
//显示一个带有说明和触发请求按钮的快捷键。
Snackbar.Make(布局,“需要存储权限”,
Snackbar.LengthIndefinite.SetAction(“确定”),新操作(委托(视图obj)
{
ActivityCompat.RequestPermissions(这是权限存储,请求存储);
})).Show();
}
其他的
{
//尚未授予权限。请直接请求权限。
ActivityCompat.RequestPermissions(这是权限存储,请求存储);
}
}
public override void OnRequestPermissionsResult(int-requestCode,字符串[]权限,[GeneratedEnum]权限[]grantResults)
{
if(requestCode==请求存储)
{
//已收到权限的权限结果。
Log.Info(标记“已收到存储权限请求的响应”);
//检查是否已授予唯一必需的权限
if((grantResults.Length==1)和&(grantResults[0]==Permission.grated))
{
Log.Info(标记“存储权限现已授予”);
}
其他的
{
Log.Info(标记“未授予存储权限”);
}
}
其他的
{
base.OnRequestPermissionsResult(请求代码、权限、GrantResult);
}
}

在Android 6.0之后,您必须请求用户授予某些权限。请参阅