HarmonyOS编程跨设备跳转 | Java注释版

开发 后端 OpenHarmony
文章由鸿蒙社区产出,想要了解更多内容请前往:51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com

[[407016]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

前言

这里有HarmonyOS文档学习 | 分布式任务调度 | 思维导图,是关于文档部分的思维导图,跨设备调用也是用到里面的知识

本文章只是说明书,是代码的补充部分。不建议仅根据该文进行实践

正确的做法是下载附件中的源码,对照源码和文章的步骤,进行实践复现

跨设备跳转是页面跳转的进阶版,如果页面跳转还不熟悉,可以在我的第一弹中练习。在安卓中由于没有跨设备的接口,所以要实现都需要自己写。而在鸿蒙中,只需要用一两行代码就能实现跨设备的的核心操作

三种跨设备跳转的区别

只把页面内容迁移过去

把编辑中的内容迁移过去,支持双向控制

把编辑中的内容迁移过去,并可撤回迁移,仅支持单向控制

正文

1. 实现步骤

跨设备调用属于不同页面跳转,所以要有两个以上的Ability

第一步:创建多个Ability,创建后,会在slice、layout和graphic中自动生成对应的文件

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙HarmonyOS技术社区

第二步:编写xml布局文件,这里只是简单的示例,所以就只有简单的内容

第三步:编写业务逻辑代码

1. 声明权限

因为涉及到跨设备调度,所以为了安全,需要获取权限才能进行交互

声明获取设备列表即设备信息的权限

config.json

  1. "reqPermissions": [ 
  2.     { 
  3.         "name""ohos.permission.DISTRIBUTED_DATASYNC" 
  4.     }, 
  5.     { 
  6.         "name""ohos.permission.GET_BUNDLE_INFO" 
  7.     }, 
  8.     { 
  9.         "name""ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE" 
  10.     }, 
  11.     { 
  12.         "name""ohos.permission.GET_DISTRIBUTED_DEVICE_INFO" 
  13.     } 

注意:

第三方应用使用:ohos.permission.DISTRIBUTED_DATASYNC

还需要在主Ability代码中显式声明

  1. public class MainAbility extends Ability { 
  2.    @Override 
  3.    public void onStart(Intent intent) { 
  4.       super.onStart(intent); 
  5.       super.setMainRoute(MainAbilitySlice.class.getName()); 
  6.  
  7.       // 为第三方应用权限的主动声明 
  8.       requestPermissionsFromUser(new String[] {"ohos.permission.DISTRIBUTED_DATASYNC"}, 0); 
  9.    } 

2. 获取设备Id

只有拿到设备Id,跳转的时候才会根据Id进行页面迁移

3. 实现迁移功能代码

……

补充模拟器如何分布式跨设备测试:

如何多开模拟器,进行分布式应用开发(在DES 2.1版本之前,只能用真机进行分布式跨设备开发)

1. 先确保自己DES版本是2.1以上,可以通过 Help > Check for Updates 进行更新

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙HarmonyOS技术社区

2. 更新完之后也可以顺便更新自己的 SDK 和 Previewer (Previewer这个挺好用的,写完布局可直接预览而不用开模拟器)

3. 点击 SDK Platforms 和 SDK Tools 查看,在这里我都更新了,反正内存多~

4. 都更新完之后,可以去 File > Settings 或者按 Ctrl + Alt + S 快捷键进入设置面板,点击 DevEco Labs,勾选 Enable Super Device(其他也可以勾选,Java Previewr贼好用,在写完xml布局文件后,点击最右边导航栏或者按 Alt + 3 就可以预览了)

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙HarmonyOS技术社区

5. 然后就可以看到模拟器上多了 Super Device

2. 核心代码部分

2.1. 只把页面内容迁移过去

MainAbilitySlice.java

  1. // 通过组件id获得组件 
  2. btn1 = (Button)findComponentById(ResourceTable.Id_migration_btn_01); 
  3. // 设置按钮的点击监听事件 
  4. btn1.setClickedListener(component -> { 
  5.     // 要实现跨设备的打开FA 
  6.     // 第一步当然就是要获取到设备id 
  7.  
  8.     // 通过设备管理的获得设备列表方法获得 
  9.     List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); 
  10.     // 判空 
  11.     if (deviceList.isEmpty()) { 
  12.         return null
  13.     } 
  14.     // 获得设备数量 
  15.     int deviceNum = deviceList.size(); 
  16.     // 创建两个列表,分别存设备id和设备名 
  17.     ArrayList<String> deviceIds = new ArrayList<>(deviceNum); 
  18.     ArrayList<String> deviceNames = new ArrayList<>(deviceNum); 
  19.     // 遍历设备列表,将设备id和设备名分别存到两个列表中 
  20.     deviceList.forEach(device -> { 
  21.         deviceIds.add(device.getDeviceId()); 
  22.         deviceNames.add(device.getDeviceName()); 
  23.     }); 
  24.  
  25.     // 我就直接使用deviceIds的第一个元素,作为启动远程设备的目标id 
  26.     String deviceId = deviceIds.get(0); 
  27.  
  28.     if (deviceId != null) { 
  29.         // 新建Intent,意图:信息的载体 
  30.         Intent btn_1_intent = new Intent(); 
  31.         // OperationBuilder()方式 
  32.         Operation operation = new Intent.OperationBuilder() 
  33.             .withDeviceId(deviceId) // 获得设备id,在本地的时候可以为空 
  34.             .withBundleName("com.anzia.study_2")    // 包名,在config.json中可找到 
  35.             .withAbilityName("com.anzia.study_2.RemoteAbility") // 设立目标页面,一定要路径名!!! 
  36.             .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)   // 设立标签,允许跨设备 
  37.             .build();   // 构建 
  38.  
  39.         btn_1_intent.setOperation(operation);   // 把operation存进intent中 
  40.  
  41.         startAbility(btn_1_intent); 
  42.     } 
  43.  
  44. }); 

测试结果:

这里用的是模拟器,项目要在两个模拟上都进行打包安装

安装好后会提示用户获取权限,获得权限才能获取设备Id,从而进行跨设备页面跳转

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙HarmonyOS技术社区

点击第一个按钮,即可看到另一设备启动

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙HarmonyOS技术社区

2.2. 把编辑中的内容迁移过去,支持双向控制

由于获取设备Id的这部分代码经常使用,所以可以把这部分封装为一个工具类

如果要获取设备Id,只需要实现这个工具类即可

DeviceUtils.java

  1. public class DeviceUtils { 
  2.    public static String getDeviceId() { 
  3.       // 通过设备管理的获得设备列表方法获得 
  4.       List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE); 
  5.       // 判空 
  6.       if (deviceList.isEmpty()) { 
  7.          return null
  8.       } 
  9.       // 获得设备数量 
  10.       int deviceNum = deviceList.size(); 
  11.       // 创建两个列表,分别存设备id和设备名 
  12.       ArrayList<String> deviceIds = new ArrayList<>(deviceNum); 
  13.       ArrayList<String> deviceNames = new ArrayList<>(deviceNum); 
  14.       // 遍历设备列表,将设备id和设备名分别存到两个列表中 
  15.       deviceList.forEach(device -> { 
  16.          deviceIds.add(device.getDeviceId()); 
  17.          deviceNames.add(device.getDeviceName()); 
  18.       }); 
  19.  
  20.       // 我就直接使用deviceIds的第一个元素,作为启动远程设备的目标id 
  21.       String deviceIdStr = deviceIds.get(0); 
  22.       return deviceIdStr; 
  23.    } 

在MainAbilitySlice.java中实现可交互的页面跳转

使用new ElementName()设备模板页面路径

  1. btn2 = (Button)findComponentById(ResourceTable.Id_migration_btn_02); 
  2. btn2.setClickedListener(component -> { 
  3.    Intent btn_2_intent = new Intent(); 
  4.    ElementName migrationSliceEn = new ElementName("""com.anzia.study_2""MigrationAbility"); 
  5.    btn_2_intent.setElement(migrationSliceEn); 
  6.    startAbility(btn_2_intent); 
  7. }); 

要把编辑中的文字迁移到其他设备,需要对目标Ability和Slice实现IAbilityContinuation接口,并把构造方法设置为true

MigrationAbility.java

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙HarmonyOS技术社区

MigrationAbilitySlice.java

  1. public class MigrationAbilitySlice extends AbilitySlice implements IAbilityContinuation { 
  2.  
  3.    private TextField textField; 
  4.    private Button mgBtn; 
  5.    private String tfStr = ""
  6.  
  7.    @Override 
  8.    public void onStart(Intent intent) { 
  9.       super.onStart(intent); 
  10.       super.setUIContent(ResourceTable.Layout_ability_migration); 
  11.  
  12.       // 编辑的文字 
  13.       textField = (TextField) findComponentById(ResourceTable.Id_textfield_migration); 
  14.       // 默认为空 
  15.       textField.setText(tfStr); 
  16.  
  17.       mgBtn = (Button) findComponentById(ResourceTable.Id_migration_button); 
  18.       mgBtn.setClickedListener(component -> { 
  19.          // 核心代码,点击按钮,实现FA的迁移 
  20.          // 第一步获取设备id 
  21.          String deviceId = DeviceUtils.getDeviceId(); 
  22.          if (deviceId != null) { 
  23.             // 实现设备迁移 
  24.             continueAbility(deviceId); 
  25.          } 
  26.       }); 
  27.  
  28.    } 
  29.  
  30.    @Override 
  31.    public void onActive() { 
  32.       super.onActive(); 
  33.    } 
  34.  
  35.    @Override 
  36.    public void onForeground(Intent intent) { 
  37.       super.onForeground(intent); 
  38.    } 
  39.  
  40.    @Override 
  41.    public boolean onStartContinuation() { 
  42.       return true
  43.    } 
  44.  
  45.    @Override 
  46.    // 保持数据 
  47.    public boolean onSaveData(IntentParams intentParams) { 
  48.       // 获得文本框中的文字,并保存到data中,键值对形式 
  49.       intentParams.setParam("data", textField.getText()); 
  50.       return true
  51.    } 
  52.  
  53.    @Override 
  54.    // 恢复数据 
  55.    public boolean onRestoreData(IntentParams intentParams) { 
  56.       // 在其他设备恢复数据时,从data读取内容 
  57.       tfStr = intentParams.getParam("data").toString(); 
  58.       return true
  59.    } 
  60.  
  61.    @Override 
  62.    public void onCompleteContinuation(int i) { 
  63.  
  64.    } 

测试结果

点击按钮进入MigrationAbility页面,在输入框中输入文本内容,再点击按钮,可以看到已经迁移过去了

在目标设备上添加新的内容,再按点击迁移,可以对源设备的内容进行修改。即,可以双向控制

2.3. 把编辑中的内容迁移过去,并可撤回迁移,仅支持单向控制

实现方式和上面的基本差不多,也要实现IAbilityContinuation接口,在部分细节不同

不同点:

1. 在页面中多了一个回迁的按钮

2. 在Slice中

跨设备的方法由continueAbility()变为continueAbilityReversibly()

撤回迁移使用的方法是reverseContinueAbility()

MigrationBackAbilitySlice.java

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙HarmonyOS技术社区

测试结果:

在文本框输入数据后,点击迁移按钮,就可以在目标设备唤起应用了。点击撤回按钮,也可以把目标设备的页面撤回

这个操作是单向的,不能再迁移后,对目标设备内容修改再点击迁移修改源设备内容。这样做会闪退

3. 总结

因为涉及到设备之间的流转,涉及到安全,所以要在config.json中声明权限。如果想利用第三方设备,除了要在config.json中声明,还需要在代码中显式声明

跨设备需要获取设备Id,如果多个Slice中都要获取设备Id,那么可以将获取设备Id的这个步骤封装为一个工具类

在简单的跨设备调用,可以使用OperationBuilder()方法即可

要将设备编辑中的内容跨设备的话,需要为目标页面的Ability和Slice实现IAbilityContinuation()接口,使用new ElementName()

使用continueAbility进行双向交互

使用continueAbilityReversibly()和reverseContinueAbility()进行单向跨设备跳转及撤回内容

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-06-22 16:40:32

鸿蒙HarmonyOS应用

2020-11-05 10:05:25

App

2021-06-16 15:18:03

鸿蒙HarmonyOS应用

2021-01-06 10:59:14

鸿蒙HarmonyOSPage Abilit

2021-07-08 09:42:04

鸿蒙HarmonyOS应用

2021-01-06 11:21:56

鸿蒙HarmonyOS应用开发

2021-03-23 09:52:39

鸿蒙HarmonyOS应用开发

2021-03-29 09:59:09

鸿蒙HarmonyOS应用开发

2021-10-28 14:48:46

鸿蒙HarmonyOS应用

2022-10-11 15:26:16

网络编程鸿蒙

2011-04-07 10:50:47

数据库编程注释规范

2015-03-17 09:59:41

跨平台

2021-12-21 09:56:47

鸿蒙HarmonyOS应用

2020-11-24 11:58:19

HarmonyOS

2014-06-26 11:09:13

2020-11-13 12:09:46

HarmonyOS

2014-12-11 11:03:20

Qt跨平台开发

2022-08-27 15:23:52

开发者大会谷歌Android 应用
点赞
收藏

51CTO技术栈公众号