Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android taking screenshot of offscreen page

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.

like image 826
Krishnabhadra Avatar asked Apr 09 '11 09:04

Krishnabhadra


3 Answers

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...

like image 154
Kandha Avatar answered Nov 20 '22 22:11

Kandha


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);
        } 
      }
    }
    
like image 34
Krishnabhadra Avatar answered Nov 20 '22 20:11

Krishnabhadra


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.

like image 1
dronus Avatar answered Nov 20 '22 21:11

dronus