HarmonyOS编程 | 跨设备跳转 | Java注释版 原创 精华

Anzia
发布于 2021-6-16 20:44
浏览
7收藏

 

HarmonyOS编程 —— 第二弹

跨设备跳转

 

前言

 

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

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

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

 

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

 

三种跨设备跳转的区别

  1. 只把页面内容迁移过去
  2. 把编辑中的内容迁移过去,支持双向控制
  3. 把编辑中的内容迁移过去,并可撤回迁移,仅支持单向控制

 

正文

 

1. 实现步骤

 

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

 

第一步:创建多个Ability,创建后,会在slice、layout和graphic中自动生成对应的文件HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区第二步:编写xml布局文件,这里只是简单的示例,所以就只有简单的内容HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区第三步:编写业务逻辑代码

1. 声明权限

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

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

config.json

"reqPermissions": [
    {
        "name": "ohos.permission.DISTRIBUTED_DATASYNC"
    },
    {
        "name": "ohos.permission.GET_BUNDLE_INFO"
    },
    {
        "name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"
    },
    {
        "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
    }
]

注意:

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

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

public class MainAbility extends Ability {
   @Override
   public void onStart(Intent intent) {
      super.onStart(intent);
      super.setMainRoute(MainAbilitySlice.class.getName());

      // 为第三方应用权限的主动声明
      requestPermissionsFromUser(new String[] {"ohos.permission.DISTRIBUTED_DATASYNC"}, 0);
   }
}

2. 获取设备Id

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

3. 实现迁移功能代码

……

 

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

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

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

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

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

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

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

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

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

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

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

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

 

2. 核心代码部分

 

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

MainAbilitySlice.java

// 通过组件id获得组件
btn1 = (Button)findComponentById(ResourceTable.Id_migration_btn_01);
// 设置按钮的点击监听事件
btn1.setClickedListener(component -> {
    // 要实现跨设备的打开FA
    // 第一步当然就是要获取到设备id

    // 通过设备管理的获得设备列表方法获得
    List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
    // 判空
    if (deviceList.isEmpty()) {
        return null;
    }
    // 获得设备数量
    int deviceNum = deviceList.size();
    // 创建两个列表,分别存设备id和设备名
    ArrayList<String> deviceIds = new ArrayList<>(deviceNum);
    ArrayList<String> deviceNames = new ArrayList<>(deviceNum);
    // 遍历设备列表,将设备id和设备名分别存到两个列表中
    deviceList.forEach(device -> {
        deviceIds.add(device.getDeviceId());
        deviceNames.add(device.getDeviceName());
    });

    // 我就直接使用deviceIds的第一个元素,作为启动远程设备的目标id
    String deviceId = deviceIds.get(0);

    if (deviceId != null) {
        // 新建Intent,意图:信息的载体
        Intent btn_1_intent = new Intent();
        // OperationBuilder()方式
        Operation operation = new Intent.OperationBuilder()
            .withDeviceId(deviceId) // 获得设备id,在本地的时候可以为空
            .withBundleName("com.anzia.study_2")	// 包名,在config.json中可找到
            .withAbilityName("com.anzia.study_2.RemoteAbility") // 设立目标页面,一定要路径名!!!
            .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)	// 设立标签,允许跨设备
            .build();	// 构建

        btn_1_intent.setOperation(operation);	// 把operation存进intent中

        startAbility(btn_1_intent);
    }

});

 

测试结果:

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

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

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

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

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

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

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

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

DeviceUtils.java

public class DeviceUtils {
   public static String getDeviceId() {
      // 通过设备管理的获得设备列表方法获得
      List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
      // 判空
      if (deviceList.isEmpty()) {
         return null;
      }
      // 获得设备数量
      int deviceNum = deviceList.size();
      // 创建两个列表,分别存设备id和设备名
      ArrayList<String> deviceIds = new ArrayList<>(deviceNum);
      ArrayList<String> deviceNames = new ArrayList<>(deviceNum);
      // 遍历设备列表,将设备id和设备名分别存到两个列表中
      deviceList.forEach(device -> {
         deviceIds.add(device.getDeviceId());
         deviceNames.add(device.getDeviceName());
      });

      // 我就直接使用deviceIds的第一个元素,作为启动远程设备的目标id
      String deviceIdStr = deviceIds.get(0);
      return deviceIdStr;
   }
}

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

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

btn2 = (Button)findComponentById(ResourceTable.Id_migration_btn_02);
btn2.setClickedListener(component -> {
   Intent btn_2_intent = new Intent();
   ElementName migrationSliceEn = new ElementName("", "com.anzia.study_2", "MigrationAbility");
   btn_2_intent.setElement(migrationSliceEn);
   startAbility(btn_2_intent);
});

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

MigrationAbility.java

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

MigrationAbilitySlice.java

public class MigrationAbilitySlice extends AbilitySlice implements IAbilityContinuation {

   private TextField textField;
   private Button mgBtn;
   private String tfStr = "";

   @Override
   public void onStart(Intent intent) {
      super.onStart(intent);
      super.setUIContent(ResourceTable.Layout_ability_migration);

      // 编辑的文字
      textField = (TextField) findComponentById(ResourceTable.Id_textfield_migration);
      // 默认为空
      textField.setText(tfStr);

      mgBtn = (Button) findComponentById(ResourceTable.Id_migration_button);
      mgBtn.setClickedListener(component -> {
         // 核心代码,点击按钮,实现FA的迁移
         // 第一步获取设备id
         String deviceId = DeviceUtils.getDeviceId();
         if (deviceId != null) {
            // 实现设备迁移
            continueAbility(deviceId);
         }
      });

   }

   @Override
   public void onActive() {
      super.onActive();
   }

   @Override
   public void onForeground(Intent intent) {
      super.onForeground(intent);
   }

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

   @Override
   // 保持数据
   public boolean onSaveData(IntentParams intentParams) {
      // 获得文本框中的文字,并保存到data中,键值对形式
      intentParams.setParam("data", textField.getText());
      return true;
   }

   @Override
   // 恢复数据
   public boolean onRestoreData(IntentParams intentParams) {
      // 在其他设备恢复数据时,从data读取内容
      tfStr = intentParams.getParam("data").toString();
      return true;
   }

   @Override
   public void onCompleteContinuation(int i) {

   }
}

测试结果

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

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

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

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

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

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

不同点:

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

2. 在Slice中

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

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

MigrationBackAbilitySlice.java

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

测试结果:

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

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

HarmonyOS编程 | 跨设备跳转 | Java注释版-鸿蒙开发者社区

 

3. 总结

 

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

 

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

 

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

 

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

使用continueAbility进行双向交互

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

 

引用

 

代码案例是鸿蒙手机应用开发入门(Java)课程中的

 

觉得老师讲的不错,也为了方便自己理解,所以写了该篇文章用于整理自己的思绪

如果你也在学北向开发,推荐入手这个教程

 

 

PS:友情提示

# 图片模糊怎么办?

对图片右键在新窗口打开
对图片右键另存为本地看
 

# 下面有一个文件

【跨设备调用源代码.rar】是源码

 

在专栏中还有大量这样类似的文章,如果觉得对你有用,不妨关注一起学习~

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
跨设备调用源代码.rar 17.13K 94次下载
已于2021-6-17 00:25:35修改
5
收藏 7
回复
举报
2条回复
按时间正序
/
按时间倒序
Anzia
Anzia

在文章新添加了 如何开启两个模拟器进行分布式跨设备调试 的内容,并用红字说明补充了,不要看漏了噢

1
回复
2021-6-17 00:27:48
Anzia
Anzia

要断更一会,先把期末考试和要做的实验报告给完成了才有精力去学鸿蒙~

回复
2021-6-17 00:36:14
回复
    相关推荐