2013-11-22 2 views
14

내 응용 프로그램을 설치하고 200 밀리 초마다 백그라운드에서 실행하고 내 컴퓨터에 이미지를 저장할 때 프로그래밍 방식으로 Android 장치 또는 에뮬레이터의 스크린 샷이 필요합니다. 아래 코드를 사용하여이 절차를 구현했으며 응용 프로그램이 포 그라운드에있는 경우에만 작동합니다. 내 응용 프로그램이 백그라운드에있을 때도 스크린 샷을 찍고 싶습니다.Android - 프로그래밍 방식으로 스크린 샷을 찍는 방법

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

는 어떻게 프로그래밍 Devices -> DDMS에 Screencapture의 새로 고침하고 저장 버튼의 기능을 구현할 수 있습니다 : 다음은 내 코드? 나는 그것을 얻을 수 있습니까?

+9

권한을 추가합니다. 이를 수행하는 응용 프로그램은 심각한 보안 문제를 야기합니다. –

+1

** 전화가 루팅 된 경우 (* kitkat *) **를 제외하고는이 작업을 수행 할 수 없습니다. "심각한 보안 우려"에 관해서는, 나는 다른 곳에서 심각한 보안 문제가 있다고 생각한다. 앱이 스크린 샷을 찍을 수있는 권한을 요청할 수 있다면 큰 문제는 아닙니다. –

+2

이것은 스크린 샷이 아니기 때문에 ... 그것은 200ms마다 스크린 샷입니다. 본질적으로 5 FPS 비디오. 이렇게하면 휴대 전화로 완료된 모든 것을 쉽게 포착 할 수 있습니다. 제 자신의 사용 (앱의 비디오 제작)을 위해 그것을하는 것에 반대하지 않고 제 3 자 앱에게 스크린 샷을 찍을 수있는 권한을주는 것은 긴 토끼 구멍이 될 것입니다. –

답변

15

휴대 전화는 다음이

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

을 다음과 같이 응용 프로그램이있는 경우 화면에 액세스 할 수 없습니다 JPG로 변환 뿌리를두고있는 경우 배경에 뿌리 박혀 있지 않는 한, 위의 코드는 백그라운드에 있어도 화면의 스크린 샷을 가장 효과적으로 캡처 할 수 있습니다.

구글은 당신이 응원하지 않고 화면을 캡처 할 수있는 라이브러리를 가지고

UPDATE, 나는 것을 시도했다, 그러나 가능한 한 빨리 메모리를 먹을 것이라고 확신 스피.

당신이 할 수있는, http://code.google.com/p/android-screenshot-library/

+0

에뮬레이터에서 작동하지만 실제 장치에서 작동하지 않는 화면 캡쳐 – Harsha

+0

장치가 루팅되어 있습니까? –

+0

아니요, 사용자가 목록 항목 계획에 lisk를 사용하여 공유 옵션이있는 detailview를 표시하면 해당 레이아웃 비트 맵을 저장해야합니다. 그런 다음 해당 파일을 화면에 표시하고 sendmail 의도를 공유하여 에뮬레이터에서 작동하도록 해당 파일을 sahre해야합니다. 실제 작동하지 않는 것을 시도합니다 – Harsha

14

여기 방법이 있습니다.

Android taking Screen shots through code

결과 출력 :

enter image description here

enter image description here

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

} 
+2

응용 프로그램이 포 그라운드에있는 경우에만 작동합니까? –

+2

'새로운 BitmapDrawable (비트 맵)'생성자가 사용되지 않습니다. 대신에 image.setImageBitmap (bm)을 사용하십시오. – Darpan

5

이 (ADB 등) 백그라운드에서 스크린 샷을 촬영은 그룹 = 1003 (그래픽)이 필요합니다. 그렇지 않으면 자신의 프로세스에 대한 스크린 샷 만 얻을 수 있습니다. 따라서 루트 된 장치에서만이 작업을 수행하거나 ADB 기본 프로그램을 실행하여 수행 할 수 있습니다.

기본 CPP 코드 샘플은 https://android.googlesource.com/platform/frameworks/base/+/android-4.3_r2.3/cmds/screencap/

에서 찾을 그리고 당신은 자바 코드에서 수행하려는 경우, 당신은 표면 클래스의 숨겨진 API에 액세스 할 수 있습니다 :

/** 
* 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 릴리스 이후 OK, GB와 같은 초기 릴리스의 경우 원시 cpp 코드를 확인할 수 있습니다.

그러나 일부 Android 기기에서는 미디어 시스템 및 캔버스 등의 구현이 좋지 않으므로이 경우 모든 동영상 재생 또는 표면보기 콘텐츠를 캡처 할 수 없습니다.

+4

이 메소드는 Android 4.3 이상에서 제거되었습니다. – Tom

0
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 변수에 나는 다운로드의 경로를 제공했기 때문에 스크린 샷을 다운로드 폴더에 저장됩니다 이 경우에도 가능하면 변경 폴더 path.In 매니페스트 파일 그것은 나를 흥분 것이다 쓰기

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

관련 문제