43

I need to take a screenshot of Activity (without the title bar, and the user should NOT see that a screenshot has actually been taken) and then share it via an action menu button "share". I have already tried some solutions, but they didn't work for me. Any ideas?

SilentKnight
  • 13,063
  • 18
  • 46
  • 76
just_deko
  • 892
  • 1
  • 12
  • 25
  • 1
    try [this](http://stackoverflow.com/questions/21228239/android-capture-screenshot-programmatically-without-title-bar) – dora May 12 '15 at 16:52
  • @dora this is not the perfect solution for me because it uses layouts and I don't want to do anything except just taking a screenshot of the activity. – just_deko May 12 '15 at 17:01
  • Either way you be capturing a view. Either through the xml layout or the programmatically created layout. Dora is right. – SmulianJulian May 12 '15 at 18:38
  • 1
    Possible duplicate of [How to programmatically take a screenshot in Android?](http://stackoverflow.com/questions/2661536/how-to-programmatically-take-a-screenshot-in-android) – bummi Jan 17 '16 at 07:58
  • here's how you can do it http://hackerseve.com/android-save-view-as-image-and-share-externally/ – hard coder Apr 12 '20 at 05:07

13 Answers13

103

This is how I captured the screen and shared it.

First, get root view from current activity:

View rootView = getWindow().getDecorView().findViewById(android.R.id.content);

Second, capture the root view:

 public static Bitmap getScreenShot(View view) {
       View screenView = view.getRootView();
       screenView.setDrawingCacheEnabled(true);
       Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());
       screenView.setDrawingCacheEnabled(false);
       return bitmap;
 }

Third, store the Bitmap into the SDCard:

public static void store(Bitmap bm, String fileName){
    final static String dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Screenshots";
    File dir = new File(dirPath);
    if(!dir.exists())
        dir.mkdirs();
    File file = new File(dirPath, fileName);
    try {
        FileOutputStream fOut = new FileOutputStream(file);
        bm.compress(Bitmap.CompressFormat.PNG, 85, fOut);
        fOut.flush();
        fOut.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

At last, share the screenshot of current Activity:

private void shareImage(File file){
    Uri uri = Uri.fromFile(file);
    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, "");
    intent.putExtra(Intent.EXTRA_STREAM, uri);
    try {
        startActivity(Intent.createChooser(intent, "Share Screenshot"));
    } catch (ActivityNotFoundException e) {
        Toast.makeText(context, "No App Available", Toast.LENGTH_SHORT).show();
    }
}

I hope you will be inspired by my codes.

UPDATE:

Add below permissions into your AndroidManifest.xml:

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

Because it creates and accesses files in external storage.

UPDATE:

Starting from Android 7.0 Nougat sharing file links are forbiden. To deal with this you have to implement FileProvider and share "content://" uri not "file://" uri.

Here is a good description how to do it.

CopsOnRoad
  • 109,635
  • 30
  • 367
  • 257
SilentKnight
  • 13,063
  • 18
  • 46
  • 76
  • its taking the screenshot but not showing in gallery when i check the device storage there are screenshot files but when i try to click them it says unable to find app to open this file – Asad Mehmood Jul 24 '15 at 06:29
  • It can't be. Catch `ActivityNotFoundException` of `startActivity(Intent.createChooser(intent, "Share Screenshot"));` and after that `Toast.makeText(context, "No App Available", Toast.LENGTH_SHORT).show();`. – SilentKnight Jul 24 '15 at 09:58
  • 5
    java.io.FileNotFoundException: /storage/emulated/0/Screenshots/image: open failed: ENOENT (No such file or directory) – Chase Roberts Nov 10 '15 at 17:50
  • There's a few wrong things. On the **store()** method, both the String and the File have the same name (*dir*), so the compiler is obviously going to complain. Just change one of those names. Secondly, on the **shareImage()** method you're passing a String argument, but then you call the **Uri.fromFile()** with that String argument, which is obviously wrong since this last method is expecting a File and not a String. Just pass a File instead of a String. Finally the **store()** method should return the written file, so then you can pass it to the **shareImage()** one as an argument. – Miquel Perez Apr 15 '16 at 21:11
  • @MiquelPerez It's not the absolute solution. You can modify partial parameters, right? – SilentKnight Aug 05 '16 at 09:56
  • @HamzehSoboh this method applied for `View`, is google maps a `View`? – SilentKnight Aug 11 '16 at 09:46
  • There's indeed a mapView `com.google.android.gms.maps.MapView` that extends FrameLayout, but I think there's a special way to take a screenshot for the map alone (somewhere else on stackoverflow) but your way still perfect for the normal cases. – Hamzeh Soboh Aug 11 '16 at 10:35
  • @HamzehSoboh I didn't try, but i'm afraid the content of `MapView` and `VideoView` can't be sreenshotted in this way. – SilentKnight Aug 11 '16 at 11:25
  • 2
    Worked like a charm but if you want to use this code you should be good at coding! – Java Nerd Nov 22 '16 at 16:17
  • How i use this if I am using Xamarin forms as well as a dependency logic to trigger the screen capture method? – DrPatience Feb 14 '17 at 16:57
  • The file format is not supporting is showing .. I call like shareImage(store(getScreenShot(rootView),"anyname")); – Tapan Kumar Patro Jun 04 '17 at 14:29
  • I am getting null value in screenView.getDrawingCache(). Please help! – Neha Prakash Dec 07 '17 at 13:12
  • @NehaPrakash Did you inflate your screenView? Did you screenView.setDrawingCacheEnabled(true)? – SilentKnight Dec 10 '17 at 07:24
17

create share button with click on listener

    share = (Button)findViewById(R.id.share);
    share.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Bitmap bitmap = takeScreenshot();
            saveBitmap(bitmap);
            shareIt();
        }
    });

Add two methods

    public Bitmap takeScreenshot() {
    View rootView = findViewById(android.R.id.content).getRootView();
    rootView.setDrawingCacheEnabled(true);
    return rootView.getDrawingCache();
    }

public void saveBitmap(Bitmap bitmap) {
    imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(imagePath);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();
    } catch (FileNotFoundException e) {
        Log.e("GREC", e.getMessage(), e);
    } catch (IOException e) {
        Log.e("GREC", e.getMessage(), e);
    }
}

Share screen shot. sharing implementation here

    private void shareIt() {
    Uri uri = Uri.fromFile(imagePath);
    Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
    sharingIntent.setType("image/*");
    String shareBody = "In Tweecher, My highest score with screen shot";
    sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "My Tweecher score");
    sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
    sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);

    startActivity(Intent.createChooser(sharingIntent, "Share via"));
    }
Mani kandan
  • 331
  • 3
  • 12
5

You can the below code to get the bitmap for the view you are seeing on screen You can specify which view to create bitmap.

    public static Bitmap getScreenShot(View view) {
           View screenView = view.getRootView();
           screenView.setDrawingCacheEnabled(true);
           Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());
           screenView.setDrawingCacheEnabled(false);
           return bitmap;
     }
Manish
  • 1,085
  • 8
  • 27
5

I couldn't get Silent Knight's answer to work to work until I added

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

to my AndroidManifest.xml.

Community
  • 1
  • 1
Chase Roberts
  • 8,262
  • 10
  • 64
  • 118
3

You can take screenshot of any portion of your view.You just need the reference of the layout of which you want the screenshot. for example in your case you want the screen shot of your activity. let assume that your activity root layout is Linear Layout .

   // find the reference of the layout which screenshot is required

     LinearLayout LL = (LinearLayout) findViewById(R.id.yourlayout);
      Bitmap screenshot = getscreenshot(LL);

     //use this method to get the bitmap
      private Bitmap getscreenshot(View view) {
        View v = view;
        v.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(v.getDrawingCache());
        return bitmap;
      }
Chandra Sharma
  • 1,269
  • 12
  • 25
  • This throws this error: `java.lang.NullPointerException: Attempt to invoke virtual method 'int android.graphics.Bitmap.getWidth()' on a null object reference` – bonafernando May 09 '18 at 20:56
  • @bonafernando It seems you are passing a null view .check your layout reference null. – Chandra Sharma May 11 '18 at 07:04
  • I was passing the LinearLayout of that view, I have double checked that... But it's ok. I have turned it around screen shooting the scroll view. – bonafernando May 14 '18 at 17:42
3

for taking screenshot

 public Bitmap takeScreenshot() {
    View rootView = findViewById(android.R.id.content).getRootView();
    rootView.setDrawingCacheEnabled(true);
    return rootView.getDrawingCache();
}

for saving screenshot

private void saveBitmap(Bitmap bitmap) {
    imagePath = new File(Environment.getExternalStorageDirectory() + "/scrnshot.png"); ////File imagePath
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(imagePath);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();
    } catch (FileNotFoundException e) {
        Log.e("GREC", e.getMessage(), e);
    } catch (IOException e) {
        Log.e("GREC", e.getMessage(), e);
    }
}

and for sharing

private void shareIt() {
    Uri uri = Uri.fromFile(imagePath);
    Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
    sharingIntent.setType("image/*");
    String shareBody = "My highest score with screen shot";
    sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "My Catch score");
    sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, shareBody);
    sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);

    startActivity(Intent.createChooser(sharingIntent, "Share via"));
}

and simply in the onclick you can call these methods

shareScoreCatch.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Bitmap bitmap = takeScreenshot();
        saveBitmap(bitmap);
        shareIt();
   }
});
Rupesh K.C
  • 41
  • 6
2

For all the Xamarin Users:

Xamarin.Android Code:

Create an external Class (I have an interface for each platform, and I implemented those 3 below functions from android platform):

    public static Bitmap TakeScreenShot(View view)
    {
        View screenView = view.RootView;
        screenView.DrawingCacheEnabled = true;
        Bitmap bitmap = Bitmap.CreateBitmap(screenView.DrawingCache);
        screenView.DrawingCacheEnabled = false;
        return bitmap;
    }
    public static Java.IO.File StoreScreenShot(Bitmap picture)
    {
        var folder = Android.OS.Environment.ExternalStorageDirectory + Java.IO.File.Separator + "MyFolderName";
        var extFileName = Android.OS.Environment.ExternalStorageDirectory +
                          Java.IO.File.Separator +
                          Guid.NewGuid() + ".jpeg";
        try
        {
            if (!Directory.Exists(folder))
                Directory.CreateDirectory(folder);

            Java.IO.File file = new Java.IO.File(extFileName);

            using (var fs = new FileStream(extFileName, FileMode.OpenOrCreate))
            {
                try
                {
                    picture.Compress(Bitmap.CompressFormat.Jpeg, 100, fs);
                }
                finally
                {
                    fs.Flush();
                    fs.Close();
                }
                return file;
            }
        }
        catch (UnauthorizedAccessException ex)
        {
            Log.Error(LogPriority.Error.ToString(), "-------------------" + ex.Message.ToString());
            return null;
        }
        catch (Exception ex)
        {
            Log.Error(LogPriority.Error.ToString(), "-------------------" + ex.Message.ToString());
            return null;
        }
    }
    public static void ShareImage(Java.IO.File file, Activity activity, string appToSend, string subject, string message)
    {
        //Push to Whatsapp to send
        Android.Net.Uri uri = Android.Net.Uri.FromFile(file);
        Intent i = new Intent(Intent.ActionSendMultiple);
        i.SetPackage(appToSend); // so that only Whatsapp reacts and not the chooser
        i.AddFlags(ActivityFlags.GrantReadUriPermission);
        i.PutExtra(Intent.ExtraSubject, subject);
        i.PutExtra(Intent.ExtraText, message);
        i.PutExtra(Intent.ExtraStream, uri);
        i.SetType("image/*");
        try
        {
            activity.StartActivity(Intent.CreateChooser(i, "Share Screenshot"));
        }
        catch (ActivityNotFoundException ex)
        {
            Toast.MakeText(activity.ApplicationContext, "No App Available", ToastLength.Long).Show();
        }
    }`

Now, from your Activity, you run the above code like this:

                    RunOnUiThread(() =>
                {
                    //take silent screenshot
                    View rootView = Window.DecorView.FindViewById(Resource.Id.ActivityLayout);
                    Bitmap tmpPic = ShareHandler.TakeScreenShot(this.CurrentFocus); //TakeScreenShot(this);
                    Java.IO.File imageSaved = ShareHandler.StoreScreenShot(tmpPic);
                    if (imageSaved != null)
                    {
                        ShareHandler.ShareImage(imageSaved, this, "com.whatsapp", "", "ScreenShot Taken from: " + "Somewhere");
                    }
                });

Hope it will be of use to anyone.

Roy Doron
  • 1,099
  • 9
  • 22
1

You can try the below code to capture the screenshot of current screen and share that image without any LIBRARY & PERMISSION. I have tested this its working perfectly.

Just copy paste this.

  1. In MainAtivity.java

     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);
    
            StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build());
            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)));
        }
    }
    
    1. ScreenshotType.java

      public enum ScreenshotType {
          FULL, CUSTOM;
      }
      
    2. ScreenshotUtils.java

      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_DOWNLOADS), "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;
      
      
      
      }
      

      }

4.activity_main.xml

<?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>
Zeeshan Fareed
  • 469
  • 2
  • 13
1

A consolidated copy and paste code:

private void takeScreenshot() {
        Date now = new Date();
        android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);

        try {
            // image naming and path  to include sd card  appending name you choose for file
            String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
            String screenshotPath = mPath;

            // create bitmap screen capture
            View v1 = getWindow().getDecorView().getRootView();
            v1.setDrawingCacheEnabled(true);
            Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
            v1.setDrawingCacheEnabled(false);

            File imageFile = new File(mPath);

            FileOutputStream outputStream = new FileOutputStream(imageFile);
            int quality = 100;
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
            outputStream.flush();
            outputStream.close();

//            openScreenshot(imageFile);
        } catch (Throwable e) {
            // Several error may come out with file handling or DOM
            e.printStackTrace();
        }
    }



    //Function to share Screenshot
    private void shareScreenshots(File file){
        Uri uri = Uri.fromFile(file);
        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, "");
        intent.putExtra(Intent.EXTRA_STREAM, uri);
        try {
            startActivity(Intent.createChooser(intent, "Share Screenshot"));
        } catch (ActivityNotFoundException e) {
            Toast.makeText(this, "No App Available", Toast.LENGTH_SHORT).show();
        }
    }

    //Function to open screenshot
    private void openScreenshot(File imageFile) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        Uri uri = Uri.fromFile(imageFile);
        intent.setDataAndType(uri, "image/*");
        startActivity(intent);
    }

chia yongkang
  • 369
  • 4
  • 13
0

This is how I captured the screen and shared it. Take a look if you are interested.

public Bitmap takeScreenshot() {
  View rootView = findViewById(android.R.id.content).getRootView();
  rootView.setDrawingCacheEnabled(true);
  return rootView.getDrawingCache();
 }

And the method that saves the bitmap image to external storage:

public void saveBitmap(Bitmap bitmap) {
File imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
FileOutputStream fos;
try {
    fos = new FileOutputStream(imagePath);
    bitmap.compress(CompressFormat.JPEG, 100, fos);
    fos.flush();
    fos.close();
} catch (FileNotFoundException e) {
    Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
    Log.e("GREC", e.getMessage(), e);
 }}

see more in : https://www.youtube.com/watch?v=LRCRNvzamwY&feature=youtu.be

0

If someone is getting an java.io.FileNotFoundException, following SilengKnight's solution, the problem is probably that writing in storage was not permited (Although we added the user-permission in the manifest). I solved it by adding this in the store function before making a new FileOutputStream.

if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {
        //Permission was denied
        //Request for permission
        ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                MY_PERMISSIONS_CODE_EXTERNAL_STORAGE);
    }
0

This Method Doesn't Need to Store and Retrieve Screenshot for Sharing Again. On just Method Call you will Able to Share Screenshot.

private Bitmap screenShot(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),view.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}

private void share(Bitmap bitmap){
    String pathofBmp=
            MediaStore.Images.Media.insertImage(ctx.getContentResolver(),
                    bitmap,"title", null);
    Uri uri = Uri.parse(pathofBmp);
    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.setType("image/*");
    shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Star App");
    shareIntent.putExtra(Intent.EXTRA_TEXT, "");
    shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
    ctx.startActivity(Intent.createChooser(shareIntent, "hello hello"));
}

Called this Method like this

share(screenShot(view));

By using this Direct Share Screenshot without having READ & WRITE Permission

Sarvesh Hon
  • 143
  • 9
-1

This is what I use to take a screenshot. The solutions described above work fine for API < 24, but for API 24 and greater another solution is needed. I've tested this method on API 15, 24, & 27.

I placed the following methods in MainActivity.java:

public class MainActivity {

...

String[] permissions = new String[]{"android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE"};
View sshotView;

...

private boolean checkPermission() {
List arrayList = new ArrayList();
for (String str : this.permissions) {
if (ContextCompat.checkSelfPermission(this, str) != 0) {
arrayList.add(str);
}
}
if (arrayList.isEmpty()) {
return true;
}
ActivityCompat.requestPermissions(this, (String[]) arrayList.toArray(new String[arrayList.size()]), 100);
return false;
}

protected void onCreate(Bundle savedInstanceState) {
...

this.sshotView = getWindow().getDecorView().findViewById(R.id.parent);
...

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

int id = item.getItemId();
switch (id) {


case R.id.action_shareScreenshot:
boolean checkPermission = checkPermission();
Bitmap screenShot = getScreenShot(this.sshotView);
if (!checkPermission) {
return true;
}
shareScreenshot(store(screenShot));
return true;

case R.id.option2:      
...    
return true;
}

return false;
}

private void shareScreenshot(File file) {
Parcelable fromFile = FileProvider.getUriForFile(MainActivity.this,
BuildConfig.APPLICATION_ID + ".com.redtiger.applehands.provider", file);
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setAction("android.intent.action.SEND");
intent.setType("image/*");
intent.putExtra("android.intent.extra.SUBJECT", XmlPullParser.NO_NAMESPACE);
intent.putExtra("android.intent.extra.TEXT", XmlPullParser.NO_NAMESPACE);
intent.putExtra("android.intent.extra.STREAM", fromFile);
try {
startActivity(Intent.createChooser(intent, "Share Screenshot"));
} catch (ActivityNotFoundException e) {
Toast.makeText(getApplicationContext(), "No Communication Platform Available", Toast.LENGTH_SHORT).show();
}
}

public static Bitmap getScreenShot(View view) {
View rootView = view.getRootView();
rootView.setDrawingCacheEnabled(true);
Bitmap createBitmap = Bitmap.createBitmap(rootView.getDrawingCache());
rootView.setDrawingCacheEnabled(false);
return createBitmap;

public File store(Bitmap bitmap) {
String str = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Pictures/Screenshots";
File file = new File(str);
if (!file.exists()) {
file.mkdirs();
}
file = new File(str + "/sshot.png");
try {
OutputStream fileOutputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 80, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "External Storage Permission Is Required", Toast.LENGTH_LONG).show();
}
return file;
}
}

I placed the following permissions and provider in my AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.redtiger.applehands">

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

<application

...

<provider
android:name="com.redtiger.applehands.util.GenericFileProvider"
android:authorities="${applicationId}.com.redtiger.applehands.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>

...

</application>

</manifest>

I created a file called provider_paths.xml (please see below) to direct the FileProvider where to save the screenshot. The file contains a simple tag that points to the root of the external directory.

The File was placed in the resource folder res/xml (if you don't have an xml folder here, just create one and place your file there).

provider_paths.xml:

<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
Purkey
  • 61
  • 6