Android – 如何以编程方式截图
我需要安装Android设备或模拟器的屏幕截图,当我的应用程序每隔200毫秒安装并在后台运行,并将图像保存在我的电脑中。 我已经使用下面的代码实现了这个过程,只有当我的应用程序在前台时才起作用。 当我的应用程序在后台时,我也想截图。 以下是我的代码:
public static Bitmap takeScreenshot(Activity activity, int ResourceID) { Random r = new Random(); int iterator=r.nextInt(); String mPath = Environment.getExternalStorageDirectory().toString() + "/screenshots/"; View v1 = activity.getWindow().getDecorView().findViewById(ResourceID); v1.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); v1.layout(0, 0, v1.getMeasuredWidth(), v1.getMeasuredHeight()); v1.setDrawingCacheEnabled(true); final Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache()); Bitmap resultBitmap = Bitmap.createScaledBitmap(bitmap, 640, 480, false); v1.setDrawingCacheEnabled(false); File imageFile = new File(mPath); imageFile.mkdirs(); imageFile = new File(imageFile+"/"+iterator+"_screenshot.png"); try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); resultBitmap.compress(CompressFormat.PNG, 100, bos); byte[] bitmapdata = bos.toByteArray(); //write the bytes in file FileOutputStream fos = new FileOutputStream(imageFile); fos.write(bitmapdata); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return bitmap; }
我怎样才能实现Screencapture的刷新和保存button在Devices -> DDMS
编程的function? 我能做到吗?
如果你的手机是根植的尝试这个
Process sh = Runtime.getRuntime().exec("su", null,null); OutputStream os = sh.getOutputStream(); os.write(("/system/bin/screencap -p " + "/sdcard/img.png").getBytes("ASCII")); os.flush(); os.close(); sh.waitFor();
然后读取img.png作为位图,并将其转换为jpg,如下所示
Bitmap screen = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+ File.separator +"img.png"); //my code for saving ByteArrayOutputStream bytes = new ByteArrayOutputStream(); screen.compress(Bitmap.CompressFormat.JPEG, 15, bytes); //you can create a new file name "test.jpg" in sdcard folder. File f = new File(Environment.getExternalStorageDirectory()+ File.separator + "test.jpg"); f.createNewFile(); //write the bytes in file FileOutputStream fo = new FileOutputStream(f); fo.write(bytes.toByteArray()); // remember close de FileOutput fo.close();
如果您的应用程序处于后台,您将无法访问屏幕,除非您身在其中,否则即使您处于后台,上面的代码也可以在任何屏幕上最有效地使用屏幕截图。
UPDATE
谷歌有一个图书馆,你可以采取截图没有生根,我试过,但我相信它会尽快吃掉内存。
这是做到这一点的方法。
Android通过代码拍摄屏幕截图
结果输出:
public class CaptureScreenShots extends Activity { LinearLayout L1; ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.screen_shots); L1 = (LinearLayout) findViewById(R.id.LinearLayout01); Button but = (Button) findViewById(R.id.munchscreen); but.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { View v1 = L1.getRootView(); v1.setDrawingCacheEnabled(true); Bitmap bm = v1.getDrawingCache(); BitmapDrawable bitmapDrawable = new BitmapDrawable(bm); image = (ImageView) findViewById(R.id.screenshots); image.setBackgroundDrawable(bitmapDrawable); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.screen_shots, menu); return true; } }
在背景中拍摄屏幕截图(如ADB)需要groups = 1003(graphics) 。 否则,你只能得到你自己的过程的屏幕截图。 所以你只能在一个根设备上做,或者通过运行ADB本地程序来完成。
本地CPP代码示例可以在https://android.googlesource.com/platform/frameworks/base/+/android-4.3_r2.3/cmds/screencap/
如果你想在java代码中做到这一点,你需要访问Surface类的隐藏API:
/** * Like {@link #screenshot(int, int, int, int)} but includes all * Surfaces in the screenshot. * * @hide */ public static native Bitmap screenshot(int width, int height);
这两个应该都可以,因为ICS发布后,像GB这样的早期版本,你可以检查出本地的cpp代码。
但是,在某些Android设备上,媒体系统和canvas等的实现并不是很好,因此在这种情况下,您不能捕获任何video回放或任何表面视图内容。
private void takeScreenshot() throws IOException { Date now = new Date(); android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now); String fileName = now + ".jpg"; try { File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + ""); folder.mkdirs(); //create directory // create bitmap screen capture View v1 = getWindow().getDecorView().getRootView(); v1.setDrawingCacheEnabled(true); Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache()); v1.setDrawingCacheEnabled(false); File imageFile = new File(folder, fileName); imageFile.createNewFile(); FileOutputStream outputStream = new FileOutputStream(imageFile); int quality = 100; bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream); outputStream.flush(); outputStream.close(); Toast.makeText(MainActivity.this, "ScreenShot Captured", Toast.LENGTH_SHORT).show(); MediaScannerConnection.scanFile(this, new String[]{imageFile.toString()}, null, new MediaScannerConnection.OnScanCompletedListener() { public void onScanCompleted(String path, Uri uri) { Log.i("ExternalStorage", "Scanned " + path + ":"); Log.i("ExternalStorage", "-> uri=" + uri); } }); } catch (Throwable e) { // Several error may come out with file handling or OOM e.printStackTrace(); } }
将此方法添加到button单击事件或选项菜单项选定事件中,屏幕快照将存储在下载文件夹中,因为在folder
variables中我已经提供了下载path,您可以更改文件夹path。在清单文件中添加写入权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />