【问题标题】:Android 6.0 open failed: EACCES (Permission denied)Android 6.0 打开失败:EACCES(权限被拒绝)
【发布时间】:2016-01-06 23:16:06
【问题描述】:

我已将uses-permission 包括WRITE_EXTERNAL_STORAGEMOUNT_UNMOUNT_FILESYSTEMSREAD_EXTERNAL_STORAGE 添加到AndroidManifest.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 在权限上有区别吗?

【问题讨论】:

  • 我认为您应该检查Android 6.0上添加的新权限功能并根据它更改您的代码..!!
  • 我已阅读页面Manifest.permission,并没有发现什么特别之处。
  • @samuel40 : 我想你不知道新模型。这是旧的,所以请检查一下 -> android-developers.blogspot.in/2015/08/…
  • 检查下面的答案并参考链接以实施新模型..!!
  • 对我来说,在谷歌搜索并尝试了很多方法都没有成功。我打开 Settings 并发现 Android 6.0 在 Settings > Privacy and safety > App permissions > Storage 部分阻止了我的应用程序权限。在 Storage Permissions 部分启用后,它就可以工作了。希望对其他人有所帮助

标签: java android android-6.0-marshmallow


【解决方案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

【讨论】:

  • @samuel40 : 如果这对你有用,请检查这个 -> meta.stackexchange.com/questions/5234/…
  • 非常感谢,我去看看。
  • 我理解他们为什么这样做,但是...当您拥有十几个权限并且必须找到每个权限的使用位置并添加所有这些代码时,这有点痛苦...
  • @Michael:是的,你是对的!但对我们来说user 比付出努力来获取他们的信息更重要secure!!
【解决方案2】:

Android 6(Marshmallow) 中,即使用户在安装时接受了您的所有权限,但他们稍后可以决定取消您的部分权限。

快速解决方案但不推荐:如果你把gradle中的targetSdkVersion改成22,问题就解决了。

如何实施?(最佳实践)

  1. 首先判断用户的设备是否为 Marshmallow 设备:

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

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

建议的权限流程:

更多信息:

拥有 Marshmallow 设备的用户现在可以通过应用设置撤销危险权限

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

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

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

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

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

使用 Dexter 库:

您可以使用Dexter。简化运行时请求权限过程的 Android 库。

【讨论】:

  • 很好的答案,谢谢!一件事:perms 字符串应该是“android.permission.WRITE_EXTERNAL_STORAGE”而不是“android.permission.WRITE_EXTERNAL_STORAGE”(没有空格)
【解决方案3】:

您也可以使用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();
        }
    }
}

【讨论】:

    【解决方案4】:

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

    要使用,只需在 onCreate 中调用 verifyStoragePermissions(this);。 这应该是有希望的。

    【讨论】:

    • 我有这个检查并且权限被授予但是我不能 File.createTempFile(prefix,sufix,directory);
    【解决方案5】:

    如果你很懒,只需将 targetSdkVersion 降级为 22(棒棒糖之前)

    【讨论】:

    • 是的,这适用于我的 Android 6 或更高版本。至少在本地可以使用 repo 中的第 2 版,您仍然可以推送第 23 版
    【解决方案6】:

    这对我有用。

    转到设置 -> 应用程序 -> YourApp -> 提供对存储、联系人等的权限。

    【讨论】:

    • 没有找到任何有用的东西
    【解决方案7】:

    Google 在 Android Q 上有一项新功能:用于外部存储的过滤视图。对此的快速解决方法是在 AndroidManifest.xml 文件中添加此代码:

    <manifest ... >
        <!-- This attribute is "false" by default on apps targeting Android Q. -->
        <application android:requestLegacyExternalStorage="true" ... >
         ...
        </application>
    </manifest>
    

    您可以在此处阅读更多信息:https://developer.android.com/training/data-storage/compatibility

    【讨论】:

      【解决方案8】:

      对我来说,我的手机作为 MTP 连接为 USB 是问题所在,即使在完成此处所述的所有操作之后也是如此。将其切换为“仅充电”对我有用。

      【讨论】:

        【解决方案9】:

        我遇到了同样的麻烦。

        可能是您的手机安全机制造成的。你可以去“设置”授权写/读权限。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-12-23
          • 2021-07-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-01-12
          • 2016-06-14
          相关资源
          最近更新 更多