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<Readonly<DeviceInfo>> | 查询扩展外设详细信息列表。 | 35| queryDriverInfo(driverUid?: string): Array<Readonly<DriverInfo>> | 查询扩展外设驱动详细信息列表。 | 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_DRIVER及ohos.permission.ACCESS_DDK_DRIVERS。 224- ohos.permission.ACCESS_EXTENSIONAL_DEVICE_DRIVER 225 226 在module.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-->