簡體   English   中英

如何在Android的>= 23平台上檢查和請求sd卡的讀、寫權限

[英]How to check and request read, write permission for sd card in platform >= 23 of Android

我有以下代碼來請求對稱為模擬的外部(共享)存儲的讀、寫權限。 現在我也想讀寫 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 .

即使您擁有外部存儲的所有權限,您仍然無法在該位置的微型 SD 卡上進行寫入。

您只能在卡上的應用程序特定目錄中寫入。

要找到該路徑,請使用 getExternalFilesDirs()。 如果幸運的話,它是返回的條目之一。

對你來說,路徑看起來像

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

看看文件瀏覽器應用程序。 它可能已經在那里了。

如果您想在卡上的任何地方寫入,請使用存儲訪問框架。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM