文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android无需读写权限通过临时授权读写用户文件详解

2023-03-19 17:51

关注

正文

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

<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("**"那就代表文件夹
val launcher = registerForActivityResult(ActivityResultContracts.CreateDocument("*/*")){uri->
    //这里获取到的uri是已经创建好的文件的uri
}
//这里传入要创建的文件名
launcher.launch("cache.png")

启动之后是这个界面

通过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 {
}

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

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

(先截了张图,过两天填坑)

通过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临时授权读写用户文件的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯