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

时间:2015-10-09 06:01:56

标签: java android android-6.0-marshmallow

我已将QPainterPath QPainterPath::intersecteduses-permissionWRITE_EXTERNAL_STORAGE添加到MOUNT_UNMOUNT_FILESYSTEMS

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

READ_EXTERNAL_STORAGE

我尝试了另一款Android手机(Android 5.1),一切都还可以。这是代码:

AndroidManifest.xml

Android 6.0对权限有区别吗?

9 个答案:

答案 0 :(得分:51)

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

答案 1 :(得分:49)

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

快速解决方案但不建议:如果您将平板中的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);
    
  3. 方法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;
      
      }
      
      }
      
    2. 收到结果后,您需要妥善处理。

      建议的权限流程

      enter image description here

      更多信息:

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

      Android将某些权限定义为“危险”,将某些权限定义为“正常。”应用程序清单中都需要这两种权限,但只有危险权限才需要运行时请求。< / p>

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

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

      enter image description here

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

      <强>来源: http://www.captechconsulting.com

      使用Dexter Library:

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

答案 2 :(得分:13)

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

答案 3 :(得分:10)

从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);即可。 这应该是有希望的。

答案 4 :(得分:2)

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

答案 5 :(得分:2)

这对我有用。

转到设置 - &gt;应用程序 - &gt; YourApp - &gt;提供存储,联系人等权限。

答案 6 :(得分:0)

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

答案 7 :(得分:-4)

对我来说,即使在完成此处所述的所有操作后,我的手机也以USB作为MTP连接。切换到&#34;仅充电&#34;为我工作。

答案 8 :(得分:-5)

我遇到了同样的麻烦。

可能是由您的手机安全机制引起的。您可以转到“设置”以授权写入/读取权限。