Android toma una captura de pantalla programáticamente

En primer lugar, estoy escribiendo una aplicación raíz para que los permisos de root no sean un problema. He buscado y buscado y he encontrado un montón de código que nunca funcionó para mí. Es lo que he reconstruido hasta ahora y funciona. Cuando digo sorta me refiero a que hace una imagen en mi /sdcard/test.png, sin embargo, el archivo tiene 0 bytes y obviamente no se puede ver.

public class ScreenShot extends Activity{ View content; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.blank); content = findViewById(R.id.blankview); getScreen(); } private void getScreen(){ Bitmap bitmap = content.getDrawingCache(); File file = new File("/sdcard/test.png"); try { file.createNewFile(); FileOutputStream ostream = new FileOutputStream(file); bitmap.compress(CompressFormat.PNG, 100, ostream); ostream.close(); } catch (Exception e) { e.printStackTrace(); } } } 

Cualquier ayuda sobre cómo puedo tomar una captura de pantalla en Android a través del código sería muy apreciada gracias!

=== EDITAR ===

El siguiente es todo lo que estoy usando, la imagen está hecha en mi tarjeta SD y ya no es 0 bytes, pero todo es negro, no hay nada en él. He vinculado la actividad a mi botón de búsqueda, así que cuando estoy en algún lugar de mi teléfono, presiono durante mucho tiempo la búsqueda y se supone que debe tomar una captura de pantalla, pero acabo de obtener una imagen en negro. Todo está configurado de manera transparente, así que creo que debería tomar lo que sea que esté en la pantalla, pero sigo teniendo negro

Manifiesto

       

XML

    

Clase de captura de pantalla

 public class ScreenShot extends Activity{ View content; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.screenshot); content = findViewById(R.id.screenRoot); ViewTreeObserver vto = content.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { content.getViewTreeObserver().removeGlobalOnLayoutListener(this); getScreen(); } }); } private void getScreen(){ View view = content; View v = view.getRootView(); v.setDrawingCacheEnabled(true); Bitmap b = v.getDrawingCache(); String extr = Environment.getExternalStorageDirectory().toString(); File myPath = new File(extr, "test.jpg"); FileOutputStream fos = null; try { fos = new FileOutputStream(myPath); b.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); MediaStore.Images.Media.insertImage(getContentResolver(), b, "Screen", "screen"); }catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finish(); } } 

Aquí tienes … Usé esto:

 View v = view.getRootView(); v.setDrawingCacheEnabled(true); Bitmap b = v.getDrawingCache(); String extr = Environment.getExternalStorageDirectory().toString(); File myPath = new File(extr, getString(R.string.free_tiket)+".jpg"); FileOutputStream fos = null; try { fos = new FileOutputStream(myPath); b.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); MediaStore.Images.Media.insertImage( getContentResolver(), b, "Screen", "screen"); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } 

v iz diseño raíz … solo para señalar;)))

Para el próximo lector de esta pregunta-

La manera muy simple de hacer esto es dibujar su vista en canvas-

pase su referencia de diseño principal a este método-

  Bitmap file = save(layout); Bitmap save(View v) { Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); v.draw(c); return b; } 

Creo que tienes que esperar hasta que el diseño se dibuje por completo … Usa ViewTreeObserver para recuperar una llamada cuando el diseño se dibuja por completo …

En su onCreate, agregue este código. Solo llame a getScreen desde inside onGlobalLayout () ..

 ViewTreeObserver vto = content.getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { content.getViewTreeObserver().removeGlobalOnLayoutListener(this); getScreen(); } }); 

Una vez hice una pregunta un tanto similar … Por favor, vea mi pregunta que explica la manera de tomar una captura de pantalla en Android. Espero que esto ayude

 public class MainActivity extends Activity { Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Bitmap bitmap = takeScreenshot(); saveBitmap(bitmap); } }); } public Bitmap takeScreenshot() { View rootView = findViewById(android.R.id.content).getRootView(); rootView.setDrawingCacheEnabled(true); return rootView.getDrawingCache(); } public void saveBitmap(Bitmap bitmap) { File imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png"); FileOutputStream fos; try { fos = new FileOutputStream(imagePath); bitmap.compress(CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); } catch (FileNotFoundException e) { Log.e("GREC", e.getMessage(), e); } catch (IOException e) { Log.e("GREC", e.getMessage(), e); } } } 

¡no olvide dar permiso de escritura de almacenamiento externo!

Usted toma la captura de pantalla Como esto ……..

 View view = findViewById(R.id.rellayout); view.getRootView(); String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { File picDir = new File(Environment.getExternalStorageDirectory()+ "/name"); if (!picDir.exists()) { picDir.mkdir(); } view.setDrawingCacheEnabled(true); view.buildDrawingCache(true); Bitmap bitmap = view.getDrawingCache(); // Date date = new Date(); String fileName = "mylove" + ".jpg"; File picFile = new File(picDir + "/" + fileName); try { picFile.createNewFile(); FileOutputStream picOut = new FileOutputStream(picFile); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), (int)(bitmap.getHeight()/1.2));//Optional boolean saved = bitmap.compress(CompressFormat.JPEG, 100, picOut); if (saved) { Toast.makeText(getApplicationContext(), "Image saved to your device Pictures "+ "directory!", Toast.LENGTH_SHORT).show(); } else { //Error } picOut.close(); } catch (Exception e) { e.printStackTrace(); } view.destroyDrawingCache(); } else { } 

Mi problema era con “TargetApi (23)”, que es necesario si tu minSdkVersion está debajo de 23.

Entonces, solicito permiso con el siguiente fragmento

 protected boolean shouldAskPermissions() { return (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1); } @TargetApi(23) protected void askPermissions() { String[] permissions = { "android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE" }; int requestCode = 200; requestPermissions(permissions, requestCode); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // ... if (shouldAskPermissions()) { askPermissions(); } }