问题描述
- Ability包含多个Slice。
- Slice中需要申请权限,但Slice中无法接收权限申请结果,只有Ability可以重写onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults)。
- 根据权限申请结果跳转至不同的Slice。
解决方案
方案一
方法
- 在Slice中requestPermissionsFromUser(String[] permissions, int requestCode)。
- 在Ability重写的onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults)中发布无序的公共事件。
- 在Slice中订阅公共事件,根据公共事件参数调用present(AbilitySlice targetSlice, Intent intent) 进行Slice直接的跳转。
优点
使用了Slice之间的跳转,方便简单。使用公共事件降低了代码的耦合性。
缺点
发布公共事件提升了代码的复杂性。
方案二
方法
- 在Ability中申请权限。
- 在Ability重写的onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults)中调用startAbility(Intent intent) 开启新的Slice。
优点
使用简单,无需对结果进行多次处理。
缺点
调用startAbility(Intent intent) 自己打开自己,栈中存在两个相同的Ability。
由于方案二中存在打开新的Slice栈中存在两个相同的Ability后续路由处理麻烦,所以选择方案一,
代码编写
- 申请权限,以申请读取用户存储权限,权限申请请求码为102为例。
public class MainAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
// 申请权限
requestPermissionsFromUser(new String[]{"ohos.permission.READ_USER_STORAGE"}, 102);
}
}
- 定义公共事件,订阅公共事件,以无序公共事件为例。
public class MainAbilitySlice extends AbilitySlice {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
// 申请权限
requestPermissionsFromUser(new String[]{"ohos.permission.READ_USER_STORAGE"}, 102);
// 定义事件名
String event = "com.test.event";
// 自定义公共事件
MatchingSkills matchingSkills = new MatchingSkills();
matchingSkills.addEvent(event);
// 封装公共事件发布相关属性、限制等信息
CommonEventSubscribeInfo subscribeInfo = new CommonEventSubscribeInfo(matchingSkills);
// 创建公共事件订阅者
MyCommonEventSubscriber subscriber = new MyCommonEventSubscriber(subscribeInfo);
try {
// 订阅公共事件
CommonEventManager.subscribeCommonEvent(subscriber);
} catch (RemoteException e) {
e.printStackTrace();
System.out.println("******订阅失败");
}
}
/**
* 自定义事件订阅者
*/
class MyCommonEventSubscriber extends CommonEventSubscriber {
MyCommonEventSubscriber(CommonEventSubscribeInfo info) {
super(info);
}
@Override
public void onReceiveEvent(CommonEventData commonEventData) {
// 接收事件
if (commonEventData == null || commonEventData.getIntent() == null) {
return;
}
// 获取事件Action
String receivedAction = commonEventData.getIntent().getOperation().getAction();
if ("com.test.event".equals(receivedAction)) {
// 跳转至指定页面
present(new SecondAbilitySlice(), new Intent());
}
}
}
}
自定义事件订阅者MyCommonEventSubscriber 继承至CommonEventSubscriber ,在重写的(CommonEventData commonEventData)中接收发布的事件,并对事件进行处理。当前事件命名为"com.test.event"。
- 发布公共事件。Slice中没有onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) ,无法接收权限申请结果,所以只能在Ability中发送事件。
public class MainAbility extends Ability {
@Override
public void onStart(Intent intent) {
super.onStart(intent);
setMainRoute(MainAbilitySlice.class.getName());
}
@Override
public void onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsFromUserResult(requestCode, permissions, grantResults);
if(requestCode == 102){
System.out.println("权限申请成功");
try {
Intent intent = new Intent();
Operation operation = new Intent.OperationBuilder()
.withAction("com.test.event")
.build();
intent.setOperation(operation);
// 封装公共事件相关信息
CommonEventData eventData = new CommonEventData(intent);
// 发布公共事件
CommonEventManager.publishCommonEvent(eventData);
} catch (RemoteException e) {
System.out.println("事件发送失败");}
}
}
}
使用CommonEventData封装公共事件相关信息时,intent不允许为空,否则发布公共事件失败。
效果预览
当Ability被调用时,应用会默认进入MainAbilitySlice ,在MainAbilitySlice 中申请权限,然后在Ability中对权限申请的结果进行接收,若用户同意权限,则发布“com.test.event”无序公共事件,MainAbilitySlice接收到“com.test.event”事件后跳转至SecondAbilitySlice。