android 申请sdcard权限_Android M写入SD卡-权限被拒绝

I'm trying to copy file from within my application to the SD card, but I get the error eacces (permission denied). The OS is Android M and I have allowed runtime Storage permissions (checked in app info). I have also set the uses-permission in AndroidManifest.xml

...

Doesn't work if I copy to SD card

Source: data/user/0/com.example.myapp/cache/SomeFile.txt

Destination: /storage/1032-2568/SomeFolder/

Error: java.io.FileNotFoundException: /storage/1032-2568/SomeFolder/SomeFile.txt: open failed: EACCES (Permission denied)

Works if I copy to internal storage

Source: data/user/0/com.example.myapp/cache/SomeFile.txt

Destination: /storage/emulated/0/SomeFolder/

Code to copy file from source to destination

/*

* Below are the parameters I have tried

*

* inputPath - data/user/0/com.example.myapp/cache or data/user/0/com.example.myapp/cache/

* inputFile - /SomeFile.txt or SomeFile.txt

* outputPath - /storage/1032-2568/SomeFolder/ or /storage/1032-2568/SomeFolder

*/

public static void copyFile(String inputPath, String inputFile, String outputPath) {

InputStream in = null;

OutputStream out = null;

try {

//create output directory if it doesn't exist

File dir = new File (outputPath);

if (!dir.exists()) {

dir.mkdirs();

}

in = new FileInputStream(inputPath + inputFile);

out = new FileOutputStream(outputPath + inputFile);

byte[] buffer = new byte[1024];

int read;

while ((read = in.read(buffer)) != -1) {

out.write(buffer, 0, read);

}

in.close();

// write the output file (You have now copied the file)

out.flush();

out.close();

}

catch (FileNotFoundException fnfe1) {

/* I get the error here */

Log.e("tag", fnfe1.getMessage());

}

catch (Exception e) {

Log.e("tag", e.getMessage());

}

}

ES File Explorer

I saw that ES File Explorer also cannot write anything on the SD Card on Redmi devices. Here's a video with solution. Following the steps worked for ES Explorer on my device. Can this be done programmatically?

解决方案

As suggested by @CommonsWare here we have to use the new Storage Access Framework provided by android and will have to take permission from user to write SD card file as you said this is already written in the File Manager Application ES File Explorer.

Here is the code for Letting the user choose the "SD card" :

startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), requestCode);

which will look somewhat like this :

And get the Document path in pickedDirand pass further in your copyFile block

and use this path for writing the file :

public void onActivityResult(int requestCode, int resultCode, Intent resultData) {

if (resultCode != RESULT_OK)

return;

else {

Uri treeUri = resultData.getData();

DocumentFile pickedDir = DocumentFile.fromTreeUri(this, treeUri);

grantUriPermission(getPackageName(), treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

copyFile(sdCard.toString(), "/File.txt", path + "/new", pickedDir);

}

}

public void copyFile(String inputPath, String inputFile, String outputPath, DocumentFile pickedDir) {

InputStream in = null;

OutputStream out = null;

try {

//create output directory if it doesn't exist

File dir = new File(outputPath);

if (!dir.exists()) {

dir.mkdirs();

}

in = new FileInputStream(inputPath + inputFile);

//out = new FileOutputStream(outputPath + inputFile);

DocumentFile file = pickedDir.createFile("//MIME type", outputPath);

out = getContentResolver().openOutputStream(file.getUri());

byte[] buffer = new byte[1024];

int read;

while ((read = in.read(buffer)) != -1) {

out.write(buffer, 0, read);

}

in.close();

// write the output file (You have now copied the file)

out.flush();

out.close();

} catch (FileNotFoundException fnfe1) {

/* I get the error here */

Log.e("tag", fnfe1.getMessage());

} catch (Exception e) {

Log.e("tag", e.getMessage());

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值