I am trying to get a image of a view (constraint-layout) and share it via an android send-intent.
I tried a lot of methods, but until now none have worked.
This is what I have so far:
public void shareStatsImage(){
constraintLayout.setDrawingCacheEnabled(true);
Bitmap bitmap = constraintLayout.getDrawingCache();
File path = null;
try {
path = saveImageToExternal(generateImageTitle(), bitmap);
} catch (IOException e) {
e.printStackTrace();
}
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/png");
final File photoFile = new File(Objects.requireNonNull(getActivity()).getFilesDir(), Objects.requireNonNull(path).getAbsolutePath());
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(photoFile));
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(shareIntent, "Share image using"));
}
public static String generateImageTitle(){
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy-hh-mm-ss");
return sdf.format(new Date());
}
public File saveImageToExternal(String imgName, Bitmap bm) throws IOException {
//Create Path to save Image
String appFolder = "test";
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES + File.separator + appFolder); //Creates app specific folder
path.mkdirs();
File imageFile = new File(path, imgName+".png"); // Imagename.png
FileOutputStream out = new FileOutputStream(imageFile);
try{
bm.compress(Bitmap.CompressFormat.PNG, 100, out); // Compress Image
out.flush();
out.close();
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(getContext(),new String[] { imageFile.getAbsolutePath() }, null,new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
} catch(Exception e) {
throw new IOException();
}
return imageFile;
}
There are multiple problems with this solution, for example I am getting an error message ("Permission denied for the attachment") when sharing the image to gmail. When uploading the image to google drive I only get an "upload unsuccessful message".
One good thing is that the images seem to appear in the phone's gallery, just not when sharing them via the intent :(
Thanks for your help!
Convert Bitmap to Uri
private Uri getImageUri(Context context, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(context.getContentResolver(), inImage, "Image Title", null);
return Uri.parse(path);
}
You can send Image using Uri.
Uri imageUri = set your image Uri;
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
shareIntent.setType("image/jpeg");
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(shareIntent, "send"));
Related
I use the following code to create image file and save them in to sd card
private File createImageFile(Bitmap bitmap) throws IOException {
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
PICNAME,
".png",
storageDir);
FileOutputStream out = null;
try {
out = new FileOutputStream(image);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
The issue is that, though I take picture in full screen mode but the above code always saves the image in very less amount of dimension which is 320x240. why so.. is there by any means that I can save the image without resizing?
you can do it like this :
public static Uri takePhotoByCamera(Activity activity) {
File publicDirectory = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES + "/myFolder");
double d = new Random().nextDouble();
File file = new File(publicDirectory, d + ".jpg");
String path = file.getAbsolutePath();
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DATA, path);
values.put(MediaStore.MediaColumns.TITLE, "New Picture");
values.put(MediaStore.Images.ImageColumns.DESCRIPTION, "From your Camera");
activity.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Uri photoUri = Uri.parse("file://" + path);
if (!publicDirectory.exists())
publicDirectory.mkdirs();
else if (!publicDirectory.isDirectory() && publicDirectory.canWrite()) {
publicDirectory.delete();
publicDirectory.mkdirs();
} else {
Log.d("tag550", "can't access");
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
activity.startActivityForResult(intent, requestCamera);
return photoUri;
}
I am trying to share image using intent. Here is the method that i created
public void shareImg(int fileNum) //Consider fileNum=R.drawable.img
{
Uri uri= Uri.parse("android.resource://"
+ context.getPackageName() + "/" + fileNum);
Intent share=new Intent();
share.setAction(Intent.ACTION_SEND);
share.setType("image/*");
share.putExtra(Intent.EXTRA_STREAM, uri);
share.putExtra(Intent.EXTRA_TEXT, "Sent Via ---");
Intent chooser= Intent.createChooser(share, "Share Via");
context.startActivity(chooser);
}
The image is shared properly with Whatsapp with caption. But when I try to share app with Gmail, Messenger, etc it gives error shown in Toast.
For eg.
Gmail says : Can't attach empty file
Messenger says : Failed to convert to image
You can share image using share intent, but you've to decode image to a localized Bitmap
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, "Hey view/download this image");
String path = Images.Media.insertImage(getContentResolver(), loadedImage, "", null);
Uri screenshotUri = Uri.parse(path);
intent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
intent.setType("image/*");
startActivity(Intent.createChooser(intent, "Share image via..."));
loadedImage is the Path of image
Here is the steps you can perform.
Step 1. First create bitmap from drawable
Drawable d = ImagesArrayList.get(0);
Bitmap bitmap = ((BitmapDrawable)d).getBitmap();
Step 2. Save Bitmap to File
FileOutputStream out = null;
String filename = Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg";
try {
out = new FileOutputStream(filename);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
// PNG is a lossless format, the compression factor (100) is ignored
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
Step 3. Share this image File with fileurl. Share the Image same as you sharing gallery image.
Complete Answer
Bitmap bitmap= BitmapFactory.decodeResource(getResources(),R.drawable.xxxx); // your resource ID here
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+"/LatestShare.jpg";
OutputStream out = null;
File file=new File(path);
try {
out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
path=file.getPath();
Uri bmpUri = Uri.parse("file://"+path);
Intent shareIntent = new Intent();
shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shareIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
shareIntent.setType("image/jpg");
startActivity(Intent.createChooser(shareIntent,"Share with"));
I am trying to share an image to other apps.
From the doc, I understand I have to create a ContentProvider to ensure access to my resource from outside the app. It works with most apps but Facebook Messenger and Messages (com.android.mms). I have the following errors:
FB Messenger: "Sorry, messenger was unable to process the file"
com.android.mms: "Unable to attach. File not supported"
The code I call in the activity to share:
Uri path = Uri.parse("content://com.myauthority/test.png");
Intent shareIntent = new Intent(Intent.ACTION_SEND).putExtra(Intent.EXTRA_STREAM, path).setType("image/png");
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.share)));
The in my content provider I only override openFile:
#Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
String fileName = uri.getLastPathSegment();
String resName = fileName.replaceAll(".png","");
int resId = getContext().getResources().getIdentifier(resName,"drawable",getContext().getPackageName());
File file = new File(getContext().getCacheDir(), fileName);
Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), resId);
FileOutputStream fileoutputstream = new FileOutputStream(file);
boolean flag = bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileoutputstream);
try {
ParcelFileDescriptor parcelfiledescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY | ParcelFileDescriptor.MODE_WORLD_READABLE);
return parcelfiledescriptor;
} catch (IOException e) {
e.printStackTrace();
return null;
}
Has anyone an idea or experience to share regarding this issue?
Here am Including my code which i used to share data from my app to facebook app or messenger app.
imageView.setDrawingCacheEnabled(true);
Bitmap bitmap = imageView.getDrawingCache();
File root = Environment.getExternalStorageDirectory();
final File cachePath = new File(root.getAbsolutePath()
+ "/DCIM/Camera/Avi.jpg");
try {
cachePath.createNewFile();
FileOutputStream ostream = new FileOutputStream(
cachePath);
bitmap.compress(CompressFormat.JPEG, 100, ostream);
ostream.flush();
ostream.close();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(
Intent.EXTRA_STREAM,
Uri.fromFile(new File(cachePath
.getAbsolutePath())));
Log.e("Path for sending ",
""+Uri.fromFile(new File(cachePath
.getAbsolutePath())));
mContext.startActivity(intent);
}
}, 3000);
just provide your image uri and use this code.
I want to share animated gif images that are in my drawable folder.
The code works so far, but the shared gif file is not animated. You can only see the first image of the animation. Does someone know how it could work?
Bitmap icon = BitmapFactory.decodeResource(this.getResources(),
R.drawable.animated_gif);
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/gif");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
icon.compress(Bitmap.CompressFormat.PNG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + "temporary_file.gif");
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f, true);
fo.write(bytes.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
share.putExtra(Intent.EXTRA_STREAM,
Uri.parse("file:///sdcard/temporary_file.gif"));
startActivity(Intent.createChooser(share, "Share Image"));
Well, you are geting static bitmap from drawable. I recomend you to use GifDrawable in Glide library and this approach for sending animated gifs (in case you loaded your gif image into ImageView):
private Uri getLocalBitmapUri(ImageView imageView, String link) {
// Extract Bitmap from ImageView drawable
Drawable drawable = imageView.getDrawable();
if (drawable instanceof GifDrawable) {
try {
// Store image to default external storage directory
String fileName = link.substring(link.lastIndexOf('/') + 1, link.length());
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "shared_gif_" + System.currentTimeMillis() + ".gif");
file.getParentFile().mkdirs();
GifDrawable gifDrawable = ((GifDrawable) imageView.getDrawable());
FileOutputStream out = new FileOutputStream(file);
out.write(gifDrawable.getData());
out.close();
return Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
...
Uri bmpUri = Utils.getLocalBitmapUri(gifImageView, post.media_content.get(0).file);
if (bmpUri != null) {
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("image/gif");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "title");
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, "text");
sharingIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
startActivity(Intent.createChooser(sharingIntent, "Share via"));
} else {
// ...sharing failed, handle error
}
...
I have an app where the user creates an image and then I want to save it so it's visible form the default gallery application.
Now I don't want the pictures to be saved in the same folder as the pictures taken from the camera, I want them to be saved in a folder dedicated to the app, just like images from apps like whatsapp or facebook.
I've tried saving them in this two locations:
File imagePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)+ File.separator + appDirectoryName + File.separator);
and here
File imagePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+ File.separator + appDirectoryName + File.separator);
If I browse through the phone I see that I successfully save the images but they don't show in the gallery app. It is obvious that I'm missing something but I don't know what it is. Maybe adding some kind of metadata to the files or folders so the gallery recognizes them?
Well I found the answer in the end.
It turned out to be what I suspected. The saved image needs to have some metadata added in order to be seen in the gallery (at least in my device).
This is what I did:
OutputStream fOut = null;
File file = new File(imagePath,"GE_"+ System.currentTimeMillis() +".jpg");
try {
fOut = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
try {
fOut.flush();
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, this.getString(R.string.picture_title));
values.put(Images.Media.DESCRIPTION, this.getString(R.string.picture_description));
values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis ());
values.put(Images.ImageColumns.BUCKET_ID, file.toString().toLowerCase(Locale.US).hashCode());
values.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, file.getName().toLowerCase(Locale.US));
values.put("_data", file.getAbsolutePath());
ContentResolver cr = getContentResolver();
cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
I have had the same problem.
The second way is the correct way, but you don't see the images in the Gallery because the gallery needs to be refreshed.
So, you can wait a while until it refreshes itself, or you can use the MediaScanner -
look here
Hope this helped!
I did the following to get it to work:
public void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
String mCurrentPhotoPath = "file:" + image.getAbsolutePath(); // image is the created file image
File file = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
Try this
private void createDirectoryAndSaveFile(Bitmap imageToSave, String fileName) {
File direct = new File(Environment.getExternalStorageDirectory() + "/DirName");
if (!direct.exists()) {
File wallpaperDirectory = new File("/sdcard/DirName/");
wallpaperDirectory.mkdirs();
}
File file = new File(new File("/sdcard/DirName/"), fileName);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I tried this it works perfectly.
private Uri imageUri;
String getimgname, getimgpath;
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photo = new File(Environment.getExternalStorageDirectory(), "IMG"+System.currentTimeMillis()+".jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
getimgname = photo.getName();
getimgpath = photo.getAbsolutePath();
Try this
MediaScannerConnection.scanFile(context,
new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});