核心目标
- 什么是ddmlib?
- 如何实现Android设备连接监听?
- 如何实现Android设备管理?
解答1:
ddmlib是Google提供的基于Java的adb封装库,包含了很多实用的设备操作方法。
解答2:
主要有以下几个步骤
- 实现AndroiDebugBridge的IDeviceChangeListener接口,并定义设备连接和断开时的操作内容
- 设置监听器,并初始化AndroidDebugBridge
- 测试监听效果
/**
* 实现IDeviceChangeListener接口,其中包含deviceConnected和deviceDisconnected
* deviceChanged方法在实践中测试可以不用写业务逻辑。
**/
@Component
@Slf4j
public class AndroidDeviceStatusListener implements AndroidDebugBridge.IDeviceChangeListener {
@Override
public void deviceConnected(IDevice device) {
log.info("Device: " + device.getSerialNumber() + " is online......");
}
@Override
public void deviceDisconnected(IDevice device) {
log.info("Device: " + device.getSerialNumber() + " is offline......");
}
@Override
public void deviceChanged(IDevice device, int changeMask) {
// log.info("Device: " + device.getSerialNumber() + " state changed: " + device.getState().toString());
}
}
/**
* 结合Springboot特性,实现了ApplicationListener的接口,会在Bean初始化时调用onApplicationEvent
* 的方法,实现自动配置
* 注意,不要一上来就直接调用getDevices()的方法,那样大概率会拿到一个空的设备列表,推荐的做法是自己
* 在监听器里面设备上线时自身维护一个deviceMap,或者循环等待下hasInitialDeviceList这个方法
**/
@Component
@Slf4j
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class AndroidDeviceBridgeTool implements ApplicationListener<ContextRefreshedEvent> {
@Resource
private AndroidDeviceStatusListener androidDeviceStatusListener;
private ConfigurableApplicationContext context;
public static AndroidDebugBridge androidDebugBridge = null;
@Autowired
public void setContext(ConfigurableApplicationContext context){
this.context = context;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
String adbPath = getADBPath();
if (!StringUtils.hasLength(adbPath)){
log.info("no adb env found......");
context.close();
System.exit(0);
}
AndroidDebugBridge.addDeviceChangeListener(androidDeviceStatusListener);
try{
AndroidDebugBridge.init(false);
androidDebugBridge = AndroidDebugBridge.createBridge(adbPath, true, Long.MAX_VALUE, TimeUnit.MICROSECONDS);
if (androidDebugBridge != null){
log.info("Android device is listening........");
}
}catch (Exception e){
log.error("ADB Service 启动异常");
context.close();
System.exit(0);
}
if (androidDebugBridge != null){
int count = 0;
while (!androidDebugBridge.hasInitialDeviceList()){
try{
Thread.sleep(500);
}catch (Exception e){
log.error("Thread sleep exception: " + e.getMessage());
}
if (count > 100){
break;
}
++count;
}
log.info("count is " + count);
if (count > 100){
// 说明未初始化设备列表,可能是因为故障原因
log.info("adb initialize failed, exit......");
context.close();
System.exit(0);
}
}
}
private static String getADBPath(){
String path = System.getenv("ANDROID_HOME");
if (StringUtils.hasLength(path)){
path += File.separator + "platform-tools" + File.separator + "adb";
if (System.getProperty("os.name").toLowerCase().contains("win")){
path += ".exe";
}
return path;
}
return null;
}
}
这里要注意一个细节,就是上面这个while中对于hasInitialDeviceList的判断,因为adb初始化需要一定的时间。如果在androidDebugBridge初始化完成后,就立马调用deviceList获取设备列表的方法,那有可能会返回empty list,因此需要进行等待,如果等待超出了设定的范围还是没有获取到列表信息,那就直接退出系统。
解答3
当设备上下线可以被捕获后,设备管理就变得很简单了,无论是数据库同步还是页面展示,只需要取出对应支持的设备serialNumber即可。