java.io.FileNotFoundException:(权限被拒绝)在 oreo android
java.io.FileNotFoundException: (Permission denied) in oreo android
以下代码用于在sdcard(外部存储)中创建的文件中写入联系人详细信息:
try {
while (phones.isAfterLast() == false) {
String lookupKey = phones.getString(phones
.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(
ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd;
fd = mContext.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] buf = readBytes(fis);
fis.read(buf);
String VCard = new String(buf);
FileOutputStream mFileOutputStream = new FileOutputStream(
cpath, true);
mFileOutputStream.write(VCard.getBytes());
phones.moveToNext();
}
} catch (Exception e1) {
Applog.e(TAG, e1);
isOk = false;
}
其中,cpath是我的文件在sd卡中的路径。
这里,我在线上遇到错误:
FileOutputStream mFileOutputStream = new FileOutputStream(
cpath, true);
我低于日志:-
java.io.FileNotFoundException: /storage/9016-4EF8/AllBackupDemo/cont20181031050512.vcf (Permission denied)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:287)
at java.io.FileOutputStream.<init>(FileOutputStream.java:223)
at java.io.FileOutputStream.<init>(FileOutputStream.java:142)
文档树选择代码:
private void triggerStorageAccessFramework() {
startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), REQUEST_SAF_PERMISSION);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Log.e(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data + ")");
if (resultCode == RESULT_CANCELED) return;
switch (requestCode) {
case REQUEST_SAF_PERMISSION:{
Uri treeUri = data.getData();
if(treeUri != null){
session.setPrefURI(treeUri.toString());
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
toast(getString(R.string.permission_granted_saf));
break;
}
}
}
注意:
- 我只在 android oreo 版本中遇到此错误。它在牛轧糖中工作正常。
- 我已经授予了运行时权限并且在清单文件中也提到了。
- 我已经为文档文件权限实施了 SAF。
解法:
我分析并比较了我的代码和你的代码,发现你使用的所有代码都是一样的。
必须更改出现错误的行。此错误是由于使用了 FileOutputStream
,这表明您正在从文件系统访问,而不是从 DocumentTree
.
因此,而不是:
FileOutputStream mFileOutputStream = new FileOutputStream(
cpath, true);
尝试这样的事情:
try {
OutputStream out = getContentResolver().openOutputStream(cpath.getUri());
try {
// Do whatever you wish to do.
} finally {
out.close();
}
} catch (IOException e) {
throw new RuntimeException("Something went wrong : " + e.getMessage(), e);
}
我不确定你的程序的实际流程,你可能想自己过一遍。但是,这肯定会给你一个继续前进的想法。
希望对您有所帮助。
以下代码用于在sdcard(外部存储)中创建的文件中写入联系人详细信息:
try {
while (phones.isAfterLast() == false) {
String lookupKey = phones.getString(phones
.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(
ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd;
fd = mContext.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] buf = readBytes(fis);
fis.read(buf);
String VCard = new String(buf);
FileOutputStream mFileOutputStream = new FileOutputStream(
cpath, true);
mFileOutputStream.write(VCard.getBytes());
phones.moveToNext();
}
} catch (Exception e1) {
Applog.e(TAG, e1);
isOk = false;
}
其中,cpath是我的文件在sd卡中的路径。
这里,我在线上遇到错误:
FileOutputStream mFileOutputStream = new FileOutputStream(
cpath, true);
我低于日志:-
java.io.FileNotFoundException: /storage/9016-4EF8/AllBackupDemo/cont20181031050512.vcf (Permission denied)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:287)
at java.io.FileOutputStream.<init>(FileOutputStream.java:223)
at java.io.FileOutputStream.<init>(FileOutputStream.java:142)
文档树选择代码:
private void triggerStorageAccessFramework() {
startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), REQUEST_SAF_PERMISSION);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Log.e(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data + ")");
if (resultCode == RESULT_CANCELED) return;
switch (requestCode) {
case REQUEST_SAF_PERMISSION:{
Uri treeUri = data.getData();
if(treeUri != null){
session.setPrefURI(treeUri.toString());
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getContentResolver().takePersistableUriPermission(treeUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
}
toast(getString(R.string.permission_granted_saf));
break;
}
}
}
注意:
- 我只在 android oreo 版本中遇到此错误。它在牛轧糖中工作正常。
- 我已经授予了运行时权限并且在清单文件中也提到了。
- 我已经为文档文件权限实施了 SAF。
解法:
我分析并比较了我的代码和你的代码,发现你使用的所有代码都是一样的。
必须更改出现错误的行。此错误是由于使用了 FileOutputStream
,这表明您正在从文件系统访问,而不是从 DocumentTree
.
因此,而不是:
FileOutputStream mFileOutputStream = new FileOutputStream(
cpath, true);
尝试这样的事情:
try {
OutputStream out = getContentResolver().openOutputStream(cpath.getUri());
try {
// Do whatever you wish to do.
} finally {
out.close();
}
} catch (IOException e) {
throw new RuntimeException("Something went wrong : " + e.getMessage(), e);
}
我不确定你的程序的实际流程,你可能想自己过一遍。但是,这肯定会给你一个继续前进的想法。
希望对您有所帮助。