Android 6.0打开失败:EACCES(权限被拒绝)

我已经添加了uses-permission包括WRITE_EXTERNAL_STORAGEMOUNT_UNMOUNT_FILESYSTEMSREAD_EXTERNAL_STORAGEAndroidManifest.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)添加了新的权限模型。

http://www.captechconsulting.com/blogs/runtime-permissions-best-practices-and-how-to-gracefully-handle-permission-removal

所以你必须检查Runtime Permission

什么是运行时权限?

借助Android 6.0 Marshmallow,Google推出了一种新的权限模式,允许用户更好地理解为什么应用程序可能会请求特定的权限。 用户不是在安装时盲目地接受所有权限,而是提示用户在应用程序使用期间接受权限。

何时实施新模式?

除非您select在您的应用程序中使用版本23,否则不需要完全支持。 如果您的目标版本是22或更低版本,则应用程序将在安装时请求所有权限,就像运行低于棉花糖的操作系统的任何设备一样。

这些信息来自于这里:

请检查如何从此链接实施:

http://www.captechconsulting.com/blogs/runtime-permissions-best-practices-and-how-to-gracefully-handle-permission-removal

Android 6(棉花糖)中 ,即使用户在安装时已经接受了所有的权限,他们以后也可以决定将这些权限从您那里拿走。

快速的解决scheme,但不build议:也许如果你改变你的targetSdkVersion在gradle 22 ,问题将得到解决。

如何实施?(最佳实践)

  1. 首先确定用户的设备是否是棉花糖设备:

     private boolean shouldAskPermission(){ return(Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1); } 
  2. 如果shouldAskPermission()返回true ,则请求您需要的权限:

     String[] perms = {"android.permission.WRITE_EXTERNAL_STORAGE"}; int permsRequestCode = 200; requestPermissions(perms, permsRequestCode); 

requestPermissions(String[] permissions, int requestCode); 是Android Activity类中的一个公共方法。

  1. 您将在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。 切换到“充电”只为我工作。