Kyle Banks

Programmatically Create a Screenshot of your Android App or Game - or Even a Single View

Written by @kylewbanks on Sep 10, 2016.

Allowing users to share screenshots of a their progress in a game, or their view of an app, is a great way to drive installs and increase the reach of your Android application. Users can certainly use the native screenshot functionality of their device, but it would be great to be able to provide a button or any other means of sharing their view from within the app, that takes a screenshot of the relevant content for them.

Turns out, the Android View class provides the means for this functionality out-of-the-box, with very minimal effort. What we can do is take a particular View, and create a Bitmap from it’s contents, which can then be compressed into JPEG, PNG or WEBP format and shared natively to any app that accepts images.

Here’s how you can get the Bitmap:

private Bitmap getScreenshot(View view) {
    view.setDrawingCacheEnabled(true);
    Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
    view.setDrawingCacheEnabled(false);
    
    return bitmap;
}

What we’re doing is setting the Drawing Cache Enabled flag of the View to true. This allows us to request the drawing cache from the View which is returned as a Bitmap. We then create a copy of the Bitmap using Bitmap.createBitmap, because the one returned from getDrawingCache is already recycled and cannot be modified. Finally, we reset the Drawing Cache Enabled flag to false to prevent the View from constantly creating cached Bitmap objects of it’s contents, since we won’t be needing them again.

Now that we have access to a Bitmap, we can store it in a file like so:

Bitmap bitmap = getScreenshot(view);
String path = Environment.getExternalStorageDirectory().toString() + "/screenshot.jpg";

FileOutputStream outputStream = new FileOutputStream(new File(path));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.flush();
outputStream.close();
bitmap.recycle();

We take the Bitmap returned by getScreenshot, and compress it into a FileOutputStream. The Bitmap will be saved in JPEG format, but you could also use PNG or WEBP as you see fit.

Now with the file in place, we can easily share it with other apps, such as Twitter or Facebook:

Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_TEXT, "Check out my sweet screenshot!");
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + path));
shareIntent.setType("image/jpeg");
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

startActivity(Intent.createChooser(shareIntent, "Share"));

The user will then be presented with a native UI to select an app to share the image with - easy!

Additional Considerations

Don’t forget though, since we’re writing the image file to an external directory, we’ll need the appropriate permissions:

AndroidManifest.xml:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Or for Android 6.0 and up you’ll need to request the permissions at runtime:

if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED()) {
    requestPermissions(this, new String[]{
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    }, WRITE_EXTERNAL_REQUEST_CODE);
}

Refer to the Android documentation for more detailed instructions and examples on requesting permissions at runtime.

Let me know if this post was helpful on Twitter @kylewbanks or down below!