亞寵展、全球寵物產業風向標——亞洲寵物展覽會深度解析
1137
2022-05-29
文章目錄
一、分區存儲模式下使用 MediaStore 插入圖片
二、分區存儲模式下使用 MediaStore 查詢圖片
三、相關文檔資料
Android 分區存儲系列博客 :
【Android 文件管理】應用可訪問的存儲空間 ( 存儲空間分類 | 存儲空間訪問權限 | 分區存儲 )
【Android 文件管理】分區存儲 ( 分區存儲機制 和 文件索引數據 )
【Android 文件管理】分區存儲 ( MediaStore 文件操作 )
一、分區存儲模式下使用 MediaStore 插入圖片
在上一篇博客 【Android 文件管理】分區存儲 ( MediaStore 文件操作 ) 中 , 創建了一個文本文件 , 并向其寫出一個字符串 ;
創建文件時注意 , 使用 MediaStore 向
" external.db " 數據庫
中插入了文件數據 , 只是生成了文件索引 , 如果不向文件中寫出數據 ,
并不會真正的創建文件
; 插入數據后 ,
依據返回的 android.net.Uri 類型打開輸出流 ,
然后通過該輸出流寫出數據 ,
文件創建完成 ;
圖片創建流程 :
首先 , 獲取
操作數據庫的 Uri ;
// 操作 external.db 數據庫 // 獲取 Uri 路徑 var uri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
1
2
3
其次 ,
構造插入數據庫的 ContentValues 數據結構
, 設置的 “external.db” 數據庫中的 “files” 數據表的各個字段與 MediaStore 中的常量對應關系如下 :
MediaStore.Downloads.RELATIVE_PATH :
relative_path
MediaStore.Downloads.DISPLAY_NAME :
display_ame
MediaStore.Downloads.TITLE :
tittle
MediaStore.Downloads.MIME_TYPE :
mime_type
// 將要新建的文件的文件索引插入到 external.db 數據庫中 // 需要插入到 external.db 數據庫 files 表中, 這里就需要設置一些描述信息 var contentValues: ContentValues = ContentValues() // 設置插入 external.db 數據庫中的 files 數據表的各個字段的值 // 設置存儲路徑 , files 數據表中的對應 relative_path 字段在 MediaStore 中以常量形式定義 contentValues.put(MediaStore.Downloads.RELATIVE_PATH, "${Environment.DIRECTORY_MOVIES}/image") // 設置文件名稱 contentValues.put(MediaStore.Downloads.DISPLAY_NAME, "image.jpg") // 設置文件標題, 一般是刪除后綴, 可以不設置 contentValues.put(MediaStore.Downloads.TITLE, "image") // 設置 MIME_TYPE contentValues.put(MediaStore.Downloads.MIME_TYPE, "image/jpg")
1
2
3
4
5
6
7
8
9
10
11
12
13
再次 , 獲取該上下文對應的 ContentResolver , 調用 insert 方法 , 將上述構建的 ContentValues 插入到數據庫中 , 返回 Uri ;
// uri 表示操作哪個數據庫 , contentValues 表示要插入的數據內容 var insert: Uri = contentResolver.insert(uri, contentValues)!!
1
2
最后 , 根據插入數據返回的 Uri , 打開輸出流 , 然后向輸出流中寫出圖片數據 ;
// 向 Download/hello/hello.jpg 文件中插入數據 var os: OutputStream = contentResolver.openOutputStream(insert)!! var bitmap: Bitmap = BitmapFactory.decodeResource(resources, R.drawable.icon) bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os) os.close()
1
2
3
4
5
圖片數據寫出完成 , 輸出流正式關閉 , 圖片創建成功 ;
創建完成后 , 可以在 " Device Explorer " 面板中顯示新創建的圖片 ;
關于 圖片 MIME_TYPE :
圖片文件創建 與 文本文件創建 唯一的區別就是需要設置 MIME_TYPE 字段 , 根據傳入的圖片格式設置不同的 mimetype , 如 : 傳入 jpeg 圖片 , 則設置字段值為 “image/jpg” ;
保存圖片文件時 , 傳入的 MIME_TYPE 為 “image/jpg” , 如果傳錯了 , 寫成 “vedio/mp3” , 創建文件時不會拋出異常 , 但是使用該文件時會出錯 ;
圖片創建部分代碼示例 :
/** * 創建圖片文件 * 在 Download 目錄下創建 hello.txt */ fun createImageFile(){ // 操作 external.db 數據庫 // 獲取 Uri 路徑 var uri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI // 將要新建的文件的文件索引插入到 external.db 數據庫中 // 需要插入到 external.db 數據庫 files 表中, 這里就需要設置一些描述信息 var contentValues: ContentValues = ContentValues() // 設置插入 external.db 數據庫中的 files 數據表的各個字段的值 // 設置存儲路徑 , files 數據表中的對應 relative_path 字段在 MediaStore 中以常量形式定義 contentValues.put(MediaStore.Downloads.RELATIVE_PATH, "${Environment.DIRECTORY_MOVIES}/image") // 設置文件名稱 contentValues.put(MediaStore.Downloads.DISPLAY_NAME, "image.jpg") // 設置文件標題, 一般是刪除后綴, 可以不設置 contentValues.put(MediaStore.Downloads.TITLE, "image") // 設置 MIME_TYPE contentValues.put(MediaStore.Downloads.MIME_TYPE, "image/jpg") // uri 表示操作哪個數據庫 , contentValues 表示要插入的數據內容 var insert: Uri = contentResolver.insert(uri, contentValues)!! // 向 Download/hello/hello.jpg 文件中插入數據 var os: OutputStream = contentResolver.openOutputStream(insert)!! var bitmap: Bitmap = BitmapFactory.decodeResource(resources, R.drawable.icon) bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os) os.close() }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
二、分區存儲模式下使用 MediaStore 查詢圖片
首先 , 根據查詢的位置 , 獲取其對應的數據庫操作 Uri ; 這里獲取外置 SD 卡 Pictures 目錄對應的 Uri 對象 ;
// 獲取外置 SD 卡 Pictures 對應的 Uri 對象 var externalContentUri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
1
2
然后 , 使用 SQLite 查詢機制 , 查詢對應圖片的 Uri ; 查詢 Pictures 目錄下的 image.jpg 圖片 ;
// 拼接查詢語句 var selection: String = "${MediaStore.Images.Media.DISPLAY_NAME}=?"; // 查詢語句參數 var selectionArgs: Array
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
最后 , 通過 Cursor 查詢數據表中各個字段的信息 , 如 id 字段 , relative_path 相對路徑字段 , data 絕對路徑字段 , _display_name 文件名稱字段 ;
// 先獲取該圖片在數據庫中的 id , 然后通過 id 獲取 Uri if (cursor != null && cursor.moveToFirst()){ // 獲取第 0 行 _id 所在列的值 var id = cursor.getLong( // 獲取 _id 所在列的索引 cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID) ) var path = cursor.getString( // 獲取 relative_path 所在列的索引 cursor.getColumnIndexOrThrow(MediaStore.Images.Media.RELATIVE_PATH) ) var name = cursor.getString( // 獲取 _display_name 所在列的索引 cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME) ) // 絕對路徑 var absolutePath = cursor.getString( // 獲取 data 所在列的索引 cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) ) // 通過 _id 字段獲取圖片 Uri var uri = ContentUris.withAppendedId(externalContentUri, id); Log.i(TAG, "查詢到的 Uri = $uri , 路徑 = $path , 文件名稱 = $name , 絕對路徑 = $absolutePath") // 關閉游標 cursor.close() }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
查詢文件代碼示例 :
/** * 查詢所有的圖片 */ fun queryImages(){ // 獲取外置 SD 卡 Pictures 對應的 Uri 對象 var externalContentUri: Uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; // 拼接查詢語句 var selection: String = "${MediaStore.Images.Media.DISPLAY_NAME}=?"; // 查詢語句參數 var selectionArgs: Array
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
執行打印的結果 :
查詢到的 Uri = content://media/external/images/media/42 , 路徑 = Pictures/image/ , 文件名稱 = image.jpg , 絕對路徑 = /storage/emulated/0/Pictures/image/image.jpg
1
注意 : 該文件的
Uri 是 " content://media/external/images/media/42 " ,
絕對路徑是 " /storage/emulated/0/Pictures/image/image.jpg " ;
Uri 最后的 42 數字 , 就是在 " external.db " 數據庫中 files 數據表中該 image.jpg 文件對應的 _id 字段數據 ;
絕對路徑
在 Android 11 的 分區存儲機制 中不能用來做任何操作 , 否則會產生崩潰 ;
對文件的操作 , 如 : 訪問圖片 , 刪除圖片 等操作 , 必須使用 Uri 進行操作 ;
三、相關文檔資料
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/18932254
Android 數據庫
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。