
Today we are going to learn how to take screenshot programatically in Android. It will help you if you want to share any screen from your app to WhatsApp, Facebook, Hangout or any other app.
Before starting the article please go through Share Image and Text article it will help you in this article.
Example
In this tutorial, we are going to learn how to take Screenshot and share the taken Screenshot to other apps.
VIDEO DEMO
1. Create a new project in Android Studio by navigating to File ⇒ New ⇒ New Project and fill required details. By default my activity is MainActivity.java.
2. Open res ⇒ values ⇒ strings.xml and add below string values. These are some strings that we are going to use in our project.
1 2 3 4 5 6 7 8 9 10 |
<resources> <string name="app_name">Take Screenshot Demo</string> <string name="sharing_text">Your sharing text goes here…</string> <string name="share_title">Share Screenshot</string> <string name="screenshot_take_failed">Failed to take screenshot!!</string> <string name="wait">Please wait…</string> <string name="full_page_screenshot">Full Page Screenshot</string> <string name="hidden_text">Hidden Text</string> <string name="custom_page_screenshot">Custom Page Screenshot</string> </resources> |
3. Now, open activity_main.xml layout and add the below code to it. In this layout we are taking some Button to take Screenshot and an ImageView to show taken ScreenShot.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/root_content" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp" tools:context="com.takescreenshot_demo.MainActivity"> <!-- Button which will take full page screenshot --> <Button android:id="@+id/full_page_screenshot" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/full_page_screenshot" android:textColor="@android:color/white" android:textSize="14sp" /> <!-- Hidden Text which will shown when taking screenshot from below Button --> <TextView android:id="@+id/hidden_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/hidden_text" android:textColor="@android:color/white" android:textSize="14sp" android:visibility="invisible" /> <!-- Button which will take screenshot after hiding some view and showing some view --> <Button android:id="@+id/custom_page_screenshot" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/custom_page_screenshot" android:textColor="@android:color/white" android:textSize="14sp" /> <!-- ImageView to show taken Screenshot --> <ImageView android:id="@+id/image_view" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter" android:src="@mipmap/ic_launcher" /> </LinearLayout> |
4. Create an enum java class naming ScreenshotType and add two type FULL and CUSTOM. This class will help me to distinguish between type of screenshot that i need to take.
1 2 3 4 5 6 7 8 9 10 11 |
package com.takescreenshot_demo; /** * Created by sonu on 23/03/17. */ /* ENUM to identify the type of Screenshot */ public enum ScreenshotType { FULL, CUSTOM; } |
5. Now open your MainActivity.java and add the below code. In below class the code that is important for taking screenshot and sharing it are:
- Take Screenshot : For Custom screenshot where you need to hide some view or show some view then there for hiding views you need to use visibility mode INVISIBLE instead of GONE because for GONE mode it won’t consider the view in frame and will not show up or hide while taking screenshot.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
/* Method which will take screenshot on Basis of Screenshot Type ENUM */ private void takeScreenshot(ScreenshotType screenshotType) { Bitmap b = null; switch (screenshotType) { case FULL: //If Screenshot type is FULL take full page screenshot i.e our root content. b = ScreenshotUtils.getScreenShot(rootContent); break; case CUSTOM: //If Screenshot type is CUSTOM fullPageScreenshot.setVisibility(View.INVISIBLE);//set the visibility to INVISIBLE of first button hiddenText.setVisibility(View.VISIBLE);//set the visibility to VISIBLE of hidden text b = ScreenshotUtils.getScreenShot(rootContent); //After taking screenshot reset the button and view again fullPageScreenshot.setVisibility(View.VISIBLE);//set the visibility to VISIBLE of first button again hiddenText.setVisibility(View.INVISIBLE);//set the visibility to INVISIBLE of hidden text //NOTE: You need to use visibility INVISIBLE instead of GONE to remove the view from frame else it wont consider the view in frame and you will not get screenshot as you required. break; } //If bitmap is not null if (b != null) { showScreenShotImage(b);//show bitmap over imageview File saveFile = ScreenshotUtils.getMainDirectoryName(this);//get the path to save screenshot File file = ScreenshotUtils.store(b, "screenshot" + screenshotType + ".jpg", saveFile);//save the screenshot to selected path shareScreenshot(file);//finally share screenshot } else //If bitmap is null show toast message Toast.makeText(this, R.string.screenshot_take_failed, Toast.LENGTH_SHORT).show(); } |
- Share Screenshot
1 2 3 4 5 6 7 8 9 10 11 |
/* Share Screenshot */ private void shareScreenshot(File file) { Uri uri = Uri.fromFile(file);//Convert file path into Uri for sharing Intent intent = new Intent(); intent.setAction(Intent.ACTION_SEND); intent.setType("image/*"); intent.putExtra(android.content.Intent.EXTRA_SUBJECT, ""); intent.putExtra(android.content.Intent.EXTRA_TEXT, getString(R.string.sharing_text)); intent.putExtra(Intent.EXTRA_STREAM, uri);//pass uri here startActivity(Intent.createChooser(intent, getString(R.string.share_title))); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
package com.takescreenshot_demo; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import java.io.File; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button fullPageScreenshot, customPageScreenshot; private LinearLayout rootContent; private ImageView imageView; private TextView hiddenText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViews(); implementClickEvents(); } /* Find all views Ids */ private void findViews() { fullPageScreenshot = (Button) findViewById(R.id.full_page_screenshot); customPageScreenshot = (Button) findViewById(R.id.custom_page_screenshot); rootContent = (LinearLayout) findViewById(R.id.root_content); imageView = (ImageView) findViewById(R.id.image_view); hiddenText = (TextView) findViewById(R.id.hidden_text); } /* Implement Click events over Buttons */ private void implementClickEvents() { fullPageScreenshot.setOnClickListener(this); customPageScreenshot.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.full_page_screenshot: takeScreenshot(ScreenshotType.FULL); break; case R.id.custom_page_screenshot: takeScreenshot(ScreenshotType.CUSTOM); break; } } /* Method which will take screenshot on Basis of Screenshot Type ENUM */ private void takeScreenshot(ScreenshotType screenshotType) { Bitmap b = null; switch (screenshotType) { case FULL: //If Screenshot type is FULL take full page screenshot i.e our root content. b = ScreenshotUtils.getScreenShot(rootContent); break; case CUSTOM: //If Screenshot type is CUSTOM fullPageScreenshot.setVisibility(View.INVISIBLE);//set the visibility to INVISIBLE of first button hiddenText.setVisibility(View.VISIBLE);//set the visibility to VISIBLE of hidden text b = ScreenshotUtils.getScreenShot(rootContent); //After taking screenshot reset the button and view again fullPageScreenshot.setVisibility(View.VISIBLE);//set the visibility to VISIBLE of first button again hiddenText.setVisibility(View.INVISIBLE);//set the visibility to INVISIBLE of hidden text //NOTE: You need to use visibility INVISIBLE instead of GONE to remove the view from frame else it wont consider the view in frame and you will not get screenshot as you required. break; } //If bitmap is not null if (b != null) { showScreenShotImage(b);//show bitmap over imageview File saveFile = ScreenshotUtils.getMainDirectoryName(this);//get the path to save screenshot File file = ScreenshotUtils.store(b, "screenshot" + screenshotType + ".jpg", saveFile);//save the screenshot to selected path shareScreenshot(file);//finally share screenshot } else //If bitmap is null show toast message Toast.makeText(this, R.string.screenshot_take_failed, Toast.LENGTH_SHORT).show(); } /* Show screenshot Bitmap */ private void showScreenShotImage(Bitmap b) { imageView.setImageBitmap(b); } /* Share Screenshot */ private void shareScreenshot(File file) { Uri uri = Uri.fromFile(file);//Convert file path into Uri for sharing Intent intent = new Intent(); intent.setAction(Intent.ACTION_SEND); intent.setType("image/*"); intent.putExtra(android.content.Intent.EXTRA_SUBJECT, ""); intent.putExtra(android.content.Intent.EXTRA_TEXT, getString(R.string.sharing_text)); intent.putExtra(Intent.EXTRA_STREAM, uri);//pass uri here startActivity(Intent.createChooser(intent, getString(R.string.share_title))); } } |
- Take Screenshot
1 2 3 4 5 6 7 8 |
/* Method which will return Bitmap after taking screenshot. We have to pass the view which we want to take screenshot. */ public static Bitmap getScreenShot(View view) { View screenView = view.getRootView(); screenView.setDrawingCacheEnabled(true); Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache()); screenView.setDrawingCacheEnabled(false); return bitmap; } |
- Create Directory : Here you need to use getExternalFilesDir instead of getExternalStorageDirectory because when you uninstall app then the images/screenshots will deleted automatically.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* Create Directory where screenshot will save for sharing screenshot */ public static File getMainDirectoryName(Context context) { //Here we will use getExternalFilesDir and inside that we will make our Demo folder //benefit of getExternalFilesDir is that whenever the app uninstalls the images will get deleted automatically. File mainDir = new File( context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "Demo"); //If File is not present create directory if (!mainDir.exists()) { if (mainDir.mkdir()) Log.e("Create Directory", "Main Directory Created : " + mainDir); } return mainDir; } |
- Store Screenshot
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
/* Store taken screenshot into above created path */ public static File store(Bitmap bm, String fileName, File saveFilePath) { File dir = new File(saveFilePath.getAbsolutePath()); if (!dir.exists()) dir.mkdirs(); File file = new File(saveFilePath.getAbsolutePath(), fileName); try { FileOutputStream fOut = new FileOutputStream(file); bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut); fOut.flush(); fOut.close(); } catch (Exception e) { e.printStackTrace(); } return file; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
package com.takescreenshot_demo; import android.content.Context; import android.graphics.Bitmap; import android.os.Environment; import android.util.Log; import android.view.View; import java.io.File; import java.io.FileOutputStream; /** * Created by sonu on 23/03/17. */ public class ScreenshotUtils { /* Method which will return Bitmap after taking screenshot. We have to pass the view which we want to take screenshot. */ public static Bitmap getScreenShot(View view) { View screenView = view.getRootView(); screenView.setDrawingCacheEnabled(true); Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache()); screenView.setDrawingCacheEnabled(false); return bitmap; } /* Create Directory where screenshot will save for sharing screenshot */ public static File getMainDirectoryName(Context context) { //Here we will use getExternalFilesDir and inside that we will make our Demo folder //benefit of getExternalFilesDir is that whenever the app uninstalls the images will get deleted automatically. File mainDir = new File( context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "Demo"); //If File is not present create directory if (!mainDir.exists()) { if (mainDir.mkdir()) Log.e("Create Directory", "Main Directory Created : " + mainDir); } return mainDir; } /* Store taken screenshot into above created path */ public static File store(Bitmap bm, String fileName, File saveFilePath) { File dir = new File(saveFilePath.getAbsolutePath()); if (!dir.exists()) dir.mkdirs(); File file = new File(saveFilePath.getAbsolutePath(), fileName); try { FileOutputStream fOut = new FileOutputStream(file); bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut); fOut.flush(); fOut.close(); } catch (Exception e) { e.printStackTrace(); } return file; } } |
Thanks.
THANK YOU! this works perfectly.
Jochen