首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android 11作用域存储权限

Android 11作用域存储权限
EN

Stack Overflow用户
提问于 2020-07-08 03:35:44
回答 4查看 85.4K关注 0票数 67

我正在尝试更好地理解,一旦Android 11版本发布,我将能够做些什么。

我的应用程序使用提供的图片文件路径

Environment.getExternalStorageDirectory()

创建相册,但使用

Android 11我将无法直接访问文件。根据Android开发人员文档,他们最近引入了

MANAGE_EXTERNAL_STORAGE权限,但我不知道如果添加此权限,我可以通过以下方式继续访问文件Environment或者不是。有没有人有主意?

谢谢

更新2021年1月

我在Android 11虚拟设备上试用了我的应用程序,它似乎可以完美地工作,即使没有请求MANAGE_EXTERNAL_STORAGE允许!

阅读有关Android开发人员的文档,似乎使用FILE用于访问照片和媒体的API仅限位置可以继续工作,但是我不确定。

有没有人能更好地理解Android文档?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-07-08 04:39:55

根据Android开发人员文档,他们最近引入了管理_外部_存储权限,但我不知道添加此权限是否可以继续按环境访问文件。

是的,你会的。但是,请记住,如果您打算在Play Store (可能在其他地方)上分发您的应用程序,则需要证明请求该许可的理由。所以,除非你有一个

非常使用的好理由MANAGE_EXTERNAL_STORAGE,请使用something else.

票数 11
EN

Stack Overflow用户

发布于 2021-02-25 17:46:22

Android 11

如果您的目标是Android 11 (targetSdkVersion 30)然后,您需要在AndroidManifest.xml中声明以下权限以进行修改和文档访问。

对于Android10,您可以在AndroidManifest.xml标记中放置以下行

代码语言:js
复制
android:requestLegacyExternalStorage="true"

以下检查权限的代码是允许还是拒绝

代码语言:javascript
运行
复制
private boolean checkPermission() {
    if (SDK_INT >= Build.VERSION_CODES.R) {
        return Environment.isExternalStorageManager();
    } else {
        int result = ContextCompat.checkSelfPermission(PermissionActivity.this, READ_EXTERNAL_STORAGE);
        int result1 = ContextCompat.checkSelfPermission(PermissionActivity.this, WRITE_EXTERNAL_STORAGE);
        return result == PackageManager.PERMISSION_GRANTED && result1 == PackageManager.PERMISSION_GRANTED;
    }
}

android 11或更低版本的权限请求代码如下

代码语言:javascript
运行
复制
private void requestPermission() {
    if (SDK_INT >= Build.VERSION_CODES.R) {
        try {
            Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
            intent.addCategory("android.intent.category.DEFAULT");
            intent.setData(Uri.parse(String.format("package:%s", new Object[]{getApplicationContext().getPackageName()})));
            startActivityForResult(intent, 2296);
        } catch (Exception e) {
            Intent intent = new Intent();
            intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
            startActivityForResult(intent, 2296);
        }
    } else {
        //below android 11
        ActivityCompat.requestPermissions(PermissionActivity.this, new String[]{WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
    }
}

Android 11及以上版本权限回调处理

代码语言:javascript
运行
复制
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 2296) {
        if (SDK_INT >= Build.VERSION_CODES.R) {
            if (Environment.isExternalStorageManager()) {
                // perform action when allow permission success
            } else {
                Toast.makeText(this, "Allow permission for storage access!", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

处理Android 11以下版本的权限回调

代码语言:javascript
运行
复制
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            if (grantResults.length > 0) {
                boolean READ_EXTERNAL_STORAGE = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                boolean WRITE_EXTERNAL_STORAGE = grantResults[1] == PackageManager.PERMISSION_GRANTED;

                if (READ_EXTERNAL_STORAGE && WRITE_EXTERNAL_STORAGE) {
                    // perform action when allow permission success
                } else {
                    Toast.makeText(this, "Allow permission for storage access!", Toast.LENGTH_SHORT).show();
                }
            }
            break;
    }
}
票数 97
EN

Stack Overflow用户

发布于 2021-01-13 17:52:27

Android 11不允许直接访问存储中的文件,你必须从存储中选择文件并将该文件复制到应用程序包chache com.android.myapp中。以下是将文件从存储复制到应用程序包缓存的方法

代码语言:javascript
运行
复制
private String copyFileToInternalStorage(Uri uri, String newDirName) {
    Uri returnUri = uri;

    Cursor returnCursor = mContext.getContentResolver().query(returnUri, new String[]{
            OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE
    }, null, null, null);


    /*
     * Get the column indexes of the data in the Cursor,
     *     * move to the first row in the Cursor, get the data,
     *     * and display it.
     * */
    int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
    int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
    returnCursor.moveToFirst();
    String name = (returnCursor.getString(nameIndex));
    String size = (Long.toString(returnCursor.getLong(sizeIndex)));

    File output;
    if (!newDirName.equals("")) {
        File dir = new File(mContext.getFilesDir() + "/" + newDirName);
        if (!dir.exists()) {
            dir.mkdir();
        }
        output = new File(mContext.getFilesDir() + "/" + newDirName + "/" + name);
    } else {
        output = new File(mContext.getFilesDir() + "/" + name);
    }
    try {
        InputStream inputStream = mContext.getContentResolver().openInputStream(uri);
        FileOutputStream outputStream = new FileOutputStream(output);
        int read = 0;
        int bufferSize = 1024;
        final byte[] buffers = new byte[bufferSize];
        while ((read = inputStream.read(buffers)) != -1) {
            outputStream.write(buffers, 0, read);
        }

        inputStream.close();
        outputStream.close();

    } catch (Exception e) {

        Log.e("Exception", e.getMessage());
    }

    return output.getPath();
}
票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62782648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档