Loading... > 近期在构建新项目的时候,发现**onActivityResult**方法已经被废弃了,于是有了尝试**registerForActivityResult**的想法。 ### 标准使用 三个类`ActivityResultLauncher`、`ActivityResultContract`、`ActivityResultCallback` 首先`ActivityResultLauncher`作为主角,它需要配置一个泛型,这个泛型跟我们`ActivityResultContract`的返回值相同,`ActivityResultLauncher`通过`launch`方法来启动相应的界面或者功能。 1. ActivityResultContract ``` public static class GalleryContract extends ActivityResultContract<Void, Uri> { @NonNull @Override public Intent createIntent(@NonNull Context context, Void input) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_PICK); intent.setType("image/*"); return intent; } @Override public Uri parseResult(int resultCode, @Nullable Intent intent) { return intent.getData(); } } ``` 可以看到`ActivityResultContract`需要传入两个泛型,一个泛型作为`createIntent`方法的第二参数类型,这里可以作为我们intent传值的参数载体,`ActivityResultContract`的另一个泛型作为`parseResult`方法的返回值类型,我们可以自行定义从intent返回的参数类型。 2. ActivityResultLauncher ``` private ActivityResultLauncher<Void> galleryLauncher = registerForActivityResult(new GalleryContract(), new ActivityResultCallback<Uri>() { @Override public void onActivityResult(Uri result) { //todo something } }); ``` 把contract和ActivityResultCallback作为launcher的参数构建出launcher 3. ActivityResultCallback 这个里面就和`onActivityResult`方法回调一样的,只不过提供的结果参数是我们在contract中定义的。 4.启动launch 通过` galleryLauncher.launch(null);`启动即可。 ### 简单使用 `ActivityResultContracts` 这个类中提供了许多通用的方法 | ActivityResultContracts.* | 说明 | 参数 |回调 | | - | - | - | - | | **StartActivityForResult** | 可以理解为startActivityForResult |Intent |ActivityResult(code,data) | | **TakePicture** | 通过MediaStore.ACTION_IMAGE_CAPTURE拍照并保存 |保存文件的Uri |是否保存成功 | | **TakePicturePreview** | 通过MediaStore.ACTION_IMAGE_CAPTURE拍照,但是只会拍一张小照片,作为thumbnail使用比较合适 | null(Void) | 图片的Bitmap | | **CaptureVideo** | 通过MediaStore.ACTION_VIDEO_CAPTURE拍摄视频并保存(androidx.activity 1.3.0-alpha08后提供,androidx.appcompat好像还没提供该类) |保存文件的Uri | 是否保存成功。| | **RequestPermission** | 请求单个权限 |Manifest.permission.* | 用户是否授予该权限| RequestMultiplePermissions | 请求多个权限 |Array| 回调为map, key为请求的权限,value为用户是否授予该权限 | | **CreateDocument** | 通过Intent.ACTION_CREATE_DOCUMENT创建一个文件 |默认文件名| 选择目录后返回该文件的Uri| | **GetContent** | 通过Intent.ACTION_GET_CONTENT获取一个文件(这个方法可以通过android.content.ContentResolver.openInputStream获取到文件的原始数据) | MIME类型 | 文件Uri | | **GetMultipleContents** | 通过Intent.ACTION_GET_CONTENT及Intent.EXTRA_ALLOW_MULTIPLE获取一个或多个文件(这个方法可以通过android.content.ContentResolver.openInputStream获取到文件的原始数据) | MIME类型 | 文件List | | **OpenDocument** | 通过Intent.ACTION_OPEN_DOCUMENT选择文件 | MIME类型 | 文件Uri | | **OpenDocumentTree** | 通过Intent.ACTION_OPEN_DOCUMENT_TREE选择一个目录,返回一个Uri并得到该目录下全部文档的管理权 |目录初始位置Uri | 选择目录Uri | | **OpenMultipleDocuments** | 通过Intent.ACTION_OPEN_DOCUMENT及Intent.EXTRA_ALLOW_MULTIPLE获取一个或多个文件 | MIME类型 | 文件List | | **PickContact** | 通过Intent.ACTION_PICK从系统通讯录中获取联系人 | null(Void) | 联系人Uri | StartIntentSenderForResult* | 构建IntentSender或PendingIntent | 使用IntentSenderRequest.Builder构建 | ActivityResult(code,data) | | **~TakeVideo~** | 通过MediaStore.ACTION_VIDEO_CAPTURE拍摄视频并保存(弃用了,官方解释是缩略图的Bitmap的返回不稳定,替换为上面的CaptureVideo即可) | 保存文件的Uri | 视频缩略图Bitmap | 类似的使用如下 ``` private ActivityResultLauncher<String> fileLauncher = registerForActivityResult(new ActivityResultContracts.GetContent(), new ActivityResultCallback<Uri>() { @Override public void onActivityResult(Uri result) { } }); ``` ``` private ActivityResultLauncher<Uri> videoLauncher = registerForActivityResult(new ActivityResultContracts.CaptureVideo(), new ActivityResultCallback<Boolean>() { @Override public void onActivityResult(Boolean result) { } }); ``` ### 注意 不能在需要使用的时候再去构建我们需要的launcher,否则会抛出异常 在`Activity`中 在`Fragment`中  最后修改:2021 年 12 月 01 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 2 如果觉得我的文章对你有用,请随意赞赏
1 条评论
使用这个替换权限申请框架如何OωO