是做网站设计好还是杂志美编好,用asp制作一个简单的网站,网站方案编写,建网站的网站Android沙盒机制
Android Q文件存储机制修改成了沙盒模式#xff0c;应用只能访问自己沙盒下的文件和公共媒体文件
存储#xff08;也就是write#xff09;私有目录和公共媒体文件都不需要WRITE_EXTERNAL_STORAGE权限读取#xff08;也就是read#xff09;私有目录不需要…Android沙盒机制
Android Q文件存储机制修改成了沙盒模式应用只能访问自己沙盒下的文件和公共媒体文件
存储也就是write私有目录和公共媒体文件都不需要WRITE_EXTERNAL_STORAGE权限读取也就是read私有目录不需要READ_EXTERNAL_STORAGE权限读取公共媒体文件需要READ_EXTERNAL_STORAGE权限也就是说只能访问。
1、私有目录自己沙盒
getExternalFilesDir这是APP自身目录下的文件夹 Android/data/包名/fils
APP 卸载在这里插入代码片后数据会清除。APP 访问自己的 App-specific 目录时无需任何权限。可以使用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;//至为falsereturn 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)等
公共目录下的文件在 APP 卸载后不会删除。APP 可以通过 SAF框架(System Access Framework)、MediaStore 接口访问其中的文件。无法直接使用路径访问公共目录文件。
由于公共目录没有办法直接访问和处理文件所以我们需要按照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沙盒机制使用探究