• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 开发带UI界面基础驱动
2
3## 场景介绍
4
5开发者开发带UI界面的基础驱动,适用于各种复合设备,需要通过UI界面设置对应的独特驱动能力或者通过UI界面展示从设备侧获取的信息,例如带有侧键的鼠标,手写板,身份证读卡器等设备。
6
7## 环境搭建
8
9请参考[环境准备](environmental-preparation.md)完成开发前的准备工作。
10
11## 接口说明
12
13扩展外设管理基本能力如下,更多详情请查阅[API参考文档](../../reference/apis-driverdevelopment-kit/js-apis-driver-deviceManager.md)。
14
15**表1** 扩展外设管理基本能力接口
16
17| 接口名                                                                                                                                                       | 描述                                                                                    |
18| -----------------------------------------------------------------------------------------------------------------------------------------------------------  | --------------------------------------------------------------------------------------- |
19| queryDevices(busType?: number): Array<Readonly<Device>>                                                                                          | 查询扩展外设列表。                                                                       |
20| bindDevice(deviceId: number, onDisconnect: AsyncCallback<number>, callback: AsyncCallback<{deviceId: number; remote: rpc.IRemoteObject;}>): void | 绑定设备,绑定成功后返回设备驱动的IRemoteObject通信对象,通过该对象与设备驱动进行交互。 |
21| bindDevice(deviceId: number, onDisconnect: AsyncCallback<number>): Promise<{deviceId: number; remote: rpc.IRemoteObject;}>                       | 绑定设备的Promise形式。                                                                 |
22| bindDeviceDriver(deviceId: number, onDisconnect: AsyncCallback<number>, callback: AsyncCallback>RemoteDeviceDriver>): void;                                  | 绑定设备,API11开始支持。                                                                 |
23| bindDeviceDriver(deviceId: number, onDisconnect: AsyncCallback<number>): Promise<RemoteDeviceDriver>;                                                        | 绑定设备的Promise形式,API11开始支持。
24| unbindDevice(deviceId: number, callback: AsyncCallback<number>): void                                                                                  | 解绑设备。                                                                              |
25| unbindDevice(deviceId: number): Promise<number>                                                                                                        | 解绑设备的Promise形式。                                                                              |
26
27<!--Del-->
28扩展外设管理系统接口如下,具体请查阅[API参考文档](../../reference/apis-driverdevelopment-kit/js-apis-driver-deviceManager-sys.md)。
29
30**表2** 扩展外设管理系统接口
31
32| 接口名                                                                          | 描述              |
33|------------------------------------------------------------------------------|-----------------|
34| queryDeviceInfo(deviceId?: number): Array&lt;Readonly&lt;DeviceInfo&gt;&gt;  | 查询扩展外设详细信息列表。   |
35| queryDriverInfo(driverUid?: string): Array&lt;Readonly&lt;DriverInfo&gt;&gt; | 查询扩展外设驱动详细信息列表。 |
36<!--DelEnd-->
37
38## 开发步骤
39
40应用可通过查询绑定扩展外设,从而使用扩展外设的定制驱动能力。
41
42开发示例如下(仅供参考):为开发者提供的示例代码为同时开发客户端和服务端的Demo,并实现IPC通信。
43
441. 创建新工程,请参考[创建一个新的工程](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/ide-create-new-project),创建一个OpenHarmony工程。
45
46    **注意:**
47
48    > 开发驱动客户端,请选择Empty Ability模板。
49    >
50    > 开发驱动服务端,请选择Native C++模板。
51    >
52    >同时开发驱动客户端和服务端,请选择Native C++模板。
53
54
552. 在文件中导入相关Kit,并声明想要绑定的USB设备的productId、vendorId以及与驱动通信的Code。
56
57    **说明:**
58
59    > 以下示例代码均写在entry/src/main/ets/pages/Index.ets文件中。
60
61    ```ts
62    import { hilog } from '@kit.PerformanceAnalysisKit';
63    import { deviceManager } from '@kit.DriverDevelopmentKit';
64    import { BusinessError } from '@kit.BasicServicesKit';
65    import { rpc } from '@kit.IPCKit';
66
67    const REQUEST_CODE: number = 99; // 自定义通信Code,此处仅供参考
68    const productId: number = 4258;  // 请声明连接的USB设备的productId
69    const vendorId: number = 4817;   // 请声明连接的USB设备的vendorId
70    ```
71
723. 定义message变量和远程对象变量,后续与驱动通信使用。
73
74    **说明:**
75
76    > 第3步开始,以下接口均在struct Index{}中定义。
77
78    ```ts
79    @State message: string = 'Hello';
80    private remote: rpc.IRemoteObject | null = null;
81    ```
82
834. 定义查询设备接口,通过queryDevices获取目标设备ID。
84
85    ```ts
86    private async queryTargetDeviceId(): Promise<number> {
87    try {
88      const devices: Array<deviceManager.Device> = deviceManager.queryDevices(deviceManager.BusType.USB);
89      const index = devices.findIndex((item: deviceManager.Device) => {
90        let usbDevice = item as deviceManager.USBDevice;
91        // 如果不知道设备productId和vendorId,可以通过该日志查看连接的usb设备的相关信息
92        hilog.info(0, 'testTag', `usbDevice.productId = ${usbDevice.productId}, usbDevice.vendorId = ${usbDevice.vendorId}`);
93        return usbDevice.productId === productId && usbDevice.vendorId === vendorId;
94      });
95      if (index < 0) {
96        hilog.error(0, 'testTag', 'can not find device');
97        return -1;
98      }
99      return devices[index].deviceId;
100    } catch (error) {
101      hilog.error(0, 'testTag', `queryDevice failed, err: ${JSON.stringify(error)}`);
102    }
103    return -1;
104    }
105    ```
106
1075. 定义获取对应驱动远程对象的接口,通过bindDeviceDriver获取远程对象。
108
109    ```ts
110    private async getDriverRemote(deviceId: number): Promise<rpc.IRemoteObject | null> {
111    try {
112      let remoteDeviceDriver: deviceManager.RemoteDeviceDriver = await deviceManager.bindDeviceDriver(deviceId,
113        (err: BusinessError, id: number) => {
114        hilog.info(0, 'testTag', `device[${id}] id disconnect, err: ${JSON.stringify(err)}}`);
115      });
116      return remoteDeviceDriver.remote;
117    } catch (error) {
118      hilog.error(0, 'testTag', `bindDeviceDriver failed, err: ${JSON.stringify(error)}`);
119    }
120      return null;
121    }
122    ```
123
1246. 定义与远程对象通信接口,通过sendMessageRequest与远程对象进行IPC通信。
125
126    ```ts
127    private async communicateWithRemote(): Promise<void> {
128      const deviceId: number = await this.queryTargetDeviceId();
129      if (deviceId < 0) {
130        hilog.error(0, 'testTag', 'can not find target device');
131        return;
132      }
133      this.remote = await this.getDriverRemote(deviceId);
134      if (this.remote === null) {
135        hilog.error(0, 'testTag', `getDriverRemote failed`);
136        return;
137      }
138
139      let option = new rpc.MessageOption();
140      let data = new rpc.MessageSequence();
141      let reply = new rpc.MessageSequence();
142
143      // 向驱动发送信息"Hello"
144      data.writeString(this.message);
145
146      try {
147        await this.remote.sendMessageRequest(REQUEST_CODE, data, reply, option);
148        // 获取驱动返回信息"Hello world"
149        this.message = reply.readString();
150        hilog.info(0, 'testTag', `sendMessageRequest, message: ${this.message}}`);
151      } catch (error) {
152        hilog.error(0, 'testTag', `sendMessageRequest failed, err: ${JSON.stringify(error)}`);
153      }
154    }
155    ```
156
1577. 渲染UI界面,更多UI界面开发请参考[UI开发](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-ui-development-V5)158
159    ```ts
160    build() {
161      Row() {
162        Column() {
163          Text(this.message) // 显示"Hello"
164            .fontSize(60)
165            .fontWeight(FontWeight.Bold)
166            .onClick(() => { // 点击"Hello",与远程对象通信,显示"Hello World"
167              this.communicateWithRemote();
168            })
169        }
170        .width('100%')
171      }
172      .height('100%')
173    }
174    ```
175
1768. 接下来请参考[开发无UI界面基础驱动](driverextensionability.md),进行对应驱动的示例代码开发。
177
178<!--Del-->
179系统应用可通过查询外设详细信息和驱动详细信息,从而管理外设和驱动。开发示例如下:
180
1811. 导入相关Kit。
182
183    ```ts
184     import { deviceManager } from '@kit.DriverDevelopmentKit';
185     import { BusinessError } from '@kit.BasicServicesKit';
186    ```
187
1882. 查询扩展外设详细信息列表。
189
190    ```ts
191    try {
192       // 12345678为示例deviceId,应用开发时可通过queryDevices查询到相应设备的deviceId作为入参
193       let deviceInfos : Array<deviceManager.DeviceInfo> = deviceManager.queryDeviceInfo(12345678);
194       for (let item of deviceInfos) {
195          console.info(`Device id is ${item.deviceId}`)
196       }
197     } catch (error) {
198       let err: BusinessError = error as BusinessError;
199       console.error(`Failed to query device info. Code is ${err.code}, message is ${err.message}`);
200     }
201    ```
202
2033. 查询扩展外设驱动详细信息列表。
204
205    ```ts
206    try {
207       // driver-12345为示例driverUid,应用开发时可通过queryDeviceInfo查询到相应设备匹配到的驱动的driverUid作为入参
208       let driverInfos : Array<deviceManager.DriverInfo> = deviceManager.queryDriverInfo("driver-12345");
209       for (let item of driverInfos) {
210          console.info(`driver name is ${item.driverName}`)
211       }
212    } catch (error) {
213       let err: BusinessError = error as BusinessError;
214       console.error(`Failed to query driver info. Code is ${err.code}, message is ${err.message}`);
215    }
216    ```
217<!--DelEnd-->
218<!--RP1-->
219## 应用签名
220
221**注意:** 先配置权限,再自动签名。
222
223应用需要配置签名文件才能在设备上运行,并且扩展外设管理客户端开发,需要配置扩展外设的权限:ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVERohos.permission.ACCESS_DDK_DRIVERS224- ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVER
225
226module.json5配置文件的requestPermissions标签中[声明权限](../../security/AccessToken/declare-permissions.md)后,即可获得授权。
227
228- ohos.permission.ACCESS_DDK_DRIVERS
229
230  1. 在module.json5配置文件的requestPermissions标签中[声明权限](../../security/AccessToken/declare-permissions.md)。
231  2. HarmonyAppProvision配置文件中,修改acls字段,跨级别申请权限,可参考[申请使用受限权限](../../security/AccessToken/declare-permissions-in-acl.md)。
232  3. 在HarmonyAppProvision配置文件(即SDK目录下的“Sdk/openharmony/_{Version} _/toolchains /lib/UnsgnedReleasedProfileTemplate.json”文件)中,配置当前客户需要连接的驱动服务端的bundleName,如果存在多个服务端,多个服务端的bundleName以逗号分隔。
233
234      具体配置方法如下:
235
236      在文件的根节点加上app-services-capabilities节点,并采用以下格式进行配置。
237      ```json
238      "app-services-capabilities": {
239        "ohos.permission.ACCESS_DDK_DRIVERS": {"bundleNames": "bundleName0,bundleName1,bundleName2"}
240      }
241      ```
242
243自动签名方法: 请参考[自动签名](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/ide-signing-V13#section18815157237)244<!--RP1End-->