亞寵展、全球寵物產業風向標——亞洲寵物展覽會深度解析
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
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小時內刪除侵權內容。