I am getting picture from a layout and do not want to save it. I want to share it directly through intent ACTION_SEND service. when I send it gives exception Transaction Too many Large: data parcel size 2315980 bytes
Here is my code snippet
View myview = (View) findViewById(R.id.mylayout);
Bitmap mypicture = getBitmapFromView(myview);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra("", mypicture);
intent.setType("image/jpeg");
startActivity(intent);
I want to share it directly through intent ACTION_SEND service
That is not an option. EXTRA_TEXT holds text. EXTRA_STREAM holds a Uri. Neither of those is a Bitmap.
Here is my code snippet
Your extra is pointless, as no ACTION_SEND activities will be looking for an extra with an empty key.
you can save your bitmap to a file, then share the uri/link to that file.
public static File saveBitmapInternal(Context context, Bitmap bitmap) {
File imagePath = new File(context.getFilesDir(), "images");
if (!imagePath.exists() && !imagePath.mkdirs()) {
print("Make dir failed");
}
return saveBitmap(bitmap, "preview.png", imagePath);
}
private static File saveBitmap(Bitmap bitmap, String filename, File root) {
print(String.format("Saving %dx%d bitmap to %s.", bitmap.getWidth(), bitmap.getHeight(), filename));
final File file = new File(root, filename);
if (file.exists()) {
file.delete();
}
try {
final FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 99, out);
out.flush();
out.close();
return file;
} catch (final Exception e) {
print("Exception!" + e);
}
return null;
}
then to share it,
// Uri uri = Uri.fromFile(file);
Uri uri = FileProvider.getUriForFile(context,
context.getString(R.string.file_provider_authority),
file);
final Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.putExtra(Intent.EXTRA_TEXT, shareText);
context.startActivity(Intent.createChooser(intent, "Share media"));
you need to set up the file provider in your manifest (refer to https://developer.android.com/reference/android/support/v4/content/FileProvider.html). you can create another question if you have queries regarding the fileprovider.
Related
I want to make a function which share my images using Intent . Problem is; i have png images and when i share images using Intent, it change the format of image form png to jpeg . for example there is no background (transparent) of my image.png when i call intent to share, it changes image background to black and format to image.jpg.
Here is my code
protected void ShareImage( )
{
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("image/png");
Bitmap imgBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.image );
String imgBitmapPath= MediaStore.Images.Media.insertImage(getContentResolver(),imgBitmap,"title",null);
Uri imageUri=Uri.parse(imgBitmapPath);
sharingIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
startActivity(Intent.createChooser(sharingIntent, "Share images to.."));
}
Please Help me to share image without changing its format .. Thanks
MediaStore.Images.Media.insertImage always writes a JPEG. See its implementation.
You can easily adapt its code to write a PNG instead:
private void shareAsPng(Bitmap bitmap, String title)
{
Long now = System.currentTimeMillis() / 1000;
ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, title);
values.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
values.put(MediaStore.MediaColumns.DATE_ADDED, now);
values.put(MediaStore.MediaColumns.DATE_MODIFIED, now);
ContentResolver cr = getContentResolver();
Uri uri = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
try (OutputStream os = cr.openOutputStream(uri)) {
bitmap.compress(Bitmap.CompressFormat.PNG, 0, os);
}
catch (IOException e) {
cr.delete(uri, null, null);
return;
}
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/png");
intent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(intent);
}
The compression quality parameter is documented to be ignored for PNG.
I intentionally omitted IS_PENDING because that requires Android 10.
Convert bitmap to Uri
private Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.PNG, 99, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
and add your application manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I want to share the screenshot that gets stored in internal storage but all I'm getting while sharing is a blank screen. I came to know that another app cannot use ones won app private data. This is the code I have used to save the image :
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.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();
}
And the share intent is:
public void send(File path)
{
Uri uri = Uri.fromFile(path);
Log.d("uri", String.valueOf(path));
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "My App");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.setType("image/*");
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(shareIntent, "Share via"));
}
The path in which the image is getting saved and the value of path is :
/data/user/0/com.sample.myapp/app_Default/myapp/myapp.png
Now how would I make sure that the screenshot is getting accessed and made available for sharing.
You are getting image URI not Real Image path
to get Real path check this
public String getRealPathFromURI(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
just pass this image uri and get full image path
I solved it by exporting the image to external storage and then sharing.
String url = null;
try {
url = MediaStore.Images.Media.insertImage(getContentResolver(), path.getAbsolutePath(), path.getName(), path.getName());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Uri uri = Uri.parse(url);
I need to share an image (.png format) with transparent background, through sent_action intent.
I searched a lot and tried a lot of samples but couldn't find the solution.
The is this method in witch the image will get shared directly from the resources, but for some reason from some point it has stop working.
Uri url = Uri.parse("android.resource://"
+ getPackageName() + "/" + R.drawable.ic_launcher);
Intent share_intent = new Intent();
share_intent.setAction(Intent.ACTION_SEND);
share_intent.setType("image/png");
share_intent.putExtra(Intent.EXTRA_STREAM,
Uri.fromFile(new File(url.toString())));
startActivity(Intent.createChooser(share_intent, "choose app"));
and there is this function which works fine, the problem is it adds a black background to the image.
private void share3()
{
Bitmap bitmap;
OutputStream output;
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
File filepath = Environment.getExternalStorageDirectory();
File dir = new File(filepath.getAbsolutePath() + "/Gallery/");
dir.mkdirs();
File file = new File(dir, "ic_launcher" + ".png");
try {
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("image/png");
output = new FileOutputStream(file);
bitmap. compress(Bitmap.CompressFormat.PNG/*Bitmap.CompressFormat.PNG*/, 0, output);
output.flush();
output.close();
Uri uri = Uri.fromFile(file);
share.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(share, "choose app"));
} catch (Exception e) {
e.printStackTrace();
}
}
I need to share the image from "raw" folder in the resources and share it without background. What should I do?
I found the problem, It is telegram itself. Telegram adds a black background to .png images you share.
Try this ..its work for me to share image from drawable folder.
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/LatestShare.png";
OutputStream out = null;
File file = new File(path);
try {
out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 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(Intent.ACTION_SEND);
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shareIntent.putExtra(Intent.EXTRA_STREAM, bmpUri);
shareIntent.setType("image/png");
startActivity(Intent.createChooser(shareIntent, "Share with"));
I use below code to take screen shot from my layout and share it via android intent but the captured screen shot in the selected app is not showing any thing.
#Override
public void onClick(View view) {
shareBitmap(this,takeScreenshot());
}
public Bitmap takeScreenshot() {
try{
View rootView = getWindow().getDecorView().findViewById(R.id.lyt_main_report_activity);
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
}catch (Exception ex){
ex.printStackTrace();
}
return null;
}
public static void shareBitmap(Context context, Bitmap bitmap){
//save to sd card
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 (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try{
//start share activity
File imagePath = new File(context.getCacheDir(), "images");
File newFile = new File(imagePath, "image.png");
Uri contentUri = Uri.fromFile(newFile); //FileProvider.getUriForFile(context, "com.persianswitch.apmb.app.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, context. getContentResolver().getType(contentUri));
shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
shareIntent.setType("image/*");
context.startActivity(Intent.createChooser(shareIntent, context.getResources().getString(R.string.share_using)));
}
}catch (Exception ex){
ex.printStackTrace();
}
}
Please use this code this is tested code :
public static void takeScreenshot(Context context, View view) {
String path = Environment.getExternalStorageDirectory().toString() +
"/" + "test.png";
View v = view.findViewById(android.R.id.content).getRootView();
v.setDrawingCacheEnabled(true);
v.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
OutputStream out = null;
File imageFile = new File(path);
try {
out = new FileOutputStream(imageFile);
// choose JPEG format
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
} catch (FileNotFoundException e) {
// manage exception
} catch (IOException e) {
// manage exception
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception exc) {}
}
// onPauseVideo();
Intent share = new Intent(Intent.ACTION_SEND);
share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
share.setType("image/png");
((Activity) context).startActivityForResult(
Intent.createChooser(share, "Share Drawing"), 111);
}
Since DrawingCache() deprecated above 28 so using Canvas will sort the issues for many. below answer can be used for share Screenshot including text without requesting for permissions.
To take the Screenshot
private Bitmap takeScreenShot(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
To share the Screenshot
private void shareContent(Bitmap bitmap) {
String bitmapPath = MediaStore.Images.Media.insertImage(
binding.getRoot().getContext().getContentResolver(), bitmap, "title", "");
Uri uri = Uri.parse(bitmapPath);
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "App");
shareIntent.putExtra(Intent.EXTRA_TEXT, "Currently a new version of KiKi app is available.");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
binding.getRoot().getContext().startActivity(Intent.createChooser(shareIntent, "Share"));
}
if nothing happens it means your Bitmap is null kindly check that. or you could also fall on View.buildDrawingCache(); which will draw the View to Bitmap and then call your View.getDrawingCache();
also When hardware acceleration is turned on, enabling the drawing cache has no effect on rendering because the system uses a different mechanism for acceleration which ignores the flag. If you want to use a Bitmap for the view, even when hardware acceleration is enabled, see setLayerType(int, android.graphics.Paint) for information on how to enable software and hardware layers.
the quote was taken from the documented page
hope it helps
Tipp:The checked answer works when your device has external storage. On the Samsung 6 for example, it doesnt. Therefore you need to work with fileprovider.
Just incase somebody fell into this trap like me. The problem is that you are putting the name of the image twice.
FileOutputStream stream = new FileOutputStream(cachePath + "/image.png");
and than again.
File newFile = new File(imagePath, "image.png");
Change The seconed one to
File newFile = new File(imagePath);
Otherwise the contentUri give you the bitmap of your screenshot. I hope this helps someone. Took me 3 hours to figure it out :)
I'm creating an ACTION_SEND intent in android and attaching an image file with the following code:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/html");
intent.putExtra(Intent.EXTRA_EMAIL, "");
intent.putExtra(Intent.EXTRA_SUBJECT, "Receipt From: XXX");
intent.putExtra(Intent.EXTRA_TEXT, message);
byte[] b = Base64.decode(signature, Base64.DEFAULT); //Where signature is a base64 encoded string
final Bitmap mBitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
String path = Images.Media.insertImage(getContentResolver(), mBitmap, "signature", null);
Uri sigURI = Uri.parse(path);
intent.putExtra(Intent.EXTRA_STREAM, sigURI);
startActivity(Intent.createChooser(intent, "Send Email"));
This works, the image is attached to the email. However I'm having trouble deleting the image afterwords. The images are getting stored in the DCIM\Camera folder with a large number as the file name.
I've tried
File tempFile = File(getRealPathFromURI(sigURI)); //a subroutine which gives me the full path
tempFile.delete();
tempFile.delete returns true, however the file is still there.
One odd thing I noticed is that the image saved is of file size 0 and appears empty both before and after I try to delete.
How do I properly delete this image after sending it with the email? Or is there an alternative way of attaching the image without saving it?
Also, not the main question here but if you could include how to change the name of the image/attachment from 1375729812685.jpg (or what ever the number may be) to something else, I'de appreciate it.
As a last note, I've been testing on an HTC Evo if it makes any difference.
I have found a solution for anyone who is interested.
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{});
intent.putExtra(android.content.Intent.EXTRA_CC, new String[ {"test#test.net"});
intent.putExtra(Intent.EXTRA_SUBJECT, "Receipt From: " + receipt[1]);
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
String imageFileName = "IMG_" + timeStamp + "_";
File albumF = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Receipt");
if (albumF != null) {
if (! albumF.mkdirs()) {
if (! albumF.exists()){
Log.d("CameraSample", "failed to create directory");
return;
}
}
}
File imageF = File.createTempFile(imageFileName, ".jpg", albumF);
byte[] b = Base64.decode(sig, Base64.DEFAULT);
if (b.length > 0) {
Bitmap mBitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
FileOutputStream ostream = new FileOutputStream(imageF);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, ostream);
ostream.flush();
ostream.close();
Uri fileUri = Uri.fromFile(imageF);
intent.putExtra(Intent.EXTRA_STREAM, fileUri);
}
intent.putExtra(Intent.EXTRA_TEXT, message);
intent.setType("message/rfc822");
startActivity(Intent.createChooser(intent, "Send Email Using"));