DeviceVirtualization Kit(简称DV Kit)是华为提供的多设备虚拟化平台,通过该平台,将周边的设备或设备器件转换为手机的虚拟器件,能够将周边设备能力作为手机系统通用能力来提供和使用,同时能够实现多虚拟设备能力同步协同使用。

应用开发者通过集成DV Kit,可以便捷使用外部的设备,包括但不限于摄像头、扬声器、显示器、麦克风、穿戴等外部设备能力以及相关器件的能力,并可以支持灵活的控制和切换,充分使用外部设备的资源优势,致力为消费者打造更佳的协同体验。

您将建立什么

在这个Codelab中,你将创建Demo Project,并将DeviceVirtualization Kit集成到Demo Project中,以及完成DeviceVirtualization Kit服务的整体流程搭建。

您将会学到什么

硬件要求

软件要求

需要的知识点

集成DeviceVirtualization Kit能力,需要完成以下准备工作:

具体操作,请按照《DeviceVirtualization Kit 接入准备》中详细说明来完成。

1、集成DeviceVirtualization Kit。

配置DeviceVirtualization Kit依赖库,配置时要使用最新版本:

点击同步工程按钮,进行工程同步,如下图所示:

同步成功后,如下图所示:

2、添加appid信息。

在自身应用AndroidManifest.xml中添加开发者联盟创建应用时生成的appid信息,name为"com.huawei.hms.client.appid",value为"appid=*",*用自己注册的appid。DeviceVirtualization Kit接入权限申请,请依照《DeviceVirtualization Kit 接入准备》中第四步"权限申请"的详细说明来完成。需要注意的是权限申请通过后才能接入,否则会在连接服务时抛出异常,调用DV Kit接口会返回ERROR_CODE_NO_PERMISSION。

3、兼容性检查:

MainActivity.java

// 根据当前集成的DV Kit版本来定义CURRENT_KIT_VERSION static final String CURRENT_KIT_VERSION = "1.0.2.300"; ...... private boolean isDvKitSupport() { boolean isSupport = true; try { //获取当前DvKit服务的运行版本 String version = DvKit.getVersion(); if (version.compareTo(CURRENT_KIT_VERSION) < 0) { //当前DvKit服务版本不满足应用的运行要求 isSupport = false; } } catch (NoClassDefFoundError e) { //当前运行环境不支持DvKit isSupport = false; Log.e(TAG, "DvKit not exist", e); } return isSupport; }

4、应用权限申请。

AndroidManifest.xml

<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.BODY_SENSORS" /> <uses-permission android:name="com.huawei.permission.DISTRIBUTED_VIRTUALDEVICE" />

MainActivity.java

String[] permissions = new String[] {Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO, Manifest.permission.BODY_SENSORS," com.huawei.permission.DISTRIBUTED_VIRTUALDEVICE"}; ...... mPermissionList.clear(); for (int i = 0; i < permissions.length; i++) { if (ContextCompat.checkSelfPermission(MainActivity.this, permissions[i]) != PackageManager.PERMISSION_GRANTED) { mPermissionList.add(permissions[i]); } } if (mPermissionList.isEmpty()) { // 未授予的权限为空,表示都授予了 Intent intent = new Intent(MainActivity.this, DvKitDemoActivity.class); startActivity(intent); } else { // 请求权限方法 String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);// 将List转为数组 requestPermissions(permissions, PERMISSIONS_REQUEST); } ...... // 获取到权限后,打开DvKitDemo Activity @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == PERMISSIONS_REQUEST) { for (int i = 0; i < grantResults.length; i++) { if (grantResults[i] == PackageManager.PERMISSION_GRANTED) { mPermissionList.remove(permissions[i]); } } if (mPermissionList.isEmpty()) { Intent intent = new Intent(MainActivity.this, DvKitDemoActivity.class); startActivity(intent); } } super.onRequestPermissionsResult(requestCode, permissions, grantResults); }

5、连接DV Kit服务并订阅设备能力状态变化事件。

DvKitDemoActivity.java

DvKit.getInstance().connect(getApplicationContext(), new IDvKitConnectCallback() { //当DvKit服务连接成功时 @Override public void onConnect(int i) { addLog("init MSDPService done"); //获取虚拟设备服务实例 mVirtualDeviceManager = (VirtualDeviceManager) DvKit.getInstance().getKitService(VIRTUAL_DEVICE_CLASS); //订阅虚拟设备能力状态变化事件 mVirtualDeviceManager.subscribe(EnumSet.of(VIRTUALDEVICE), observer); } @Override public void onDisconnect() { } });

6、发现设备

DvKitDemoActivity.java

//设置发现按钮 mStartDiscoveryButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mVirtualDeviceManager == null) { addLog("WechatAdapter is null"); return; } //调用发现接口 int ret = mVirtualDeviceManager.startDiscovery(discoveryCallback); addLog("start discovery result is " + ret); } }); ...... /** * 设备发现的回调接口,获取发现到的虚拟设备 */ private IDiscoveryCallback discoveryCallback = new IDiscoveryCallback() { @Override public void onFound(VirtualDevice device, int state) { if (device == null) { addLog("onDevice callback but device is null"); } else { //将发现的设备存储到容器中,并且在界面上显示 if (!mVirtualDeviceMap.containsKey(device.getDeviceId())) { addLog("onDevice Found: " + device.getDeviceId() + " Name: " + device.getDeviceName() + " Type:" + device.getDeviceType()); mVirtualDeviceMap.put(device.getDeviceId(), device); handler.sendMessage(handler.obtainMessage(DEVICE_ADD, device)); } } } @Override public void onState(int state) { } };

7、设备列表选择呈现

任何使用"华为DeviceVirtualization Kit"的应用,都必须提供如下界面供用户选择对应的可支持虚拟化的设备,由用户授权选择对应的设备完成能力接续。在发现设备后要弹出设备列表显式让用户选择,UI效果参考下图。

8、使能设备能力。

DvKitDemoActivity.java

holder.camera_button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final String deviceId = (String) v.getTag(); VirtualDevice device = mVirtualDeviceMap.get(deviceId); if (device == null) { addLog("do not contains " + deviceId); return; } if (!cameraOpend.containsKey(deviceId) || !cameraOpend.get(deviceId)) { addLog("open camera " + device.getDeviceName()); //使能虚拟Camera int ret = mVirtualDeviceManager.enableVirtualDevice(deviceId, EnumSet.of(CAMERA), null); addLog("open camera result is " + ret); } else { ...... } } }); ...... /** * 设备能力状态变化的观察接口,用于获取设备能力的使能去使能状态变化 */ private IVirtualDeviceObserver observer = new IVirtualDeviceObserver() { //设备状态变化时的回调 @Override public void onDeviceStateChange(VirtualDevice virtualDevice, int returncode) { } /** *设备能力状态变化时的回调 */ @Override public void onDeviceCapabilityStateChange(VirtualDevice virtualDevice, Capability capability, int returncode) { if (returncode == EventType.EVENT_DEVICE_CAPABILITY_ENABLE) { //当设备能力使能成功时,应用处理 onEnable(virtualDevice, capability); } else if (returncode == EventType.EVENT_DEVICE_CAPABILITY_DISABLE) { //设备能力去使能成功时,应用处理逻辑 onDisable(virtualDevice, capability); } else { //设备能力异常时,应用处理逻辑 onError(virtualDevice, capability, returncode); } } ...... }

9、通过Android接口使用虚拟设备能力,下面通过两个例子进行举例说明:

DvKitDemoActivity.java

/** * 当设备能力使能成功时,应用处理 */ public void onEnable(VirtualDevice device, Capability capability) { switch (capability) { case CAMERA: //Camera使能成功 addLog("open camera success"); //将camera使能状态设置为true cameraOpend.put(device.getDeviceId(), true); //获取cameraID String data = device.getData(Constants.ANDROID_CAMERAID_FRONT); addLog("open camera " + device.getDeviceName() + " cameraId " + data); //打开虚拟camera Intent intent = new Intent(DvKitDemoActivity.this, RegitsterCameraAPI2.class); intent.putExtra("cameraId", data); Log.i(TAG, "cameraId is " + data); startActivity(intent); break; case DISPLAY: //display使能成功,将display使能状态设置为true addLog("open display success"); displayOpend.put(device.getDeviceId(), true); break; case MIC: //mic使能成功,将mic使能状态设置为true addLog("open mic success"); micOpend.put(device.getDeviceId(), true); break; case SPEAKER: //speaker使能成功,将speaker使能状态设置为true addLog("open speaker success"); speakerOpend.put(device.getDeviceId(), true); break; case VIBRATE: //vibrate使能成功,将vibrate使能状态设置为true addLog("open vibrate success"); speakerOpend.put(device.getDeviceId(), true); break; case SENSOR: //sensor使能成功,将sensor使能状态设置为true addLog("open sensor success"); speakerOpend.put(device.getDeviceId(), true); break; case NOTIFICATION: //notification使能成功,将notification使能状态设置为true addLog("open notification success"); speakerOpend.put(device.getDeviceId(), true); break; } }

10、去使能虚拟设备能力。应用不想使用虚拟设备能力时,例如切回到手机能力时可以增加去使能操作。

DvKitDemoActivity.java

holder.camera_button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final String deviceId = (String) v.getTag(); VirtualDevice device = mVirtualDeviceMap.get(deviceId); if (device == null) { addLog("do not contains " + deviceId); return; } if (!cameraOpend.containsKey(deviceId) || !cameraOpend.get(deviceId)) { ...... } else { ...... //去使能虚拟Camera int ret = mVirtualDeviceManager.disableVirtualDevice(deviceId, EnumSet.of(CAMERA)); ...... } } }); ...... /** * 设备能力状态变化的观察接口,用于获取设备能力的使能去使能状态变化 */ private IVirtualDeviceObserver observer = new IVirtualDeviceObserver() { //设备状态变化时的回调 @Override public void onDeviceStateChange(VirtualDevice virtualDevice, int returncode) { } /** *设备能力状态变化时的回调 */ @Override public void onDeviceCapabilityStateChange(VirtualDevice virtualDevice, Capability capability, int returncode) { if (returncode == EventType.EVENT_DEVICE_CAPABILITY_ENABLE) { //当设备能力使能成功时,应用处理 onEnable(virtualDevice, capability); } else if (returncode == EventType.EVENT_DEVICE_CAPABILITY_DISABLE) { //设备能力去使能成功时,应用处理逻辑 onDisable(virtualDevice, capability); } else { //设备能力异常时,应用处理逻辑 onError(virtualDevice, capability, returncode); } } ...... }

11、断开连接

DvKitDemoActivity.java

public void onDestroy() { DvKit.getInstance().disConnect(); ...... }

干得好,你已经成功完成了Codelab并学到了:

您可以阅读下面链接,了解更多相关的信息。
相关文档

已复制代码