I am trying to share image stored in Internal memory using Intent. The process is as follows
- Generate bitmap of a layout
- Save this bitmap to a file in Internal
- memory Share this file using intent (to Gmail)
Only empty file seem to be generated on execution (hence, cannot be attached to Gmail). I am not sure where the code begins getting messy. So, here goes the code
Method to Generate and Save Bitmap
public void generateAndSaveBitmap(View layout) {
//Generate bitmap
layout.setDrawingCacheEnabled(true);
layout.buildDrawingCache();
Bitmap imageToSave = layout.getDrawingCache();
layout.destroyDrawingCache();
//Create a file and path
File directory = layout.getContext().getDir("images", Context.MODE_PRIVATE);
File fileName = new File(directory, "sharableImage.jpg");
if (fileName.exists())
fileName.delete();
//Compress and save bitmap under the mentioned fileName
FileOutputStream fos = null;
try {
fos = new FileOutputStream(fileName);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.flush();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// return directory.getAbsolutePath();
}
Method to Share the Image
public void moreShareOptions(Context context) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/jpg");
File photoFile = new File("sharableImage.jpg");
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(photoFile));
context.startActivity(Intent.createChooser(shareIntent, context.getResources().getText(R.string.opsh_share_this)));
}
These two methods are placed inside onClickListener as below
case R.id.more_share_options:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
optionsShareThis.generateAndSaveBitmap(toolbarWebView);
}
});
t.start();
optionsShareThis.moreShareOptions(this);
break;
Trying to find the issue. Am I missing something? Also, I would love to hear suggestions (if any) to improve the code.
Regards
EDIT:
Thanks for mentioning about FileProvider
. Good to know about getCacheDir
. However, even after using FileProvider
, my code is continuing to return empty file. I have been exploring multiple resources, yet unable to generate a file with actual Image of the mentioned layout.
generateAndSaveBitmap(View layout) - no changes have been made to this method (code mentioned above).
Below is the code related to FileProvider
AndroidManifest.xml - nothing new to discuss
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.android"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_path" />
</provider>
file_path.xml - used to mention the file name and its path
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="sharableImage" path="images/"/>
</paths>
moreShareOptions() -
public void moreShareOptions(Context context) {
// concatenate the internal cache folder with the document its path and filename
final File file = new File(context.getFilesDir(), "images/sharableImage.jpg");
// let the FileProvider generate an URI for this private file
final Uri uri = FileProvider.getUriForFile(context, "com.example.android", file);
// create an intent, so the user can choose which application he/she wants to use to share this file
final Intent intent;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
intent = ShareCompat.IntentBuilder.from((Activity) context)
.setType("image/jpg")
.setStream(uri)
.createChooserIntent()
.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(intent);
}else {
intent = ShareCompat.IntentBuilder.from((Activity) context)
.setType("image/jpg")
.setStream(uri)
.createChooserIntent()
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
context.startActivity(intent);
}
}
What have I been missing? I have spent hours searching for ways to get the necessary result. Nothing fruitful. Hence, I am posting this code with hope that others might be able to point out where I am going wrong.