24

在 Android 10 中,需要访问存储的应用程序需要请求访问具体路径的权限。但是文件资源管理器等应用程序可以请求访问根存储的权限,并获得对所有存储的读/写权限。这就是我想要做的。

根据Android,我们必须ACTION_OPEN_DOCUMENT_TREE为此使用。我遇到的问题是一切似乎都是正确的,但没有授予应用程序权限。

  private void askAndroid10Perm()
    {
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
        intent.addFlags(
                Intent.FLAG_GRANT_READ_URI_PERMISSION
                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                        | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
                        | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
        startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE);
    }

在这里,用户可以看到 Android 文件树,并在选择主存储的情况下,单击以授予权限。“它将允许 - 应用程序名称 - 完全访问当前存储在此位置下的所有文件,以及存储在此处的任何未来内容”-> 允许

然后:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case REQUEST_CODE_OPEN_DOCUMENT_TREE:
            if (resultCode == Activity.RESULT_OK) {
                Uri treeUri = data.getData();
                int takeFlags = data.getFlags();
                takeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION |
                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

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

                    Log.i("TAG", "takePersistableUriPermission: " + treeUri);
                    this.getContentResolver().takePersistableUriPermission(treeUri, takeFlags);

                }

            }
    }
}

日志:

takePersistableUriPermission: content://com.android.externalstorage.documents/tree/primary%3A

然后该应用程序仍然没有访问root的权限。

打开失败:EACCES(权限被拒绝)

我当然有:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

由用户授予。

4

5 回答 5

41

在清单中添加行

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:requestLegacyExternalStorage="true" //Add this Line
    android:label="@string/app_name">

---------<Activity, Sevices or Recivers>----------

</application>
于 2020-02-20T09:00:30.997 回答
11

你必须在你的 AndroidManifest.xml 中添加这一行

android:requestLegacyExternalStorage="true"
于 2020-07-30T16:46:00.533 回答
7

问题是我使用 File 对象来访问文件,但只有当我们使用 DocumentFile 对象来操作文件时,权限才有效。

使用 DocumentFile 而不是 File 解决。

使用 DocumentFile 有多个缺点,例如性能以及您无权访问 apache 公共库,但没有其他选择。

于 2019-08-14T15:19:54.773 回答
1

使用Simple Storage可能会更简单。您可以向用户请求存储完全访问权限:

class MainActivity : AppCompatActivity() {

    private val storageHelper = SimpleStorageHelper(this)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btnRequestStorageAccess.setOnClickListener {
            storageHelper.requestStorageAccess()
        }

        storageHelper.onStorageAccessGranted = { requestCode, root ->
            // do stuff
        }
    }
}

它适用于 Android 10 及更高版本。无需添加android:requestLegacyExternalStorage="true"到清单文件中。

于 2021-07-17T16:48:31.263 回答
0

(不适用于 ANDROID 11)将此添加到应用程序的清单文件中,以便您的应用程序如下所示:

<application
    android:requestLegacyExternalStorage="true"

对于android 11,我确实喜欢这样

        ContextWrapper cw = new ContextWrapper(mContext);
String fullPath =cw.getExternalFilesDir(Environment.DIRECTORY_MUSIC).toString();
File directory = cw.getExternalFilesDir(Environment.DIRECTORY_MUSIC);

在这里查看https://www.programmersought.com/article/50766505696/

于 2021-02-26T13:01:44.777 回答