HarmonyOS开发之跨设备启动APP

时间:2025-03-24 18:57:38

在Harmony系统中,分布式技术是其核心亮点之一。通过分布式能力,设备之间可以无缝协同工作,实现跨设备的任务调度和资源共享。本文将详细介绍如何在鸿蒙系统中,通过分布式调度能力,实现从 A 设备点击按钮唤起 B 设备的 APP 的功能,并附上详细的代码示例。

1. 实现前的基础条件

在开始编码之前,需要确保以下基础条件已满足:

1) 设备绑定

  • A 和 B 设备已经通过分布式能力成功绑定。
  • 确保两台设备处于同一分布式网络中(例如连接到同一个 Wi-Fi)。

2) 相同应用安装

  • A 和 B 设备上都已安装同一个 APP。
  • 目标 APP 需要支持分布式能力。

3) 权限配置

config.json 文件中,为应用配置分布式相关的权限:

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

2. 使用分布式调度能力

鸿蒙提供了丰富的 API 来实现跨设备的操作。以下是具体实现步骤和代码示例。

1) 获取目标设备信息

首先,我们需要获取目标设备(B 设备)的信息,包括设备 ID。可以通过 DeviceManager 获取可用设备列表:

import ohos.distributedschedule.interwork.DeviceInfo;
import ohos.distributedschedule.interwork.DeviceManager;

// 获取在线设备列表
List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
if (deviceList != null && !deviceList.isEmpty()) {
    // 假设选择第一个设备作为目标设备
    DeviceInfo targetDevice = deviceList.get(0);
    String deviceId = targetDevice.getDeviceId();
    System.out.println("目标设备 ID: " + deviceId);
} else {
    System.out.println("未找到在线设备");
}

2) 构造跨设备启动参数

接下来,我们需要构造一个 Intent,设置目标设备的 ID 和目标 Ability 的相关信息:

import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;

// 创建 Intent 对象
Intent intent = new Intent();

// 设置目标设备和目标 Ability
Operation operation = new Operation.Builder()
        .withDeviceId(deviceId) // 目标设备 ID
        .withBundleName("com.example.myapp") // 目标应用包名
        .withAbilityName("com.example.myapp.MainAbility") // 目标 Ability 名称
        .build();

intent.setOperation(operation);

3) 启动目标设备上的 Ability

在 A 设备中,我们可以通过 startAbility 方法,启动 B 设备上的目标 Ability。以下是一个完整的按钮点击事件处理逻辑:

import ohos.aafwk.ability.Ability;
import ohos.agp.components.Button;

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

        // 找到按钮组件
        Button button = (Button) findComponentById(ResourceTable.Id_button);

        // 设置按钮点击事件
        button.setClickedListener(component -> {
            try {
                // 跨设备启动目标 Ability
                startAbility(intent);
                System.out.println("成功启动目标设备上的 APP");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("启动失败:" + e.getMessage());
            }
        });
    }
}

3. 注意事项

在实际开发中,需要注意以下几点:

1) 权限校验

确保应用已经申请并获得以下权限:

  • ohos.permission.DISTRIBUTED_DATASYNC
  • ohos.permission.INTERCONNECTIVITY

2) 设备在线状态

调用跨设备操作前,务必检查目标设备是否在线。可以通过 DeviceManager.getDeviceList 获取在线设备列表。

3) 错误处理

如果目标设备不可用或启动失败,需要添加相应的错误处理逻辑。例如:

if (deviceList == null || deviceList.isEmpty()) {
    System.out.println("没有可用的目标设备");
    return;
}

4. 测试与调试

(1) 测试环境

  • 在开发环境中,可以使用模拟器或真实设备进行测试。
  • 确保分布式网络环境稳定,并且设备之间的连接正常。

(2) 调试建议

  • 使用日志输出关键信息,例如设备 ID、启动结果等。
  • 如果启动失败,检查设备绑定状态、权限配置以及目标 Ability 的声明。

5. 总结

通过以上步骤,我们可以在鸿蒙系统中实现从 A 设备点击按钮唤起 B 设备的 APP 功能。这一过程充分利用了鸿蒙系统的分布式调度能力和跨设备启动能力,展示了鸿蒙系统在多设备协同方面的强大优势。

以下是完整的核心代码片段整合:

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Button;
import ohos.distributedschedule.interwork.DeviceInfo;
import ohos.distributedschedule.interwork.DeviceManager;

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

        // 获取目标设备信息
        List<DeviceInfo> deviceList = DeviceManager.getDeviceList(DeviceInfo.FLAG_GET_ONLINE_DEVICE);
        if (deviceList == null || deviceList.isEmpty()) {
            System.out.println("未找到在线设备");
            return;
        }

        DeviceInfo targetDevice = deviceList.get(0);
        String deviceId = targetDevice.getDeviceId();

        // 构造跨设备启动参数
        Intent crossDeviceIntent = new Intent();
        Operation operation = new Operation.Builder()
                .withDeviceId(deviceId)
                .withBundleName("com.example.myapp")
                .withAbilityName("com.example.myapp.MainAbility")
                .build();
        crossDeviceIntent.setOperation(operation);

        // 按钮点击事件
        Button button = (Button) findComponentById(ResourceTable.Id_button);
        button.setClickedListener(component -> {
            try {
                startAbility(crossDeviceIntent);
                System.out.println("成功启动目标设备上的 APP");
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("启动失败:" + e.getMessage());
            }
        });
    }
}