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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【android】关于android10-11存储的一些知识

發布時間:2023/12/31 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【android】关于android10-11存储的一些知识 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據存儲簡述

名稱作用詳細說明
應用專屬存儲空間存儲應用專屬的文件專屬存儲空間可以在內部存儲和外部存儲為用戶開辟專屬的目錄,可以用來存儲其它用戶不能訪問的文件,可以通過File api訪問,應用被卸載后文件同時被刪除,訪問不需要權限
共享存儲存儲所有應用共享的數據存儲您的應用打算與其他應用共享的文件,包括媒體、文檔和其他文件,可以使用MediaStoreapi訪問,應用卸載數據仍然存在,訪問需要申請存儲權限

外部存儲空間的使用

使用外部專屬存儲空間

在android4.4-android9的版本之中,應用被分配了外部專屬存儲空間,這個空間無需權限即可訪問,如果應用想訪問其它應用的外部專屬存儲空間(分區存儲),那么需要申請存儲權限。

android10以上的版本中,應用的外部存儲空間成為了應用的私有空間,任何應用不可以訪問其它應用的專屬存儲空間

  • 特性
  • 外部專屬存儲空間位于應用的外部存儲中,我們可以在不申請權限的情況下訪問外部專屬存儲空間,外部專屬存儲空間可以在應用卸載后被刪除,專屬空間目錄媒體文件通常不應該被相冊等媒體應用收錄(也就是說相冊中不會展示這個目錄下的圖片)(我們自定義的圖片選擇器也不應該掃描這個目錄下的圖片)

    在低于 android10 的版本中,這個目錄是對所有應用可見的

  • 訪問方式
  • 獲取目錄路徑:

    • getExternalFilesDir(""):/storage/emulated/0/Android/data/com.ananananzhuo.storage10demo/files

    • getExternalFilesDirs():獲取目錄下所有文件的列表

  • 使用 demo
  • val file = File(getExternalFilesDir(""),"安安安安安卓.txt")val fos = FileOutputStream(file)fos.write("公眾號:安安安安安卓".toByteArray(Charsets.UTF_8))fos.close()

    上面的代碼中會在外部專屬存儲目錄(/storage/emulated/0/Android/data/com.ananananzhuo.storage10demo/files)下創建一個安安安安安卓.txt的文件,這里我們沒有聲明和申請任何權限。執行代碼后去看文件選擇器中的展示如下:

    在外部存儲中訪問非私有目錄則必須聲明申請權限
    下面我們寫一個反面案例

  • 代碼
  • ItemData(title = "訪問外部存儲空間",{val file = File(Environment.getExternalStorageDirectory().absolutePath)val fileAn = File(file,"安安安.txt")logEE(file.absolutePath)val fos = FileOutputStream(fileAn)fos.write("公眾號:安安安安安卓".toByteArray(Charsets.UTF_8))fos.close()})
  • 運行后崩潰日志
    提示沒有權限
  • 將媒體文件存儲在外部專屬存儲目錄的媒體文件夾中

    將圖片存儲到圖片文件夾中

  • 代碼
  • val picFile = getExternalFilesDir(Environment.DIRECTORY_PICTURES)?.apply {if (!exists()) {mkdirs()}}val file = File(picFile,"pic.jpg")FileOutputStream(file).apply {write(12)flush()close()}
  • 結果
  • 成功存儲文件

    媒體文件夾還有其他選項:

    • Environment.DIRECTORY_MOVIES
    • Environment.DIRECTORY_DOWNLOADS
    • Environment.DIRECTORY_DOCUMENTS
    • Environment.DIRECTORY_SCREENSHOTS

    存儲媒體的時候我們應該盡量使用 Environment 中的字符串常量獲取媒體文件目錄

    android10 以上版本能否使用 Environment.getExternalStorageDirectory 存取文件

    高于android10的版本無法使用getExternalStorageDirectory api操作文件,因為 api 已經被刪除,低于android10可以繼續使用該 api

    那么高于android10的版本我們應該如何訪問這部分的文件呢?別急,后續的共享存儲會詳細說明

  • 代碼
  • 效果圖
  • android10以上版本如何獲取sd卡中普通目錄的圖片

    我們可以通過SAF在android11以上版本獲取普通目錄圖片(即非專屬目錄,非共享目錄的圖片)

    本例中的方法不適用于android10以下系統版本(強行使用會崩潰)

  • 代碼
  • override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_directory_scan11)findViewById<Button>(R.id.btn_secletdirectory).setOnClickListener {val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)intent.addCategory(Intent.CATEGORY_OPENABLE)intent.type = "image/jpeg"startActivityForResult(intent, 100)//跳轉系統瀏覽器}}override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)data?.data?.let {iv.setImageURI(it)//通過url處理圖片}}
  • 效果
  • 內部存儲

    使用 openFileOutput 和 openFileInput 操作內部存儲

    將一個文件存儲到內部存儲的 files 目錄下

  • 代碼
  • openFileOutput("安安安安卓openfileoutput.txt", MODE_PRIVATE).apply {write("openFileOutput方法輸入流".toByteArray(Charsets.UTF_8))flush()close() }
  • 執行后文件查看
  • openFileInput 方法和 openFileOutput 一樣的使用方式

    fileList 獲取內部存儲全部文件路徑

  • 代碼
  • ItemData(title = "獲取目錄中所有文件路徑",{fileList().forEach {logEE("文件路徑:$it")}})
  • 輸出日志
  • E/安安安安卓: 文件路徑:安安安安卓openfileoutput.txt

    getCacheDir 獲取內部存儲緩存文件

    內部存儲緩存中的文件可能會在應用被卸載后被刪除,也可能在未卸載前被刪除(內部存儲空間不足的情況)。所以我們使用內部存儲空間緩存文件的時候需要先判斷文件是否存在

    context.getCacheDir()

    共享存儲空間(android10 以上版本)

    媒體

    android10以上將媒體文件文件按類型保存在公共目錄上,可以使用 MediaStore 訪問媒體文件

    以下表格列舉所有共享媒體文件類型

    媒體類型位置備注
    圖片存儲在 Pictures 和 DICM 目錄中,系統將這些文件存放在 MediaStore.Images 中
    視頻存儲 DICM、Movies、Pictures 目錄中,系統將這些文件添加到 MediaStore.VIDEO 表中
    音頻文件存儲在 Alarms、Audiobooks、Music、Notifications、Podcasts、Ringtones 目錄中,系統將這些文件添加到 MediaStore.Audio 表中
    下載文件存儲在 Download 目錄下,系統將這些文件添加到 MediaStore.Download 表中低于 android10 的版本中不可用
    文件集合存在于 MediaStore.Files 表中如果使用了分區存儲,這個集合只會顯示本應用創建的照片、視頻、音頻文件

    開啟分區存儲權限,媒體的處理

    如果應用使用分區存儲,您需要在應用的清單中聲明 ACCESS_MEDIA_LOCATION 權限,然后在運行時申請此權限。申請方法后面會講

    編寫一個相冊

  • 首先需要獲取共享存儲中所有的圖片地址,代碼如下
  • private fun getGallaryData(): MutableList<Image> {val cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,null, null, null, "${MediaStore.Images.Media.DISPLAY_NAME} ASC")val tempdatas = mutableListOf<Image>()cursor?.use {val idColumn = it.getColumnIndexOrThrow(MediaStore.Images.Media._ID)val nameColumn = it.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME)while (it.moveToNext()) {val id = it.getLong(idColumn)val contentUrl =ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)val name = it.getString(nameColumn)val image = Image(contentUrl, "")tempdatas.add(image)logEE("文件名:${contentUrl.path}")}it.close()}return tempdatas}
  • 在協程中獲取圖片 uri,并展示到適配器上
  • private fun initData() {lifecycleScope.launch(Dispatchers.IO) {datas.addAll(getGallaryData())withContext(Dispatchers.Main) {recycle.adapter?.notifyDataSetChanged()}}}
  • 效果
  • 關于android11版本MANAGE_EXTERNAL_STORAGE權限

    android10的版本是不能訪問所有文件的,可能google也意識到這是不合理的,所以在android11的版本上重新支持了所有文件的訪問

    在android11的系統版本上,如果想掃描應用的所有文件,那么可以聲明MANAGE_EXTERNAL_STORAGE權限

    MANAGE_EXTERNAL_STORAGE權限需要使用Intent進行權限申請,會跳轉到一個系統頁面確認權限

    需要說明的是:這種方式可以訪問共享存儲中的文件,但是不可以訪問專屬存儲目錄中的文件(Android/data)

    如下方法可以判斷是否擁有MANAGE_EXTERNAL_STORAGE權限

    Environment.isExternalStorageManager()

    聲明權限方式如下:

  • manifest中聲明權限
  • <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
  • 申請權限代碼
  • if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {startActivity(Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)) }
  • 實現效果
  • 其它

    權限方面

    • 使用使用共享存儲空間訪問其它應用創建的應用需要申請存儲權限,自己應用本次安裝創建的文件不需要申請權限。

    • 如果應用target版本大于 9,那么我們僅應該在<=9 的版本中進行權限申請,可以通過如下配置設置:

    maxSdkVersion

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"android:maxSdkVersion="28" />
    • 如果應用使用了存儲兼容功能,那么仍然需要訪問存儲權限

    存儲兼容指的就是我們準備升級android10但是暫時不想使用分區存儲

    開啟使用存儲兼容只需要在 manifest 中 application 標簽聲明如下配置即可:

    android:requestLegacyExternalStorage="true"

    切換媒體文件待處理狀態

    如果應用操作可能非常耗時(例如寫入文件),那么在我們操作文件期間應該避免讓其他應用有處理文件的機會。我們可以通過將 ContentValue.put(MediaStore.Audio.Media.IS_PENDING, 1) 標記的值設為 1 來獲取此獨占訪問權限。這樣就只有我們的的應用可以操作該文件,直到我們的應用將 IS_PENDING 的值改回 0。

    照片中的位置信息

    相冊中的照片可能會包含敏感信息,例如位置信息,這個信息默認是不允許用戶進行查看的,如果想查看需要申請 ACCESS_MEDIA_LOCATION權限

    關注公眾號學習更多知識

    總結

    以上是生活随笔為你收集整理的【android】关于android10-11存储的一些知识的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。