Android: cómo tomar una captura de pantalla mediante progtwigción

Necesito capturas de pantalla de dispositivos Android o emuladores programáticamente cuando mi aplicación está instalada y ejecutándose en segundo plano por cada 200 milisegundos y guardo las imágenes en mi computadora. Implementé este procedimiento usando el código a continuación y solo funciona cuando mi aplicación está en primer plano. También quiero tomar capturas de pantalla cuando mi aplicación esté en segundo plano. A continuación está mi código:

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; } 

¿Cómo puedo implementar la funcionalidad de Actualizar y Guardar botones de Captura de pantalla en Devices -> DDMS programáticamente? ¿Puedo lograr eso?

Si su teléfono está rooteado, intente esto

 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(); 

luego lea img.png como bitmap y conviértalo en jpg de la siguiente manera

 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(); 

no tiene acceso a la pantalla si su aplicación está en segundo plano a menos que esté rooteado, el código anterior puede tomar la captura de pantalla más eficazmente de cualquier pantalla, incluso si está en segundo plano.

ACTUALIZAR

Google tiene una biblioteca con la que puede tomar una captura de pantalla sin enrutar, lo intenté, pero estoy seguro de que se comerá la memoria lo antes posible.

Prueba http://code.google.com/p/android-screenshot-library/

Aquí está la manera de hacerlo.

Android tomando capturas de pantalla a través del código

Resultado de salida:

enter image description here

enter image description here

 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; } } 

Tomar capturas de pantalla en segundo plano (como ADB) requiere grupos = 1003 (gráficos) . De lo contrario, solo puede obtener la captura de pantalla de su propio proceso. Por lo tanto, solo puede hacerlo en un dispositivo rooteado o hacerlo ejecutando el progtwig nativo de ADB.

Se puede encontrar un ejemplo de código cpp nativo en https://android.googlesource.com/platform/frameworks/base/+/android-4.3_r2.3/cmds/screencap/

Y si quieres hacerlo en código java, necesitas acceder a la API oculta de la clase Surface:

 /** * Like {@link #screenshot(int, int, int, int)} but includes all * Surfaces in the screenshot. * * @hide */ public static native Bitmap screenshot(int width, int height); 

Estos dos deberían estar bien desde el lanzamiento de ICS, para una versión temprana como GB, puedes ver el código nativo de cpp.

Sin embargo, en algunos dispositivos Android, la implementación del sistema de medios y el canvas, etc. no es muy buena, por lo tanto, no puede capturar ninguna reproducción de video ni contenido de vista de superficie en este caso.

 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(); } } 

Agregue este método al evento de clic de botón o en el evento de elemento de menú de opción, y la captura de pantalla se almacenará en la carpeta de descarga porque en la variable de folder proporcioné la ruta de descarga, puede cambiar la ruta de la carpeta. En el archivo de manifiesto, agregue permiso para escribir