爱笑的姑娘|拖不得了,Android11真的要来了,最全适配实践指南奉上( 二 )


ok , 那到底应该怎么改呢?三种方法访问文件:
1)应用专属目录
//分区存储空间val file = File(context.filesDir, filename)//应用专属外部存储空间val appSpecificExternalDir = File(context.getExternalFilesDir(), filename)2)访问公共媒体目录文件
val cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, "${MediaStore.MediaColumns.DATE_ADDED} desc")if (cursor != null) {while (cursor.moveToNext()) {val id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))val uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)println("image uri is $uri")}cursor.close()}3) SAF(存储访问框架--Storage Access Framework)
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)intent.addCategory(Intent.CATEGORY_OPENABLE)intent.type = "image/*"startActivityForResult(intent, 100)@RequiresApi(Build.VERSION_CODES.KITKAT)override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)if (data =http://kandian.youth.cn/index/= null || resultCode != Activity.RESULT_OK) returnif (requestCode == 100) {val uri = data.dataprintln("image uri is $uri")}}【爱笑的姑娘|拖不得了,Android11真的要来了,最全适配实践指南奉上】具体还有很多操作可以看看网上关于分区存储的资料 , 因为Android10已经出来很久了 , 所以资料还是很多的 , 这里推荐几篇
访问应用专属文件
Android 10适配要点 , 作用域存储
AndroidQ(10)分区存储完美适配
说到这里可能又有人问了 , 那我的应用就是个手机管理器 , 总不能不让我清其他应用的缓存了吧 , 有办法!Android提供了两个intent入口:

  • 调用ACTION_MANAGE_STORAGE intent 操作检查可用空间 。
  • 调用ACTION_CLEAR_APP_CACHE intent 操作清除所有缓存 。
说来说去 , 反正应用数据私有化是大势所趋 , 还是早点适配分区存储 , 别等以后手机只有沙盒机制的时候 , 就来不及了 。
媒体文件访问权限 ?为了在保证用户隐私的同时可以更轻松地访问媒体 , Android 11 增加了以下功能 。 执行批量操作和使用直接文件路径和原生库访问文件 。
1)执行批量操作
这里的批量操作指的是Android 11 向 MediaStore API 中添加了多种方法 , 用于简化特定媒体文件更改流程(例如在原位置编辑照片) , 分别是:
  • createWriteRequest() 用户向应用授予对指定媒体文件组的写入访问权限的请求 。
  • createFavoriteRequest()用户将设备上指定的媒体文件标记为“收藏”的请求 。 对该文件具有读取访问权限的任何应用都可以看到用户已将该文件标记为“收藏” 。
  • createTrashRequest() 用户将指定的媒体文件放入设备垃圾箱的请求 。 垃圾箱中的内容会在系统定义的时间段后被永久删除 。
  • createDeleteRequest() 用户立即永久删除指定的媒体文件(而不是先将其放入垃圾箱)的请求 。
直接看个例子:
val urisToModify = listOf(uri,uri,...)val editPendingIntent = MediaStore.createWriteRequest(contentResolver,urisToModify)// Launch a system prompt requesting user permission for the operation.startIntentSenderForResult(editPendingIntent.intentSender, EDIT_REQUEST_CODE,null, 0, 0, 0)override fun onActivityResult(requestCode: Int, resultCode: Int,data: Intent?) {when (requestCode) {EDIT_REQUEST_CODE ->if (resultCode == Activity.RESULT_OK) {/* Edit request granted; proceed. */} else {/* Edit request not granted; explain to the user. */}}}