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.
In this tutorial, we are going to learn how to take Screenshot and share the taken Screenshot to other apps.
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:
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(); } |
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))); } |
Full Code:
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))); } } |
6. Finally create new java class naming ScreenshotUtils.java. In this class we add some static method which help to take screenshot, make directory and store taken 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; } |
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; } |
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; } |
Full Code:
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; } } |
7. Hurray!! Now you are all set up and can add this feature to your apps.
Thanks.
Subscribe to us and get the latest news.
8 Comments
Jochen
Sunday, September 24th, 2017THANK YOU! this works perfectly.
Jochen
Reza
Friday, July 6th, 2018thank you so much man 🙂
God bless you
thomas
Tuesday, August 7th, 2018using marshmallow, app crashes when clicking screenshot button
Dr. Droid
Tuesday, August 7th, 2018Hi Thomas,
The app is crashing due to there is no Run-Time Permission for Marshmallow Device. You can check the below link to add this permission :
https://www.androhub.com/working-android-marshmallow-6-0-permissions/
Thanks
thomas
Tuesday, August 7th, 2018thanks!~
Aman Rohilla
Tuesday, January 28th, 2020Can you tell me how to take screenshot of videoView. I mean the current frame that is being played in the videoView.
Dr. Droid
Tuesday, January 28th, 2020Hi Aman,
Please check this link : https://stackoverflow.com/questions/10736517/playing-video-on-textureview
here you have to use textureView to take screenshot.
Hope it helps.
Thanks
Anton
Friday, August 27th, 2021Excellent, but some methods are deprecated, e.g. .setDrawaingCache(). I have a problem in that this code works if I run it in .onResume(), but if I use it later in the process, through the click button, certain views disseappaers in the screenshot. Specifically, mpandroid chart charts are gone. Any idea how to scrupulously ensure ALL view that there visible when screenshot is initiated, also become part of screenshot?