Android沙盒机制

Android沙盒机制

Android Q文件存储机制修改成了沙盒模式,应用只能访问自己沙盒下的文件和公共媒体文件

  • 存储(也就是write)私有目录和公共媒体文件都不需要WRITE_EXTERNAL_STORAGE权限
  • 读取(也就是read)私有目录不需要READ_EXTERNAL_STORAGE权限,读取公共媒体文件需要READ_EXTERNAL_STORAGE权限,也就是说只能访问。

1、私有目录(自己沙盒)

getExternalFilesDir(这是APP自身目录下的文件夹 (Android/data/包名/fils))

  1. APP 卸载在这里插入代码片后,数据会清除。
  2. APP 访问自己的 App-specific 目录时无需任何权限。
  3. 可以使用FileProvider分享使用自己私有目录的文件。

所以在沙盒化的Q系统下,私有目录下的文件会跟随APP卸载而删除。在其目录内部的文件操作和Q之前的版本一样,可以随意处理。

保存到APP的私有目录PICTURES下面

private void saveAppPrivateFils(Bitmap bitmap) {
        File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "刘亦菲2.jpg");
        BufferedOutputStream bos = null;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(file));
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);
            bos.flush();
            bos.close();
            Toast.makeText(MainActivity.this, "保存成功", Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(MainActivity.this, "保存失败" + e.toString(), Toast.LENGTH_SHORT).show();
        }
    }

读取私有目录指定的path下的图片

 Bitmap bitmap = BitmapFactory.decodeFile(path);获取图片

有时候filePath下的文件会很大所以我们通过宽高的比例来缩放图片

   /**
     * 从文件路径中获取bitmap,根据比例inSampleSize,来缩放图片
     */
    public static Bitmap getBitmapFromPath(String pathName, int newWidth, int newHeight) {
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inJustDecodeBounds = true;//设置为ture只获取图片大小
        BitmapFactory.decodeFile(pathName, opts);

        opts.inSampleSize = getInSampleSize(opts, newWidth, newHeight);//计算缩放率,缩放图片
        opts.inJustDecodeBounds = false;//至为false
        return BitmapFactory.decodeFile(pathName, opts);
    }

   /**
     * 计算InSampleSize,大于1的整数时是缩小原图
     */
    private static int getInSampleSize(BitmapFactory.Options opts, int newW, int newH) {
        int outWidth = opts.outWidth;
        int outHeight = opts.outHeight;
        if (outWidth > newW || outHeight > newH)
            return (int) Math.ceil(Math.max(outWidth * 1d / newW, outHeight * 1d / newH));
        return 1;
    }

2、公共媒体文件

公有目录包括Downloads、Documents、Pictures 、DCIM、Movies、Music、Ringtones等
相对应的地址为/storage/emulated/0/Downloads(Pictures)等

  1. 公共目录下的文件在 APP 卸载后,不会删除。
  2. APP 可以通过 SAF框架(System Access Framework)、MediaStore 接口访问其中的文件。
  3. 无法直接使用路径访问公共目录文件。

由于公共目录没有办法直接访问和处理文件,所以我们需要按照Android Q的新规则来进行文件的处理,要使用到ContentResolver 和MediaStore数据库和Cursor 来进行查询等,也就是说如果你的项目中照片存储的路径就是APP的私有目录那么就没必要去适配AndroidQ

保存到共享媒体文件夹中DCIM(相册)

private void saveAppDCIMFils(Bitmap bitmap) {
        Uri uri =null;
        ContentResolver contentResolver = getContentResolver();
        ContentValues contentValues =new ContentValues();
        contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, "刘亦菲.jpg");
        contentValues.put(MediaStore.Images.Media.DESCRIPTION, "刘亦菲.jpg");
         //兼容Android Q和以下版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                //android Q中不再使用DATA字段,而用RELATIVE_PATH代替
                //RELATIVE_PATH是相对路径不是绝对路径
                //DCIM是系统文件夹,关于系统文件夹可以到系统自带的文件管理器中查看,不可以写没存在的名字
                contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "DCIM/MNMZ");
                //contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, "Music/signImage");
            } else {
                contentValues.put(MediaStore.Images.Media.DATA, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getPath());
            }
        contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
        OutputStream outputStream =null;
        try {
            outputStream = getContentResolver().openOutputStream(uri);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, outputStream);
            outputStream.flush();
            outputStream.close();
            Toast.makeText(MainActivity.this,"保存成功",Toast.LENGTH_SHORT).show();
        }catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(MainActivity.this,"保存失败"+e.toString(),Toast.LENGTH_SHORT).show();
        }
    }

在指定的公共path下获取图片

在公共媒体不能直接通过path来获取文件只能操作文件的uri来操作,所以我们可以根据path转换成uri。

public static Uri getImageContentUri(Context context, String path) {
        Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                new String[] { MediaStore.Images.Media._ID }, MediaStore.Images.Media.DATA + "=? ",
                new String[] { path }, null);
        if (cursor != null && cursor.moveToFirst()) {
            int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
            Uri baseUri = Uri.parse("content://media/external/images/media");
            return Uri.withAppendedPath(baseUri, "" + id);
        } else {
            // 如果图片不在手机的共享图片数据库,就先把它插入。
            if (new File(path).exists()) {
                ContentValues values = new ContentValues();
                values.put(MediaStore.Images.Media.DATA, path);
                return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            } else {
                return null;
            }
        }
    }

可以直接操作文件的uri,也可以转换成bitmap(通过getContentResolver().openFileDescriptor(uri,“r”)) "r"表示读,"w"表示写

public static Bitmap getBitmapFromUri(Context context, Uri uri) {
        try {
            ParcelFileDescriptor parcelFileDescriptor =
                    context.getContentResolver().openFileDescriptor(uri, "r");
            FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
            Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
            parcelFileDescriptor.close();
            return image;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

参考文档

  • Android Q存储机制-沙盒机制
  • AOSP-应用沙盒
  • Android沙盒机制使用探究

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/549763.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++】哈希一

这篇博客要说的是哈希算法,哈希又称为散列,它是将存储的值和存储的位置建立起关联关系的一种算法,或者说是一种将任意长度的数据映射为固定长度的输出的算法。 什么意思呢?我们来看一个例子:比如说我们要存储1&#xf…

控制某个对象缩放

效果如下: 您只需要控制此对象进行激活,将对象设置为:gameObject.SetActive(true);即可实现此次效果 代码如下: public class StartShowRun : MonoBehaviour {Transform _localTransfrom;Vector3 _localScale;public AnimationC…

高效可扩展,使用Dask进行大数据分析

大家好,Dask技术作为并行计算领域的创新力量,正在重塑大数据的处理模式。这项开源项目为Python语言带来了强大的并行计算能力,突破了传统数据处理在扩展性和性能上的瓶颈。 本文将介绍Dask的发展历程、架构设计,并分析其在大数据…

Qt中连接mysql

1、安装mysql,workbench,为mysql添加环境变量 2、安装Qt带src,然后到如下目录,找到mysql.pro(建议做个副本先) http://D:\Qt\Qt5.13.2\5.13.2\Src\qtbase\src\plugins\sqldrivers\mysql mysql.pro 注意路径的 \ / 和双引号的使…

算法练习第15天|226.翻转二叉树

226.翻转二叉树 力扣链接https://leetcode.cn/problems/invert-binary-tree/description/ 题目描述: 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出&am…

高分二号卫星(GF-2):中国遥感科技的新高度

​高分二号卫星(GF-2)是中国在高分辨率地球观测领域的重要成就,其引入了先进的成像技术和灵活的数据获取模式,为地球资源监测、环境保护、城市规划等领域提供了强大的数据支持。本文将深入介绍高分二号卫星的技术特点、成像能力以…

软件测试---性能测试

1.常见的性能问题有哪些 如图所示 系统内部以及软件的代码实现 1,资源泄漏,包括内存泄漏。 2,CPU使用率达到100%,系统被锁定等。 3,线程死锁,阻塞等造成系统越来越慢。 4,查询速度慢&#xff0c…

Console口和Telnet功能配置实验

一、基础配置 <Huawei>system-view //进入系统视图 Enter system view, return user view with CtrlZ. [Huawei]undo info-center enable //关闭接口提示 Info: Information center is disabled. [Huawei]sysname AR1 //配置设备名为 R1 [AR1]interface GigabitEthern…

pta L1-027 出租

L1-027 出租 分数 20 全屏浏览 切换布局 作者 陈越 单位 浙江大学 下面是新浪微博上曾经很火的一张图&#xff1a; 一时间网上一片求救声&#xff0c;急问这个怎么破。其实这段代码很简单&#xff0c;index数组就是arr数组的下标&#xff0c;index[0]2 对应 arr[2]1&#x…

steam怎么退款?steam退款教程?简单几步即可轻松实现退款

steam怎么退款&#xff1f;steam退款教程&#xff1f;简单几步即可轻松实现退款 说到steam平台大家肯定不会陌生&#xff0c;随着现代的发展&#xff0c;在steam上进行购买游戏已经成了很普遍的东西&#xff0c;但是许多玩家在购买游戏试完之后发现游戏并不符合自己的胃口&…

transformer上手(9)—— 翻译任务

运用 Transformers 库来完成翻译任务。翻译是典型的序列到序列 (sequence-to-sequence, Seq2Seq) 任务&#xff0c;即对于每一个输入序列都会输出一个对应的序列。翻译在任务形式上与许多其他任务很接近&#xff0c;例如&#xff1a; 文本摘要 (Summarization)&#xff1a;将长…

地质灾害监测预警系统:科技守护,构筑智能预警屏障

随着全球气候变化和人为活动的加剧&#xff0c;地质灾害频繁发生&#xff0c;给人们的生命财产安全带来了严重威胁。为了降低地质灾害带来的损失&#xff0c;地质灾害监测预警系统应运而生。本文将为您详细介绍地质灾害监测预警系统的原理、功能以及在实际应用中的效果。 一、地…

【考研数学】全年各阶段用书汇总+资料分享

我一战备考很迷茫&#xff0c;身边室友也都是&#xff0c;和室友一起去买资料&#xff0c;网上推荐的看到了就都买了 大家都不知道怎么样才能选对数学参考书然后快速进入备考状态&#xff0c;最后犹犹豫豫买了一堆资料都没有正式开始备考... 从小都算是身边人口中“偏科&…

L2-3 完全二叉树的层序遍历

完全二叉树的层序遍历 一个二叉树&#xff0c;如果每一个层的结点数都达到最大值&#xff0c;则这个二叉树就是完美二叉树。对于深度为 D 的&#xff0c;有 N 个结点的二叉树&#xff0c;若其结点对应于相同深度完美二叉树的层序遍历的前 N 个结点&#xff0c;这样的树就是完全…

箭头函数有哪些不适用场景

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

预分频器×重装载值)/LSI频率 为什么等于总时间

1. 第一种算法理解&#xff1a;分频系数 64 &#xff0c;外部低速时钟40khz&#xff0c; 则一次计数周期1.6ms &#xff0c;计数625个数&#xff0c;则有625个周期 &#xff0c;1.6ms*625 等于1s 如果分频系数是64&#xff0c;外部低速时钟&#xff08;LSI&#xff09;频率是…

动态规划|416.分割等和子集

力扣题目链接 class Solution { public:bool canPartition(vector<int>& nums) {int sum 0;// dp[i]中的i表示背包内总和// 题目中说&#xff1a;每个数组中的元素不会超过 100&#xff0c;数组的大小不会超过 200// 总和不会大于20000&#xff0c;背包最大只需要其…

STM32标准库+HAL库 | CPU片内FLASH存储器数据掉电读写

一、片内FLASH 在STM32芯片内部有一个FLASH存储器&#xff0c;它主要用于存储代码&#xff0c;我们在电脑上编写好应用程序后&#xff0c;使用下载器把编译后的代码文件烧录到该内部FLASH中&#xff0c; 由于FLASH存储器的内容在掉电后不会丢失&#xff0c;芯片重新上电复位后&…

车载摄像头畸变校正解决方案,打造无畸变高清视界

在车载摄像头日益普及的今天&#xff0c;摄像头图像的畸变问题成为了制约图像质量提升的一大瓶颈。畸变不仅影响画面的美观度&#xff0c;更关键的是它可能导致智能驾驶系统对环境的误判&#xff0c;进而威胁到行车安全。美摄科技凭借其在图像处理领域的深厚实力&#xff0c;推…

双位置继电器RXMD2-1MRK001984 DC220V JOSEF约瑟

系列型号&#xff1a; RXMD2 1MRK 001 984双位置继电器&#xff1b; RXMD2 1MRK 001 985双位置继电器&#xff1b; RXMD2 1MRK 001 986双位置继电器&#xff1b; 用途 该继电器主要用于直流操作的继电保护和自动化回路中作为大容量双稳态元件进行切换和闭锁。 特点 本继电器…