package com.suwish.device.util;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.android.ddmlib.AdbCommandRejectedException;
import com.android.ddmlib.FileListingService;
import com.android.ddmlib.FileListingService.FileEntry;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.RawImage;
import com.android.ddmlib.ShellCommandUnresponsiveException;
import com.android.ddmlib.SyncService;
import com.android.ddmlib.SyncService.SyncResult;
import com.android.ddmlib.TimeoutException;
import com.suwish.device.SyncProgressMonitorAdapter;
import com.suwish.pc.ui.util.DeviceHelper;
import com.suwish.pc.ui.util.UIHelper;
import com.suwish.pc.util.StringUtils;
/**
*
*
* 设备工具类,直接对设备的操作方法,其实局势一种封装。</p>
*
* 此类的方法与UI无关,也可以说无需考虑为UI调用带来便利。对于UI的调用原则
* 可参见设备帮助类的解释{@link DeviceHelper}
* </p>
*
*
* 新版DDMLIB存在文件锁定的问题,现在直接使用源代码,并修改一些设计上的问题。
* 目前的DDMS库即ddmlib过于粗糙,对外部调用和回调过于简单,下个版本需要大量改造才可以,
* 如果知道了ADB的socket通信的数据包协议,将会尽可能少的减少对adb命令的依赖。
* @author Min
*
*/
public final class DeviceUtils {
private DeviceUtils() {}
/**
*
* @param device
* @param landscape
* @return
* @throws TimeoutException
* @throws AdbCommandRejectedException
* @throws IOException
*/
public static BufferedImage parseScreenshot(IDevice device, boolean landscape)
throws TimeoutException, AdbCommandRejectedException, IOException{
return parseScreenshot(device.getScreenshot(), landscape);
}
/**
*
* @param rawImage
* @param landscape
* @return
*/
public static BufferedImage parseScreenshot(RawImage rawImage, boolean landscape){
int width2 = landscape ? rawImage.height : rawImage.width;
int height2 = landscape ? rawImage.width : rawImage.height;
BufferedImage image = new BufferedImage(width2, height2, BufferedImage.TYPE_INT_RGB);
if (image.getHeight() != height2 || image.getWidth() != width2) {
image = new BufferedImage(width2, height2, BufferedImage.TYPE_INT_RGB);
}
int index = 0;
int indexInc = rawImage.bpp >> 3;
for (int y = 0; y < rawImage.height; y++) {
for (int x = 0; x < rawImage.width; x++, index += indexInc) {
int value = rawImage.getARGB(index);
if (landscape)
image.setRGB(y, rawImage.width - x - 1, value);
else
image.setRGB(x, y, value);
}
}
return image;
}
/**
*
* 返回设备的描述信息,主要的目的是返回尽量详细的描述信息,便于在界面上区分设备。
*
* @param device
* @return
*/
public static String getDeviceInfo4List(IDevice device){
return device.isEmulator() ? (device.getSerialNumber() + " " + device.getState().toString()) :
(device.getProperty(Platform.PROP_OR_PRODUCT_MANUFACTURE) + " " + device.getProperty(Platform.PROP_OR_PRODUCT_MODEL)
+ " " + device.getState().toString() + " (" + device.getSerialNumber() + ")");
}
/**
*
* @param device
* @param path
* @param fileName
* @throws TimeoutException
* @throws AdbCommandRejectedException
* @throws IOException
*/
public static void saveScreenshot(IDevice device, String path, String fileName)
throws TimeoutException, AdbCommandRejectedException, IOException{
BufferedImage image = parseScreenshot(device, false);
ImageIO.write(image, "png", new File(path, fileName));
}
/**
*
* @param device
* @param file
* @throws TimeoutException
* @throws AdbCommandRejectedException
* @throws IOException
*/
public static void saveScreenshot(IDevice device, File file)
throws TimeoutException, AdbCommandRejectedException, IOException{
BufferedImage image = parseScreenshot(device, false);
ImageIO.write(image, "png", file);
}
/**
*
* 将本地文件上传到设备的制定路径</p>
*
* 新版本的库参数改动好多啊233
*
* @param device
* @param localFrom
* @param remoteTo
* @throws IOException
* @throws AdbCommandRejectedException
* @throws TimeoutException
* @throws SyncException
*/
public static void pushFile(IDevice device, final String[] localFrom, final FileEntry remoteTo)
throws TimeoutException, AdbCommandRejectedException, IOException{
SyncService server = device.getSyncService();
SyncResult result = server.push(localFrom, remoteTo, SyncService.getNullProgressMonitor());
UIHelper.showMessageDialog(result.getMessage());
// new SyncProgressMonitorAdapter(){
// @Override
// public void stop() {
// UIHelper.showMessageDialog("upload " + localFrom[0] + " to " + remoteTo.getFullPath() + " stop");
//
// }
// });
}
/**
*
* 上传文件到设备目录
*
* @param device
* @param localFrom
* @param remoteTo
* @throws TimeoutException
* @throws AdbCommandRejectedException
* @throws IOException
* @throws SyncException
*/
public static void pushFile(IDevice device, final String localFrom, final String remoteTo)
throws TimeoutException, AdbCommandRejectedException, IOException{
SyncService server = device.getSyncService();
server.pushFile(localFrom, remoteTo, new SyncProgressMonitorAdapter(){
@Override
public void stop() {
UIHelper.showMessageDialog("upload " + localFrom + " to " + remoteTo + " stop");
}
});
}
/**
* 从设备拉取文件到本地
*
* @param device
* @param remoteFrom
* @param localTo
*/
public static void pullFile(IDevice device, final FileEntry remoteFrom, final String localTo)
throws TimeoutException, AdbCommandRejectedException, IOException{
SyncService server = device.getSyncService();
SyncResult result = server.pullFile(remoteFrom, localTo, SyncService.getNullProgressMonitor());
UIHelper.showMessageDialog(result.getMessage());
// new SyncProgressMonitorAdapter(){
// @Override
// public void stop() {
// UIHelper.showMessageDialog("download " + remoteFrom.getName() + " to " + localTo + " stop");
//// server.
// }
// });
}
/**
*
* @param device
* @param remoteFrom
* @param localTo
* @throws TimeoutException
* @throws AdbCommandRejectedException
* @throws IOException
* @throws SyncException
*/
public static void pullFile(IDevice device, FileEntry[] remoteFrom, String localTo)
throws TimeoutException, AdbCommandRejectedException, IOException{
SyncService server = device.getSyncService();
server.pull(remoteFrom, localTo, new SyncProgressMonitorAdapter(){
@Override
public void stop() {
// UIHelper.showMessageDialog(parent, message, title, messageType);
}
});
}
/**
*
* @param device
* @param entry
* @return
* @throws TimeoutException
* @throws AdbCommandRejectedException
* @throws ShellCommandUnresponsiveException
* @throws IOException
*/
public static FileEntry[] getChildrenEntry(IDevice device, FileEntry entry)
throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException{
FileListingService server = device.getFileListingService();
return server.getChildren(entry, false, null);
}
/**
*
* @param device
* @return
*/
public static FileEntry getRootEntry(IDevice device){
return device.getFileListingService().getRoot();
}
/**
* 看ddmib的源码是push到temp,然后远程安装,远程安装使用远程命令的方式,而远程命令有回调。
*
*
*
* @param device
* @param filePath
* @param reinstall
* @throws InstallException
*
* @version 1.0 由于此方法无法获得进度,将在下个版本被替换。
* @throws IOException
* @throws ShellCommandUnresponsiveException
* @throws AdbCommandRejectedException
* @throws TimeoutException
*
*/
public static void installAPK(IDevice device, String filePath, boolean reinstall)
throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException{
String result = device.installPackage(filePath, reinstall);
UIHelper.showMessageDialog(StringUtils.isEmpty(result) ? "install Success!" : result);
}
/**
*
*
* @param device
* @param packageName
* @throws InstallException
*
* @version 1.0 由于此方法无法获得进度,将在下个版本被替换。
* @throws IOException
* @throws ShellCommandUnresponsiveException
* @throws AdbCommandRejectedException
* @throws TimeoutException
*/
public static void uninstallAPK(IDevice device, String packageName)
throws TimeoutException, AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException{
String result = device.uninstallPackage(packageName);
UIHelper.showMessageDialog(StringUtils.isEmpty(result) ? "uninstall Success!" : result);
}
}