Android 文件管理】分區存儲 ( MediaStore 文件操作 )

      網友投稿 1082 2022-05-29

      文章目錄

      一、動態權限申請

      二、MediaStore 操作文件

      三、完整代碼示例

      1、MainActivity 核心代碼

      2、build.gradle 構建腳本

      3、清單文件

      五、相關文檔資料

      特別注意 Android 低版本中不能使用分區存儲 API 操作文件 , 【錯誤記錄】Android 低版本使用分區存儲錯誤 ( IllegalArgumentException:no path was provided when inserting new file )

      一、動態權限申請

      進行 SD 卡讀寫操作前 , 必須先申請 SD 卡讀寫的動態權限 ;

      動態權限參考 :

      【Android 應用開發】Google 官方 EasyPermissions 權限申請庫 ( 最簡單用法 | 一行代碼搞定權限申請 | 推薦用法 )

      【Android 應用開發】Google 官方 EasyPermissions 權限申請庫 ( 完整代碼示例 | 申請權限 | 申請權限原理對話框 | 引導用戶手動設置權限對話框 )

      清單文件中的配置 :

      1

      2

      3

      4

      5

      6

      7

      8

      9

      構建腳本中的配置 :

      dependencies { // 使用 Android X 的應用添加該依賴 implementation 'pub.devrel:easypermissions:3.0.0' }

      1

      2

      3

      4

      Activity 中的權限申請源碼 : 分支一是有權限的情況下的后續處理 , 分支二是申請動態權限 ;

      @AfterPermissionGranted( 100 ) fun doSomethingWithPermissions(){ if(EasyPermissions.hasPermissions(this, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)){ // 分支一 : 如果有上述權限, 執行該操作 Toast.makeText(this, "權限申請通過", Toast.LENGTH_LONG).show() }else{ // 分之二 : 如果沒有上述權限 , 那么申請權限 EasyPermissions.requestPermissions( this, "權限申請原理對話框 : 描述申請權限的原理", 100, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE ) } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      二、MediaStore 操作文件

      在 Android 11 11 11 之后 , 不能使用 File 進行文件操作 , 需要使用 MediaStore 進行文件操作 ,

      MediaStore 的如下內部類

      Files ,

      Images ,

      Downloads ,

      Audio ,

      Video ,

      負責相應目錄的文件操作 , 分別對應外置存儲中的

      Document ,

      Pictures ,

      Download ,

      Music ,

      Movies

      目錄 ;

      如 : MediaStore 下的 Images 內部類 , 負責 Pictures 下的文件操作 ;

      package android.provider; public final class MediaStore { public static final class Images { public Images() { throw new RuntimeException("Stub!"); } } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      一個 文本文件 , 只能存儲在 Download 和 Documents 目錄下 , Download 目錄可以存放任何類型的文件 , Documents 目錄只能存儲文本文件 ;

      首先通過 MediaStore 獲取 Files 內部類對象 , 調用該內部類的 getContentUri(“external”) , 即可獲取在 【Android 文件管理】分區存儲 ( 分區存儲機制 和 文件索引數據 ) 四、文件索引數據庫 博客章節提到的文件索引數據庫 , 然后就可以通過 ContentValues 向其中插入數據 ;

      獲取數據庫 :

      // 操作 external.db 數據庫 // 獲取 Uri 路徑 var uri: Uri = MediaStore.Files.getContentUri("external")

      1

      2

      3

      插入數據時 , 構造 ContentValues 數據結構 , 主要是設置 external.db 數據庫中 files 數據表對應的條目 , 設置該條目的主要字段值 ;

      構造 ContentValues 數據 :

      // 將要新建的文件的文件索引插入到 external.db 數據庫中 // 需要插入到 external.db 數據庫 files 表中, 這里就需要設置一些描述信息 var contentValues: ContentValues = ContentValues() // 設置插入 external.db 數據庫中的 files 數據表的各個字段的值 // 設置存儲路徑 , files 數據表中的對應 relative_path 字段在 MediaStore 中以常量形式定義 contentValues.put(MediaStore.Downloads.RELATIVE_PATH, "${Environment.DIRECTORY_DOWNLOADS}/hello") // 設置文件名稱 contentValues.put(MediaStore.Downloads.DISPLAY_NAME, "hello.txt") // 設置文件標題, 一般是刪除后綴, 可以不設置 contentValues.put(MediaStore.Downloads.TITLE, "hello")

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      ContentValues 構造成功后 , 使用 ContentResolver 將數據插入數據庫中 ; 系統會自動創建對應的文件 ;

      向數據庫中插入數據 :

      // uri 表示操作哪個數據庫 , contentValues 表示要插入的數據內容 var insert: Uri = contentResolver.insert(uri, contentValues)!!

      1

      2

      系統自動創建的文件是一個目錄文件 , 向其中寫出 “Hello World” 文本數據 , 即可完成相關文件創建 ;

      通過返回的 Uri 打開輸出流 , 向文件中寫出數據 :

      // 向 Download/hello/hello.txt 文件中插入數據 var os: OutputStream = contentResolver.openOutputStream(insert)!! var bos = BufferedOutputStream(os) bos.write("Hello World".toByteArray()) bos.close()

      1

      2

      3

      4

      5

      啟動 Android 11 系統的模擬器 , 然后部署該應用 , 文件創建成功 ;

      三、完整代碼示例

      1、MainActivity 核心代碼

      package kim.hsl.file import android.Manifest import android.content.ContentValues import android.net.Uri import android.os.Bundle import android.os.Environment import android.provider.MediaStore import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import pub.devrel.easypermissions.AfterPermissionGranted import pub.devrel.easypermissions.EasyPermissions import java.io.BufferedOutputStream import java.io.OutputStream class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 動態權限獲取 doSomethingWithPermissions() } @AfterPermissionGranted( 100 ) fun doSomethingWithPermissions(){ if(EasyPermissions.hasPermissions(this, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)){ // 分支一 : 如果有上述權限, 執行該操作 Toast.makeText(this, "權限申請通過", Toast.LENGTH_LONG).show() // Android 11 中創建文件 createFile() }else{ // 分支二 : 如果沒有上述權限 , 那么申請權限 EasyPermissions.requestPermissions( this, "權限申請原理對話框 : 描述申請權限的原理", 100, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE ) } } /** * 創建文件 * 在 Download 目錄下創建 hello.txt */ fun createFile(){ // 操作 external.db 數據庫 // 獲取 Uri 路徑 var uri: Uri = MediaStore.Files.getContentUri("external") // 將要新建的文件的文件索引插入到 external.db 數據庫中 // 需要插入到 external.db 數據庫 files 表中, 這里就需要設置一些描述信息 var contentValues: ContentValues = ContentValues() // 設置插入 external.db 數據庫中的 files 數據表的各個字段的值 // 設置存儲路徑 , files 數據表中的對應 relative_path 字段在 MediaStore 中以常量形式定義 contentValues.put(MediaStore.Downloads.RELATIVE_PATH, "${Environment.DIRECTORY_DOWNLOADS}/hello") // 設置文件名稱 contentValues.put(MediaStore.Downloads.DISPLAY_NAME, "hello.txt") // 設置文件標題, 一般是刪除后綴, 可以不設置 contentValues.put(MediaStore.Downloads.TITLE, "hello") // uri 表示操作哪個數據庫 , contentValues 表示要插入的數據內容 var insert: Uri = contentResolver.insert(uri, contentValues)!! // 向 Download/hello/hello.txt 文件中插入數據 var os: OutputStream = contentResolver.openOutputStream(insert)!! var bos = BufferedOutputStream(os) bos.write("Hello World".toByteArray()) bos.close() } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      【Android 文件管理】分區存儲 ( MediaStore 文件操作 )

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      79

      80

      81

      82

      83

      84

      2、build.gradle 構建腳本

      引入 pub.devrel:easypermissions:3.0.0 依賴庫 ; ( 其它省略 )

      dependencies { // 使用 Android X 的應用添加該依賴 implementation 'pub.devrel:easypermissions:3.0.0' }

      1

      2

      3

      4

      3、清單文件

      配置 SD 卡讀寫權限 ; ( 其它省略 )

      1

      2

      3

      4

      5

      6

      7

      8

      五、相關文檔資料

      Android 文件處理參考文檔 :

      數據和文件存儲概覽 : https://developer.android.google.cn/training/data-storage

      訪問應用專屬文件 : https://developer.android.google.cn/training/data-storage/app-specific#kotlin

      保存到共享的存儲空間 : https://developer.android.google.cn/training/data-storage/shared

      管理存儲設備上的所有文件 : https://developer.android.google.cn/training/data-storage/manage-all-files

      分享文件 : https://developer.android.google.cn/training/secure-file-sharing

      應用安裝位置 : https://developer.android.google.cn/guide/topics/data/install-location

      Android 存儲用例和最佳做法 : https://developer.android.google.cn/training/data-storage/use-cases

      FileProvider : https://developer.android.google.cn/reference/androidx/core/content/FileProvider

      博客源碼 :

      GitHub : https://github.com/han1202012/File

      CSDN : https://download.csdn.net/download/han1202012/18832417

      Android

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:文檔識別工具讓紙質文檔處理工作事半功倍!
      下一篇:Pandas官方文檔(中文版)Pdf
      相關文章
      久久青青草原亚洲av无码app| 久久亚洲高清综合| 亚洲区小说区图片区| 久久亚洲AV成人无码国产电影| 亚洲AV无码无限在线观看不卡 | 18gay台湾男同亚洲男同| 亚洲免费在线视频| 久久亚洲精品成人av无码网站| 亚洲va在线va天堂va四虎| 亚洲av无码专区在线播放| 亚洲国产成人久久综合一| 亚洲成a人片77777老司机| 亚洲av成人无码久久精品| 亚洲AV无码国产精品色午友在线| 精品国产综合成人亚洲区| 国产成人亚洲综合无码精品| 久久亚洲精品中文字幕无码| 久久久久亚洲av无码专区 | 爱情岛亚洲论坛在线观看| 亚洲成av人在片观看| 亚洲AⅤ优女AV综合久久久| 国产精品亚洲αv天堂无码| 国产亚洲色婷婷久久99精品| 亚洲成AV人片一区二区| 亚洲高清在线视频| 亚洲小说区图片区| 亚洲а∨天堂久久精品9966| 亚洲Aⅴ在线无码播放毛片一线天| 亚洲av综合日韩| 国产L精品国产亚洲区久久| 亚洲色自偷自拍另类小说| 久久久无码精品亚洲日韩蜜桃| 亚洲黄色在线播放| 精品国产成人亚洲午夜福利| 亚洲av无码一区二区三区天堂| 亚洲国产中文v高清在线观看| 亚洲精品成人片在线播放| 麻豆亚洲AV永久无码精品久久| 亚洲国产91在线| 亚洲av无一区二区三区| 亚洲综合亚洲综合网成人|