Save Screenshot into Internal Storage and Sync into Gallery? - android

I have searched high and low for a way to do this and the best I could find involved saving the screenshot into the SD Card. What I want to do instead is to onclick(), take a screenshot of the current activity and saves it in the internal storage so that the user can view it in their gallery as and when they want.
Any help is greatly appreciated.

It is harder to post a whole code in here. I think you should follow some tutorials.
According to the your requirement what I got is, You need to take a screenshot using an your application and it should be stored in device SD card.
For that you should add proper permission to the manifest first,
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
and add following code to the activity:
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, you can change it to your path
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
// 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) {
e.printStackTrace();
}
}
this code will open the generated image(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);
}
This is how I did for my project. Sometimes this might be not satisfied for you requirement. It it is not satisfied, please follow these tutorials, Thanks
Reference List : http://www.androhub.com/take-a-screenshot-programmatically-in-android/
http://devdeeds.com/take-screenshot-programmatically/
https://www.viralandroid.com/2016/01/how-to-take-screenshot-programmatically-in-android.html
if you want to check whether SD card is available or not. here is the way. If SD card is not available then you can use internal storage to store the image.
Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
Boolean isSDSupportedDevice = Environment.isExternalStorageRemovable();
if(isSDSupportedDevice && isSDPresent)
{
// yes SD-card is present
}
else
{
// SD-card not available
}

Related

Share screenshot in android

I don't have SD card in my mobile also was hoping people who use my app may or may not have it. Now when I tried to share my screenshot it works in few mobiles and does not work in few. In all these mobiles none of them have SD card. Also I want to make sure that the screenshots should not get saved anywhere so that it will not be visible in the gallery. I tried with the following methods:
getExternalStorageState()
getDatadirectory()
getFilesDir()
getDir()
getCacheDir()
But I still couldn't get the right approach in doing so. This is the present code that I'm working on :
view.setDrawingCacheEnabled(true);
view.measure(View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(view.getHeight(), View.MeasureSpec.EXACTLY));
view.layout( view.getLeft(), view.getTop(), view.getLeft() + view.getMeasuredWidth(), view.getTop() + view.getMeasuredHeight());
bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
view.destroyDrawingCache();
view.invalidate();
view.refreshDrawableState();
File path = new File(getApplicationContext().getDir("Default", Context.MODE_ENABLE_WRITE_AHEAD_LOGGING),"myapp");
File directory = new File(path.getAbsolutePath());
directory.mkdirs();
String filename = "myapp" + new Date() + ".png";
File yourFile = new File(directory, filename);
try
{
FileOutputStream out = new FileOutputStream(yourFile, true);
bitmap.compress(Bitmap.CompressFormat.PNG, 90,out);
out.flush();
out.close();
send(yourFile);
}catch (IOException e)
{
e.printStackTrace();
}
Now my focus is on sharing the screenshot in a mobile where it does not have SD card and it should not save anywhere so that the screenshots wouldn't keep dumping as I go on sharing. How to do it ?
EDIT :
Now I started working on getDir() method so that the files will be getting saved on Application data as noted by my friend Ashish Vora. I have found that the files are getting saved inside but it is not retrieved back for sharing. All I'm getting is a blank screen.
Best thing is to save it using getDir().
So it will be in your Application data and not visible in Gallery. Also you can share it using your Application.
So save it as:
File path = new File( getDir(YOUR_DEFAULT_DIRECTORY_NAME, Context.MODE_ENABLE_WRITE_AHEAD_LOGGING));
File directory = new File(path.getAbsolutePath()+ "/my app");
Else you can use as:
File directory = new File(getDir("my app", Context.MODE_ENABLE_WRITE_AHEAD_LOGGING));

internal storage for app and uri

So I'm using the twitter api and I want to tweet with an image I use:
TweetUri = Uri.fromFile(saveIT);
TweetComposer.Builder builder = new TweetComposer.Builder(this)
.text("")
.image(TweetUri);
builder.show();
The original image is a bitmap, so what I did (not sure if this is the optimal way) was save in the internal storage:
private File saveToInternalStorage(Bitmap bitmapImage){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
// Create imageDir
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmss").format(new Date());
String mImageName="MI_"+ timeStamp +".jpg";
File mypath=new File(directory,mImageName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try
{
fos.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
return mypath;
}
The file it returns will be the "saveIT" in the TweetUri when it does the fromfile method. Of course this will overload the storage so what I plan to do is wipe the internal storage for the app when it is stopped (no other data is saved in the internal storage other than the temp images I save for the tweet):
#Override
protected void onStop() {
super.onStop();
File MSD = this.getApplicationContext().getFilesDir();
File [] lisFiles = MSD.listFiles();
for(int i=0;i<lisFiles.length;i++)
{
boolean deleted = lisFiles[i].delete();
}
}
None of this works... I can't seem to find any of the images when I save them to verify if the deleting is happening. Also, when the user clicks tweet no image is added to the tweet as well. No idea what I'm doing wrong here... In reality I don't want to save the image in the internal storage but I do because the tweet api uses a URI to tweet and not a bitmap.
I switched it to write to external storage and it worked fine. Also I switched it to delete at onDestroy. This is better because, when I invoke the Twitter API it switches activities so the onstop is invoked which would delete the temp picture too early. It's too early becuase if the user clicks cancel at the twitter api, comes back to my api and then invokes the twitter api again the uri will point to nothing since the picture was already deleted. THATS ALL FOLKS :)

Extract exif information of image in android

Im new to android development and trying to get metadata of image using ExifInterface. I stored the image under drawable and trying to get the metadata but getting null values for all fields(date, imagelength, imagewidth). I tried to access image path as this :
String path = "drawable://" + R.drawable.testimage;
and provided this path to ExifInterface.
ExifInterface exif = new ExifInterface(path);
I dont know if storing image under drawable is correct or not because when I run the app in emulator I get something like this :
E/JHEAD﹕ can't open 'drawable://2130837561'
So if this is wrong then please tell me where should I store the image and how to provide image path to ExifInterface.
Thank you in advance.
To get a drawable, you can you this snippet:
Drawable drawable = getResources().getDrawable(android.R.drawable.your_drawable);
I'm not sure if your way is correct, as I've never seen it like that. Do you really need the path to your image to use it on that ExifInterface class?
Ok, I did some digging and found this question, which led me to this one. As it seems, you can not get an absolute path from a resource inside your apk. A good solution would be for you to save it as a file on the external memory, and then you can get the path you want.
First of all, add this to your AndroidManifest.xml, so your app can write to the cellphone memory:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Ok, to save it you can try this, first create a bitmap from your drawable resource:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.your_drawable);
After that get the path you want to save your images, and put it on a String. More info on that here.
The Android docs have a good example on how to get the path. You can see it here.
To keep it simple, I'll copy and paste the snippet from the docs.
void createExternalStoragePrivateFile() {
// Create a path where we will place our private file on external
// storage.
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
try {
// Very simple code to copy a picture from the application's
// resource into the external file. Note that this code does
// no error checking, and assumes the picture is small (does not
// try to copy it in chunks). Note that if external storage is
// not currently mounted this will silently fail.
InputStream is = getResources().openRawResource(R.drawable.balloons);
OutputStream os = new FileOutputStream(file);
byte[] data = new byte[is.available()];
is.read(data);
os.write(data);
is.close();
os.close();
} catch (IOException e) {
// Unable to create file, likely because external storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + file, e);
}
}
void deleteExternalStoragePrivateFile() {
// Get path for the file on external storage. If external
// storage is not currently mounted this will fail.
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
if (file != null) {
file.delete();
}
}
boolean hasExternalStoragePrivateFile() {
// Get path for the file on external storage. If external
// storage is not currently mounted this will fail.
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
if (file != null) {
return file.exists();
}
return false;
}
After that, get the path of the file you saved on the external memory, and do as you wish.
I'll keep the old example as well. You can use the method getExternalStorageDirectory() to get the path, or getExternalCacheDir(). After that, you can use File method called getAbsolutePath() to get your String.
String path = (...) // (you can choose where to save here.)
File file = new File(path, "your_drawable.png");
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // You can change the quality from 0 to 100 here, and the format of the file. It can be PNG, JPEG or WEBP.
out.flush();
out.close();
For more info on the Bitmap class, check the docs.
If you need more info, let me know and I'll try to show more samples.
EDIT: I saw your link, and there was this snippet there:
//change with the filename & location of your photo file
String filename = "/sdcard/DSC_3509.JPG";
try {
ExifInterface exif = new ExifInterface(filename);
ShowExif(exif);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(this, "Error!",
Toast.LENGTH_LONG).show();
}
As you can see, if you really want to see the exif data of a internal image resource, you'll have to save it somewhere else, and then you can try to get the absolute path for that File, then, call the method to show the exif.

how to get photo absolute path from removable SD card

background information
I have been writing a backup photos service, which needs to get all photo absolute paths from Android external storage (like photos stored in 'DCIM' directory and its subdirectores) and upload them to remote server. The problem is how to get all validate photo absolute paths from Android device. Since there is a vast majority of Android devices, it`s tough to ensure the get-photo-absolute-path algorithm to successfully reach all validate photos Gallery directory and traverse all photos paths inside of it.
Now my app only supports uploading photos from primary external storage (not the secondary external storage, like removable SD card). That`s to say.
if the device only has one emulated external storage (on-board flash), camera upload service can scan photo paths on it correctly.
if the device only has a removable storage (like SD card), camera upload service can scan photo paths correctly as well.
the algorithm above scans photo paths from primary external storage which works correctly. But when it comes to
if the device both has a emulated external storage and a removable storage, camera upload service only scans photo paths on the emulated external storage (primary storage), but a majority of users save their photos to the 16G or bigger size removable SD card (secondary storage) which will be ignored by my app, that`s the problem. see the complete issue here.
Code implementation
To get absolute photo path from internal storage, I hard coded an "external directory list",
String[] paths = {
"/DCIM",
"/DCIM/Camera",
"/DCIM/100MEDIA",
// Many Samsung phones mount the external sd card to /sdcard/external_sd
"/external_sd/DCIM",
"/external_sd/DCIM/Camera",
"/external_sd/DCIM/100MEDIA"
};
and combined the absolute path like
String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + path;
I know that`s not the best practice, that`s why ask for help. BTW, see the complete external directory list
Question
To get absolute photo paths from Android storage
check if external storage mounted, then scan photos from internal storage by default. This can fit a majority of getting photo path requirements, see the complete implementation here
let user choose a specific directory to upload photos from SD card (if mounted one)
So I wonder if the proposal above is right or not?
Any comments or reference will be greatly appreciated.
EDIT
Different manufacturers set their SD card mounted point differently, there is no regular rules for that, it almost impossible (or say, bad practice) to scan and upload photos by the app in the background automatically. To get photos path from SD card, the practical way I think is to only scan root directories, then shows such directories in a file browser window to let user choose a specific gallery directory and persist the path locally instead of scanning by the app itself. Because it`s error prone to scan photos directives automatically on SD card.
You can try this way
for popup
private void selectImage()
{
final CharSequence[] items = { "Camera", "Gallery","Cancel" };
AlertDialog.Builder builder = new AlertDialog.Builder(Detail_mul.this);
builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int item)
{
if (items[item].equals("Camera"))
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File f = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
startActivityForResult(intent, REQUEST_CAMERA);
} else if (items[item].equals("Gallery")) {
Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "Select File"),SELECT_FILE);
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
for getting the result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bitmap bm = null;
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_CAMERA) {
File f = new File(Environment.getExternalStorageDirectory().toString());
for (File temp : f.listFiles()) {
if (temp.getName().equals("temp.jpg")) {
f = temp;
break;
}
}
try {
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
bm = BitmapFactory.decodeFile(f.getAbsolutePath(),btmapOptions);
bm = Bitmap.createScaledBitmap(bm, 300, 200, true);
String path = android.os.Environment.getExternalStorageDirectory()+ File.separator+ "Phoenix" + File.separator + "default";
PreferenceManager.getDefaultSharedPreferences(getBaseContext()).edit().putString("endum_image_"+count, f.toString()).commit();
OutputStream fOut = null;
File file = new File(path, String.valueOf(System.currentTimeMillis()) + ".jpg");
try {
fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
fOut.flush();
fOut.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
} else if (requestCode == SELECT_FILE)
{
Uri selectedImageUri = data.getData();
//getRealPathFromURI(selectedImageUri);
String tempPath = getPath(selectedImageUri, Detail_mul.this);
PreferenceManager.getDefaultSharedPreferences(getBaseContext()).edit().putString("endum_image_"+count, tempPath).commit();
BitmapFactory.Options btmapOptions = new BitmapFactory.Options();
bm = BitmapFactory.decodeFile(tempPath,btmapOptions);
bm = Bitmap.createScaledBitmap(bm, 300, 200, true);
bm = BitmapFactory.decodeFile(tempPath, btmapOptions);
}
} }
I think you are uploading images for your photo service.You can access the gallery to select a particular picture because every picture in your phone is there in your Gallery whether on SDcard or Primary memory.
Code for accessing gallery
you can see
this code.I think this would help

Android Share Intent for a Bitmap - is it possible not to save it prior sharing?

I try to export a bitmap from my app using share intent without saving a file for a temporal location. All the examples I found are two-step
1) save to SD Card and create Uri for that file
2) start the intent with this Uri
Is it possible to make it without requiring WRITE_EXTERNAL_STORAGE permission, saving the file [and removing it afterwards]? How to address devices without ExternalStorage?
I had this same problem. I didn't want to have to ask for the read and write external storage permissions. Also, sometimes there are problems when phones don't have SD cards or the cards get unmounted.
The following method uses a ContentProvider called FileProvider. Technically, you are still saving the bitmap (in internal storage) prior to sharing, but you don't need to request any permissions. Also, every time you share the bitmap the image file gets overwritten. And since it is in the internal cache, it will be deleted when the user uninstalls the app. So in my opinion, it is just as good as not saving the image. This method is also more secure than saving it to external storage.
The documentation is pretty good (see the Further Reading below), but some parts are a little tricky. Here is a summary that worked for me.
Set up the FileProvider in the Manifest
<manifest>
...
<application>
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.myapp.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepaths" />
</provider>
...
</application>
</manifest>
Replace com.example.myapp with your app package name.
Create res/xml/filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="shared_images" path="images/"/>
</paths>
This tells the FileProvider where to get the files to share (using the cache directory in this case).
Save the image to internal storage
// save bitmap to cache directory
try {
File cachePath = new File(context.getCacheDir(), "images");
cachePath.mkdirs(); // don't forget to make the directory
FileOutputStream stream = new FileOutputStream(cachePath + "/image.png"); // overwrites this image every time
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
Share the image
File imagePath = new File(context.getCacheDir(), "images");
File newFile = new File(imagePath, "image.png");
Uri contentUri = FileProvider.getUriForFile(context, "com.example.myapp.fileprovider", newFile);
if (contentUri != null) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // temp permission for receiving app to read this file
shareIntent.setDataAndType(contentUri, getContentResolver().getType(contentUri));
shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
startActivity(Intent.createChooser(shareIntent, "Choose an app"));
}
Further reading
FileProvider
Storage Options - Internal Storage
Sharing Files
Saving Files
I try to export a bitmap from my app using share intent without saving a file for a temporal location.
In theory, this is possible. In practice, it is probably not possible.
In theory, all you need to share is a Uri that will resolve to the bitmap. The simplest approach is if that is a file that is directly accessible by the other application, such as on external storage.
To not write it to flash at all, you would need to implement your own ContentProvider, figure out how to implement openFile() to return your in-memory bitmap, and then pass a Uri representing that bitmap in the ACTION_SEND Intent. Since openFile() needs to return a ParcelFileDescriptor, I don't know how you would do that without an on-disk representation, but I have not spent much time searching.
Is it possible to make it without requiring WRITE_EXTERNAL_STORAGE permission, saving the file [and removing it afterwards]?
If you simply do not want it on external storage, you can go the ContentProvider route, using a file on internal storage. This sample project demonstrates a ContentProvider that serves up a PDF file via ACTION_VIEW to a PDF viewer on a device; the same approach could be used for ACTION_SEND.
If anyone still looking for easy and short solution without any storage permission (Supports nougat 7.0 as well). Here it is.
Add this in Manifest
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
Now create provider_paths.xml
<paths>
<external-path name="external_files" path="."/>
</paths>
Finally Add this method to your activity/fragment (rootView is the view you want share)
private void ShareIt(View rootView){
if (rootView != null && context != null && !context.isFinishing()) {
rootView.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(rootView.getDrawingCache());
if (bitmap != null ) {
//Save the image inside the APPLICTION folder
File mediaStorageDir = new File(AppContext.getInstance().getExternalCacheDir() + "Image.png");
try {
FileOutputStream outputStream = new FileOutputStream(String.valueOf(mediaStorageDir));
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (ObjectUtils.isNotNull(mediaStorageDir)) {
Uri imageUri = FileProvider.getUriForFile(getActivity(), getActivity().getApplicationContext().getPackageName() + ".provider", mediaStorageDir);
if (ObjectUtils.isNotNull(imageUri)) {
Intent waIntent = new Intent(Intent.ACTION_SEND);
waIntent.setType("image/*");
waIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
startActivity(Intent.createChooser(waIntent, "Share with"));
}
}
}
}
}
Update:
As #Kathir mentioned in comments,
DrawingCache is deprecated from API 28+. Use below code to use Canvas instead.
Bitmap bitmap = Bitmap.createBitmap(rootView.getWidth(), rootView.getHeight(), quality);
Canvas canvas = new Canvas(bitmap);
Drawable backgroundDrawable = view.getBackground();
if (backgroundDrawable != null) {
backgroundDrawable.draw(canvas);
} else {
canvas.drawColor(Color.WHITE);
}
view.draw(canvas);
return bitmap;
This for sharing CardView as an Image then saving it in the cache subdirectory of the app's internal storage area.
hope it will be helpful.
#Override
public void onClick(View view) {
CardView.setDrawingCacheEnabled(true);
CardView.buildDrawingCache();
Bitmap bitmap = CardView.getDrawingCache();
try{
File file = new File(getContext().getCacheDir()+"/Image.png");
bitmap.compress(Bitmap.CompressFormat.PNG,100,new FileOutputStream(file));
Uri uri = FileProvider.getUriForFile(getContext(),"com.mydomain.app", file);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.setType("image/jpeg");
getContext().startActivity(Intent.createChooser(shareIntent, "Share"));
}catch (FileNotFoundException e) {e.printStackTrace();}
}
});
Here is working method to make a screenshot of own app and share it as image via any messanger or email client.
To fix the bitmap not updating problem I improved Suragch's answer, using Gurupad Mamadapur's comment and added own modifications.
Here is code in Kotlin language:
private lateinit var myRootView:View // root view of activity
#SuppressLint("SimpleDateFormat")
private fun shareScreenshot() {
// We need date and time to be added to image name to make it unique every time, otherwise bitmap will not update
val sdf = SimpleDateFormat("yyyyMMdd_HHmmss")
val currentDateandTime = sdf.format(Date())
val imageName = "/image_$currentDateandTime.jpg"
// CREATE
myRootView = window.decorView.rootView
myRootView.isDrawingCacheEnabled = true
myRootView.buildDrawingCache(true) // maybe You dont need this
val bitmap = Bitmap.createBitmap(myRootView.drawingCache)
myRootView.isDrawingCacheEnabled = false
// SAVE
try {
File(this.cacheDir, "images").deleteRecursively() // delete old images
val cachePath = File(this.cacheDir, "images")
cachePath.mkdirs() // don't forget to make the directory
val stream = FileOutputStream("$cachePath$imageName")
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, stream) // can be png and any quality level
stream.close()
} catch (ex: Exception) {
Toast.makeText(this, ex.javaClass.canonicalName, Toast.LENGTH_LONG).show() // You can replace this with Log.e(...)
}
// SHARE
val imagePath = File(this.cacheDir, "images")
val newFile = File(imagePath, imageName)
val contentUri = FileProvider.getUriForFile(this, "com.example.myapp.fileprovider", newFile)
if (contentUri != null) {
val shareIntent = Intent()
shareIntent.action = Intent.ACTION_SEND
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // temp permission for receiving app to read this file
shareIntent.type = "image/jpeg" // just assign type. we don't need to set data, otherwise intent will not work properly
shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri)
startActivity(Intent.createChooser(shareIntent, "Choose app"))
}
}

Categories

Resources