2015-04-01 62 views
2

我有一个根应用程序应该在执行期间的某个点捕获屏幕。为了做到这一点,我与Android外壳交互使用下面的代码:确保从InputStream读取正确的数据

private static Process su = Runtime.getRuntime().exec("su"); 
private static DataOutputStream outputStream = new DataOutputStream(su.getOutputStream()); 
private static DataInputStream inputStream = new DataInputStream(su.getInputStream()); 

private void CaptureScreen() { 
    outputStream.writeBytes("/system/bin/screencap -p\n"); 
    outputStream.flush(); 
    Bitmap bitmap = BitmapFactory.decodeStream(inputStream); 
    //outputStream.writeBytes("echo test\n"); 
    //outputStream.flush(); 
} 

它正常工作,甚至当我把它称为多次,但此刻我发出产生之间的外壳输出的虚拟指令CaptureScreen调用,BitmapFactory.decodeStream失败。考虑到这一点,我有几个问题:

  • 我想这是因为InputStream中内的数据是没有 不再是单纯的与图像数据有关。由于运行时间是单个 实例(如here),我再次假设其他 进程也可以在我的InputStream中的 实时系统中引入它们的输出。我如何确保只从 InputStream获取我需要的数据?
  • 为什么CaptureScreen在被多次调用时工作正常?如何 BitmapFactory.decodeStream管理从 InputStream获取最后一张图片?成功后是否“消耗”相关数据? 它是否从InputStream搜索最后的图像数据?如果是这样,为什么当 InputStream中的图像数据之前存在不相关的数据时,它会失败 ?

我知道我可以通过将图像写入文件然后从那里读取来解决此问题,但是我希望避免I/O操作而改用性能。

回答

1

这个玩弄了一段时间后,我找到了答案,以我自己的问题:

  • 虽然运行时是单实例,执行代码,就可以开始在自己的一个新的进程。与此进程相关的输入和输出流只能由此进程写入/读取(除非另一进程专门将其流重定向到此进程,这在我的情况中极不可能)。
  • 输入流的内容在读取时确实“消耗殆尽”,因此多次调用此函数全部写入/读取图像数据。使用与图像无关的数据“污染”进程的输入流会破坏decodeStream的功能。

另请注意,“su”不是结束的命令。直到被调用才会终止。下面是修改后的类我在我的代码中使用:

public class BitmapScreencap { 
    public final static BitmapScreencap Get = new BitmapScreencap(); 
    private BitmapScreencap() { } 
    public Bitmap Screen() { 
     try { 
      Process process = Runtime.getRuntime().exec("su"); 
      OutputStreamWriter outputStream = new OutputStreamWriter(process.getOutputStream()); 
      outputStream.write("/system/bin/screencap -p\n"); 
      outputStream.flush(); 
      Bitmap screen = BitmapFactory.decodeStream(process.getInputStream()); 
      outputStream.write("exit\n"); 
      outputStream.flush(); 
      outputStream.close(); 
      return screen; 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 

而且它可以从任何地方你的项目中被称为:

BitmapScreencap.Get.Screen(); 
0

如何确保只从InputStream获取所需的数据?

至少你可以检查为什么CaptureScreen正常工作时,多次调用过程

的exitValue?

它只是读取流,直到读取结果为-1。当您发送“/ system/bin/screencap -p \ n”进行处理时,InputStream会再次开始返回新数据。