1

I know that one can take a screenshot from the Android device via ADB with

$ adb shell screencap -p /mnt/sdcard/sc.png
$ adb pull /mnt/sdcard/sc.png

However this writes a file on your phone and on your PC, which I want to avoid.

So I found the following SO question and the answer suggested that the image gets printed to the Std output when you do not specify a file. I tested this from console and it really printed binary data to the console.

Android: It there a way to read screenshot from memory without saving to internal/external storage?

Now I want to utilize this technique and start a process from java, execute the

adb shell screencap

command, read the output and create a BufferedImage from the output.

I tried something like this

ProcessBuilder pb = new ProcessBuilder("cmd"); 
Process start = pb.start();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(outputStream));
bw.write("adb shell screencap");
bw.newLine();
bw.flush();
// wait some time for the process to print the image to the console
start.waitFor(10, TimeUnit.SECONDS);
StringBuilder sb = new StringBuilder(9000000);
Scanner s = new Scanner(start.getInputStream());
while (s.hasNext()) {
      sb.append(s.next());
}
String result = sb.toString();

Unluckily there are quite a few issues with my Code.

  1. the program does not terminate after getting the screenshot - so start.waitFor does not quite work as I wanted it to work

  2. currently my code reads characters, where i actually want to read bytes

  3. reading with scanner seems kind of slow when reading millions of characters/bytes

Maybe someone can point me in a direction such that I can get it to work. Thanks!

2
  • Why are you using java to invoke adb? Commented Jul 16, 2017 at 21:29
  • Cause I have a java programm which will then process that image further Commented Jul 20, 2017 at 8:49

3 Answers 3

5

Why complicating things. If you are invoking adb and want its output just run

adb exec-out screencap -p > myimg.png

exec-out is used instead of shell to get raw data (i.e. the image).

2
  • There are quite a few problems with the OP's question but the general intention of running adb command from a java program and capturing its output without having to save it to a file is absolutely fine. If you do not agree with the premise - that discussion belongs to the comments section.
    – Alex P.
    Commented Jul 16, 2017 at 21:49
  • thank you for your answer! I tried the exec-out command and got it working correctly. However performance was not as good as i expected (~1FPS). So I searched further and found a library which i can use, such that I don´t have to write everything manually Commented Jul 20, 2017 at 8:51
0

After searching some more time I came across ddmlib which already has the functionality to take screenshots and perform various other tasks via ADB built in.
The library works great and definitely made it easier for me to execute commands via ADB.

0
private static byte[] captureScreen() throws IOException {
    ByteArrayBuffer bab = new ByteArrayBuffer();
    Process process = Runtime.getRuntime()
                             .exec("/path_to_adb/adb exec-out screencap -p");
    bab.write(process.getInputStream());
    return bab.getRawData();
}
1
  • Learn to use markdown to format your posts.
    – Abra
    Commented Apr 21, 2024 at 9:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.