19

我正在开发一个安卓应用程序。我有一个活动,比如说 A,它用视图填充整个屏幕。在 AI 中单击一个按钮想启动另一个活动,比如说 B,它也有一些视图和控件。我希望活动 B 不在屏幕上,并想从 A 截取 B 的屏幕截图。是否可以?

注意:我通过将绘图缓存保存到位图中成功地截取了页面 A 的屏幕截图,但努力截取屏幕外页面的屏幕截图。

4

4 回答 4

14

是的,有可能...您应该在活动“A”中扩展 ActivityGroup。然后在您的按钮单击事件中执行此操作...

 View view =getLocalActivityManager().startActivity("B",new Intent(this,B.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();

然后将该视图转换为位图...

我觉得这对你很有帮助...

于 2011-04-16T09:37:57.680 回答
5

好吧,我已经实现了我想要的。这些是我使用的步骤。

  1. 使用 startActivityForResult() 而不是 startActivity() 启动活动 B。

    Intent bIntent = new Intent(A.this,B.class);
    startActivityForResult(bIntent,B_REQUEST_CODE);
    
  2. 在活动 B 的 onCreate 中,获取 B 的 mainLayout 并启用其绘图缓存

    final LinearLayout layout = (LinearLayout)
                         findViewById(R.id.app_parent_layout);
    layout.setDrawingCacheEnabled(true);
    layout.setDrawingCacheQuality(LinearLayout.DRAWING_CACHE_QUALITY_HIGH);
    
  3. 在活动 B 中,等待其布局完全绘制(这非常重要)。在活动B的onCreate()中,获取B的mainLayout,当其布局绘制完成时,使用ViewTreeObserver获取回调。

    ViewTreeObserver vto = layout.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
     @Override
     public void onGlobalLayout() {
      layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
      getDrawingBitmap();
     }
    });
    
  4. 现在 getDrawingBitmap() 在完全绘制布局时被调用。有你的截图。

    public void getDrawingBitmap(){
        LinearLayout mainLayout = (LinearLayout)
                            findViewById(R.id.app_parent_layout);
        Bitmap b = mainLayout.getDrawingCache();
    
        File file = saveBitmapAsFile(b);
    
        Intent resultIntent = new Intent();
        resultIntent.putExtra("FullFileName",file.getAbsolutePath());
        setResult(Activity.RESULT_OK,resultIntent);
        finish();
    }
    

    在这里,我将位图保存为文件并将文件名作为结果代码返回。我确信有更好的方法将位图发送到父活动,而不是保存为文件并发送文件名。但无论如何我都需要保存位图一段时间。所以对我来说这是更简单的方法。设置结果完成活动后。

  5. 现在在 Activity A onActivityResult() 上检索文件名。

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if(requestCode == B_REQUEST_CODE){
        if (resultCode == Activity.RESULT_OK) { 
          String newText = data.getStringExtra("FullFileName");
         File dir = new File (newText);
        } 
      }
    }
    
于 2013-09-19T07:16:21.807 回答
1

我认为这样做会非常困难,因为我不知道如何控制这些视图的绘制方法,而且除非可见,否则 android 操作系统也不会绘制它们。

但是,可能只在很短的时间内将另一个视图前景化以填充其绘图缓存。也许它甚至可以在它变得可见之前再次放置背景,因为为了流畅的体验,操作系统似乎在它们实际合成到前景之前将视图绘制在屏幕外。

另一个技巧可能是将您的前景视图作为子视图附加到背景上,并赋予它非常轻微的 alpha 透明度。例如 WebView 可以通过这种方式很好地叠加,实际上是强制同时绘制 WebView 及其背景。也许这也适用于其他视图。

于 2011-04-15T00:42:26.087 回答
0

我使用这种方式它工作得很好但是有一个问题我只是在我第一次拍摄快照时拍摄一个布局的快照它给了我正确的图片但是经过一些更改我再次拍摄它给了我之前的快照。

RelativeLayout layout = (RelativeLayout)findViewById(R.id.mainview);
    layout.setDrawingCacheEnabled(true);
    layout.setDrawingCacheQuality(LinearLayout.DRAWING_CACHE_QUALITY_HIGH);
    layout.buildDrawingCache();
    Bitmap bitmap = layout.getDrawingCache();

          File file =  new File(Environment.getExternalStorageDirectory().toString() + "/sPenimg.png");
          FileOutputStream ostream;
          try {
              ostream = new FileOutputStream(file);
              bitmap.compress(CompressFormat.PNG, 100, ostream);
              ostream.flush();
              ostream.close();      
          } catch (FileNotFoundException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }

解决这个问题添加 ((RelativeLayout)findViewById(R.id.mainview)).destroyDrawingCache();

于 2012-07-24T09:50:53.487 回答