Android 写入下载文件夹时出错打开失败的EPERM操作不允许
我正在写一个Xamarin.Android应用程序,但是用原生Android回答就足够了。我正在尝试将pdf文件(以字节[]形式下载)保存到下载文件夹中。这是我的密码: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");
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之后,您必须请求用户授予某些权限。请参阅