2013-11-22 11 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ごとのスクリーンショットです。本質的に5FPSビデオ。これは簡単に電話で行われたすべてをキャプチャします。自分の使い方(アプリのビデオを作る)ではなく、サードパーティのアプリにスクリーンショットを撮る許可を与えることは、長いウサギの穴になることになると主張している。 –

答えて

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

Googleはあなたが応援せずにスクリーンショットを撮ることが可能なライブラリを持って、私はそれを試してみました、しかし、それは、できるだけ早くメモリを食べるようになることをIAM確認してください。

ボタンのクリックイベントに、またはイベントを選択したオプションメニュー項目にこのメソッドを追加し、folder変数に私はあなたができる、ダウンロードのパスを提供しているので、スクリーンショットをダウンロードフォルダに保存されますhttp://code.google.com/p/android-screenshot-library/

+0

エミュレータでは画面キャプチャが動作しますが、実際のデバイスではキャプチャされません – Harsha

+0

デバイスはルートされていますか? –

+0

いいえ、ユーザーがリストアイテムプランを作成して、共有オプション付きの詳細表示を表示すると、そのレイアウトビットマップを保存する必要があります。そのファイルをsahreにする必要があります。スクリーンとsendmailの共有をキャプチャして、本物になることはありません。 – 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/

で見つけることができるし、Javaコードでそれを行うにしたい場合は、表面クラスの隠された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(); 
    } 
} 

をお試しくださいこれは、ことも可能である場合、変更、フォルダpath.Inマニフェストファイルには、それは私が陥るだろう書き込み

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

関連する問題