在此章节,我们需要将完成这篇Codelab学习,所需要的软硬件环境,及能力使用权限等信息。
集成DeviceVirtualization Engine能力,需要完成以下准备工作:
具体操作,请按照《DeviceVirtualization Engine 接入准备》中详细说明来完成。
1. 集成DeviceVirtualization Engine。
在工程APP目录中的build.gradle中添加如下代码,将下载好的aar包添加至工程中
build.gradle
dependencies {
implementation files('libs/devicevirtualization-device-android-1.0.0.300.aar')
}
点击同步工程按钮,进行工程同步,如下图所示:
同步成功后,如下图所示:
2. 在AndroidManifest.xml中配置应用为系统权限。
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.huawei.dmsdptest"
android:sharedUserId="android.uid.system">
......
3. 初始化服务。
使用VirtualizationAdapter的静态方法initInstance初始化,初始化时需要指定设备的名称与类型。初始化结果通过onInitSuccess和onInitFail回调方法获取。
4. 注册虚拟化服务回调接口
在初始化成功后,回调接口onInitSuccess将会返回一个VirtualizationAdapter实例对象。此时需要为该实例对象注册IVirtualizationCallback回调接口,该接口需要实现以下五个回调方法:
5. 启动发现监听
通过VirtualizationAdapter实例对象的startAdv方法启动发现监听,监听启动成功后,手机便可以发现该设备。完成此步骤后,设备虚拟化能力的基本功能就可以使用了。
MainActivity.java
mVirtualizationAdapter.startAdv();
6. 断开连接设备
设备可在需要的时候通过VirtualizationAdapter实例对象的disconnectDevice方法断开当前的连接设备。
MainActivity.java
mVirtualizationAdapter.disconnectDevice();
7. 释放连接对象
通过使用VirtualizationAdapter的静态方法releaseInstance释放连接对象
MainActivity.java
mVirtualizationCallback = new IVirtualizationCallback() {
@Override
public void onDeviceChange(String remoteDevice, int state) {
if (state == CONNECT) {
HwLog.i(TAG, "device has connected");
AdapterUtil.getInstance().setConnectedDevice(remoteDevice);
} else if (state == DISCONNECT) {
HwLog.i(TAG, "device has disconnected");
AdapterUtil.getInstance().setConnectedDevice(null);
mDisplayService.set(false);
//设备断开连接,需销毁显示投屏画面的Surface
MainActivity.this.sendBroadcast(new Intent(ACTION_CLOSE_SURFACE_ACTIVITY));
} else if (state == START_PROJECTION) {
HwLog.i(TAG, "service all ready,start project");
mDisplayService.set(true);
//创建Surface,并通过startProjection接口传递给DV服务,用来显示投屏画面
Intent intent = new Intent(MainActivity.this, SurfaceActivity.class);
MainActivity.this.startActivity(intent);
} else if (state == STOP_PROJECTION) {
HwLog.i(TAG, "stopProjection");
mDisplayService.set(false);
//投屏能力停止,也需销毁显示投屏画面的Surface
MainActivity.this.sendBroadcast(new Intent(ACTION_CLOSE_SURFACE_ACTIVITY));
} else if (state == REQUEST_CONNECTION) {
//自定义弹窗布局文件
View dialogView = View.inflate(mContext, R.layout.dialog_permission, null);
final AlertDialog dialog = new AlertDialog.Builder(mContext).setView(dialogView).create();
TextView titleTextView = dialogView.findViewById(R.id.title_id);
TextView informationTextView = dialogView.findViewById(R.id.information_id);
Button refuseButton = dialogView.findViewById(R.id.button_prohibition);
Button permanentButton = dialogView.findViewById(R.id.button_permission_permanent);
Button temporaryButton = dialogView.findViewById(R.id.button_permission_temporary);
temporaryButton.requestFocus();
titleTextView.setText("是否允许"" + remoteDevice + ""访问本设备?");
informationTextView.setText("使用中可能会调用麦克风、摄像头用于音视频协同等服务。");
refuseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mVirtualizationAdapter != null) {
int result = mVirtualizationAdapter.disconnectDevice();
HwLog.i(TAG, "disconnect device result:" + result);
dialog.dismiss();
}
}
});
permanentButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int result = mVirtualizationAdapter.acceptConnection(true);
HwLog.i(TAG, "permanent permit result:" + result);
dialog.dismiss();
}
});
temporaryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
int result = mVirtualizationAdapter.acceptConnection(false);
HwLog.i(TAG, "temporary permit result:" + result);
dialog.dismiss();
}
});
dialog.show();
}
}
@Override
public void onPinCode(String deviceName, final String pinCode) {
HwLog.i(TAG, "pinCode:" + pinCode);
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
if (!TextUtils.isEmpty(pinCode)) {
//显示pinCode
mCode.setText(pinCode);
} else {
//如果pinCode是空串,不显示pinCode
mCode.setText("");
}
}
});
}
@Override
public long getSecureFileSize(String fileName) {
HwLog.i(TAG, "readSecureFile fileName:" + fileName);
try (FileInputStream fileInputStream = openFileInput(fileName)) {
FileChannel channel = fileInputStream.getChannel();
return channel.size();
} catch (IOException e) {
HwLog.e(TAG, "getSecureFileSize failed");
}
return 0;
}
@Override
public byte[] readSecureFile(String fileName) {
HwLog.i(TAG, "readSecureFile fileName:" + fileName);
try (FileInputStream fileInputStream = openFileInput(fileName)) {
int canRead = fileInputStream.available();
byte[] buffer = new byte[canRead];
int read = fileInputStream.read(buffer);
if (read != canRead) {
HwLog.e(TAG, "read file size failed");
} else {
HwLog.i(TAG, "read file success");
return buffer;
}
} catch (IOException e) {
HwLog.e(TAG, "read file failed");
}
return new byte[0];
}
@Override
public boolean writeSecureFile(String fileName, byte[] bytes) {
HwLog.i(TAG, "writeSecureFile fileName:" + fileName);
try (FileOutputStream fileOutputStream = openFileOutput(fileName, MODE_PRIVATE)) {
fileOutputStream.write(bytes);
fileOutputStream.flush();
} catch (IOException e) {
HwLog.e(TAG, "write file exception," + e);
return false;
}
return true;
}
};
int status = mVirtualizationAdapter.setVirtualizationCallback(mVirtualizationCallback);
MainActivity.java
@Override
protected void onDestroy() {
HwLog.i(TAG, "onDestroy");
disconnect();
HwLog.i(TAG, "onDestroy end");
super.onDestroy();
}
//全部释放干净
private void disconnect() {
if (mVirtualizationAdapter != null) {
//停止投屏
if (mDisplayService.get()) {
int stopStatus = mVirtualizationAdapter.stopProjection();
HwLog.d(TAG, "disconnect stopProjection stopStatus:" + stopStatus);
mDisplayService.set(false);
}
//停止连接监听
int disconnectDeviceStatus = mVirtualizationAdapter.disconnectDevice();
HwLog.i(TAG, "disconnect disconnectDevice status:" + disconnectDeviceStatus);
//停止发现监听
int result = mVirtualizationAdapter.stopAdv();
HwLog.i(TAG, "disconnect stop listen result:" + result);
}
//释放adapter对象
VirtualizationAdapter.releaseInstance();
mVirtualizationAdapter = null;
}
干得好,你已经成功完成了Codelab并学到了:
您可以阅读下面链接,了解更多相关的信息。
您可以点击下方按钮下载源码。