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之前的版本一样,可以随意处理。

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

在AndroidQ中适配存储图片

1.保存到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();

}

}

2.保存到共享媒体文件夹中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();

}

}

在AndroidQ中适配读取图片

1.在指定的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;

}

公共媒体:

在公共媒体不能直接通过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 沙盒存储,Android Q存储机制-沙盒机制相关推荐

  1. Android Q 存储新特性适配脑壳疼?指南来了!

    码个蛋(codeegg)第 692 次推文 原文: https://mp.weixin.qq.com/s/aiDMyAfAZvaYIHuIMLAlcg 简单回顾下:Android Q 适配 之 存储新 ...

  2. android读写相册权限,androidQ 关于存储权限相册图片

    关于存储位置 内部存储(Internal Storage) //路径:(data/data/packageName/cache) getCacheDir() //路径:(data/data/packa ...

  3. Android—内部存储与外部存储、保存图片到相册

    内部存储: 当一个应用卸载之后,内部存储中的这些文件也被删除.在创建内部存储文件的时候将文件属性设置成可读,其他app能够访问自己应用的数据,前提是他知道你这个应用的包名,如果一个文件的属性是私有(p ...

  4. android 源码分析 内置 sd storage,Android开罐头———外部存储与内部存储完全解析...

    context.getExternalFilesDir(),Environment.getExternalStorageDirectory(),傻傻分不清?到底什么算安卓手机的external sto ...

  5. Android存储之分区存储适配

    一.Android存储分区介绍 1.简介 Android 存储分为内部存储(Internal storage)和外部存储(External storage).有许多用户认为外部存储意味着SD存储卡或外 ...

  6. 【Android 内存优化】Android 原生 API 图片压缩代码示例 ( PNG 格式压缩 | JPEG 格式压缩 | WEBP 格式压缩 | 动态权限申请 | Android10 存储策略 )

    文章目录 一. 图片质量压缩 二. 图片尺寸压缩 三. Android 10 文件访问 四. 完整源码示例 上一篇博客 [Android 内存优化]图片文件压缩 ( Android 原生 API 提供 ...

  7. Android数据存储之文件存储(瞬时数据的存储与读取)项目已上传GitHub

    GitHub地址: https://github.com/Skymqq/FileSave.git 数据持久化就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然 ...

  8. android中资源文件的两种访问方式,Android_Android学习笔记-保存文件(Saving Files),Android设备有两种文件存储区域 - phpStudy...

    Android学习笔记-保存文件(Saving Files) Android设备有两种文件存储区域: 内部存储和外部存储 ("internal" and "externa ...

  9. Android中的5种数据存储方式

    Android中的5种数据存储方式 Android中的5种数据存储方式 数据存储在开发中是使用最频繁的,在这里主要介绍Android平台中实现数据存储的5种方式,分别是: 1 使用SharedPref ...

最新文章

  1. 王茂霖:数据挖掘提分三板斧!
  2. Android开发--Http操作介绍(二)
  3. 给Vista系统加入一键还原功能
  4. 操作系统上机作业-- 使用信号量解决生产者、计算者、消费者问题(多线程)
  5. SwitchHosts提示切换hosts失败!没有修改'C:\WINDOWS\system32\drivers\etc\hosts'的权限问题
  6. 6 键盘高级操作技巧
  7. Java企业介绍,Hunson 介绍
  8. tar命令--解压缩
  9. .NET 类、网站dll反编译工具
  10. 潘多拉固件设置ipv6_OpenWRT IPv6配置
  11. android语音到账,支付宝到账语音包
  12. 爬取实习僧并进行数据可视化
  13. 李白打酒*C语言简易版(递归)
  14. 逻辑思维训练和推理思维训练
  15. c#MVC文件(图片,word,excel,zip等)批量上传
  16. “燕云十六将”之毛毛杜倩(7)
  17. 政府大数据中心数据资源平台 建设方案
  18. 【数据库-MySql】单姓第二字用*号代替,复姓第三个字用*号代替。
  19. MATLAB中散点图的绘制方法
  20. java去除音频无声_如何给视频消音 把视频中的声音去掉只留视频画面

热门文章

  1. andriod开发外包
  2. Oracle入门笔记—基础配置(一)
  3. 高通滤波器matlab程序,高通滤波器matlab程序代码解析
  4. 12.写一个简单的发布器与订阅器(C++)
  5. 针对飞机线缆分布式检测线束测试仪方案
  6. 群发淘宝消息 另外的思路 使用 UI Automation 和 api
  7. 白帽学院靶场之编辑器的奥秘(二)
  8. 微信8.0状态视频素材免费下载
  9. VS Code安装教程
  10. 电子信息工程专业学生的就业方向