1

I'm trying to implement a system whereby if an uncaught exception occurs, my exception handler will take a screenshot of the activity, to be saved and sent off as part of a bug report. Is this even possible in Android? I'm passing the activity to the exception handler in the constructor, but every attempt I've used so far to get the screenshot has returned null.

I've tried the following:

Attempt One:

private Bitmap screenshot() {
    View view = activity.getWindow().getDecorView(); //also tried getDecorView().getRootView()
    view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    view.setDrawingCacheEnabled(true);
    view.buildDrawingCache(true);
    Bitmap image = view.getDrawingCache();
    Rect windowbounds = new Rect();
    view.getWindowVisibleDisplayFrame(windowbounds);
    int width = activity.getWindowManager().getDefaultDisplay().getWidth();
    int height = activity.getWindowManager().getDefaultDisplay().getHeight();
    Bitmap secondaryBitmap = Bitmap.createBitmap(image, 0, 0, width, height);
    view.destroyDrawingCache();
    return secondaryBitmap;
}

Attempt Two:

private Bitmap screenshot2()
{
    View view = activity.getWindow().getDecorView(); //also tried getDecorView().getRootView()
    view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    Bitmap viewBmp = Bitmap.createBitmap(view.getWidth(),view.getHeight(),
            Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(viewBmp);
    view.draw(canvas);
    return viewBmp;
}

In attempt #1 the view.getDrawingCache() returns null, and in attempt #2 Bitmap.createBitmap returns null.

Any Android developers have any idea on how to take a screenshot in the UncaughtExceptionHandler?

user2459186
  • 37
  • 1
  • 6

1 Answers1

0

You do not want:

Bitmap viewBmp = Bitmap.createBitmap(view.getLayoutParams().width, view.getLayoutParams().height,
        Bitmap.Config.ARGB_8888);

The LayoutParams does not normally have the actual width and height. Often it has negative values, indicating wrap_content or match_parent.

Instead, try:

Bitmap viewBmp = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
        Bitmap.Config.ARGB_8888);

or something along those lines. You want the actual width and height of the container, not the width and height requested by its LayoutParams.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Thanks for your answer CW. I've changed it to "view.getWidth()" and "getHeight()" and both of these functions are returning 0? Is it possible that the layout no longer exists by the time that the exception handler is called? – user2459186 Oct 28 '13 at 11:44
  • @user2459186: Either that, or the exception occurred before the layout was measured (e.g., in `onCreate()` of the activity). – CommonsWare Oct 28 '13 at 12:02
  • Thanks for your input, I was actually deliberately causing a null pointer exception in my OnResume method in order to test this code, and it seems that you are correct, the layout wasn't measured at this point in time. – user2459186 Oct 28 '13 at 13:21
  • @user2459186: Since exceptions are, well, exceptional, you will need smarts in your uncaught exception handler to see if your width/height is non-zero, and only try to take the screenshot when that is true. – CommonsWare Oct 28 '13 at 13:32
  • You're quite right, I've tightened up the handler a lot now. Thanks again! – user2459186 Oct 28 '13 at 13:58