Android 文件管理】分区存储 ( MediaStore 文件操作 )

网友投稿 865 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

【Android 文件管理】分区存储 ( MediaStore 文件操作 )

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小时内删除侵权内容。

上一篇:文档识别工具让纸质文档处理工作事半功倍!
下一篇:从MATLAB帮助文档上学习 chirp
相关文章