java.io.FileNotFoundException :(奥利奥android

时间:2018-10-31 11:38:15

标签: android android-permissions android-storage

以下代码用于在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;
            }
        }
    }

注意:

  1. 我仅在android oreo版本中遇到此错误。在牛轧糖中工作正常。
  2. 我已经授予运行时权限,并且在清单文件中也有提及。
  3. 我为文档文件权限实施了SAF。

1 个答案:

答案 0 :(得分:1)

解决方案:

我分析了我的代码并将其与您的代码进行比较,发现您使用的所有代码都是相同的。

您要更改错误所在的行。该错误是由于使用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);
}

我不确定您的程序的实际流程,您可能需要仔细阅读。但是,这肯定会让您有个继续前进的想法。

希望有帮助。