Java Android 6.0 打开失败:EACCES(权限被拒绝)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33030933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android 6.0 open failed: EACCES (Permission denied)
提问by HelloSilence
I have added uses-permission
including WRITE_EXTERNAL_STORAGE
,MOUNT_UNMOUNT_FILESYSTEMS
,READ_EXTERNAL_STORAGE
to AndroidManifest.xml
.
我添加了uses-permission
包括WRITE_EXTERNAL_STORAGE
,MOUNT_UNMOUNT_FILESYSTEMS
,READ_EXTERNAL_STORAGE
到AndroidManifest.xml
。
When I tried to run my application in Nexus5 (Android 6.0),it threw a exception as below:
当我尝试在 Nexus5 (Android 6.0) 中运行我的应用程序时,它抛出了如下异常:
java.io.IOException: open failed: EACCES (Permission denied)
java.io.IOException: open failed: EACCES (Permission denied)
And I tried another Android phone(Android 5.1),everything was OK.Here's the code:
我尝试了另一部 Android 手机(Android 5.1),一切正常。代码如下:
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
currentPhotoPath = image.getAbsolutePath();
return image;
}
Does Android 6.0 have difference about permission?
Android 6.0 在权限上有区别吗?
采纳答案by AndiGeeky
Android added new permission model for Android 6.0 (Marshmallow).
Android 为Android 6.0 (Marshmallow)添加了新的权限模型。
So you have to check Runtime Permission
:
所以你必须检查Runtime Permission
:
What Are Runtime Permissions?
什么是运行时权限?
With Android 6.0 Marshmallow, Google introduced a new permission model that allows users to better understand why an application may be requesting specific permissions. Rather than the user blindly accepting all permissions at install time, the user is now prompted to accept permissions as they become necessary during application use.
在 Android 6.0 Marshmallow 中,Google 引入了一种新的权限模型,使用户能够更好地了解应用程序可能会请求特定权限的原因。与用户在安装时盲目地接受所有权限不同,现在会提示用户接受在应用程序使用过程中变得必要的权限。
When to Implement the New Model?
何时实施新模式?
it doesn't require full support until you choose to target version 23 in your application. If you are targeting version 22 or below, your application will request all permissions at install time just as it would on any device running an OS below Marshmallow.
在您选择在应用程序中定位到版本 23 之前,它不需要完全支持。如果您的目标是版本 22 或更低版本,您的应用程序将在安装时请求所有权限,就像在运行 Marshmallow 以下操作系统的任何设备上一样。
This information is taken from here :
此信息取自此处:
Please check How to implement from this link :
请检查如何从此链接实施:
回答by Hamed Ghadirian
In Android 6(Marshmallow), even though the user accepted all your permissions at install time, they can later decide to take some of those permissions away from you.
在Android 6(Marshmallow) 中,即使用户在安装时接受了您的所有权限,他们也可以稍后决定从您那里拿走其中的一些权限。
Fast solution but not recommended:maybe if you change your targetSdkVersion
in the gradle to 22
, the problem will be solved.
快速解决方案但不推荐:也许如果您targetSdkVersion
将 gradle更改为22
,问题将得到解决。
How To Implement?(Best Practices)
如何实施?(最佳实践)
First determine if the user's device is a Marshmallow device or not:
private boolean shouldAskPermission(){ return(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1); }
If
shouldAskPermission()
returntrue
, ask for permission you need:String[] perms = {"android.permission.WRITE_EXTERNAL_STORAGE"}; int permsRequestCode = 200; requestPermissions(perms, permsRequestCode);
首先判断用户的设备是否是 Marshmallow 设备:
private boolean shouldAskPermission(){ return(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1); }
如果
shouldAskPermission()
returntrue
,请求你需要的许可:String[] perms = {"android.permission.WRITE_EXTERNAL_STORAGE"}; int permsRequestCode = 200; requestPermissions(perms, permsRequestCode);
The method requestPermissions(String[] permissions, int requestCode);
is a public method found inside of the Android Activity class.
该方法requestPermissions(String[] permissions, int requestCode);
是在 Android Activity 类中找到的公共方法。
You will receive the results of your request in the method onRequestPermissionResult as shown below:
@Override public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){ switch(permsRequestCode){ case 200: boolean writeAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED; break; } }
您将在方法 onRequestPermissionResult 中收到您的请求结果,如下所示:
@Override public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){ switch(permsRequestCode){ case 200: boolean writeAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED; break; } }
After receiving the results, you will need to handle them appropriately.
收到结果后,您需要妥善处理。
Suggested Permissions Flow:
建议的权限流程:
More Info:
更多信息:
A user with a Marshmallow device will now have the ability to revoke dangerous permissionsvia the application settings
拥有 Marshmallow 设备的用户现在可以通过应用程序设置撤销危险权限
Android defines some permissions as “dangerous” and some permissions as “normal.” Both are required in your application's manifest but only dangerous permissions require a runtime request.
Android 将一些权限定义为“危险”,将一些权限定义为“正常”。您的应用程序清单中都需要两者,但只有危险权限需要运行时请求。
If you have chosen not to implement the new permissions model(runtime request), the revocation of permissions can cause unwanted user experiences and in some cases application crashes.
如果您选择不实施新的权限模型(运行时请求),权限的撤销可能会导致不必要的用户体验,并且在某些情况下会导致应用程序崩溃。
The table below lists all the current dangerous permissions and their respective groups:
下表列出了所有当前的危险权限及其各自的组:
If the user accepts one permission in a group/category they accept the entire group!
如果用户接受一个组/类别中的一个权限,则他们接受整个组!
Source:http://www.captechconsulting.com
资料来源:http: //www.captechconsulting.com
Using Dexter Library:
使用德克斯特库:
You can use Dexter. Android library that simplifies the process of requesting permissions at runtime.
您可以使用德克斯特。Android 库,可简化在运行时请求权限的过程。
回答by c0ming
You can also use ActivityCompat.requestPermissionsfor backwards compatible.
您还可以使用ActivityCompat.requestPermissions进行向后兼容。
example:
例子:
private static final int REQUEST_CODE = 0x11;
String[] permissions = {"android.permission.WRITE_EXTERNAL_STORAGE"};
ActivityCompat.requestPermissions(this, permissions, REQUEST_CODE); // without sdk version check
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// save file
} else {
Toast.makeText(getApplicationContext(), "PERMISSION_DENIED", Toast.LENGTH_SHORT).show();
}
}
}
回答by Ronny Kibet
From API-23 you need to declare the permission in activity even if you have already declared in manifest.
从 API-23 开始,即使您已经在清单中声明,您也需要在活动中声明权限。
// Storage Permissions variables
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
//persmission method.
public static void verifyStoragePermissions(Activity activity) {
// Check if we have read or write permission
int writePermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int readPermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
if (writePermission != PackageManager.PERMISSION_GRANTED || readPermission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
To use simply call verifyStoragePermissions(this);
in onCreate.
That should do it hopefully.
要使用,只需调用verifyStoragePermissions(this);
onCreate。那应该有希望。
回答by gderaco
If you are lazy, just downgrade targetSdkVersion to 22 (before lollipop)
如果你懒惰,只需将 targetSdkVersion 降级到 22(棒棒糖之前)
回答by Uma
This worked for me.
这对我有用。
Go to Settings -> Applications -> YourApp -> Provide permissions to Storage, Contacts etc.
转到设置 -> 应用程序 -> YourApp -> 提供对存储、联系人等的权限。
回答by HDQ
I met the same trouble.
我遇到了同样的麻烦。
Maybe it is caused by your phone security mechanism. You may go to 'settings' to authorize write/read permissions.
可能是你的手机安全机制造成的。您可以转到“设置”来授权写/读权限。
回答by kunal agarwal
For me, my phone connected as USB as MTP was the issue even after doing everything stated here. Switched it to "Charging Only" worked for me.
对我来说,即使完成了此处所述的所有操作,我的手机仍以 USB 作为 MTP 连接,这仍然是问题。将其切换为“仅充电”对我有用。
回答by Remy
Google has a new feature on Android Q: filtered view for external storage. A quick fix for that is to add this code in the AndroidManifest.xml file:
谷歌在 Android Q 上有一个新功能:外部存储的过滤视图。对此的快速解决方法是在 AndroidManifest.xml 文件中添加以下代码:
<manifest ... >
<!-- This attribute is "false" by default on apps targeting Android Q. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
You can read more about it here: https://developer.android.com/training/data-storage/compatibility
您可以在此处阅读更多相关信息:https: //developer.android.com/training/data-storage/compatibility