HarmonyOS Sample 之 AbilityInteraction设备迁移 原创 精华

Buty9147
发布于 2021-8-10 10:50
浏览
2收藏

@toc

AbilityInteraction设备迁移

介绍

本示例演示了Feature Ability的基本交互和跨设备迁移的功能。
在终端A随机生成一个数字,并计算这个数的平方值,然后将这个数传递给终端B,在终端B中同样计算出结果。

效果展示

HarmonyOS Sample 之 AbilityInteraction设备迁移-鸿蒙开发者社区

搭建环境

安装DevEco Studio,详情请参考DevEco Studio下载
设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:

如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。
如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境

实现步骤

1.config.json声明使用跨设备迁移的权限

"reqPermissions": [
    {
    "name": "ohos.permission.DISTRIBUTED_DATASYNC"
    }
]

2.Ability实现IAbilityContinuation接口及相关方法

public class FirstAbility extends Ability implements IAbilityContinuation {
    ...
}

3.Ability中申请用户对敏感权限授权

@Override
public void onStart(Intent intent) {
    super.onStart(intent);
    super.setMainRoute(FirstAbilitySlice.class.getName());
    requestPermission();
}

private void requestPermission() {
    if (verifySelfPermission(SystemPermission.DISTRIBUTED_DATASYNC) != IBundleManager.PERMISSION_GRANTED) {
        requestPermissionsFromUser(new String[] {SystemPermission.DISTRIBUTED_DATASYNC}, 0);
    }
}

4.Ablity中下面几个方法全部返回true

@Override
public boolean onStartContinuation() {
    return true;
}

@Override
public boolean onSaveData(IntentParams intentParams) {
    return true;
}

@Override
public boolean onRestoreData(IntentParams intentParams) {
    return true;
}

@Override
public void onCompleteContinuation(int i) {
    terminateAbility();
}

5.Slice实现IAbilityContinuation接口及相关方法

public class FirstAbilitySlice extends AbilitySlice implements LifecycleStateObserver, IAbilityContinuation {
    ...
}

6.Slice按钮事件监听

private void initComponents() {
    findComponentById(ResourceTable.Id_enter_second).setClickedListener(component -> startSecondAbility());
    findComponentById(ResourceTable.Id_continue_ability).setClickedListener(component -> startContinue());
    numberText = (Text) findComponentById(ResourceTable.Id_number);
    lifecycleState = (Text) findComponentById(ResourceTable.Id_lifecycle_state);
}

7.Slice中实现设备迁移的方法

private void startContinue() {
    try {
        continueAbility();
    } catch (IllegalStateException | UnsupportedOperationException e) {
        LogUtil.error(TAG, "startContinue Exception ");
    }
}

8.Slice中实现一下几个方法,返回true

@Override
public boolean onStartContinuation() {
    return true;
}

@Override
public boolean onSaveData(IntentParams intentParams) {

    //设置设备迁移后需要恢复的数据
    intentParams.setParam(CONTINUE_PARAM_KEY_INPUT, inputNum);
    return true;
}

@Override
public boolean onRestoreData(IntentParams intentParams) {
    //恢复数据
    Object object = intentParams.getParam(CONTINUE_PARAM_KEY_INPUT);
    if (object instanceof Long) {
        inputNum = (long) object;
    }
    return true;
}

@Override
public void onCompleteContinuation(int i) {
    //设备迁移完成,关闭Slice
    terminate();
}

问题总结

1.Slice中获取bundleName:getBundleName()

2.Slice中获取Ability:getAbility()

3.如果想监听Ability/Slice的生命周期变化,可以实现LifecycleStateObserver接口,实现onStateChanged方法

public class FirstAbilitySlice extends AbilitySlice implements LifecycleStateObserver{
    ...
}

@Override
public void onStateChanged(Lifecycle.Event event, Intent intent) {
    lifecycleState.setText(lifecycleState.getText() + System.lineSeparator() + event.name());
}

4.Slice中启动另外一个Ability的方法也可以用setElement

private void startSecondAbility() {
    Intent intent = new Intent();
    intent.setElement(new ElementName("", getBundleName(), SecondAbility.class.getName()));
    intent.setParam(Const.MESSAGE_KEY_SQUARED, inputNum);
    startAbilityForResult(intent, REQUEST_CODE_TO_ABILITY_B);
}

5.Slice中在onAbilityResult方法中处理其它Abilty返回的结果

/**
 *
 * @param requestCode  发出的请求码,用来识别是自己的请求
 * @param resultCode   收到的结果码,用来校验对端的结果
 * @param resultData   返回的数据
 */
@Override
protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {

    //使用switch逻辑语句判断
    switch (requestCode) {

        //是自己发出去的请求码
        case REQUEST_CODE_TO_ABILITY_B:
            //是双方约定的结果码
            if (resultCode == Const.RESULT_CODE_FROM_ABILITY_B) {
                //根据key获取指定类型的参数
                long outputNum = resultData.getLongParam(Const.MESSAGE_KEY_SQUARED, 0);
                
                numberText.setText(String.valueOf(outputNum));
            }
            break;
        default:
            break;
    }
}

完整代码

附件直接下载

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
AbilityInteraction.zip 1.39M 40次下载
已于2021-8-10 10:50:31修改
6
收藏 2
回复
举报
7条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

gif演示的很明了

回复
2021-8-10 11:00:03
Buty9147
Buty9147 回复了 红叶亦知秋
gif演示的很明了

ScreenToGif这个小工具,可以试试

回复
2021-8-10 11:02:25
mb5ff6971d880c0
mb5ff6971d880c0

为什么我在两台真机上试不成功,我只改了包名,在模拟器上可以,在真机上不行

回复
2021-8-24 16:11:19
Buty9147
Buty9147 回复了 mb5ff6971d880c0
为什么我在两台真机上试不成功,我只改了包名,在模拟器上可以,在真机上不行

没在真机上试过,你说的不行是不能运行还是功能不行?

回复
2021-8-25 16:19:12
qq61285a1d94193
qq61285a1d94193

两个设备需要在一个局域网吗?如果有三个设备,会怎么样?

回复
2021-8-27 16:06:16
mb5ff6971d880c0
mb5ff6971d880c0 回复了 Buty9147
没在真机上试过,你说的不行是不能运行还是功能不行?

功能不行,不能在真机上迁移

回复
2021-8-27 23:32:55
Buty9147
Buty9147 回复了 qq61285a1d94193
两个设备需要在一个局域网吗?如果有三个设备,会怎么样?

需要连接同一wifi,蓝牙也可以打开,而且出于安全考虑还需要登录相同的华为账号。

回复
2021-8-28 07:25:59
回复
    相关推荐