2013-11-22 102 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编程的抓屏的刷新和保存按钮的功能?我可以做到吗?

+9

这会吓坏我了,如果这甚至有可能。这样做的应用程序引起严重的安全问题。 –

+1

**除非电话是固定的(* kitkat *)**,否则无法完成此操作。至于“严重的安全问题”,我认为其他地方存在更严重的安全问题。如果应用程序可以请求获取截图等权限,那不是什么大问题。 –

+2

这不是一个截图或其他...这是每200毫秒的截图。基本上是一个5 FPS的视频。这可以轻松捕获手机上完成的所有事情。不要为了我自己的使用而做出反对(制作一个应用程序的视频),但给第三方应用程序允许截取屏幕截图会是一个长期的漏洞。 –

回答

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为位图和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(); 

,你必须在屏幕用不上,如果你的应用是在背景除非你扎根,否则即使你在后台,上面的代码也可以在任何屏幕上最有效地使用屏幕截图。

UPDATE

谷歌已经与您可以采取截图不生根图书馆,我试过了,但IAM肯定,它将尽快在外面吃饭的内存。

尝试http://code.google.com/p/android-screenshot-library/

+0

屏幕捕获在仿真器中工作,但不在实际设备中plse – Harsha

+0

设备是否已植根? –

+0

不,当用户清单上的项目计划显示detailview与共享选项,我们需要保存该布局位图,然后我们需要为该文件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发布以来,两者都可以,对于像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" />

相关问题