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

2022-08-31 16:52:58

我已将包含,,添加到。uses-permissionWRITE_EXTERNAL_STORAGEMOUNT_UNMOUNT_FILESYSTEMSREAD_EXTERNAL_STORAGEAndroidManifest.xml

当我尝试在Nexus5(Android 6.0)中运行我的应用程序时,它抛出了如下异常:

java.io.IOException: open failed: EACCES (Permission denied)

我尝试了另一款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;
}

Android 6.0 在权限方面有区别吗?


答案 1

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引入了一种新的权限模型,使用户能够更好地了解应用程序可能请求特定权限的原因。现在,系统不会在安装时盲目地接受所有权限,而是在应用程序使用过程中需要这些权限时提示用户接受这些权限。

何时实施新模型?

在选择在应用程序中以版本 23 为目标之前,它不需要完全支持。如果您的目标是版本 22 或更低版本,则应用程序将在安装时请求所有权限,就像在运行 Marshmallow 以下操作系统的任何设备上一样。

此信息取自此处:

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

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


答案 2

Android 6(Marshmallow)中,即使用户在安装时接受了您的所有权限,他们以后也可以决定从您那里拿走其中一些权限。

快速解决方案但不推荐:也许如果你把你的在gradle更改为,问题就会得到解决。targetSdkVersion22

如何实施?(最佳实践)

  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);
    

该方法是在 Android Activity 类中找到的公共方法。requestPermissions(String[] permissions, int requestCode);

  1. 您将在方法 onRequestPermissionResult 中收到请求的结果,如下所示:

    @Override
    public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults){
    
    switch(permsRequestCode){
    
        case 200:
    
            boolean writeAccepted = grantResults[0]==PackageManager.PERMISSION_GRANTED;
    
            break;
    
    }
    
    }
    

收到结果后,您需要妥善处理它们。

建议的权限流:

enter image description here

更多信息:

拥有棉花糖设备的用户现在可以通过应用程序设置撤销危险权限

Android将某些权限定义为“危险”,将某些权限定义为“正常”。两者在应用程序的清单中都是必需的,但只有危险权限才需要运行时请求。

如果选择不实现新的权限模型(运行时请求),则权限的吊销可能会导致不必要的用户体验,并且在某些情况下会导致应用程序崩溃。

下表列出了所有当前的危险权限及其各自的组:

enter image description here

如果用户接受组/类别中的一个权限,则接受整个组!

来源:http://www.captechconsulting.com

使用德克斯特库:

您可以使用德克斯特。Android 库,简化了在运行时请求权限的过程。


推荐