Android 6.0打开失败:EACCES(权限被拒绝)
我已经添加了uses-permission
包括WRITE_EXTERNAL_STORAGE
, MOUNT_UNMOUNT_FILESYSTEMS
, READ_EXTERNAL_STORAGE
到AndroidManifest.xml
。
当我试图在Nexus5(Android 6.0)中运行我的应用程序时,它抛出了一个exception,如下所示:
java.io.IOException: open failed: EACCES (Permission denied)
而我尝试了另一个Android手机(Android 5.1),一切都OK。这里的代码:
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; }
Android 6.0对于权限有没有区别?
Android为Android 6.0(Marshmallow)添加了新的权限模型。
所以你必须检查Runtime Permission
:
什么是运行时权限?
借助Android 6.0 Marshmallow,Google推出了一种新的权限模式,允许用户更好地理解为什么应用程序可能会请求特定的权限。 用户不是在安装时盲目地接受所有权限,而是提示用户在应用程序使用期间接受权限。
何时实施新模式?
除非您select在您的应用程序中使用版本23,否则不需要完全支持。 如果您的目标版本是22或更低版本,则应用程序将在安装时请求所有权限,就像运行低于棉花糖的操作系统的任何设备一样。
这些信息来自于这里:
请检查如何从此链接实施:
在Android 6(棉花糖)中 ,即使用户在安装时已经接受了所有的权限,他们以后也可以决定将这些权限从您那里拿走。
快速的解决scheme,但不build议:也许如果你改变你的targetSdkVersion
在gradle 22
,问题将得到解决。
如何实施?(最佳实践)
-
首先确定用户的设备是否是棉花糖设备:
private boolean shouldAskPermission(){ return(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1); }
-
如果
shouldAskPermission()
返回true
,则请求您需要的权限:String[] perms = {"android.permission.WRITE_EXTERNAL_STORAGE"}; int permsRequestCode = 200; requestPermissions(perms, permsRequestCode);
requestPermissions(String[] permissions, int requestCode);
是Android Activity类中的一个公共方法。
-
您将在onRequestPermissionResult方法中收到您的请求的结果,如下所示:
@Override public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){ switch(permsRequestCode){ case 200: boolean writeAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED; break; } }
收到结果后,您需要适当地处理它们。
build议的权限stream程:
更多信息:
拥有棉花糖设备的用户现在可以通过应用程序设置撤消危险的权限
Android将某些权限定义为“ 危险 ”,某些权限定义为“ 正常” 。两者都是您的应用程序清单中所必需的,但只有危险权限才需要运行时请求。
如果您select不实施新的权限模型(运行时请求),则权限的撤销可能导致不需要的用户体验,并且在某些情况下应用程序崩溃。
下表列出了所有当前的危险权限及其各自的组:
如果用户接受一个组/类别的一个权限,他们接受整个组!
来源: http : //www.captechconsulting.com
使用德克斯特图书馆:
你可以使用德克斯特 。 Android库简化了运行时请求权限的过程。
你也可以使用ActivityCompat.requestPermissions来向后兼容。
例:
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(); } } }
从API-23开始,即使已经在manifest中声明,也需要在活动中声明权限。
// 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 ); } }
要使用简单的调用verifyStoragePermissions(this);
在onCreate。 这应该有希望。
这对我有效。
进入设置 – >应用程序 – >你的应用程序 – >提供权限存储,联系人等
如果你懒,只需将targetSdkVersion降级到22(在棒棒糖之前)
我遇到了同样的麻烦。
也许这是由您的手机安全机制造成的。 你可以去'设置'授权写/读权限。
对于我来说,即使在做了这里所说的一切之后,我的手机就像USB一样连接到MTP。 切换到“充电”只为我工作。