Android registerForActivityResult

startActivityForResult 已经被标记为不推荐的方法,推荐的替代方案是使用 registerForActivityResult:

// Activity 的 onCreate 方法中调用 registerForActivityResult
val activityResultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->  
    if(activityResult.resultCode == RESULT_OK) {
        val data = activityResult.data
    }
}

//发起请求
activityResultLauncher.launch(intent)

选取文件

除了 ActivityResultContracts.StartActivityForResult(),ActivityResultContracts 还有很多针对特定功能的其他请求,如动态申请单个或多个权限、选择文件等,选择文件还可以细分为图片、音频、视频等,总之旧代码中使用 startActivityForResult() 的地方,都可以找到对应的替代方案,由于新系统出于对隐私的保护,APP要访问手机任意目录下的文件,需要获得特定的权限,Google Play已经明确,非文件管理器等特殊应用,一般不允许APP使用“访问所有文件”的权限,所以APP如果要存储文件,并且需要导出,基本都是存储在APP专用的目录(Android/data/<packagename>/files),如果需要访问外部存储的文件,比如升级文件等,就使用 ActivityResultContracts.OpenDocument(),代码如下:

val activityResultLauncher = registerForActivityResult(ActivityResultContracts.OpenDocument()) {
    it?.let { uri ->
        DocumentFile.fromSingleUri(this, uri)?.let { documentFile ->
            println("file type: " + documentFile.type)
            println("file name: " + documentFile.name)
            Scanner(contentResolver.openInputStream(documentFile.uri)).use { reader ->
                var line: String
                while (reader.hasNextLine()) {
                    line = reader.nextLine()
                    println(line)
                }
            }
        }
    }
}

// 数组类型的参数是 MIME,如果不确定文件类型,就先设置所有类型,即 */*,之后通过 documentFile.type 查看
activityResultLauncher.launch(arrayOf("*/*"))

上面的代码用到了 DocumentFile,主要用来通过 Uri 获取文件信息,如MIME类型、文件名字、文件大小等,需要添加依赖: 

implementation "androidx.documentfile:documentfile:1.0.1"

选取图片

private lateinit var pickImageLauncher: ActivityResultLauncher<PickVisualMediaRequest>

pickImageLauncher = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
            
}

val request = PickVisualMediaRequest.Builder()
            .setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly)
            .build()
pickImageLauncher.launch(request)

请求权限

private lateinit var requestPermissionLauncher: ActivityResultLauncher<Array<String>>

requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { res ->
    if (!res.containsValue(false)) {
        // 已经授权,执行相关操作
    } else {
        // 如果用户拒绝了权限,则需要向用户解释为什么需要该权限
    }
}

requestPermissionLauncher.launch(arrayOf(Manifest.permission.CAMERA))

 

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值