Tuesday, December 2, 2008

Using the AndroidDebugBridge API to get screenshots

I needed a way to get periodic screenshots of the Android device connected to my computer through the USB port. DDMS has the ability to take screenshots on-demand, but not automatically. I dug through the DDMS source code to figure out how screenshots were taken, then a small utility in Java to do what I want. The code uses the AndroidDebugBridge API into the adb service. The jar that contains this API is ddmlib.jar, in the tools\lib directory of the Android SDK. The code is available here. It has a few limitations:
  • If there are more than one Android device connected (including emulators), it only gets screenshots from the first one we find. Ideally there would be a way to list devices and select which one we want to use.
  • Not at all configurable.
Here's what the program does: 1. Initialize the adb interface and get a handle to the bridge:
AndroidDebugBridge.init(false);
AndroidDebugBridge adb = AndroidDebugBridge.createBridge();
2. Set up a listener (an implementation of the IDeviceChangeListener interface) for device changes and add it:
Screenshot ss = new Screenshot();
AndroidDebugBridge.addDeviceChangeListener(ss);
3. Wait for a device to be connected
4. Get a list of connected devices:
Device[] devices = adb.getDevices();
5. In a loop, grab a raw image from the device, then save it as a PNG:
raw = device.getScreenshot();
PaletteData pal = new PaletteData(0xf800, 0x07e0, 0x001f);
ImageData image = new ImageData(raw.width, raw.height, raw.bpp, pal, 1, raw.data);

ImageLoader loader = new ImageLoader();
loader.data = new ImageData[] { image };
loader.save(filename, SWT.IMAGE_PNG);

And that's it. There's a lot more functionality in ddmlib.jar that could be useful for automating tasks like this.

3 comments:

xyz said...

Hi,
I tried running the program but i get the following error :
Exception in thread "main" org.eclipse.swt.SWTException: Unsupported or unrecognized format
at org.eclipse.swt.SWT.error(SWT.java:3374)
at org.eclipse.swt.SWT.error(SWT.java:3297)
at org.eclipse.swt.SWT.error(SWT.java:3268)
at org.eclipse.swt.internal.image.PNGFileFormat.unloadIntoByteStream(PNGFileFormat.java:146)
at org.eclipse.swt.internal.image.FileFormat.unloadIntoStream(FileFormat.java:122)
at org.eclipse.swt.internal.image.FileFormat.save(FileFormat.java:110)
at org.eclipse.swt.graphics.ImageLoader.save(ImageLoader.java:199)
at org.eclipse.swt.graphics.ImageLoader.save(ImageLoader.java:240)
at com.codetastrophe.android.screenshot.Screenshot.getScreenshots(Screenshot.java:98)
at com.codetastrophe.android.screenshot.Screenshot.main(Screenshot.java:44)

If I change SWT.IMG_PNG to SWT.IMG_JPEG, the program works fine. Could you suggest a solution?

r3 said...

Hi,

I am getting the following problem while trying to create bridge.

12-14 16:34:39.149: INFO/System.out(428): 04:39 E/DeviceMonitor: adb refused request: closed
12-14 16:34:39.220: INFO/System.out(428): 04:39 E/DeviceMonitor: Failed to read the adb response!

please help if anybody having any idea.

Regards,
r3

Nelson Glauber de Vasconcelos Leal said...

Thanks a lot man! You solved my problem. Best regards from Brazil.

I post your tip in my blog too.
http://nglauber.blogspot.com/2011/05/screenshot-no-android.html