Android 截取屏幕外页面的屏幕截图

发布于 2024-10-31 11:07:19 字数 193 浏览 3 评论 0原文

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

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

I am working on an android application. I have an activity, say A, which fills the entire screen with views..On a button click in A I want to start another activity, say B, which also has some views and controls. I want activity B to be offscreen , and want to take the screenshot of B from A . Is it possible?

Note: I am successful in taking the screenshot of page A by saving the drawing cache in to a bitmap, but struggling to take the offscreen page's screenshot.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心意如水 2024-11-07 11:07:19

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

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

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

我认为这对您有帮助...

Yes it is possible...You should extend ActivityGroup in Activity 'A'.
Then do this in your button click event...

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

then convert that view as bitmap...

I think this is helpful for you...

别在捏我脸啦 2024-11-07 11:07:19

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

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

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

    最终 LinearLayout 布局 = (LinearLayout)
                         findViewById(R.id.app_parent_layout);
    布局.setDrawingCacheEnabled(true);
    布局.setDrawingCacheQuality(LinearLayout.DRAWING_CACHE_QUALITY_HIGH);
    
  3. 在 Activity B 中等待其布局完全绘制(这非常
    重要的)。对于 Activity B 的 onCreate() 中,获取 mainLayout
    B、使用ViewTreeObserver在其布局绘制时获取回调
    完全。

    ViewTreeObserver vto = layout.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
     @覆盖
     公共无效onGlobalLayout(){
      布局.getViewTreeObserver().removeGlobalOnLayoutListener(this);
      getDrawingBitmap();
     }
    });
    
  4. 现在,当布局完全绘制时, getDrawingBitmap() 就会被调用。
    那里有你的屏幕截图。

    public void getDrawingBitmap(){
        线性布局主布局 = (线性布局)
                            findViewById(R.id.app_parent_layout);
        位图 b = mainLayout.getDrawingCache();
    
        文件 file = saveBitmapAsFile(b);
    
        意图结果Intent = new Intent();
        resultIntent.putExtra("FullFileName",file.getAbsolutePath());
        setResult(Activity.RESULT_OK,resultIntent);
        结束();
    }
    

    这里我正在获取位图并将其保存为文件并返回
    文件名作为结果代码。我确信有更好的发送方法
    位图到父活动而不是保存为文件并发送
    文件名。但无论如何我有一个要求保存位图
    某个时候。所以对我来说这是更简单的方法。设定后结果
    完成活动。

  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");
         文件目录=新文件(newText);
        } 
      }
    }
    

Well I have achieved what I want. These are the steps I used.

  1. Start activity B with startActivityForResult() instead of
    startActivity().

    Intent bIntent = new Intent(A.this,B.class);
    startActivityForResult(bIntent,B_REQUEST_CODE);
    
  2. In onCreate of activity B take mainLayout of B and enable its
    drawing cache

    final LinearLayout layout = (LinearLayout)
                         findViewById(R.id.app_parent_layout);
    layout.setDrawingCacheEnabled(true);
    layout.setDrawingCacheQuality(LinearLayout.DRAWING_CACHE_QUALITY_HIGH);
    
  3. In activity B wait till its layout is drawn completely(This is very
    important). For that in onCreate() of activity B, get mainLayout of
    B, use ViewTreeObserver to get a call back when its layout is drawn
    completely.

    ViewTreeObserver vto = layout.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
     @Override
     public void onGlobalLayout() {
      layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
      getDrawingBitmap();
     }
    });
    
  4. Now getDrawingBitmap() gets called when layout is drawn completely.
    There take your screenshot.

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

    Here I am taking bitmap and saving it as a file and returning the
    filename as a result code. I am sure there are better method to send
    the bitmap to parent activity than saving as a file and sending
    filename. But I have a requirement anyway to save bitmap for
    sometime. So For me this is the easier method. After setting result
    finish activity.

  5. Now on Activity A onActivityResult() retrieve the filename.

    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);
        } 
      }
    }
    
山有枢 2024-11-07 11:07:19

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

然而,也可以将另一个视图置于前台一小段时间以填充其绘图缓存。也许它可以在它变得可见之前再次放置背景,因为为了获得流畅的体验,操作系统似乎在将视图实际组合到前景之前将其绘制到屏幕外。

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

I think it would be very hard to do so, as I know no way to get in control of the drawing methods of those views, and the android OS won't draw them either unless visible.

However it may be possible to foreground the other View for only a short time to fill its drawing cache. Maybe it can be put background again before it even becomes visible, as for smooth experience the OS seems to draw views offscreen before they are actually composed to foreground.

Another trick could be to attach your foreground View as an child View onto the background, and give it a very slight alpha transparency. The WebView for example can be superimposed this way very well, actually forcing both the WebView and its background to be drawn. Maybe this works with other Views too.

我的黑色迷你裙 2024-11-07 11:07:19

我使用这种方式效果很好,但有一个问题,我只是第一次拍摄一个布局的快照,当我拍摄快照时,它给了我正确的图片,但经过一些更改后,我再次拍摄它,它给了我以前的快照。

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

i m using this way its working great but there is an issue i m just taking snapshots of one layout first time when i take the snapshoot it gives me right pic but after some changes i take it again it gives me previous snapshoot.

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

This issue is solved to add
((RelativeLayout)findViewById(R.id.mainview)).destroyDrawingCache();

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文