Android 6.0:尽管具有权限,但SD卡目录创建失败 [英] Android 6.0: SD Card Directory creation fails in spite of having permissions

查看:130
本文介绍了Android 6.0:尽管具有权限,但SD卡目录创建失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

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" />

相关代码如下:

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

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

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

推荐答案

您无权直接访问外部存储不可移动存储.

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.

改用Storage Access Framework(ACTION_OPEN_DOCUMENT_TREE和kin).或者,将您的工作限制为作为getExternalFilesDirs()getExternalCacheDirs()getExternalMediaDirs()的一部分返回的可移动存储位置(Context上的所有方法).

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

这篇关于Android 6.0:尽管具有权限,但SD卡目录创建失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆