Reputation: 4731
I am trying to share image to other apps through Intent
. This is my logic:
public void doSocialShare(String title, String text, Bitmap resource) {
Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND);
sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sendIntent.putExtra(Intent.EXTRA_TEXT, text);
sendIntent.putExtra(Intent.EXTRA_STREAM, resource);
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.setType("image/*");
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
Log.d("INFORMATION", "The current android version allow us to know what app is chosen by the user.");
Intent receiverIntent = new Intent(this, ShareBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, receiverIntent, PendingIntent.FLAG_CANCEL_CURRENT);
sendIntent = Intent.createChooser(sendIntent, "Share via...", pendingIntent.getIntentSender());
}
startActivity(sendIntent);
}
This is how I am calling doSocialShare()
method:
BitmapDrawable drawable = (BitmapDrawable) img_FPO.getDrawable();
Bitmap bitmap = drawable.getBitmap();
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 30, out);
Bitmap decoded = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
doSocialShare("Share To", "#Smile", decoded);
But I am getting this error. Its because of the bitmap size. How can I solve this ?:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.aligntech.myinvisalign, PID: 31495
java.lang.RuntimeException: Failure from system
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1533)
at android.app.Activity.startActivityForResult(Activity.java:4403)
at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:67)
at android.app.Activity.startActivityForResult(Activity.java:4362)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:732)
at android.app.Activity.startActivity(Activity.java:4686)
at android.app.Activity.startActivity(Activity.java:4654)
at com.aligntech.myinvisalign.Activities.PhotoDetailActivity.doSocialShare(PhotoDetailActivity.java:800)
at com.aligntech.myinvisalign.Activities.PhotoDetailActivity$3.onShareItemClick(PhotoDetailActivity.java:745)
at com.aligntech.myinvisalign.Adapters.HorizontalRecyclerAdapter$3.onClick(HorizontalRecyclerAdapter.java:138)
at android.view.View.performClick(View.java:6265)
at android.view.View$PerformClick.run(View.java:23764)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
Caused by: android.os.TransactionTooLargeException: data parcel size 7991424 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:628)
at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3563)
UPDATE:
This is how I am getting the Uri from Bitmap. But instead of getExternalDir()
I want to use getCacheDir()
. How can I achieve that?:
public Uri getBitmapFromDrawable(Bitmap bmp) {
// Store image to default external storage directory
Uri bmpUri = null;
try {
// Use methods on Context to access package-specific directories on external storage.
// This way, you don't need to request external read/write permission.
// See https://youtu.be/5xVh-7ywKpE?t=25m25s
File file = new File(PhotoDetailActivity.this.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "share_image_" + System.currentTimeMillis() + ".png");
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.close();
if (Build.VERSION.SDK_INT >= 24) {
// wrap File object into a content provider. NOTE: authority here should match authority in manifest declaration
bmpUri = FileProvider.getUriForFile(PhotoDetailActivity.this, "com.aligntech.myinvisalign.fileprovider", file); // use this version for API >= 24
} else {
bmpUri = Uri.fromFile(file);
}
// **Note:** For API < 24, you may use bmpUri = Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return bmpUri;
}
Upvotes: 0
Views: 3791
Reputation: 1007369
This is my logic
The documentation for EXTRA_STREAM
says that the value is a "content: URI holding a stream of data associated with the Intent". It does not say the value is "a Bitmap". You need to supply a Uri
in this extra, from which other parties can get a stream (using a ContentResolver
) to obtain your data. And then, the data needs to be in the format specified in your MIME type of the Intent
, and a Bitmap
does not have a MIME type (let alone a wildcard MIME type).
This is how I am getting the Uri from Bitmap. But instead of getExternalDir() I want to use getCacheDir(). How can I achieve that?:
Step #1: Replace:
File file = new File(PhotoDetailActivity.this.getExternalFilesDir(Environment.DIRECTORY_PICTURES), "share_image_" + System.currentTimeMillis() + ".png");
with:
File file = new File(getCacheDir(), "share_image_" + System.currentTimeMillis() + ".png");
Step #2: Use FileProvider.getUriForFile(PhotoDetailActivity.this, "com.aligntech.myinvisalign.fileprovider", file);
for all API levels, as otherwise the other app cannot access your content
Step #3: Make sure that your FileProvider
metadata XML resource is set up with a <cache-path>
element
Step #4: Use image/jpeg
in the MIME type of your Intent
(not a wildcard), since you are saving this image as a JPEG
Upvotes: 2