原因:java.lang.IllegalStateException:无法在Android 6.0设备中创建目录

时间:2016-03-03 09:20:59

标签: android android-sdcard android-download-manager imagedownload

我必须使用DownloadManager从url存储下载图像,然后使用我自己的目录(如“xyz”)将其存储到SD卡中。这是我的代码

Caused by: java.lang.IllegalStateException: Unable to create directory: /storage/emulated/0/storage/emulated/0/xyz at android.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.java:538)

此代码将运行至Android 5.1.1。当我在6.0中运行相同的代码时,它会像这样提出错误

@Html.DropDownList("drpOption", new List<SelectListItem>{
new SelectListItem{ Text="Daily", Value = "Daily" },
new SelectListItem{ Text="Weekly", Value = "Weekly" },
new SelectListItem{ Text="Monthly", Value = "Monthly" },
}, "-- Select --", new { @class = "dropdown", id = "drpOption" })

我在清单文件中添加了READ和WRITE权限。我该如何解决这个错误?任何人都可以帮助我?提前谢谢。

3 个答案:

答案 0 :(得分:3)

Caused by: java.lang.IllegalStateException: Unable to create directory: /storage/emulated/0/storage/emulated/0/xyz at android.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.java:538)

问题似乎与Android 6.0中引入的 Android Runtime Permission 相关

当您的应用定位为API级别23或更高级别时,默认情况下所有权限均为false。要解决此问题,您必须先申请权限对话框并批准该权限,然后才能将其用于您的应用。

答案 1 :(得分:0)

问题是您需要写权限才能下载文件,而即时应用程序不支持。如您在以下链接https://developer.android.com/topic/google-play-instant/faqs#general中所看到的,这是Instant应用程序中受支持的权限。

  

即时应用程序可以使用哪些权限?

     

即时应用可以使用以下Android权限:

  • 计费
  • ACCESS_COARSE_LOCATION
  • ACCESS_FINE_LOCATION
  • ACCESS_NETWORK_STATE
  • 相机
  • 仅在Android 8.0中安装INSTANT_APP_FOREGROUND_SERVICE。
  • 互联网
  • READ_PHONE_NUMBERS。此权限仅在Android 8.0(API级别26)中可用。
  • RECORD_AUDIO
  • 震动

答案 2 :(得分:0)

如上所述,由于您试图在外部存储器中创建目录,因此您需要请求所需的权限(在这种情况下,您需要WRITE_EXTERNAL_STORAGE权限)。

为此,您需要检查是否允许使用该权限,或者是否需要向用户请求该权限。这是一个示例代码:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if (context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity!!, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 0);
    }
}

如您所见,仅当版本等于或高于M(Android SDK版本23)时,才有必要。

如果要求用户授予许可,那么您将需要一种返回到代码中所需位置的方法,您可以在此处继续。为此,您首先需要重写onRequestPermissionsResult方法,以便接收用户的响应(如果用户决定是否授予请求的权限):

@Override
public void onRequestPermissionsResult(
        int requestCode, String permissions[], int[] grantResults
) {
    if (requestCode == REQUIRED_PERMISSIONS_REQUEST) {
        int index = 0;
        Map<String, Integer> permissionsMap = new HashMap<>();
        for (String permission : permissions) {
            permissionsMap.put(permission, grantResults[index]);
            index++;
        }

        if (permissionsMap.containsKey(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                && permissionsMap.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == 0) {
            //
            // Call your code from here
            //
        }
    }
}