Android无需读写权限通过临时授权读写用户文件怎么实现

发布时间:2023-03-21 15:19:06 作者:iii
来源:亿速云 阅读:173

这篇文章主要讲解了“Android无需读写权限通过临时授权读写用户文件怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Android无需读写权限通过临时授权读写用户文件怎么实现”吧!

在进行需求开发的时候,我们总是避不开和用户的数据打交道,那提到获取用户的数据一定会想到的东西就是申请权限

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

在我刚学习安卓的时候,我是以为APP一定要声明了读写用户空间权限并且在用户授权之后才能获取到用户的文件,即使是做个简简单单的更换头像的功能,或者是升级APP时下载新的APK。对于后者,我们其实可以将升级的APK包放到我们应用的私有目录下(无需权限),对于前者,有什么比较轻量,适合快速开发需求的方法来满足呢。

这里插三段小说明,如果只想知道方法的可以直接跳过

模拟获取用户的图片的逻辑

我们需要拿到代表用户临时授权给APP的Uri

通过

val intent = Intent(Intent.ACTION_GET_CONTENT)
    .addCategory(Intent.CATEGORY_OPENABLE)
    //这里传的参数是你要获取的文件类型的mimeType
    .setType(mimeType)
startActivityForResult(intent,1024)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == 1024 && resultCode == RESULT_OK) {
        val uri = data?.data
        //这里获取到的uri就是用户临时授权的文件/文件夹的的标识
    }
}

或者

val launch = registerForActivityResult(ActivityResultContracts.GetContent()){uri-> 
//这里获取到的uri就是用户临时授权的文件/文件夹的的标识
}
//这里传的参数是你要获取的文件类型的mimeType
launch.launch("*/*")

启动系统的内容选择器让用户选择要分享给我们APP的文件,以获得文件的Uri

通过contentResolver打开文件的文件描述符FileDescriptor

val pfd : ParcelFileDescriptor? = context.contentResolver.openFileDescriptor(uri, "r")

第一个参数是我们刚刚得到的文件的uri,第二个文件是表示我们对文件的操作模式,我现在示范的是读取用户图片所以用只读模式("r")就可以了,关于mode的具体注释,这里我直接粘贴原文了

mode &ndash; The string representation of the file mode. Can be "r", "w", "wt", "wa", "rw" or "rwt". SeeParcelFileDescriptor.parseMode for more details.

通过FileDescriptor可以打开一个文件IO流(FIS或者FOS),就可以读写文件啦

FileInputStream(pfd.fileDescriptor).use {
//这里可以先将用户的图片复制到私有目录中,再让用户做进一步的编辑操作
}
FileOutputStream(pfd.fileDescriptor).use {
}

但是注意,打开的fileDescriptor是Closeable对象,所以用完之后需要手动close(),这里我用的是ktolin的扩展函数,会在use代码块里的代码运行完之后自动关闭流

另一种读取文件的方法,还是使用contentResolver直接打开io流

context.contentResolver.openInputStream(uri)?.use {
}
context.contentResolver.openOutputStream(uri)?.use {
}

模拟将文件写入用户目录的操作

其实思路是一模一样的,只是你启动文件系统的意图(intent)不一样,以及对文件的操作不一样

我们需要拿到代表用户临时授权给APP的Uri

//这里传入你要创建的文件类型的mimeType,如果是"*/*"那就代表文件夹
val launcher = registerForActivityResult(ActivityResultContracts.CreateDocument("*/*")){uri->
    //这里获取到的uri是已经创建好的文件的uri
}
//这里传入要创建的文件名
launcher.launch("cache.png")

启动之后是这个界面

Android无需读写权限通过临时授权读写用户文件怎么实现

通过contentResolver打开文件的文件描述符FileDescriptor

val pfd : ParcelFileDescriptor? = context.contentResolver.openFileDescriptor(uri, "rw")

第一个参数是我们刚刚得到的文件的uri,第二个文件是表示我们对文件的操作模式,我现在示范的是保存一张图片所以要用读写模式("rw")

通过FileDescriptor可以打开一个文件IO流(FIS或者FOS),就可以写文件啦

FileOutputStream(pfd.fileDescriptor).use {
//这里将处理好的图片利用fos写到用户刚才用uri指定的地方
}

另一种读取文件的方法,还是使用contentResolver直接打开io流

context.contentResolver.openOutputStream(uri)?.use {
}

模拟获取用户文件夹控制权的操作

最后再模拟一下获取用户文件夹控制权的操作,通过这个方法你可以拿到其他应用在外置存储里的目录(例如一些聊天软件的聊天记录其实就是存放在这个目录的)

Android无需读写权限通过临时授权读写用户文件怎么实现

通过Uri获取文件信息

最后再介绍一 通过Uri获取文件信息(文件名/文件大小/文件Mime类型)的方法

//第二个参数相当于是sql里的select,列表里是要过滤的列名,如果传null那说明取所有的列,这样性能会比较差
val cursor: Cursor? = context.contentResolver.query(
    this,
    arrayOf(MediaStore.MediaColumns.DISPLAY_NAME, MediaStore.MediaColumns.SIZE),
    null,
    null,
    null
)?.use { cursor ->
    if (cursor.moveToFirst()) {
        val columnIndex1 = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)
        if (columnIndex1 > -1) {
            name = cursor.getString(columnIndex1)
        }
        val columnIndex2 = cursor.getColumnIndex(MediaStore.MediaColumns.SIZE)
        if (columnIndex2 > -1) {
            size = cursor.getLong(columnIndex2)
        }
    }

文件的话,用正常途径也只能拿到文件名(MediaStore.MediaColumns.DISPLAY_NAME),文件大小(MediaStore.MediaColumns.SIZE),文件Mime类型(MediaStore.MediaColumns.MIME_TYPE)这三个有用的信息 注意,获取到的cursor是Closeable对象,所以用完之后需要手动close()

感谢各位的阅读,以上就是“Android无需读写权限通过临时授权读写用户文件怎么实现”的内容了,经过本文的学习后,相信大家对Android无需读写权限通过临时授权读写用户文件怎么实现这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

推荐阅读:
  1. 如何用Android实现加载效果
  2. Android制作水平圆点加载进度条

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

android

上一篇:php中怎么使用重定向跳转页面

下一篇:SpringBoot如何实现RAS+AES自动接口解密

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》