如何在平台>= 23的Android中检查和请求SD卡的读取,写入权限



>我有以下代码来请求外部(共享)存储的读取,写入权限,称为模拟。现在我也想读取和写入SD卡。但是我在日志中收到错误"权限被拒绝"。

//We are calling this method to check the read permission status
public boolean isReadWriteStorageAllowed() {
    //Getting the permission status
    int resultRead   = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE);
    int resultWrite  = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    //If permission is granted returning true
    if (resultRead == PackageManager.PERMISSION_GRANTED && resultWrite == PackageManager.PERMISSION_GRANTED)
        return true;
    //If permission is not granted returning false
    return false;
}
public void requestStoragePermission(int code){
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
    }
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, code);
}

错误的日志如下

    10-12 14:23:03.998 8550-8550/com.free W/System.err: java.io.FileNotFoundException: /storage/8E14-3919/database.db (Permission denied)
10-12 14:23:03.998 8550-8550/com.free W/System.err:     at java.io.FileOutputStream.open(Native Method)
10-12 14:23:03.998 8550-8550/com.free W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
10-12 14:23:03.998 8550-8550/com. free W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:108)
10-12 14:23:03.998 8550-8550/com.free W/System.err:     at com. DatabaseManage.exportDatabase(DatabaseManage.java:140)
10-12 14:23:03.998 8550-8550/com.free W/System.err:     at com. DatabaseManage.access$000(DatabaseManage.java:50)
10-12 14:23:03.998 8550-8550/com.free W/System.err:     at com. DatabaseManage$1.onClick(DatabaseManage.java:106)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1244)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at android.widget.AdapterView.performItemClick(AdapterView.java:339)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at android.widget.AbsListView.performItemClick(AbsListView.java:1695)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at android.widget.AbsListView$PerformClick.run(AbsListView.java:4171)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at android.widget.AbsListView$13.run(AbsListView.java:6772)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at android.os.Handler.handleCallback(Handler.java:751)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at android.os.Looper.loop(Looper.java:154)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6692)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
10-12 14:23:03.999 8550-8550/com.free W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

我的问题是"询问外部存储的存储权限"是否也会授予"SD卡"的权限?如果不是,那么我的代码中有什么问题或我缺少什么?我需要一个解决方案!

代码如下

public void exportDB(){
    int size, pathSize = 0;
    String[] storageLocations = null;
    final File dbFile = context.getDatabasePath(DATABASE_NAME);//existing database file path
    File device = Environment.getExternalStorageDirectory();//device storage
    String[] sdCard = getExternalStorageDirectories();//sd cards
    size = sdCard.length;
    if(size == 0)
        pathSize = 0;
    else if(size > 0)
        pathSize = size + 1;
    pathForExports   = new String[pathSize];
    storageLocations = new String[pathSize];
    if(sdCard.length == 0){
        pathForExports[0]   = device.getAbsolutePath() + "/" + DATABASE_NAME;
        storageLocations[0] = "1) Device Storage";
    }
    else if(sdCard.length > 0) {
        pathForExports[0] = device.getAbsolutePath() + "/" + DATABASE_NAME;
        storageLocations[0] = "1) Device Storage";
        for (int i=0;i<sdCard.length; i++) {
            File file = new File(sdCard[i]);
            pathForExports[i+1] = file.getAbsolutePath() + "/" + DATABASE_NAME;
            if(sdCard.length > 1) {
                storageLocations[i+1] = (i+2) + ") Sd Card - " + (i+1);
            }
            else
                storageLocations[i+1] = (i+2) + ") Sd Card";
        }
    }
    //File file = new File(Environment.getExternalStorageDirectory() + File.separator + SAMPLE_DB_NAME);
    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setTitle("Choose Export Location");
    builder.setItems(pathForExports, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            exportDatabase(dbFile, which);
        }
    });
    AlertDialog alertDialog = builder.create();
    alertDialog.show();
}
private void exportDatabase(File dbFile, int whichButton) {
    FileChannel source = null;
    FileChannel destination = null;
    try {
        source = new FileInputStream(dbFile).getChannel();
        destination = new FileOutputStream(pathForExports[whichButton]).getChannel();
        destination.transferFrom(source, 0, source.size());
        source.close();
        destination.close();
        if(whichButton == 0)
            alert("Database is exported to device storage");
        else
            alert("Database is exported to sd Card");
    } catch(IOException e) {
        e.printStackTrace();
        if(whichButton == 0)
            alert("Failed to export database to device storage");
        else
            alert("Failed to export database to sd card");
    }
}
    /storage/8E14-3919/database.db .

即使您拥有外部存储的所有权限,您仍然无法在该位置的micro SD卡上写入。

您只能在卡上的应用程序特定目录中写入。

要查找该路径,请使用 getExternalFilesDirs()。如果幸运的话,它是返回的条目之一。

对你来说,路径看起来像

 /storage/8E14-3919/Android/data/<packagename>/files

看看文件资源管理器应用程序。它可能已经在那里了。

如果要在卡上的任何位置写入,请使用存储访问框架。

最新更新