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

Как я могу реализовать функциональность кнопок Refresh и Save Screencapture in Devices -> DDMS программно? Могу ли я добиться этого? Пожалуйста, помогите мне с вашими мыслями / примерами кодов

Solutions Collecting From Web of "Android – Как сделать скриншот программным"

Если ваш телефон укоренен, попробуйте это

 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 как bitmap и преобразуйте его в 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(); 

У вас нет доступа к экрану, если ваше приложение находится в фоновом режиме, если вы не внедрены, приведенный выше код может сделать скриншот наиболее эффективным с любого экрана, даже если вы находитесь в фоновом режиме.

ОБНОВИТЬ

У Google есть библиотека, с помощью которой вы можете снимать скриншот без укоренения, я пробовал это, но я уверен, что он как можно скорее поедает память.

Попробуйте http://code.google.com/p/android-screenshot-library/

Вот как это сделать.

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) требуются группы = 1003 (графика) . В противном случае вы можете получить только скриншот собственного процесса. Таким образом, вы можете либо сделать это только на корневом устройстве, либо сделать это, запустив собственную программу ADB.

Пример исходного кода cpp можно найти на странице https://android.googlesource.com/platform/frameworks/base/+/android-4.3_r2.3/cmds/screencap/

И если вы хотите сделать это в Java-коде, вам нужно получить доступ к скрытому API класса 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); 

Эти два должны быть как ОК с момента выпуска ICS, так и для раннего выпуска, такого как GB, вы можете проверить собственный код cpp.

Однако на некоторых устройствах Android реализация медиасистемы и холста и т. Д. Не очень хороша, поэтому в этом случае вы не можете захватывать воспроизведение видео или контент с поверхностным видом.

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

Добавьте этот метод к событию нажатия кнопки или в выбранном событии пункта меню выбора, а снимок экрана будет сохранен в папке «Загрузка», потому что в переменной folder я предоставил путь загрузки, вы можете изменить путь к папке. В файле манифеста добавить разрешение для записи

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