Android 6.0:SD卡目录创建失败,尽管有权限

时间:2017-08-23 18:40:31

标签: android android-6.0-marshmallow

我正在尝试创建外部目录结构,以便将某些文件从设备存储移动到Android手机中的SD卡。我已经按照https://developer.android.com/training/permissions/requesting.html中给出的步骤和多个stackoverflow答案进行了操作。但是,当我尝试创建目录时,我的程序失败了。

我的AndroidManifest.xml文件包含以下行:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

相关代码如下:

    public int mkFolder(String folderName){
        String state = Environment.getExternalStorageState();
        if (!Environment.MEDIA_MOUNTED.equals(state)){
            Log.d(TAG, "Error: external storage is unavailable");
            return 0;
        }
        if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            Log.d(TAG, "Error: external storage is read only.");
            return 0;
        }
        Log.d(TAG, "External storage is not read only or unavailable");

        boolean writePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
        boolean readPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
        final boolean permissionNotGranted = writePermission|| readPermission;
        if (permissionNotGranted) {
            Log.i(TAG, "STORAGE permissions NOT granted");
            // Should we show an explanation?
            boolean shouldShowRationaleForWritePermssion = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
            boolean shouldShowRationaleForReadPermssion = ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE);
            if (shouldShowRationaleForWritePermssion || shouldShowRationaleForReadPermssion) {

                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.

            } else {
                ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
            }
        } else {
            Log.i(TAG, "STORAGE permissions granted");
        }

//        File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),folderName);
        File folder = new File(folderName);
        int result = 0;
        if (folder.exists()) {
            Log.d(TAG,"folder exist:"+folder.toString());
            result = 2; // folder exist
        }else{
            try {
                if (folder.mkdirs()) {
                    Log.d(TAG, "folder created:" + folder.toString());
                    result = 0; // folder created
                } else {
                    Log.d(TAG, "create folder fails:" + folder.toString());
                    result = 1; // create folder fails
                }
            }catch (Exception ecp){
                ecp.printStackTrace();
            }
        }
        return result;
    }

    public static final int REQUEST_EXTERNAL_STORAGE = 112;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String permissions[], @NonNull int[] grantResults) {
        Log.e(TAG, "onRequestPermissionsResult invoked");
        switch (requestCode) {
            case REQUEST_EXTERNAL_STORAGE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                    Log.i(TAG, "Permission to write to external storage granted");
                    Toast.makeText(this, "Permission to write to external storage granted", Toast.LENGTH_LONG).show();
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Log.e(TAG, "Permission to write to external storage NOT granted");
                    Toast.makeText(this, "Permission to write to external storage NOT granted", Toast.LENGTH_LONG).show();
                }
            }
            // other 'case' lines to check for other
            // permissions this app might request
        }
    }

以下是日志的摘录:

MainActivity: /storage/0000-0000    false   true
MainActivity: /storage/0000-0000/MyDir does not exist. Creating target parent directory
MainActivity: STORAGE permissions granted
MainActivity: Creation of directory /storage/0000-0000/MyDir failed with return value 1. Aborting...

有人可以帮我理解我的代码中的错误吗?

1 个答案:

答案 0 :(得分:1)

从Android 4.4开始,您没有removable storage上任意位置的直接文件系统访问权限。 WRITE_EXTERNAL_STORAGE在这里没有意义,因为external storage不是可移动存储。

使用存储访问框架(ACTION_OPEN_DOCUMENT_TREE和亲属)代替。或者,将您的工作限制为getExternalFilesDirs()getExternalCacheDirs()getExternalMediaDirs()Context上的所有方法)中返回的可移动存储位置。