一、AndroidDebugBridge管理设备
引入jar,github源码地址:https://github.com/cosysoft/device【很久未更新了】
<dependency>
<groupId>com.github.cosysoft</groupId>
<artifactId>device-api</artifactId>
<version>0.9.3</version>
</dependency>
可以从它的源码中,看出依赖包有:
ext {
ddmlibVersion = '24.5.0'
}
dependencies {
compile 'org.apache.commons:commons-exec:1.2'
compile 'commons-cli:commons-cli:1.2'
compile "com.android.tools.ddms:ddmlib:$ddmlibVersion"
compile "com.android.tools:dvlib:$ddmlibVersion"
compile "com.android.tools:sdklib:$ddmlibVersion"
compile "com.android.tools:sdk-common:$ddmlibVersion"
}
我们便用到了其中一个重要的jar包
<dependency>
<groupId>com.android.tools.ddms</groupId>
<artifactId>ddmlib</artifactId>
<version>24.5.0</version>
</dependency>
- 读取环境变量:adb的path
[root@localhost ~]# env | grep "ADB_PATH"
ADB_PATH=/server/soft/platform-tools

1、实现AndroidDebugBridge.IDeviceChangeListener监听接口
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.IDevice;
import com.xxx.tools.cwp2video.evolution.domain.bean.DeviceInfo;
import com.xxx.tools.cwp2video.evolution.domain.constant.CommonState;
import com.xuehai.tools.cwp2video.evolution.infrastructure.util.device.DeviceManager;
/**
* @author xxx
* @title: DeviceChangeListener
* @projectName group-control
* @description: 监听手机连接、离线、状态改变的接口
* @date 2021/1/23-19:54
*/
public class DeviceChangeListener implements AndroidDebugBridge.IDeviceChangeListener {
private final ICustomDevice iCustomDevice;
public DeviceChangeListener(ICustomDevice iCustomDevice) {
this.iCustomDevice = iCustomDevice;
}
@Override
public void deviceConnected(IDevice device) {
DeviceManager.addDevice(device.getSerialNumber(), device);
this.iCustomDevice.run(assemblerDeviceInfo(device), device.getState().toString());
}
@Override
public void deviceChanged(IDevice device, int changeMask) {
DeviceInfo deviceInfo = assemblerDeviceInfo(device);
if (null == deviceInfo) {
return;
}
DeviceManager.changeDevice(device.getSerialNumber());
if("ONLINE".equals(device.getState().name())){
DeviceManager.addDevice(device.getSerialNumber(), device);
}
this.iCustomDevice.run(deviceInfo, device.getState().toString());
}
@Override
public void deviceDisconnected(IDevice device) {
DeviceManager.removeDevice(device.getSerialNumber());
this.iCustomDevice.run(assemblerDeviceInfo(device), device.getState().toString());
}
/**
* 组装设备信息
*/
private DeviceInfo assemblerDeviceInfo(IDevice device) {
if (null == device) {
return null;
}
DeviceInfo deviceInfo = new DeviceInfo();
deviceInfo.setDeviceId(device.getSerialNumber());
deviceInfo.setDeviceName(device.getProperty("ro.product.model"));
deviceInfo.setWorkState(CommonState.IDLE);
if (null == device.getState()) {
return null;
}
switch (device.getState().toString()) {
case "ONLINE":
deviceInfo.setDeviceState(CommonState.DEVICE_ONLINE);
break;
case "AUTHORIZING":
//授权中
deviceInfo.setDeviceState(CommonState.DEVICE_AUTHORIZING);
break;
case "OFFLINE":
deviceInfo.setDeviceState(CommonState.DEVICE_OFFLINE);
break;
case "DISCONNECTED":
deviceInfo.setDeviceState(CommonState.DEVICE_DISCONNECTED);
break;
default:
break;
}
return deviceInfo;
}
}
2、AndroidDebugBridge的包装类
import com.android.ddmlib.AndroidDebugBridge;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
/**
* AndroidDebugBridge的包装类.
*
* @author xxx
*/
@Slf4j
public class AndroidDebugBridgeWrapper {
private AndroidDebugBridge androidDebugBridge;
public AndroidDebugBridgeWrapper() {
}
public void init(boolean clientSupport) {
AndroidDebugBridge.init(clientSupport);
//即使已经存在相同位置的桥梁,也将强制创建新桥梁。false
String adbPath = System.getenv("ADB_PATH");
if (null == adbPath || adbPath.trim().length() == 0) {
log.info("请在系统环境中配置ADB_PATH={Adb存放路径},不满足程序运行条件,将终止程序运行!");
System.exit(0);
}
androidDebugBridge = AndroidDebugBridge.createBridge(adbPath + File.separator + "adb", false);
}
/**
* 设备注册监听器
*
* @param listener
*/
public void addDeviceChangeListener(AndroidDebugBridge.IDeviceChangeListener listener) {
AndroidDebugBridge.addDeviceChangeListener(listener);
}
/**
* 移除监听器
*
* @param listener
*/
public void removeDeviceChangeListener(AndroidDebugBridge.IDeviceChangeListener listener) {
AndroidDebugBridge.removeDeviceChangeListener(listener);
}
/**
* 终止ddm库。必须在应用程序终止时调用它。
*/
public void terminate() {
AndroidDebugBridge.terminate();
}
/**
* 断开桥
*/
public void disconnectBridge() {
AndroidDebugBridge.disconnectBridge();
}
}
3、ICustomDevice自定义接口
import com.xuehai.tools.cwp2video.evolution.domain.bean.DeviceInfo;
public interface ICustomDevice {
/**
* 运行检测
*
* @param deviceInfo
* @param deviceState
*/
void run(DeviceInfo deviceInfo, String deviceState);
}
二、应用初始化之设备注册

/**
* 注册设备监控
*/
public void registerDeviceMonitor() {
DeviceManager deviceManager = DeviceManager.getInstance((deviceInfo, deviceState) -> {
switch (deviceState) {
case CommonState.DEVICE_ONLINE:
deviceOnline(deviceInfo);
break;
case CommonState.DEVICE_OFFLINE:
deviceOffline(deviceInfo);
break;
case CommonState.DEVICE_DISCONNECTED:
deviceDisconnected(deviceInfo);
break;
}
});
//启动设备监听
deviceManager.start();
}
这里主要详细记录下,设备上线的方法实现。
它主要是负责把设备信息保存到数据库里
/**
* 设备上线
*
* @param deviceInfo
*/
private void deviceOnline(DeviceInfo deviceInfo) {
if (DeviceManager.addRunDevice(deviceInfo)) {
initDevice(deviceInfo);
}
}
// 正在运行的设备
private static ConcurrentHashSet<DeviceInfo> deviceRunInfo = new ConcurrentHashSet<>();
/**
* 添加设备.
*
* @param runDevice
* @return
*/
public static boolean addRunDevice(DeviceInfo runDevice) {
//防止设备重复添加
AtomicBoolean exits = new AtomicBoolean(false);
DeviceManager.deviceRunInfo.forEach(deviceInfo -> {
if (deviceInfo.getDeviceId().equalsIgnoreCase(runDevice.getDeviceId())) {
exits.set(true);
}
});
if (!exits.get()) {
return DeviceManager.deviceRunInfo.add(runDevice);
}
return false;
}
/**
* 初始化设备
*
* @param deviceInfo
*/
private void initDevice(DeviceInfo deviceInfo) {
if (null == deviceInfo.getDeviceId() || deviceInfo.getDeviceId().trim().length() == 0) {
return;
}
//安装app
//判断设备是否存在播放器
if (!DeviceUtil.existCWPPlayer(deviceInfo.getDeviceId())) {
boolean flag = DeviceUtil.installApp(deviceInfo.getDeviceId(), FileUtils.getPlayerPath());
log.info("设备:{},安装Apk结果:{}", deviceInfo.getDeviceId(), flag);
}
//将设备没有亮屏的点亮屏幕且解锁
DeviceUtil.wakeDeviceAndUnlock(deviceInfo.getDeviceId());
//降低屏幕亮度
DeviceUtil.setScreenBrightness(deviceInfo.getDeviceId(), 0);
//获取设备对象
DeviceInfo device = deviceInfoRepository.getDeviceById(deviceInfo.getDeviceId());
if (null == device) {
// 设备的工作状态设置为空闲
deviceInfo.setWorkState(CommonState.IDLE);
//将设备信息更新到库
insertDeviceInfo(deviceInfo);
}
}
private boolean insertDeviceInfo(DeviceInfo deviceInfo) {
return deviceInfoRepository.insertDeviceInfo(deviceInfo);
}
三、设备实体

private String id;
/**
* 设备名称SM-P200
*/
private String deviceName;
/**
* 设备ID: pad的序列号-SerialNumber
*/
private String deviceId;
/**
* 设备状态:上线or下线
*/
private String deviceState;
/**
* 工作状态:工作中or空闲
*/
private String workState;
网友评论