开发过程中,我们经常需要从当前活动启动另一个活动获取一些数据,比如从图库选择图片,读取通讯录,拍照等,以前我们通常都是使用startActivityForResult去启动一个Activity,但是现在发现它过时了,官方推荐使用Activity Results API,下面我们看一下它的使用方式。
1、导入依赖
implementation 'androidx.activity:activity:1.2.0-beta01'
implementation 'androidx.fragment:fragment:1.3.0-beta01'
2、构建启动器
构建启动器,注册,注册接口处理返回结果。
ActivityResultLauncher<Intent> content = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
Intent data = result.getData();
int resultCode = result.getResultCode();
}
});
注意我们这里的写法,需要启动活动,所以第一个参数是ActivityResultContracts.StartActivityForResult(),
如果是其他动作,找ActivityResultContracts下对应的类,比如权限申请,打开文件等等操作。
ActivityResultContracts.GetContent
ActivityResultContracts.openDocument
ActivityResultContracts.RequestPermission
ActivityResultContracts.PickContact
…
根据需要,我们还可以定义自己的协议类,继承自ActivityResultContracts类,而上面所提供的这些类也是这样实现的,比如PickContact这个类
public static final class PickContact extends ActivityResultContract<Void, Uri>{
}
ActivityReultLauncher:启动器,是一个泛型类,根据我们想要启动的Activity传入相应类型,如果不确定类型,可以随便传入一个,在确定ActivityResultContract类型之后再根据提示更改即可,启动器通过launch方法进行跳转。
ActivityResultContract:协议,它定义了传递的数据的类型和如何传递。
ActivityResultCallback:结果回调接口。
在合适的地方通过launch方法去启动一个活动,比如点击按钮等,当结果返回时会自动调用注册的回调函数。
content.launch(new Intent(this,MainActivity2.class));
那Activity中如何返回结果呢?使用方法和以前一样的
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity2.this,MainActivity.class);
intent.putExtra("name","我来自activity2");
setResult(Activity.RESULT_OK,intent);
finish();
}
3、其他用法
查询联系人信息
ActivityResultLauncher<Void> contacts = registerForActivityResult(new ActivityResultContracts.PickContact(),
new ActivityResultCallback<Uri>() {
@Override
public void onActivityResult(Uri result) {
if (result!=null){
Cursor cursor = getContentResolver().query(result,null,null,null,null);
if (cursor.moveToFirst()){
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
Log.d(TAG, "onActivityResult: "+name);
}
}
}
});
启动
contacts.launch(null);
申请权限
ActivityResultLauncher<String> permission = registerForActivityResult(new ActivityResultContracts.RequestPermission(),
new ActivityResultCallback<Boolean>() {
@Override
public void onActivityResult(Boolean result) {
if (result){
Toast.makeText(MainActivity.this, "申请权限成功", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(MainActivity.this, "申请权限失败", Toast.LENGTH_SHORT).show();
}
}
});
启动器传入需要申请的权限名称
permission.launch(Manifest.permission.READ_CONTACTS);
拍张照
ActivityResultLauncher<Void> takePicture = registerForActivityResult(new ActivityResultContracts.TakePicturePreview(),
new ActivityResultCallback<Bitmap>() {
@Override
public void onActivityResult(Bitmap result) {
if (result!=null){
binding.imageView.setImageBitmap(result);
}
}
});
启动
takePicture.launch(null);
4、注意事项
ActivityResultLauncher必需在activity的onCreate()方法或fragment的onCreate()、onAttach()前先注册,然后在需要调用的地方调用launch方法。
|