> 文档中心 > HarmonyOS跨端迁移开发代码演示

HarmonyOS跨端迁移开发代码演示

目录

  • 说些废话
  • 开源代码
  • 环境
  • 代码
    • ability_main.xml
    • config.json
    • MainAbility.java
    • MainAbilitySlice.java
  • 测试

说些废话

    官方文档:跨端迁移开发指导(基于java开发)
    下面环境里写的两台真机我测试的时候无法正常产生回迁效果,所以实际上我是用的远程模拟器操作成功的,但是我懒得删我的设备信息了。
    模拟器不需要登录华为账号,但是需要在 设置-超级终端-允许被发现 处打开能够被附近设备发现。
图1

开源代码

    CrossSiteMigration

环境

    HUAWEI MatePad Pro 10.8英寸 2019款
    Mate 10 Pro 全网通版
    DevEco Studio 3.0.0.993 Release
    SDK 6(使用java)
    我看的《公共事件开发指导》更新于2022-10-28 18:02

代码

ability_main.xml

<DirectionalLayout    xmlns:ohos="http://schemas.huawei.com/res/ohos"    ohos:height="match_parent"    ohos:width="match_parent"    ohos:alignment="center"    ohos:orientation="vertical">    <Text ohos:id="$+id:text_register" ohos:height="match_content" ohos:width="match_content" ohos:layout_alignment="horizontal_center" ohos:text="注册流转服务" ohos:text_size="40vp" />    <Text ohos:id="$+id:text_show" ohos:height="match_content" ohos:width="match_content" ohos:layout_alignment="horizontal_center" ohos:text="列出可流转的设备" ohos:scrollable="true" ohos:text_size="40vp" />    <Text ohos:id="$+id:text_startMigration" ohos:height="match_content" ohos:width="match_content" ohos:layout_alignment="horizontal_center" ohos:text="开始迁移" ohos:scrollable="true" ohos:text_size="40vp" />    <Text ohos:id="$+id:text_showParams" ohos:height="match_content" ohos:width="match_content" ohos:layout_alignment="horizontal_center" ohos:text="这里展示数据:无" ohos:scrollable="true" ohos:text_size="40vp" />    <Text ohos:id="$+id:text_returnMigration" ohos:height="match_content" ohos:width="match_content" ohos:layout_alignment="horizontal_center" ohos:text="迁移回去" ohos:scrollable="true" ohos:text_size="40vp" /></DirectionalLayout>

config.json

    长度问题只放module部分。

"module": {    "package": "com.openvalley.cyj.migration",    "name": ".MyApplication",    "mainAbility": "com.openvalley.cyj.migration.MainAbility",    "deviceType": [      "phone",      "tablet"    ],    "distro": {      "deliveryWithInstall": true,      "moduleName": "entry",      "moduleType": "entry",      "installationFree": false    },    "abilities": [      { "skills": [   {     "entities": ["entity.system.home"     ],     "actions": ["action.system.home"     ]   } ], "name": "com.openvalley.cyj.migration.MainAbility", "description": "$string:mainability_description", "icon": "$media:icon", "label": "$string:entry_MainAbility", "launchType": "standard", "orientation": "unspecified", "visible": true, "type": "page"      }    ],    "reqPermissions": [      { "name": "ohos.permission.DISTRIBUTED_DATASYNC"      }    ]  }

MainAbility.java

package com.openvalley.cyj.migration;import com.openvalley.cyj.migration.slice.MainAbilitySlice;import ohos.aafwk.ability.Ability;import ohos.aafwk.ability.IAbilityContinuation;import ohos.aafwk.content.Intent;import ohos.aafwk.content.IntentParams;import ohos.bundle.IBundleManager;import ohos.hiviewdfx.HiLog;import ohos.hiviewdfx.HiLogLabel;import ohos.security.SystemPermission;public class MainAbility extends Ability implements IAbilityContinuation {    private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x00001, MainAbility.class.getSimpleName());    @Override    public void onStart(Intent intent) { super.onStart(intent); super.setMainRoute(MainAbilitySlice.class.getName()); verifyAndRequestSelfPermission();    }    /     * 在此处验证和请求用户权限     */    private void verifyAndRequestSelfPermission() { try{     //返回值0有,-1没有     if(verifyCallingOrSelfPermission(SystemPermission.DISTRIBUTED_DATASYNC) == IBundleManager.PERMISSION_GRANTED){//     if(verifySelfPermission(SystemPermission.LOCATION) == IBundleManager.PERMISSION_GRANTED){  //如果有权限     }else {  //如果没授权就看这个权限能否动态授权  if(canRequestPermission(SystemPermission.DISTRIBUTED_DATASYNC)){      //如果可以弹窗授权      requestPermissionsFromUser(new String[] {SystemPermission.DISTRIBUTED_DATASYNC}, 0x10001);  }else {      //如果不能动态授权      return ;  }     } }catch (Exception e){     e.printStackTrace(); }    }    /     * 授权的回调     * @param requestCode     * @param permissions     * @param grantResults     */    @Override    public void onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsFromUserResult(requestCode, permissions, grantResults); if(requestCode == 0x10001){     if(grantResults[0] == IBundleManager.PERMISSION_GRANTED){  //如果授权成功(0)  HiLog.info(LABEL_LOG, permissions[0] + "权限授权成功。");     }else {  //如果没有授权成功(-1)  return ;     } }    }    /     * 准备开始迁移的回调     * @return     */    @Override    public boolean onStartContinuation() { //返回值为true才发起迁移 HiLog.info(LABEL_LOG, "MainAbility onStartContinuation"); return true;    }    /     * 当保存数据(要迁移的数据)的回调     * @param intentParams     * @return     */    @Override    public boolean onSaveData(IntentParams intentParams) { HiLog.info(LABEL_LOG, "MainAbility onSaveData"); return true;    }    /     * 当恢复数据的回调(应该是被迁移的设备调用     * @param intentParams     * @return     */    @Override    public boolean onRestoreData(IntentParams intentParams) { //返回为true代表恢复数据成功 HiLog.info(LABEL_LOG, "MainAbility onRestoreData"); return true;    }    /     * 迁移完成的回调     * @param i     */    @Override    public void onCompleteContinuation(int i) { HiLog.info(LABEL_LOG, " MainAbility onCompleteContinuation");    }    /     * 迁移过程中失败的回调     */    @Override    public void onRemoteTerminated() { IAbilityContinuation.super.onRemoteTerminated(); HiLog.info(LABEL_LOG, "MainAbility onRemoteTerminated");    }    /     * 回迁允许的情况下,远端中断     * @param errorCode     */    @Override    public void onFailedContinuation(int errorCode) { IAbilityContinuation.super.onFailedContinuation(errorCode); HiLog.info(LABEL_LOG, "MainAbility onFailedContinuation");    }}

MainAbilitySlice.java

package com.openvalley.cyj.migration.slice;import com.openvalley.cyj.migration.ResourceTable;import ohos.aafwk.ability.AbilitySlice;import ohos.aafwk.ability.IAbilityContinuation;import ohos.aafwk.ability.continuation.*;import ohos.aafwk.content.Intent;import ohos.aafwk.content.IntentParams;import ohos.agp.components.Text;import ohos.hiviewdfx.HiLog;import ohos.hiviewdfx.HiLogLabel;public class MainAbilitySlice extends AbilitySlice implements IAbilityContinuation {    private static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x00001, MainAbilitySlice.class.getSimpleName());    Text text_register = null;    Text text_show = null;    Text text_startMigration = null;    Text text_showParams = null;    Text text_returnMigration = null;    IContinuationRegisterManager continuationRegisterManager = null;    IContinuationDeviceCallback continuationDeviceCallback = null;    RequestCallback requestCallback = null;    String jsonParams = null;    int abilityToken = 0;    String deviceId = null;    String params = null;    boolean isMigration = false;    @Override    public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main); initContinuationRegisterManager(); initComponent();    }    /     * 初始化注册管理类     */    private void initContinuationRegisterManager(){continuationRegisterManager = getContinuationRegisterManager();//设备的回调(是在列出了设备列表后,选择某个设备进行流转连接成功或者断开时调用)continuationDeviceCallback = new IContinuationDeviceCallback() {    @Override    public void onConnected(ContinuationDeviceInfo deviceInfo) { HiLog.info(LABEL_LOG, "onConnected()"); deviceId = deviceInfo.getDeviceId(); HiLog.info(LABEL_LOG, "onConnected() 连接成功。 deviceId = " + deviceId); continuationRegisterManager.updateConnectStatus(abilityToken, deviceId, DeviceConnectState.CONNECTED.getState(), requestCallback);    }    @Override    public void onDeviceConnectDone(String s, String s1) { HiLog.info(LABEL_LOG, "onDeviceConnectDone()");    }    @Override    public void onDisconnected(String deviceId) { HiLog.info(LABEL_LOG, "onDisconnected()");    }    @Override    public void onDeviceDisconnectDone(String s) { HiLog.info(LABEL_LOG, "onDeviceDisconnectDone()");    }};//请求的回调(注册到服务中心成功) requestCallback = new RequestCallback() {     @Override     public void onResult(int i) {  if(i > 0){      //为了保证更新数据时这个值还在,所以在if里写      abilityToken = i;      HiLog.info(LABEL_LOG, "onResult() 注册成功。 abilityToken = " + abilityToken);  }else {      HiLog.info(LABEL_LOG, "onResult() 其他操作。 abilityToken = " + i);  }     } };    }    /     * 初始化组件     */    private void initComponent(){ text_register = (Text)findComponentById(ResourceTable.Id_text_register); text_register.setClickedListener(listen -> register()); text_show = (Text)findComponentById(ResourceTable.Id_text_show); text_show.setClickedListener(listen -> show()); text_startMigration = (Text)findComponentById(ResourceTable.Id_text_startMigration); text_startMigration.setClickedListener(listen -> startMigration()); text_showParams = (Text)findComponentById(ResourceTable.Id_text_showParams); text_showParams.setText("这里展示数据:" + params); text_returnMigration = (Text)findComponentById(ResourceTable.Id_text_returnMigration); text_returnMigration.setClickedListener(listen -> returnMigration());    }    /     * 点击按钮进行流转服务注册     */    private void register(){ if(continuationRegisterManager != null){     HiLog.info(LABEL_LOG, "register() 开始注册。");     continuationRegisterManager.register(getBundleName(), getExtraParams(), continuationDeviceCallback, requestCallback); }    }    /     * 展示可流转的设备     */    private void show(){ if(continuationRegisterManager != null && abilityToken > 0){     continuationRegisterManager.showDeviceList(abilityToken, getExtraParams(), requestCallback); }    }    /     * 开始迁移     */    private void startMigration(){ if(continuationRegisterManager != null && deviceId != null){     HiLog.info(LABEL_LOG, "startMigration() 开始迁移。");//     continueAbility(deviceId);     continueAbilityReversibly(deviceId);     isMigration = true;     HiLog.info(LABEL_LOG, "startMigration() 迁移结束。");     //如果是不回迁的,这边的页面就可以销毁掉//     terminateAbility(); }    }    /     * 迁移回原设备     */    private void returnMigration(){// ContinuationState. try{     boolean reverseContinueAbility = reverseContinueAbility();     HiLog.info(LABEL_LOG, "reverseContinueAbility = " + reverseContinueAbility);     isMigration = false; }catch (Exception e){     HiLog.info(LABEL_LOG, "e = " + e.getMessage()); }    }    /     * 获得注册时 额外的一些参数     * @return     */    private ExtraParams getExtraParams(){ ExtraParams extraParams = new ExtraParams(); String[] devType = {ExtraParams.DEVICETYPE_SMART_PHONE, ExtraParams.DEVICETYPE_SMART_PAD}; //显示的列表包含那些设备类型 extraParams.setDevType(devType); //添加描述(没出来) extraParams.setDescription("这是一个描述。"); //如果不写,就会默认以注册时的BundleName作为targetBundleName extraParams.setTargetBundleName(getBundleName()); //设备过滤 jsonParams = "\"{" +   "\"filter\":{" +"\"commonFilter\":{" +    "\"system\":{" + //目标设备对应的HarmonyOS版本 要≥ "\"harmonyVersion\":\"2.0.0\"" +    "}," +//    "}" +    //1为同账号,1|256为不同账号    "\"groupType\":\"1|256\"," +    //0x00000004需要在同一局域网下,0x00030004不需要在同一局域网下    "\"curComType\": 0x00030004," +    //为空就不做版本兼容性检查,要做版本兼容性检查时,需要传入目标应用包名。    "\"faFilter\":\"{" + "\"targetBundleName\":\"com.openvalley.cyj.migration\"" +    "}\"" +"}" +   "}," +   "\"transferScene\":0," +   "\"remoteAuthenticationDescription\": \"拉起HiVision扫描弹框描述\"" +      "}\"";// HiLog.info(LABEL_LOG, jsonParams); extraParams.setJsonParams(jsonParams); return extraParams;    }    @Override    public void onActive() { super.onActive();    }    @Override    public void onForeground(Intent intent) { super.onForeground(intent);    }    @Override    protected void onStop() { if(continuationRegisterManager != null && abilityToken > 0){     continuationRegisterManager.unregister(abilityToken, requestCallback); }    }    /     * 准备开始迁移的回调     * @return     */    @Override    public boolean onStartContinuation() { //返回值为true才发起迁移 HiLog.info(LABEL_LOG, "MainAbilitySlice onStartContinuation"); return true;    }    /     * 当保存数据(要迁移的数据)的回调     * @param intentParams     * @return     */    @Override    public boolean onSaveData(IntentParams intentParams) { HiLog.info(LABEL_LOG, "MainAbilitySlice onSaveData"); intentParams.setParam("userName", "陈依劼"); return true;    }    /     * 当恢复数据的回调(应该是被迁移的设备调用     * @param intentParams     * @return     */    @Override    public boolean onRestoreData(IntentParams intentParams) { //返回为true代表恢复数据成功 HiLog.info(LABEL_LOG, "MainAbilitySlice onRestoreData"); Object userName = intentParams.getParam("userName"); if(userName != null){     params = (String)userName; } return true;    }    /     * 迁移完成的回调     * @param i     */    @Override    public void onCompleteContinuation(int i) { HiLog.info(LABEL_LOG, "MainAbilitySlice onCompleteContinuation");    }    /     * 迁移过程中失败的回调     */    @Override    public void onRemoteTerminated() { HiLog.info(LABEL_LOG, "MainAbilitySlice onRemoteTerminated");    }    /     * 回迁允许的情况下,远端中断     * @param errorCode     */    @Override    public void onFailedContinuation(int errorCode) { IAbilityContinuation.super.onFailedContinuation(errorCode); HiLog.info(LABEL_LOG, "MainAbilitySlice onFailedContinuation");    }}

测试

    注意要先把想迁移到的设备的上的程序先授权。