Android 版本、权限适配相关总结

论坛 期权论坛 脚本     
niminba   2021-5-23 02:40   1109   0

请求存储权限

首先需要在 AndroidManifest.xml 文件中声明权限:

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

在代码中请求用户权限:

    // 权限请求码
    private static final int PERMISSION_REQ_ID = 0;  
    // 请求权限
    private static final String[] REQUESTED_PERMISSIONS = {
            Manifest.permission.READ_EXTERNAL_STORAGE
    };

    ...

     // 判断有没有存储权限
    if (checkSelfPermission(REQUESTED_PERMISSIONS[0],PERMISSION_REQ_ID)){
        //YSE 
    }else {
        //NO
    }
    private boolean checkSelfPermission(String permissions,int requestCode){
        if (ContextCompat.checkSelfPermission(this,permissions) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this, REQUESTED_PERMISSIONS, requestCode);
            return false;
        }
        return true;
    }

    // 重写此方法,接收用户授权回调
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        Log.i(TAG, "onRequestPermissionsResult: requestCode =" + requestCode
                +"\n,permissions =" + Arrays.toString(permissions)
                +"\n,grantResults =" + Arrays.toString(grantResults));
        if (requestCode == PERMISSION_REQ_ID){
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
                //用户同意权限
            }else {
                //用户拒绝权限
            }
        }
    

版本适配

从 Android 6.0 到 Android 10 存储/访问文件功能,有发生了很多变化。

Android 7.0 前

在Android 7.0 以前我们访问内存中的文件可以通过 Uri.fromFile,将 File 转换成 Uri 对象,这个 Uri 对象表示这本地真实路径。 访问一个图片:

String fileName = "default_Image.jpg";
File file = new File("file_path", fileName);
Uri uri = Uri.fromFile(file);

Android 7.0 后

在 7.0 后,这种通过真实路径来获取的 Uri 被认为是不安全的,所以提供了一种新的解决方案,就是通过 FileProvide 来实现文件的访问,FileProvider 是一种比较特殊的内容提供器,他使用了类似于内容提供器的机制来对数据进行保护。 访问一个图片:

    File file = new File(CACHE_IMG, "file_name");
    Uri imageUri = FileProvider.getUriForFile(activity,"com.sandan.fileprovider", file); //这里进行替换uri的获得方式

然而上面这种真的好吗,对用开发者而且这算是好处吧,但是对用用户而言,上述的无疑一些流氓作用,因为开发者完全可以访问的内存中的所有位置,并作出一些改变,导致 SD 卡中的空间变得非常乱,即使卸载了 app,但是一些垃圾文件却还在内存中。

Android 10.0

在 Android 10.0 ,为了解决上述问题,Google 在 Android 10.0 中加入了 作用域功能。

什么是作用域

就是 Android 系统对 SD 卡做了很大的限制,从 Android 10.0 开始,每个程序只能有权在自己的外置存储空间关联的目录下读取和创建相应的文件,也称作沙箱。获取该目录的代码是:getExternalFilesDir() ,关联的目录路径大致如下:

 Html CSS JavaScript Vb vbs Asp PHP Perl Python Ruby C# C++ SQL Delphi Diff Groovy Java JavaFX ActionScript3 Bash/shell powershell Plain Text Scala XML显示语言名称 显示行号 允许折叠 

将数据放在这个目录下,你可以使用之前的方法对文件进行读写,不需要作出任何变更和适配。但是这个文件夹中的文件会随着应用卸载而被随之删除。 那如果需要访问其他目录怎么办呢?比如获取相册中的图片,向相册中添加一张图片。为此,Android 系统针对系统文件类型进行了分类:图片,音频,视频 这三类文件可以通过 MediaStore API 来进行访问,这种称为共享空间,其他的系统文件需要使用 系统的文件选择器来进行访问,另外,如果程序向媒体库写入图片,视频,音频,将会自动用于读写权限,不需要额外申请权限,如果你要读取其他程序向媒体贡献的图片,视频,音频,则必须要申请 READ_EXTERNAL_STORAGE 权限,WRITE_EXTERNAL_STORAGE 权限会在未来的版本中被废弃。

举个栗子

举例说明:有一张本地图片,向这张图片添加水印,并保存到相册。

直接上代码:

    /**
     * 保存图片到相册
     *
     * @param context 上下文
     * @param text 水印文字
     */
    private void savePhotoAlbum(final Context context, final String text) {
        //7G&GRfTD6TfDRТ&WGW&SТТjhhiyNXnX8yNXKhKGТV&2F'6B6BfBGfRТffB666BE&W6W2DF7G&72GТ&WGW&GfR66Т&SУFcУ^K[i&xi8i.XX[>h{>yNXh^ZiNZIX[>KG&xi8i.XNXNiik:zKX[nZX[>ih~z
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP