Android 6.0: SD Card Directory creation fails in spite of having permissions

白昼怎懂夜的黑 提交于 2019-12-13 03:15:59

问题


I am trying to create an external directory structure to move some files from Device storage to SD card in Android phones. I have followed the steps given in https://developer.android.com/training/permissions/requesting.html and multiple stackoverflow answers. However, my program fails when I try to create the directories.

My AndroidManifest.xml file contains the following lines:

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

The relevant code is as follows:

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

Here is an extract from the logs:

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...

Can someone please help me understand what the mistake is in my code?


回答1:


You do not have direct filesystem access to arbitrary locations on removable storage, starting with Android 4.4. WRITE_EXTERNAL_STORAGE is meaningless here, as external storage is not removable storage.

Use the Storage Access Framework (ACTION_OPEN_DOCUMENT_TREE and kin) instead. Or, limit your work to the removable storage locations returned as part of getExternalFilesDirs(), getExternalCacheDirs(), and getExternalMediaDirs() (all methods on Context).



来源:https://stackoverflow.com/questions/45847179/android-6-0-sd-card-directory-creation-fails-in-spite-of-having-permissions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!