下面这些预定义的Contract中,除了StartActivityForResult和RequestMultiplePermissions之外,基本都是处理的「与其他APP交互」,返回数据的场景,比如,拍照,选择图片,选择联系人,打开文档等等。使用最多的就是StartActivityForResult和RequestMultiplePermissions了。
-
StartActivityForResult:通用的Contract,不做任何转换,Intent作为输入,ActivityResult作为输出,这也是最常用的一个协定。
-
RequestMultiplePermissions: 用于请求一组权限
-
RequestPermission: 用于请求单个权限
-
TakePicturePreview: 调用MediaStore.ACTION_IMAGE_CAPTURE拍照,返回值为Bitmap图片
-
TakePicture: 调用MediaStore.ACTION_IMAGE_CAPTURE拍照,并将图片保存到给定的Uri地址,返回true表示保存成功。
-
TakeVideo: 调用MediaStore.ACTION_VIDEO_CAPTURE 拍摄视频,保存到给定的Uri地址,返回一张缩略图。
-
PickContact: 从通讯录APP获取联系人
-
GetContent: 提示用选择一条内容,返回一个通过ContentResolver#openInputStream(Uri)访问原生数据的Uri地址(content://形式) 。默认情况下,它增加了Intent#CATEGORY_OPENABLE, 返回可以表示流的内容。
-
CreateDocument: 提示用户选择一个文档,返回一个(file:/http:/content:)开头的Uri。
-
OpenMultipleDocuments: 提示用户选择文档(可以选择多个),分别返回它们的Uri,以List的形式。
-
OpenDocumentTree: 提示用户选择一个目录,并返回用户选择的作为一个Uri返回,应用程序可以完全管理返回目录中的文档。
常规用法
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
//it.data
}
}.launch(Intent(this, ZutaiComponentActivity::class.java))
打开相机拍照
var outputImage = File(this.externalCacheDir, "output_image.jpg")
if (outputImage.exists()) {
outputImage.delete()
}
outputImage.createNewFile()
var imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
FileProvider.getUriForFile(this, "${BuildConfig.APPLICATION_ID}.fileProvider", outputImage)
} else {
Uri.fromFile(outputImage)
}
registerForActivityResult(ActivityResultContracts.TakePicture()) {
if (it) {
Glide.with(this).load(imageUri).into(bind.image)
}
}.launch(imageUri)
打开录像机录像
var outputImage = File(this.externalCacheDir, "output_image.mp4")
if (outputImage.exists()) {
outputImage.delete()
}
outputImage.createNewFile()
var imageUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
FileProvider.getUriForFile(this, "${BuildConfig.APPLICATION_ID}.fileProvider", outputImage)
} else {
Uri.fromFile(outputImage)
}
registerForActivityResult(ActivityResultContracts.TakeVideo()) {
Glide.with(this).load(imageUri).into(bind.image)
}.launch(imageUri)
调用文件选择器
mimetype 指定文本文档
registerForActivityResult(ActivityResultContracts.GetContent()){
}.launch("text/plain")
如果需要选择多种文件类型,可以使用OpenDocument
registerForActivityResult(ActivityResultContracts.OpenDocument()){
Glide.with(this).load(it).into(binding.imageView)
}.launch(arrayOf("image/*","text/plain"))
获取敏感权限
获取一个权限
registerForActivityResult(ActivityResultContracts.RequestPermission()){
if(it){
//用户同意了该权限
}else{
//用户拒绝了该权限
}
}.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE)
获取多个权限
import android.Manifest
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val requestMultiplePermissionsLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
//通过的权限
val grantedList = permissions.filterValues { it }.mapNotNull { it.key }
//是否所有权限都通过
val allGranted = grantedList.size == permissions.size
val list = (permissions - grantedList).map { it.key }
//未通过的权限
val deniedList = list.filter { ActivityCompat.shouldShowRequestPermissionRationale(this, it) }
//拒绝并且点了“不再询问”权限
val alwaysDeniedList = list - deniedList
//处理权限结果,例如更新UI或逻辑
if (allGranted) {
// 所有权限都已授予
} else {
// 处理未授予的权限
if (alwaysDeniedList.isNotEmpty()) {
// 处理“不再询问”的权限
}
}
}
// 请求权限
requestMultiplePermissionsLauncher.launch(arrayOf(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA,
Manifest.permission.ACCESS_FINE_LOCATION
))
}
}