package com.github.dee1024.wechatgame.tools; /** * @Description * @Author Dee1024 <[email protected]> * @Version 1.0 * @Since 1.0 * @Date 2018/1/3 */ import javax.imageio.ImageIO; import javax.swing.*; import java.awt.image.BufferedImage; import java.io.*; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * 封装ADB功能,通过执行ADB命令行实现 * 需要先下载 Android Debug Bridge 到本地,参考地址:https://developer.android.com/studio/command-line/adb.html#forwardports * */ public abstract class AdbToolKit { //请使用本地的ABD工具路径替换,该值需要在启动时,按照引导配置 static String adbPath = "/Users/root/Downloads/platform-tools/adb"; final static String SCRIPT_SCREEN_CAP_METHOD1 = "${adbpath} exec-out screencap -p > ${imagename}"; final static String SCRIPT_SCREEN_CAP_METHOD2_1 = "${adbpath} shell screencap -p /sdcard/${imagename}"; final static String SCRIPT_SCREEN_CAP_METHOD2_2 = "${adbpath} pull /sdcard/${imagename} > ."; final static String SCRIPT_SCREEN_TOUCH = "${adbpath} shell input swipe ${x1} ${y1} ${x2} ${y2} ${time}"; final static String SCRIPT_DEVICES = "${adbpath} devices"; static boolean isSetting = false; public static boolean init(){ LogToolKit.println("正在启动应用, 请稍等..."); if(!isADBToolOk()){ LogToolKit.println("应用启动失败."); return false; } screencap(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } screencap(); LogToolKit.println("应用启动成功."); return true; } private static String[] genBaseSysParams(){ String[] args = new String[3]; String os = System.getProperty("os.name"); if (os.toLowerCase().trim().startsWith("win")) { //LogToolKit.println("系统检测 win."); args[0] = "cmd.exe"; args[1] = "/c"; }else{ //LogToolKit.println("系统检测 Linux / Mac os."); args[0] = "bash"; args[1] = "-c"; } return args; } /** * ADB手机屏幕截图 */ private static boolean isSettingScreencapMethod = false; private static int screencapMethod = 0; public static BufferedImage screencap() { String[] args = genBaseSysParams(); try { if(!isSettingScreencapMethod){ LogToolKit.println("尝试使用方式一获取屏幕信息。"); args[2] = SCRIPT_SCREEN_CAP_METHOD1.replace("${adbpath}", adbPath).replace("${imagename}", SettingToolkit.getScreencapFilePathName()); Runtime.getRuntime().exec(args).waitFor(); if(isImageOk()){ screencapMethod = 1; isSettingScreencapMethod = true; LogToolKit.println("成功设置方式一。"); }else{ LogToolKit.println("警告:方式一获取屏幕信息失败。"); LogToolKit.println("尝试使用方式二获取屏幕信息。"); String imageName = "jumpgame.png"; String command = SCRIPT_SCREEN_CAP_METHOD2_1.replace("${adbpath}", adbPath).replace("${imagename}", imageName); Runtime.getRuntime().exec(command).waitFor(); command = SCRIPT_SCREEN_CAP_METHOD2_2.replace("${adbpath}", adbPath).replace("${imagename}", imageName); Runtime.getRuntime().exec(command).waitFor(); if(isImageOk()){ screencapMethod = 2; isSettingScreencapMethod = true; LogToolKit.println("成功设置方式二。"); }else{ LogToolKit.println("警告:方式二获取屏幕信息失败。"); } } }else{ if(screencapMethod==2){ String imageName = "jumpgame.png"; String command = SCRIPT_SCREEN_CAP_METHOD2_1.replace("${adbpath}", adbPath).replace("${imagename}", imageName); Runtime.getRuntime().exec(command).waitFor(); command = SCRIPT_SCREEN_CAP_METHOD2_2.replace("${adbpath}", adbPath).replace("${imagename}", imageName); Runtime.getRuntime().exec(command).waitFor(); }else{ args[2] = SCRIPT_SCREEN_CAP_METHOD1.replace("${adbpath}", adbPath).replace("${imagename}", SettingToolkit.getScreencapFilePathName()); Runtime.getRuntime().exec(args).waitFor(); } } } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } File rFile = new File(SettingToolkit.getScreencapFilePathName()); BufferedImage bufferedImage = null; if(rFile.exists()) { try { bufferedImage = ImageIO.read(rFile); } catch (IOException e) { e.printStackTrace(); } } return bufferedImage; } /** * ADB手机屏幕长按,长按时间 * @param time 长按时间,精确到毫秒 * Andorid 版本需要高于 4.4 */ public static void screentouch(double time) { String times = (int)time + ""; String x1 = ((new Random()).nextInt(100) + (new Random()).nextInt(100) + 1) + ""; String y1 = ((new Random()).nextInt(100) + (new Random()).nextInt(100) + 1) + ""; String x2 = ((new Random()).nextInt(100) + (new Random()).nextInt(100) + 1) + ""; String y2 = ((new Random()).nextInt(100) + (new Random()).nextInt(100) + 1) + ""; String args = SCRIPT_SCREEN_TOUCH.replace("${adbpath}", adbPath).replace("${time}", times) .replace("${x1}", x1).replace("${y1}", y1).replace("${x2}", x2).replace("${y2}", y2); try { Runtime.getRuntime().exec(args).waitFor(); LogToolKit.println("长按"+time+"毫秒"); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } /** * 检测ADB工具以及 Android 设备 * * 返回值说明: * 1:成功; * -1:ADB工具找不到; * -2:设备连接异常 * * @param path * @return */ public static int checkAdbAndDevice(String path){ if(path==null || "".equals(path)){ LogToolKit.println("ADB工具路径未设置."); return -1; } String[] args = genBaseSysParams(); args[2] =SCRIPT_DEVICES.replace("${adbpath}", path); int stauts = 0; try { Process process = Runtime.getRuntime().exec(args); InputStream is = process.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); String line; List<String> lineList = new ArrayList<String>(); LogToolKit.println("check result:"); while ((line = reader.readLine()) != null) { lineList.add(line); LogToolKit.println(line); } if(!lineList.isEmpty()) { if (lineList.get(0).indexOf("List of devices attached") > -1) { if (lineList.size() > 1 && lineList.get(1).length() > 0) { stauts = 1; LogToolKit.println("ADB检测 和 Android设备检测正常."); } else { stauts = -2; LogToolKit.println("设备检测异常,请确认是否连接正常."); } } else { stauts = -1; LogToolKit.println("ADB工具检测异常,未找到."); } }else{ stauts = -1; LogToolKit.println("ADB工具检测异常,未找到."); } process.waitFor(); is.close(); reader.close(); process.destroy(); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } return stauts; } private static boolean isImageOk() throws IOException { BufferedImage image = ImageIO.read(new File(SettingToolkit.getScreencapFilePathName())); if (image == null) { return false; }else{ return true; } } public static boolean isADBToolOk(){ String tempADBPath = SettingToolkit.getADBPath(); int checkR = AdbToolKit.checkAdbAndDevice(tempADBPath); if(checkR==1) { setAdbPath(tempADBPath); LogToolKit.println("ADB工具地址设置成功:" + adbPath); return true; }else if(checkR == -1){ if(isSetting) { JOptionPane.showMessageDialog(null, "未找到ADB工具,请重新配置ADB工具地址!", "提示", JOptionPane.ERROR_MESSAGE); } isSetting = true; Object adbpathObject = JOptionPane.showInputDialog(null,"请输入ADB工具地址:\n","系统参数设置",JOptionPane.PLAIN_MESSAGE,null,null,"例如:/Users/dee/Downloads/platform-tools/adb"); if(adbpathObject!=null){ tempADBPath = adbpathObject.toString(); SettingToolkit.setADBPath(tempADBPath); isADBToolOk(); return true; }else{ System.exit(0); } }else if(checkR == -2){ JOptionPane.showMessageDialog(null, "未找接入的 Android 设备,请检测设备连接情况,确认后再点击确认!", "提示",JOptionPane.ERROR_MESSAGE); isADBToolOk(); return true; } SettingToolkit.setADBPath(tempADBPath); setAdbPath(tempADBPath); LogToolKit.println("ADB工具地址设置成功:" + adbPath); return true; } //获取手机屏幕大小 adb shell wm size //查看机型 adb shell getprop ro.product.model public static void setAdbPath(String adbPath) { AdbToolKit.adbPath = adbPath; } public static void main(String[] args) throws IOException { System.out.println(isImageOk());; } }