如何通过代码而不是程序来截取手机屏幕的选定区域的截图?


当前回答

如果你想捕捉一个视图的截图,使用View::drawToBitmap扩展函数:

val bitmap = myTargetView.drawToBitmap(/*Optional:*/ Bitmap.Config.ARGB_8888)

只需要确保使用-ktx版本的AndroidX核心库:

implementation("androidx.core:core-ktx:1.6.0")

我已经回答过一个类似的问题。

其他回答

仅限系统应用!

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

注意:系统应用不需要执行“su”命令执行该命令。

对于那些想要捕获GLSurfaceView的人,getDrawingCache或绘制到画布方法将不起作用。

在帧呈现之后,您必须读取OpenGL帧缓冲区的内容。这里有一个很好的答案

科特林

    private fun screenShot() {
          try {
            val mPath: String = this.getExternalFilesDir(null).getAbsolutePath()
              .toString() + "/temp" + ".png" 
            // create bitmap screenshot
            val v1: View = getWindow().getDecorView().getRootView()
            v1.isDrawingCacheEnabled = true
            val bitmap = Bitmap.createBitmap(v1.drawingCache)
            v1.isDrawingCacheEnabled = false
            val imageFile = File(mPath)
            val outputStream = FileOutputStream(imageFile)
            val quality = 100
            bitmap.compress(Bitmap.CompressFormat.PNG, quality, outputStream)
            outputStream.flush()
            outputStream.close()
        
            //or you can share to test the method fast
            val uriPath =
              FileProvider.getUriForFile(this, getPackageName() + ".sharing.provider", imageFile)
            val intent = Intent(Intent.ACTION_SEND)
            intent.type = "image/*"
            intent.clipData = ClipData.newRawUri("", uriPath)
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
            intent.putExtra(Intent.EXTRA_STREAM, uriPath)
            startActivity(Intent.createChooser(intent, "Sharing to..."))
          } catch (e: Throwable) {
            e.printStackTrace()
          }
        }

Java

  private void screenShot() {
    try {
      String mPath = this.getExternalFilesDir(null).getAbsolutePath().toString() + "/temp" + ".png";
      // create bitmap screenshot
      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.PNG, quality, outputStream);
      outputStream.flush();
      outputStream.close();

      //or you can share to test the method fast

      Uri uriPath = FileProvider.getUriForFile(this, getPackageName() + ".sharing.provider", imageFile);
      Intent intent = new Intent(Intent.ACTION_SEND);
      intent.setType("image/*");
      intent.setClipData(ClipData.newRawUri("", uriPath));
      intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
      intent.putExtra(Intent.EXTRA_STREAM, uriPath);
      startActivity(Intent.createChooser(intent, "Sharing to..."));

    } catch (Throwable e) {
      e.printStackTrace();
    }
  }

从Android 11 (API级别30),你可以用辅助服务截屏:

takeScreenshot -截取指定显示的屏幕截图,并通过AccessibilityService.ScreenshotResult返回。

如果你想捕捉一个视图或布局,比如RelativeLayout或LinearLayout等。

只需使用代码:

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

现在你可以保存这个位图在设备存储:

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