日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android分区存储

發(fā)布時間:2024/3/24 Android 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android分区存储 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1、分區(qū)存儲概述

分區(qū)存儲是Android 10開始引進的Android系統(tǒng)存儲管理機制,它允許App讀取和寫入App自身創(chuàng)建的文件而不需要任何存儲權限。其中根據(jù)存儲位置的不同,可以分為內(nèi)部內(nèi)部存儲和外部存儲。內(nèi)部存儲就不用多說了,而外部存儲又分為私有空間和公共空間。私有存儲空間位置是/sdcard/Android/data/包名,而公共空間則是相冊、下載等。對我們開發(fā)者影響最大的就是對于公共存儲空間的讀寫了,總結如下:

  • 對于9.0及以下的版本,仍然使用READ和WRITE權限,之前怎么做,現(xiàn)在還是怎么做
  • 對于10.0,可以在清單文件中加入以下代碼變得跟9.0以前一樣<application android:requestLegacyExternalStorage="true" ...> ... </application> 但是不建議,因為這種方式在Android 11已經(jīng)不行了,反正都要適配
  • 對于Android 10和11,讀寫App自己創(chuàng)建的文件不需要任何存儲權限,讀取其他應用創(chuàng)建的文件需要READ權限,但是WRITE權限被廢棄了,寫入其他應用創(chuàng)建的文件需要用戶的干預。
  • Android分區(qū)存儲機制其實挺好的,讓很多軟件不能為所欲為,至少提高了“犯罪成本”。就是來得晚了一些,導致我們開發(fā)者要各種兼容…

    2、讀取

    以讀取相冊(DCIM)為例

    val uris = ArrayList<Uri>() contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null,null, "${MediaStore.MediaColumns.DATE_ADDED} desc")?.use {// 這里的it是一個Cursorwhile (it.moveToNext()) {val id = it.getLong(it.getColumnIndexOrThrow(MediaStore.MediaColumns._ID))val uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)uris.add(uri)} }

    這個contextResolver就是是Context.getContentResolver(),Actvity是Context子類,所以用kotlin就可以直接簡寫。
    這樣就拿到了相冊里面的圖片的Uri,它是“content://”形式的uri:

    content://media/external/images/media/71

    這種讀取形式在低版本也是可用的,但是需要READ權限。在Android 10和11中,如果有READ權限,則可以讀取到所有的圖片文件的Uri,否則只能讀取到App本身創(chuàng)建的文件Uri。
    在拿到Uri后,我們可以通過流的形式讀取它:

    contentResolver.openInputStream(uri)?.use { // do sth }

    如果是用于展示圖片,可以使用Glide等開源框架,它們本身就支持加載Uri。

    3、寫入

    同樣以寫入相冊(DCIM)為例:

    val bitmap = BitmapFactory.decodeResource(resources, R.drawable.girl) val values = ContentValues() values.put(MediaStore.MediaColumns.DISPLAY_NAME, "test.png") values.put(MediaStore.MediaColumns.MIME_TYPE, "image/png") if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // RELATIVE_PATH需要API 29values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM) } else {values.put(MediaStore.MediaColumns.DATA, "${Environment.getExternalStorageDirectory().path}/${Environment.DIRECTORY_DCIM}/test.png") } contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)?.also { uri ->contentResolver.openOutputStream(uri)?.use { os ->bitmap.compress(Bitmap.CompressFormat.PNG, 100, os)} }

    同樣地,在低版本寫入需要WRITE權限,在10和11上不需要。但是如果這個要修改其他App創(chuàng)建的文件,就需要寫成這樣

    private var uri: Uri? = null // 通過某些操作獲取這個uri并賦值 private fun change() {val temp = uri ?: returncontentResolver.openInputStream(temp)?.use { val bitmap = BitmapFactory.decodeStream(it)val values = ContentValues()values.put(MediaStore.MediaColumns.DISPLAY_NAME, "test.png")values.put(MediaStore.MediaColumns.MIME_TYPE, "image/png")if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // RELATIVE_PATH需要API 29values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM)} else {values.put(MediaStore.MediaColumns.DATA, "${Environment.getExternalStorageDirectory().path}/${Environment.DIRECTORY_DCIM}/test.png")}try {contentResolver.openOutputStream(temp)?.use { os ->bitmap.compress(Bitmap.CompressFormat.PNG, 80, os)Toast.makeText(this@MainActivity, "OK", Toast.LENGTH_SHORT).show()}} catch (e: Exception) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && e is RecoverableSecurityException) {startIntentSenderForResult(e.userAction.actionIntent.intentSender, 10086, null, 0, 0, 0)} else {throw e}}} }override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)if(requestCode == 10086 && resultCode == RESULT_OK) {change()} }

    會彈出這樣的彈窗

    如果是對多個文件進行寫入,在Android 11上可以這樣寫:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {val request = MediaStore.createWriteRequest(contentResolver, listOf(uri1, uri2))startIntentSenderForResult(request.intentSender, 10086, null, 0, 0, 0) }

    值得一提的是,用戶如果卸載了App后再重新安裝,即使是卸載前App自身創(chuàng)建的文件也需要相關權限。也就是說卸載重裝之后,“同一個App”其實在系統(tǒng)眼里不是同一個App。

    3、管理存儲的權限

    分區(qū)存儲機制很好地規(guī)范了Android App的存儲行為,讓它們讀自己該讀的,寫自己該寫的。但是有的應用天生就需要對SD卡進行全方位的訪問,比如各種文件瀏覽器、垃圾清理軟件等等,雖然很多所謂的垃圾清理軟件本身就是最該被清理的垃圾…對此,Android 11引入了一個新的權限:

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

    有了這個權限,就可以跟以前的版本一樣隨意玩耍了。那么是不是可以直接申請這個權限就可以了呢?機智如我,是可以的,不過應用市場不讓上架…所以大部分App是不允許使用這個權限的。如果要申請此權限,需要打開設置界面,讓用戶手動設置

    val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION) startActivityForResult(intent, 10010)

    如果在manifest中添加了requestLegacyExternalStorage屬性,還可以加上包名

    val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION) intent.data = Uri.parse("package:$packageName") startActivityForResult(intent, 10010)

    出現(xiàn)的界面長這樣

    總結

    以上是生活随笔為你收集整理的Android分区存储的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 女同性做爰三级 | 亚洲欧美另类一区 | 嘿咻视频在线观看 | 强开小受嫩苞第一次免费视频 | 轻轻色在线观看 | 四虎影视国产精品 | 91久久一区二区三区 | 国产美女精品视频国产 | 国产精品久免费的黄网站 | 午夜激情在线观看视频 | 国产欧美一区二区三区在线 | 亚洲av成人精品午夜一区二区 | 韩国伦理大片 | 成人精品在线观看 | 免费毛片视频 | 一区二区三区爱爱 | 大地资源高清播放在线观看 | 亚洲美女操 | 黄色片视频在线观看 | 久久久久噜噜噜亚洲熟女综合 | 真人一及毛片 | 夜夜操操操| 人人妻人人澡人人爽精品欧美一区 | 成人无遮挡 | 精品一二三区 | 亚洲熟妇av乱码在线观看 | 亚洲国产精品久久久久久久 | 天天干天天弄 | 国产一区亚洲二区三区 | 91禁蘑菇在线看 | 亚洲女人视频 | 日韩美一级片 | 精一区二区 | 欧美激情一区二区三区四区 | 香蕉视频成人在线 | 日日夜夜婷婷 | 日本一二三不卡 | 少妇无码av无码专区在线观看 | 欧美色图1 | 精品动漫一区二区三区的观看方式 | 精品国产美女 | 亚洲精品一卡 | 99视频一区 | 欲色影音| 91超碰免费 | 伊人久久国产 | mdyd—856冲田杏梨在线 | 六月婷婷在线 | 3d动漫精品啪啪一区二区下载 | 欧美激情图区 | 国产精品7 | 人人插插 | 中文在线免费看视频 | 激情五月综合色婷婷一区二区 | 亚卅色图 | 在线播放免费av | 激情另类视频 | 超碰在线伊人 | 国产一级α片 | 亚洲天堂av免费在线观看 | 欧美一区二区三区观看 | 男女啪啪在线观看 | 美女无遮挡网站 | 成人在线视频播放 | 两口子交换真实刺激高潮 | 国产亚洲综合精品 | 国产不卡视频在线观看 | 亚欧成人精品一区二区 | 福利社午夜影院 | 日韩少妇毛片 | 日日噜噜噜 | 一级国产片 | 蜜桃91丨九色丨蝌蚪91桃色 | 欧美片在线观看 | 法国空姐电影在线 | a级片免费视频 | 综合激情网五月 | 福利视频h| xxx性欧美 | 最近日韩中文字幕中文 | 夜夜伊人| 欧美xxxx黑人 | 婷婷国产 | 日本成人激情视频 | 亚洲精品乱码久久久久久麻豆不卡 | 精品欧美一区二区三区免费观看 | 久久机热这里只有精品 | 捆绑少妇玩各种sm调教 | 伊人久久艹 | 亚洲黄a| 亚洲电影在线看 | 五月亚洲婷婷 | 噜噜在线视频 | 一区二区久久精品66国产精品 | 久久精品波多野结衣 | 黄色一级大片免费版 | 91丨porny丨首页| 色多多视频在线 | 色噜噜在线观看 |