【问题标题】:How to access any file based on the path name in android 10+ devices如何在 Android 10+ 设备中根据路径名访问任何文件
【发布时间】:2023-01-07 13:15:41
【问题描述】:

在 android 10 以下的设备中,我们可以像这样访问任何文件:: File f = new File("storage/emulated/0/filename.txt");

但是我想在 android 10+ 设备上做同样的事情,这些设备使用的是范围存储或媒体存储类之类的东西,我在 android studio 中不理解我不知道该怎么做我不仅想访问任何目录的文件像“图片”这样的公共目录请帮助我

File f = new File("storage/emulated/0/file.jpg");

【问题讨论】:

  • 你可以用同样的方法来做。问题是什么?
  • 顺便说一句:该代码不访问该文件。

标签: android


【解决方案1】:

获取android 10以下文件夹xyz(storage/emulated/0/xyz)的所有文件:

File xyzFolder = new File(Environment.getExternalStorageDirectory() + File.separator + "xyz");

File[] allFiles = xyzFolder.listFiles();

但对于 android 10 及更高版本,要么使用 declare MANAGE_EXTERNAL_STORAGE(如果不是某种文件管理器应用程序,则不推荐使用)或者您可以使用以下方法:

1).首先获取文件夹权限

uriMain = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fmedia/document/primary%3Axyz");

private final int REQUEST_CODE = 100;

List<Object> filesList = new ArrayList<>();

private void aboveQFolderPermission() {

    try {
        Intent createOpenDocumentTreeIntent = null;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            createOpenDocumentTreeIntent = ((StorageManager) getSystemService(STORAGE_SERVICE)).getPrimaryStorageVolume().createOpenDocumentTreeIntent();
        }

        assert createOpenDocumentTreeIntent != null;
        String replace = createOpenDocumentTreeIntent.getParcelableExtra("android.provider.extra.INITIAL_URI").toString().replace("/root/", "/document/");
        createOpenDocumentTreeIntent.putExtra("android.provider.extra.INITIAL_URI", Uri.parse(replace + "%3A" + "xyz"));
        startActivityForResult(createOpenDocumentTreeIntent, REQUEST_CODE);
    } catch (Exception e) {
        e.printStackTrace()
    }

}

现在在 onActivityResult() 中,

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE) {
        if (data != null) {
            getContentResolver().takePersistableUriPermission(data.getData(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);

            //save shared preference to check whether app specific folder permission granted or not
            sharedPreferences = getSharedPreferences("tree", MODE_PRIVATE);
            SharedPreferences.Editor editor = sharedPreferences.edit();

            editor.putString("treeUriString", String.valueOf(uriMain));
            editor.apply();

            new Thread(() -> {
                getListAboveQ(uriMain);
                handler. Post(() -> /*Some code here as per your need*/);
            }).start();

        }
    }
}

2).现在获取文件列表:

private void getListAboveQ(uriMain) {


    ContentResolver contentResolver = getContext().getContentResolver();
    Uri buildChildDocumentsUriUsingTree = DocumentsContract.buildChildDocumentsUriUsingTree(uriMain, DocumentsContract.getDocumentId(uriMain));

    try (Cursor cursor = contentResolver.query(buildChildDocumentsUriUsingTree, new String[]{"document_id"}, null, null, null)) {
        while (cursor.moveToNext()) {
               filesList.add(DocumentsContract.buildDocumentUriUsingTree(uriMain, cursor.getString(0)));
        }

    } catch (Exception e) {
        e.printStackTrace();
    }

}

编辑:- 您可以使用保存的首选项,例如:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

        sharedPreferences = getSharedPreferences("tree", Context.MODE_PRIVATE);
        String uriString = sharedPreferences.getString("treeUriString", "");

        if (uriString.matches("")) {
            //ask for folder permission
            aboveQFolderPermission()
        } else {
            //Permission is already granted
            //TODO: Whatever you want
        }
}

【讨论】:

  • 我们是否需要在每次打开特定文件夹权限时或仅在第一次打开时获取该特定文件夹权限
  • 看看我们正在使用.takePersistableUriPermission(..)onActivityResult(...) 方法。这意味着该应用程序将可以长期访问 URI 中的数据,即使在该应用程序不再运行之后也是如此。
【解决方案2】:

您需要请求MANAGE_EXTERNAL_STORAGE 许可。有了该权限,您就可以使用File API 访问共享存储文件。

参考:

https://developer.android.com/training/data-storage/manage-all-files#all-files-access

【讨论】:

  • 请记住,某些应用程序分发渠道(例如 Play 商店)会限制哪些应用程序可以请求此权限。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多