una puedo porque pantalla hacer fisicos dedos con como celular capturar captura botones android screenshot

android - puedo - como hacer una captura de pantalla en el celular



¿Cómo realizar una captura de pantalla mediante programación? (23)

Aquí está el código que permitió que mi captura de pantalla se almacenara en una tarjeta SD y se usara más adelante para lo que sea que necesite:

Primero, debe agregar un permiso adecuado para guardar el archivo:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Y este es el código (que se ejecuta en una actividad):

private void takeScreenshot() { Date now = new Date(); android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now); try { // image naming and path to include sd card appending name you choose for file String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg"; // 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(mPath); FileOutputStream outputStream = new FileOutputStream(imageFile); int quality = 100; bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream); outputStream.flush(); outputStream.close(); openScreenshot(imageFile); } catch (Throwable e) { // Several error may come out with file handling or DOM e.printStackTrace(); } }

Y así es como puedes abrir la imagen generada recientemente:

private void openScreenshot(File imageFile) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); Uri uri = Uri.fromFile(imageFile); intent.setDataAndType(uri, "image/*"); startActivity(intent); }

Si desea usar esto en la vista de fragmentos, use:

View v1 = getActivity().getWindow().getDecorView().getRootView();

en lugar de

View v1 = getWindow().getDecorView().getRootView();

en la función takeScreenshot ()

Nota :

Esta solución no funciona si su diálogo contiene una vista de superficie. Para más detalles, verifique la respuesta a la siguiente pregunta:

Captura de pantalla de Android Take de Surface View muestra la pantalla en negro

¿Cómo puedo tomar una captura de pantalla de un área seleccionada de la pantalla del teléfono, no por ningún programa sino por código?


Basándonos en la respuesta de @JustinMorris arriba y @NiravDangi aquí https://.com/a/8504958/2232148 debemos tomar el fondo y el primer plano de una vista y ensamblarlos de esta manera:

public static Bitmap takeScreenshot(View view, Bitmap.Config quality) { Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), quality); Canvas canvas = new Canvas(bitmap); Drawable backgroundDrawable = view.getBackground(); if (backgroundDrawable != null) { backgroundDrawable.draw(canvas); } else { canvas.drawColor(Color.WHITE); } view.draw(canvas); return bitmap; }

El parámetro de calidad toma una constante de Bitmap.Config, normalmente Bitmap.Config.RGB_565 o Bitmap.Config.ARGB_8888 .


Camino corto es

FrameLayout layDraw = (FrameLayout) findViewById(R.id.layDraw); /*Your root view to be part of screenshot*/ layDraw.buildDrawingCache(); Bitmap bmp = layDraw.getDrawingCache();


Como referencia, una forma de capturar la pantalla (y no solo la actividad de su aplicación) es capturar el framebuffer (device / dev / graphics / fb0). Para hacer esto, debe tener privilegios de root o su aplicación debe ser una aplicación con permisos de firma ("Un permiso que el sistema otorga solo si la aplicación solicitante está firmada con el mismo certificado que la aplicación que declaró el permiso"), que es muy poco probable a menos que haya compilado su propia ROM.

Cada captura de framebuffer, desde un par de dispositivos que he probado, contenía exactamente una captura de pantalla. La gente ha informado que contiene más, supongo que depende del tamaño del marco / pantalla.

Intenté leer el framebuffer de forma continua, pero parece que vuelve a leer una cantidad fija de bytes. En mi caso, eso es (3 410 432) bytes, que es suficiente para almacenar un marco de visualización de 854 * 480 RGBA (3 279 360 bytes). Sí, el marco, en binario, generado desde fb0 es RGBA en mi dispositivo. Esto probablemente dependerá de un dispositivo a otro. Esto será importante para que lo descifres =)

En mi dispositivo / dev / graphics / fb0 los permisos son para que solo la raíz y los usuarios de gráficos de grupo puedan leer el fb0.

los gráficos son un grupo restringido, por lo que probablemente solo accederá a fb0 con un teléfono rooteado usando el comando su.

Las aplicaciones de Android tienen el ID de usuario (uid) = aplicación _ ## y el ID de grupo (guid) = aplicación _ ## .

adb shell tiene uid = shell y guid = shell , que tiene muchos más permisos que una aplicación. Puede verificar esos permisos en /system/permissions/platform.xml

Esto significa que podrá leer fb0 en el shell adb sin root, pero no podrá leerlo dentro de la aplicación sin root.

Además, otorgar los permisos READ_FRAME_BUFFER y / o ACCESS_SURFACE_FLINGER en AndroidManifest.xml no servirá de nada para una aplicación normal, ya que solo funcionarán para aplicaciones " exclusivas ".

También puedes ver este hilo cerrado para más detalles.



Junto con la captura de captura de pantalla, si también queremos reproducir el tono. Podemos usar el siguiente código

MediaPlayer _shootMP = null; AudioManager manager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE); manager.setStreamVolume(AudioManager.STREAM_NOTIFICATION, manager.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0); if (_shootMP == null) _shootMP = MediaPlayer .create(getActivity(), Uri.parse("file:///system/media/audio/ui/camera_click.ogg")); if (_shootMP != null) { try { _shootMP.start(); _shootMP.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer arg0) { // release the media _shootMP.stop(); _shootMP.reset(); _shootMP.release(); _shootMP = null; } }); } catch (IllegalStateException e) { Log.w(TAG, "Exception takeScreenShot" + e.getMessage()); } }


La mayoría de las respuestas para esta pregunta utilizan el método de dibujo de Canvas o el método de caché de dibujo. Sin embargo, el método View.setDrawingCache() está en desuso en API 28 . Actualmente, la API recomendada para realizar capturas de pantalla es la clase PixelCopy disponible en la API 24 (pero los métodos que aceptan el parámetro Window están disponibles en la API 26 == Android 8.0 Oreo). Aquí hay un ejemplo de código de Kotlin para recuperar un Bitmap :

@RequiresApi(Build.VERSION_CODES.O) fun saveScreenshot(view: View) { val window = (view.context as Activity).window if (window != null) { val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888) val locationOfViewInWindow = IntArray(2) view.getLocationInWindow(locationOfViewInWindow) try { PixelCopy.request(window, Rect(locationOfViewInWindow[0], locationOfViewInWindow[1], locationOfViewInWindow[0] + view.width, locationOfViewInWindow[1] + view.height), bitmap, { copyResult -> if (copyResult == PixelCopy.SUCCESS) { saveBitmap(bitmap) } // possible to handle other result codes ... }, Handler()) } catch (e: IllegalArgumentException) { // PixelCopy may throw IllegalArgumentException, make sure to handle it } } }


La respuesta de Mualig es muy buena, pero tuve el mismo problema que describe Ewoks: no entiendo el fondo. Entonces, algunas veces es lo suficientemente bueno y otras veces obtengo un texto negro sobre un fondo negro (dependiendo del tema).

Esta solución se basa en gran medida en el código Mualig y el código que he encontrado en Robotium. Estoy descartando el uso del caché de dibujo llamando directamente al método de dibujo. Antes de eso, intentaré obtener el dibujo de fondo de la actividad actual para dibujarlo primero.

// Some constants final static String SCREENSHOTS_LOCATIONS = Environment.getExternalStorageDirectory().toString() + "/screenshots/"; // Get device dimmensions Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); display.getSize(size); // Get root view View view = mCurrentUrlMask.getRootView(); // Create the bitmap to use to draw the screenshot final Bitmap bitmap = Bitmap.createBitmap(size.x, size.y, Bitmap.Config.ARGB_4444); final Canvas canvas = new Canvas(bitmap); // Get current theme to know which background to use final Activity activity = getCurrentActivity(); final Theme theme = activity.getTheme(); final TypedArray ta = theme .obtainStyledAttributes(new int[] { android.R.attr.windowBackground }); final int res = ta.getResourceId(0, 0); final Drawable background = activity.getResources().getDrawable(res); // Draw background background.draw(canvas); // Draw views view.draw(canvas); // Save the screenshot to the file system FileOutputStream fos = null; try { final File sddir = new File(SCREENSHOTS_LOCATIONS); if (!sddir.exists()) { sddir.mkdirs(); } fos = new FileOutputStream(SCREENSHOTS_LOCATIONS + System.currentTimeMillis() + ".jpg"); if (fos != null) { if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) { Log.d(LOGTAG, "Compress/Write failed"); } fos.flush(); fos.close(); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }


La vista de parámetros es el objeto de diseño raíz.

Process process; process = Runtime.getRuntime().exec("screencap -p " + outputPath); process.waitFor();


Llame a este método y pase el ViewGroup más exterior del que desea una captura de pantalla de:

public Bitmap screenShot(View view) { Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); view.draw(canvas); return bitmap; }


Mi solución es:

public static Bitmap loadBitmapFromView(Context context, View v) { DisplayMetrics dm = context.getResources().getDisplayMetrics(); v.measure(MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(dm.heightPixels, MeasureSpec.EXACTLY)); v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); Bitmap returnedBitmap = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(returnedBitmap); v.draw(c); return returnedBitmap; }

y

public void takeScreen() { Bitmap bitmap = ImageUtils.loadBitmapFromView(this, view); //get Bitmap from the view String mPath = Environment.getExternalStorageDirectory() + File.separator + "screen_" + System.currentTimeMillis() + ".jpeg"; File imageFile = new File(mPath); OutputStream fout = null; try { fout = new FileOutputStream(imageFile); bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout); fout.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { fout.close(); } }

Las imágenes se guardan en la carpeta de almacenamiento externo.


Para aquellos que quieran capturar un GLSurfaceView, el método getDrawingCache o el dibujo al lienzo no funcionará.

Debe leer el contenido del framebuffer de OpenGL después de que se haya procesado el marco. Hay una buena respuesta here


Puede probar la siguiente biblioteca: http://code.google.com/p/android-screenshot-library/ Android Screenshot Library (ASL) permite capturar capturas de pantalla de dispositivos Android sin necesidad de tener privilegios de acceso de root mediante programación. En su lugar, ASL utiliza un servicio nativo que se ejecuta en segundo plano, que se inicia a través del Android Debug Bridge (ADB) una vez por inicio del dispositivo.


Puedes intentar hacer algo como esto,

Obtención de un caché de mapa de bits de un diseño o una vista haciendo algo como: Primero, debe establecer setDrawingCacheEnabled en un diseño (una distribución lineal o relativa, o una vista)

entonces

Bitmap bm = layout.getDrawingCache()

Luego haces lo que quieras con el mapa de bits. Conviértalo en un archivo de imagen o envíe el uri del mapa de bits a otro lugar.


Si desea capturar una vista o un diseño como RelativeLayout o LinearLayout, etc., simplemente use el código:

LinearLayout llMain = (LinearLayout) findViewById(R.id.linearlayoutMain); Bitmap bm = loadBitmapFromView(llMain);

Ahora puede guardar este mapa de bits en el almacenamiento del dispositivo mediante:

FileOutputStream outStream = null; File f=new File(Environment.getExternalStorageDirectory()+"/Screen Shots/"); f.mkdir(); String extStorageDirectory = f.toString(); File file = new File(extStorageDirectory, "my new screen shot"); pathOfImage = file.getAbsolutePath(); try { outStream = new FileOutputStream(file); bm.compress(Bitmap.CompressFormat.PNG, 100, outStream); Toast.makeText(getApplicationContext(), "Saved at "+f.getAbsolutePath(), Toast.LENGTH_LONG).show(); addImageGallery(file); //mail.setEnabled(true); flag=true; } catch (FileNotFoundException e) {e.printStackTrace();} try { outStream.flush(); outStream.close(); } catch (IOException e) {e.printStackTrace();}


Si desea tomar una captura de pantalla del fragment siga esto:

  1. Anular onCreateView() :

    @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_one, container, false); mView = view; }

  2. Lógica para la captura de pantalla:

    button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { View view = mView.findViewById(R.id.scrollView1); shareScreenShotM(view, (NestedScrollView) view); }

  3. método shareScreenShotM)() :

    public void shareScreenShotM(View view, NestedScrollView scrollView){ bm = takeScreenShot(view,scrollView); //method to take screenshot File file = savePic(bm); // method to save screenshot in phone. }

  4. método takeScreenShot ():

    public Bitmap takeScreenShot(View u, NestedScrollView z){ u.setDrawingCacheEnabled(true); int totalHeight = z.getChildAt(0).getHeight(); int totalWidth = z.getChildAt(0).getWidth(); Log.d("yoheight",""+ totalHeight); Log.d("yowidth",""+ totalWidth); u.layout(0, 0, totalWidth, totalHeight); u.buildDrawingCache(); Bitmap b = Bitmap.createBitmap(u.getDrawingCache()); u.setDrawingCacheEnabled(false); u.destroyDrawingCache(); return b; }

  5. método savePic ():

    public static File savePic(Bitmap bm){ ByteArrayOutputStream bytes = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.JPEG, 100, bytes); File sdCardDirectory = new File(Environment.getExternalStorageDirectory() + "/Foldername"); if (!sdCardDirectory.exists()) { sdCardDirectory.mkdirs(); } // File file = new File(dir, fileName); try { file = new File(sdCardDirectory, Calendar.getInstance() .getTimeInMillis() + ".jpg"); file.createNewFile(); new FileOutputStream(file).write(bytes.toByteArray()); Log.d("Fabsolute", "File Saved::--->" + file.getAbsolutePath()); Log.d("Sabsolute", "File Saved::--->" + sdCardDirectory.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } return file; }

Para la actividad, simplemente puede usar View v1 = getWindow().getDecorView().getRootView(); en lugar de mView


Solo extendiendo la respuesta de taraloca. Debe agregar líneas de seguimiento para que funcione. He hecho el nombre de la imagen estática. Asegúrese de utilizar la variable de marca de tiempo de taraloca en caso de que necesite un nombre de imagen dinámico.

// Storage Permissions private static final int REQUEST_EXTERNAL_STORAGE = 1; private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; private void verifyStoragePermissions() { // Check if we have write permission int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { // We don''t have permission so prompt the user ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE); }else{ takeScreenshot(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (requestCode == REQUEST_EXTERNAL_STORAGE) { takeScreenshot(); } } }

Y en el archivo AndroidManifest.xml las siguientes entradas son:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


EDITAR: ten piedad con los downvotes. Fue cierto en 2010 cuando respondí la pregunta.

Todos los programas que permiten capturas de pantalla funcionan solo en teléfonos rooteados.


¡Solo para aplicaciones de sistema!

public static Bitmap screenShot(View view) { Bitmap bitmap = null; if (view.getWidth() > 0 && view.getHeight() > 0) { bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); view.draw(canvas); } return bitmap; }

Nota: las aplicaciones del sistema no necesitan ejecutar "su" para ejecutar este comando.


No se requiere permiso de root o no se requiere gran codificación para este método.

En el shell adb usando el siguiente comando puede tomar una captura de pantalla.

input keyevent 120

Este comando no requiere ningún permiso de root, por lo que también puede realizarlo desde el código java de la aplicación de Android.

Process process; process = Runtime.getRuntime().exec("input keyevent 120");

Más información sobre el código de evento clave en Android, visite http://developer.android.com/reference/android/view/KeyEvent.html

Aquí hemos utilizado. KEYCODE_SYSRQ su valor es 120 y se utiliza para la tecla Pantalla de solicitud / impresión del sistema.

Como dijo CJBS, la imagen de salida se guardará en / sdcard / Pictures / Screenshots


Nota: funciona solo para teléfono rooteado.

Programáticamente, puede ejecutar adb shell /system/bin/screencap -p /sdcard/img.png como se muestra a continuación

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 utilícelo como desee.


private void captureScreen() { View v = getWindow().getDecorView().getRootView(); v.setDrawingCacheEnabled(true); Bitmap bmp = Bitmap.createBitmap(v.getDrawingCache()); v.setDrawingCacheEnabled(false); try { FileOutputStream fos = new FileOutputStream(new File(Environment .getExternalStorageDirectory().toString(), "SCREEN" + System.currentTimeMillis() + ".png")); bmp.compress(CompressFormat.PNG, 100, fos); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }

Agregue el permiso en el manifiesto.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Para las versiones Supporting Marshmallow o superiores, agregue el siguiente código en la actividad del método onCreate

ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},00);


public class ScreenShotActivity extends Activity{ private RelativeLayout relativeLayout; private Bitmap myBitmap; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); relativeLayout = (RelativeLayout)findViewById(R.id.relative1); relativeLayout.post(new Runnable() { public void run() { //take screenshot myBitmap = captureScreen(relativeLayout); Toast.makeText(getApplicationContext(), "Screenshot captured..!", Toast.LENGTH_LONG).show(); try { if(myBitmap!=null){ //save image to SD card saveImage(myBitmap); } Toast.makeText(getApplicationContext(), "Screenshot saved..!", Toast.LENGTH_LONG).show(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } public static Bitmap captureScreen(View v) { Bitmap screenshot = null; try { if(v!=null) { screenshot = Bitmap.createBitmap(v.getMeasuredWidth(),v.getMeasuredHeight(), Config.ARGB_8888); Canvas canvas = new Canvas(screenshot); v.draw(canvas); } }catch (Exception e){ Log.d("ScreenShotActivity", "Failed to capture screenshot because:" + e.getMessage()); } return screenshot; } public static void saveImage(Bitmap bitmap) throws IOException{ ByteArrayOutputStream bytes = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 40, bytes); File f = new File(Environment.getExternalStorageDirectory() + File.separator + "test.png"); f.createNewFile(); FileOutputStream fo = new FileOutputStream(f); fo.write(bytes.toByteArray()); fo.close(); } }

AÑADIR PERMISO

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>