programing

Android에서 스크린샷을 프로그래밍 방식으로 촬영하는 방법은 무엇입니까?

mailnote 2023. 6. 20. 21:46
반응형

Android에서 스크린샷을 프로그래밍 방식으로 촬영하는 방법은 무엇입니까?

프로그램이 아닌 코드에서 전화 스크린의 선택된 영역을 스크린샷으로 촬영하려면 어떻게 해야 합니까?

다음은 SD 카드에 스크린샷을 저장하고 나중에 필요한 용도로 사용할 수 있게 해주는 코드입니다.

먼저 파일을 저장하려면 적절한 사용 권한을 추가해야 합니다.

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

다음은 코드(활동에서 실행)입니다.

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

다음과 같이 최근에 생성된 이미지를 열 수 있습니다.

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

조각 보기에서 이를 사용하려면 다음을 사용합니다.

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

대신에

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

촬영 시 스크린샷() 기능

참고:

대화 상자에 지표면 보기가 포함된 경우에는 이 솔루션이 작동하지 않습니다.자세한 내용은 다음 질문에 대한 답변을 확인하십시오.

Android Take Surface View의 스크린샷에 검은색 화면이 표시됩니다.

이 메서드를 호출하여 스크린샷을 만들려는 가장 바깥쪽의 ViewGroup을 전달합니다.

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

참고: 루트 전화에서만 작동합니다.

프로그래밍 방식으로 실행할 수 있습니다.adb shell /system/bin/screencap -p /sdcard/img.png하기와 같이

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그리고 당신의 소원대로 사용하세요.

메서드에는 루트 권한없거나코딩이 필요하지 않습니다.


아래 명령을 사용하여 adb 쉘에서 스크린샷을 촬영할 수 있습니다.

input keyevent 120

이 명령에는 루트 권한이 필요하지 않으므로 안드로이드 응용 프로그램의 Java 코드에서도 동일하게 수행할 수 있습니다.

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

Android의 주요 이벤트 코드에 대한 자세한 내용은 http://developer.android.com/reference/android/view/KeyEvent.html 를 참조하십시오.

여기 우리가 사용한 것입니다.KEYCODE_SYSRQ 값은 120이며 시스템 요청/화면 인쇄 키에 사용됩니다.


CJBS에서 말씀하신 대로 출력 사진은 /sdcard/Pictures/Screenshots에 저장됩니다.

Mualig의 대답은 매우 좋지만, 저는 Ewoks가 설명하는 것과 같은 문제를 겪었습니다. 저는 배경을 이해하지 못합니다.그래서 때로는 충분하고 때로는 검은색 배경 위에 검은색 텍스트가 표시됩니다(주제에 따라 다름).

이 솔루션은 Mualig 코드와 Robotium에서 찾은 코드를 기반으로 합니다.드로잉 방법으로 직접 호출하여 드로잉 캐시 사용을 취소하고 있습니다.그 전에 현재 활동에서 배경을 그릴 수 있도록 먼저 그려보겠습니다.

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

참고로 화면을 캡처하는 한 가지 방법은 프레임 버퍼(dev/graphics/fb0)를 캡처하는 것입니다.이렇게 하려면 루트 권한이 있거나 앱이 서명 권한이 있는 앱이어야 합니다("요청 응용 프로그램이 권한을 선언한 응용 프로그램과 동일한 인증서로 서명된 경우에만 시스템이 부여하는 권한"). 사용자가 직접 ROM을 컴파일하지 않는 한 가능성이 매우 낮습니다.

제가 테스트한 몇 대의 장치에서 각 프레임 버퍼 캡처에는 정확히 한 개의 스크린샷이 포함되어 있었습니다.사람들이 더 많이 들어간다고 보고했는데, 프레임/디스플레이 크기에 따라 다를 것 같습니다.

프레임 버퍼를 계속 읽으려고 했지만 정해진 바이트 수만큼 읽었을 때 반환되는 것 같습니다.제 경우에는 854*480 RGBA(3279 360 바이트)의 디스플레이 프레임을 저장하기에 충분한 (3410 432) 바이트입니다.예, 2진법으로 fb0에서 출력되는 프레임은 내 장치의 RGBA입니다.이 문제는 대부분 장치마다 다릅니다.이것은 디코딩하는 데 중요합니다. =)

내 장치에서 /dev/graphics/fb0 권한은 root 및 그룹 그래픽의 사용자만 fb0을 읽을 수 있습니다.

그래픽은 제한된 그룹이므로 su 명령을 사용하여 루트 전화기로만 fb0에 액세스할 수 있습니다.

Android 앱의 사용자 ID(uid) = app_##그룹 ID(vmx) = app_##입니다.

adb 셸에는 udi = guid = 이 있으며, 이는 앱보다 훨씬 많은 권한을 가집니다.실제로 이러한 권한은 /system/permissions/platform.xml에서 확인할 수 있습니다.

즉, 루트 없이는 adb 셸에서 fb0을 읽을 수 있지만 루트 없이는 앱 내에서 읽을 수 없습니다.

또한 AndroidManifest.xml에 대한 READ_FRAME_BUFFER 및/또는 ACCESS_SURFACE_FLINGER 권한을 부여해도 '서명' 앱에서만 작동하기 때문에 일반 앱에서는 아무런 효과가 없습니다.

또한 자세한 내용은 닫힌 스레드를 확인하십시오.

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

매니페스트에 권한 추가

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

Supporting Mashmallow 이상 버전의 경우 Create 메서드의 활동에 아래 코드를 추가하십시오.

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

내 솔루션은 다음과(와)

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

그리고.

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

이미지는 외부 저장소 폴더에 저장됩니다.

다음 라이브러리를 사용할 수 있습니다. http://code.google.com/p/android-screenshot-library/ Android ASL(Android Screenshot Library)을 사용하면 루트 액세스 권한 없이 Android 장치에서 스크린샷을 프로그래밍 방식으로 캡처할 수 있습니다.대신 ASL은 백그라운드에서 실행되는 기본 서비스를 사용하며, 장치 부팅 시마다 한 번씩 Android Debug Bridge(ADB)를 통해 시작됩니다.

위의 @JustinMorris와 여기 https://stackoverflow.com/a/8504958/2232148 의 @NiravDangi의 답변을 바탕으로 우리는 뷰의 배경과 전경을 가져와서 다음과 같이 조립해야 합니다.

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

품질 매개 변수는 비트맵의 상수를 사용합니다.으로 ""(" "" " " " " ")" 중 하나입니다.Bitmap.Config.RGB_565또는Bitmap.Config.ARGB_8888.

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

}

사용 권한 추가

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

이런 걸 시도할 수도 있지만,

캐시를 를에▁getting▁first▁from▁cache▁gotta합니다▁a▁by레▁bitmap▁or▁like▁doing야▁view▁you이▁something▁a▁layout▁a수해.setDrawingCacheEnabled 또는 레이아웃 뷰)에

그리고나서

Bitmap bm = layout.getDrawingCache()

그런 다음 비트맵으로 원하는 모든 것을 수행합니다.이미지 파일로 변환하거나 비트맵의 uri를 다른 곳으로 보냅니다.

지름길은

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

이 질문에 대한 대부분의 대답은 다음을 사용합니다.Canvas도면 방법 또는 도면 캐시 방법입니다.그러나 이 방법은 API 28에서 더 이상 사용되지 않습니다.현재 스크린샷을 만드는 데 권장되는 API는 API 24에서 사용할 수 있는 클래스입니다(그러나 허용하는 방법은Window매개 변수는 API 26 == Android 8.0 Oreo)에서 사용할 수 있습니다.다음은 샘플 코틀린 코드입니다.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
        }
    }
}

GLSfaceView를 캡처하려는 사용자의 경우 getDrawingCache 또는 캔버스로 그리기 방법이 작동하지 않습니다.

프레임이 렌더링된 후 OpenGL 프레임 버퍼의 내용을 읽어야 합니다.여기에 좋은 이 있습니다.

나는 스크린샷을 캡처하는 간단한 라이브러리를 만들었습니다.View합니다.

https://github.com/abdallahalaraby/Blink

다음에서 스크린샷을 찍으십시오.fragment다음을 따르는 것보다:

  1. 재정의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. 스크린샷을 촬영하기 위한 논리:

     button.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View v) {
         View view =  mView.findViewById(R.id.scrollView1);
          shareScreenShotM(view, (NestedScrollView) view); 
     }
    
  3. 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. method 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. 메서드 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;
       }
    

을 할 활을위간사수있다니습용할히단동해▁use다▁you▁simply▁for▁can▁activity활 사용할 수 있습니다.View v1 = getWindow().getDecorView().getRootView();mView

타랄로카의 답변을 연장하는 것뿐입니다.작동하려면 다음 행을 추가해야 합니다.이미지 이름을 정적으로 설정했습니다. 동적 이미지 이름이 필요한 경우 taraloca의 타임스탬프 변수를 사용하십시오.

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

AndroidManifest.xml 파일에서 다음 항목을 입력해야 합니다.

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

전체 페이지 스크롤링 스크린샷의 경우

전체 보기 스크린샷(스크롤 보기 등이 포함됨)을 캡처하려면 이 라이브러리에서 확인하십시오.

https://github.com/peter1492/LongScreenshot

Gradel을 가져와서 BigScreenshot 개체를 만들기만 하면 됩니다.

BigScreenshot longScreenshot = new BigScreenshot(this, x, y);

화면 보기 그룹을 자동으로 스크롤하는 동안 촬영한 스크린샷의 비트맵과 함께 콜백이 수신됩니다.

@Override public void getScreenshot(Bitmap bitmap) {}

다음 중 갤러리에 저장할 수 있는 항목 또는 필요한 용도

시스템 응용 프로그램에만 해당!

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

참고: 시스템 응용 프로그램은 이 명령을 실행하기 위해 "su"를 실행할 필요가 없습니다.

매개 변수 보기는 루트 레이아웃 개체입니다.

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

Android 11(API 레벨 30)에서 접근성 서비스로 스크린샷을 찍을 수 있습니다.

takeScreenshot - 지정된 디스플레이의 스크린샷을 만들고 내게 필요한 옵션 서비스를 통해 반환합니다.스크린샷 결과.

Android에서 보기의 스크린샷을 만듭니다.

public static Bitmap getViewBitmap(View v) {
    v.clearFocus();
    v.setPressed(false);

    boolean willNotCache = v.willNotCacheDrawing();
    v.setWillNotCacheDrawing(false);

    int color = v.getDrawingCacheBackgroundColor();
    v.setDrawingCacheBackgroundColor(0);

    if (color != 0) {
        v.destroyDrawingCache();
    }
    v.buildDrawingCache();
    Bitmap cacheBitmap = v.getDrawingCache();
    if (cacheBitmap == null) {
        return null;
    }

    Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);

    v.destroyDrawingCache();
    v.setWillNotCacheDrawing(willNotCache);
    v.setDrawingCacheBackgroundColor(color);

    return bitmap;
}

보기의 스크린샷을 캡처하려면 다음을 사용합니다.View::drawToBitmap확장 기능:

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

Android X Core 라이브러리의 -ktx 버전만 사용하십시오.

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

저는 이미 여기서 비슷한 질문에 답했습니다.

코틀린

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

자바

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

다음과 같은 보기 또는 레이아웃을 캡처하려는 경우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();}

언급URL : https://stackoverflow.com/questions/2661536/how-to-programmatically-take-a-screenshot-on-android

반응형