I have written a simple application to view pictures. However, after sending the picture with the common intent:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("URLSTRING"));
shareIntent.setType("image/jpeg");
mActivity.startActivity(Intent.createChooser(shareIntent, "SHARE"));
The picture can be successfully sent if I chose Google hangout. But it is deleted after that!
Tested with other file manager application (root explorer) and it is the same behavior!
However, sent picture with GooglePlusGallery application does not seem to have this problem.
What is the trick? How to avoid the picture to be deleted?
I had the same problem with Hangouts. It seems that it deletes the file even if it doesn't succeed to send it, thus always copy the file to a new temp file before calling the intent.
I had the same issue, I believe exposing a ContentProvider instead that an uri could solve.
Same problem here. My app didn't even have storage write permissions, so I'm assuming Hangouts actually is deleting the images.
So instead of sharing the file directly, i make a copy first.
Here's the full solution:
Bitmap bm = BitmapFactory.decodeFile(filePath); // original image
File myImageToShare = saveToSD(bm); // this will make and return a copy
if (myImageToShare != null) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(myImageToShare));
shareIntent.setType("image/jpeg");
context.startActivity(Intent.createChooser(shareIntent, "Share using"));
}
private File saveToSD(Bitmap outputImage){
File storagePath = new File(Environment.getExternalStorageDirectory() + yourTempSharePath);
storagePath.mkdirs();
File myImage = new File(storagePath, "shared.jpg");
if(!myImage.exists()){
try {
myImage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
} else {
myImage.delete();
try {
myImage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
FileOutputStream out = new FileOutputStream(myImage);
outputImage.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
return myImage;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Related
I want to save my bitmap to cache directory.
I use this code:
try {
File file_d = new File(dir+"screenshot.jpg");
#SuppressWarnings("unused")
boolean deleted = file_d.delete();
} catch (Exception e) {
// TODO: handle exception
}
imagePath = new File(dir+"screenshot.jpg");
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);
}
}
it s working fine. But if I want to save different img to same path, something goes wrong. I mean it is saved to same path but I see it old image, but when I click the image I can see the correct image which I saved second time.
Maybe its come from cache but I do not want to see old image because when I want to share that image with whatsapp old image seen , if i send the image it seems correct.
I want to share saved image on whatsapp like this code:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imagePath));
shareIntent.setType("image/jpeg");
startActivityForResult(Intent.createChooser(shareIntent, getResources().getText(R.string.title_share)),whtsapp_result);
How can I fix it?
thanks in advance.
Finally I solved my problem like this:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, getImageUri(context,bitmap_));
shareIntent.setType("image/jpeg");
startActivityForResult(Intent.createChooser(shareIntent, getResources().getText(R.string.title_share)),whtsapp_result);
v
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = Images.Media.insertImage(inContext.getContentResolver(), inImage, "TitleC1", null);
return Uri.parse(path);
}
This is just a guess, but since you save a new image (with the old name, or another, that’s not relevant) you should fire a media scan to that path so that the media provider is updated with new content.
See here:
MediaScannerConnection.scanFile(context, new String[]{imagePath}, null, null);
Or even better, wait for the scan to be completed:
MediaScannerConnection.scanFile(context, new String[]{imagePath}, null, new OnScanCompletedListener() {
#Override
void onScanCompleted(String path, Uri uri) {
// Send your intent now.
}
});
In any case this should be called after the new file is saved. As I said, I have not tested and this is just a random guess.
I just started using text for an app I am working on to further my android knowledge. However what I cannot figure out is how to get the pdf which was filled and then email it using the intent. I have been googling and researching everywhere but I cannot find anything. Does anyone know how to go about it?
declaration of my file before my onCreate;
File file = new File(getExternalFilesDir(null),"pvgform.pdf");
This is part of my code to add info to the fillable pdf text
OutputStream output = null;
try {
output = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
reader = new PdfReader(getResources().openRawResource(R.raw.form));
} catch (IOException e) {
e.printStackTrace();
}
try {
PdfStamper stamper = new PdfStamper(reader, output);
AcroFields acroFields = stamper.getAcroFields();
acroFields.setField("fullname", editText.getText().toString());
acroFields.setField("agedob", editText2.getText().toString());
acroFields.setField("description", editText3.getText().toString() + editText4.getText().toString() + editText5.getText().toString());
acroFields.setField("duration", editText6.getText().toString());
acroFields.setField("brandname", editText8.getText().toString());
acroFields.setField("genericname", editText9.getText().toString());
stamper.setFormFlattening(true);
stamper.close();
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
reader.close();
and this is my attempt on the email intent for the pdf form:
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_SUBJECT, "My form");
email.putExtra(Intent.EXTRA_TEXT, "Here is a form");
Log.d("file",file.getAbsolutePath());
Uri uri = Uri.fromFile(file);
email.putExtra(Intent.EXTRA_STREAM,uri);
email.setType("application/pdf");
email.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
when I run this, there is no attachment to the email to be sent.
This is part of my code to add info to the fillable pdf text
You do not appear to be writing the PDF to a file.
and this is my attempt on the email intent for the pdf form:
Uri uri=Uri.parse("file://"+ "form.pdf");
This is not a valid Uri on any platform.
Write your PDF to a file, such as on external storage. Then, use a Uri that resolves to that file, using Uri.fromFile() to convert your File object into the appropriate Uri.
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 am implementing sharing in my app. it just has to be text share.all apps worked fine with sharing text with intent but facebook doesn't allow to share text via intent. so i implemented its sdk and wrote down this code.
ShareContent linkContent = new ShareLinkContent.Builder()
.setContentTitle("Hello Facebook")
.setContentDescription(localThoughtDesc.get(finalI1))
.setContentUrl(Uri.parse("https://www.google.com"))
.build();
shareDialog.show(linkContent);
but i got output like this
i have gone through many tutorials. but most of them are deprecated. so if anyone can help me out it will be very nice.:)
Thank you :)
Facebook share doesn't support text. You can only share link and that will show the <meta content ="..."> text from that page with your link in Facebook.
Since i didn't get any way to post any thing on facebook so i tried another way to post text to facebook. Think it might helpful. By the way it is not actually sharing of text. I converted text into image file than i posted image through intent.
here's how i did it.
TextView textView=new TextView(getBaseContext());
textView.setTag("textView");
View view=innerLayout.findViewWithTag("textView");
String SCREENSHOTS_LOCATIONS = Environment.getExternalStorageDirectory().toString() + "/screenshots/";
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),view.getHeight(), Bitmap.Config.ARGB_4444);
String path=SCREENSHOTS_LOCATIONS+ System.currentTimeMillis() + ".jpg";
final Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
System.out.println(bitmap.getHeight()+" "+bitmap.getWidth());
FileOutputStream fos = null;
try {
final File sddir = new File(SCREENSHOTS_LOCATIONS);
if (!sddir.exists()) {
sddir.mkdirs();
}
fos = new FileOutputStream(path);
System.out.println(sddir.getPath().toString());
if (fos != null) {
if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) {
Log.d("abc", "Compress/Write failed");
}
fos.flush();
fos.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent intent=new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TITLE, "Title");
intent.putExtra(Intent.EXTRA_SUBJECT, "Extra Subject");
intent.putExtra(Intent.EXTRA_STREAM,Uri.fromFile(new File(path))); //optional//use this when you want to send an image
intent.setType("image/jpeg");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(Intent.createChooser(intent, "send"), REQUEST_CODE);
I saw other questions about this, tried their answers, but don't work.
I am trying to use the second method from developer.android.com.
(the second white bullet).
I save an image to applications internal memory, with appropriate permissions.
The image (bitmap) is saved successfully, but I can't attach it to a new intent, to share it.
Here is my code:
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("*/*");//Attach all types (images/text)
FileOutputStream fos;
try{
fos = openFileOutput(myfilename, Context.MODE_WORLD_READABLE);
mybitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.flush();
//Image is stored successfully (checked data/data/mypackage/files/myfilename)
Uri uri = Uri.fromFile(getFileStreamPath(myfilename));
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
}
catch (Exception e){
// noth
//Log.e(TAG, e.getStackTrace().toString());
}
shareIntent.putExtra(Intent.EXTRA_TEXT, "some text also");
return shareIntent;
}
Applications say that can't attach media items.
Gmail seems to attach item, but it shows nothing when mail send!
Also the uri.getPath returns me:
/data/data/mypackage/files/myfilename,
which is correct
Any ideas?
Thank you!
Edit:
Modified code to use sd card. And still don't get it to work:
File imgDir;
if (android.os.Environment.getExternalStorageState().equals(
android.os.Environment.MEDIA_MOUNTED))
imgDir = new File(
android.os.Environment.getExternalStorageDirectory(),
".MyAppName/Images");
else imgDir = MyActivity.this.getCacheDir();
if (!imgDir.exists()) imgDir.mkdirs();
File output = new File(imgDir, myFilename);
OutputStream imageFileOS;
try{
Uri uriSavedImage = Uri.fromFile(output);
imageFileOS = getContentResolver().openOutputStream(
uriSavedImage);
bitmapBookCover.compress(Bitmap.CompressFormat.PNG, 90,
imageFileOS);
imageFileOS.flush();
imageFileOS.close();
//Again image successfully saved
shareIntent.putExtra(Intent.EXTRA_STREAM, uriSavedImage);
}
catch (Exception e){
// noth
}
Please try usiing setData() instead of putExtra(), here android developer site - intent set data