I’m fetching an image from a URL as a bitmap using glide, and onResourceReady()
I’m trying to share the image via intent, but I’m getting an exception. I’m using Android 30.
JavaScript
x
Glide.with(this)
.asBitmap()
.load("https://i.imgur.com/lkHKgld.jpeg")
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("image/*");
i.putExtra(Intent.EXTRA_STREAM, getLocalBitmapUri(resource));
startActivity(Intent.createChooser(i, "Share Image"));
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
My method for providing file URI. Source
JavaScript
public Uri getLocalBitmapUri(Bitmap bmp) {
Uri bmpUri = null;
try {
File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "totka_" + System.currentTimeMillis() + ".png");
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
bmpUri = Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return bmpUri;
}
MY Error
JavaScript
2021-02-23 01:07:25.750 19345-19345/com.future_tech.hiravoice E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.future_tech.hiravoice, PID: 19345
com.bumptech.glide.load.engine.CallbackException: Unexpected exception thrown by non-Glide code
at com.bumptech.glide.load.engine.EngineJob.callCallbackOnResourceReady(EngineJob.java:161)
at com.bumptech.glide.load.engine.EngineJob$CallResourceReady.run(EngineJob.java:428)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:264)
at android.app.ActivityThread.main(ActivityThread.java:7581)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
Caused by: android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.future_tech.hiravoice/files/Pictures/totka_1614060445457.png exposed beyond app through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:2083)
at android.net.Uri.checkFileUriExposed(Uri.java:2388)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:977)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10759)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10765)
at android.content.Intent.prepareToLeaveProcess(Intent.java:10744)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1710)
at android.app.Activity.startActivityForResult(Activity.java:5195)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:675)
at android.app.Activity.startActivityForResult(Activity.java:5153)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:662)
at android.app.Activity.startActivity(Activity.java:5524)
at android.app.Activity.startActivity(Activity.java:5492)
at com.future_tech.hiravoice.activities.AsliTotkayActivity$2.onResourceReady(AsliTotkayActivity.java:185)
at com.future_tech.hiravoice.activities.AsliTotkayActivity$2.onResourceReady(AsliTotkayActivity.java:179)
at com.bumptech.glide.request.SingleRequest.onResourceReady(SingleRequest.java:639)
at com.bumptech.glide.request.SingleRequest.onResourceReady(SingleRequest.java:578)
at com.bumptech.glide.load.engine.EngineJob.callCallbackOnResourceReady(EngineJob.java:159)
at com.bumptech.glide.load.engine.EngineJob$CallResourceReady.run(EngineJob.java:428)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:264)
at android.app.ActivityThread.main(ActivityThread.java:7581)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
I also tried using the IntentShare Library
JavaScript
Glide.with(this)
.asBitmap()
.load("https://i.imgur.com/lkHKgld.jpeg")
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
IntentShare.with(getApplicationContext())
.chooserTitle("Share Totka: ")
.text("Default text you would like to share.")
.image(getLocalBitmapUri(resource))
.deliver();
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
But there I was getting an error that content Uri is needed.
JavaScript
com.bumptech.glide.load.engine.CallbackException: Unexpected exception thrown by non-Glide code
at com.bumptech.glide.load.engine.EngineJob.callCallbackOnResourceReady(EngineJob.java:161)
at com.bumptech.glide.load.engine.EngineJob$CallResourceReady.run(EngineJob.java:428)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:264)
at android.app.ActivityThread.main(ActivityThread.java:7581)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
Caused by: java.lang.IllegalArgumentException: Invalid image uri : only content scheme supported : file:///storage/emulated/0/Android/data/com.future_tech.hiravoice/files/Pictures/totka_1614061273090.png
at fr.tvbarthel.intentshare.IntentShare.image(IntentShare.java:229)
at com.future_tech.hiravoice.activities.AsliTotkayActivity$2.onResourceReady(AsliTotkayActivity.java:186)
at com.future_tech.hiravoice.activities.AsliTotkayActivity$2.onResourceReady(AsliTotkayActivity.java:180)
at com.bumptech.glide.request.SingleRequest.onResourceReady(SingleRequest.java:639)
at com.bumptech.glide.request.SingleRequest.onResourceReady(SingleRequest.java:578)
at com.bumptech.glide.load.engine.EngineJob.callCallbackOnResourceReady(EngineJob.java:159)
Advertisement
Answer
Well here is how I got it resolved, first add this provider tag in your manifest
JavaScript
<application>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.future_tech.hiravoice.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
</application>
then create a new xml file under res/xml/
named filepaths.xml
Source
JavaScript
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--Represents the files in the root directory of the external storage area of ••the app. The Pictures directory under the Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) directory-->
<!--/storage/emulated/0/Android/data/com.hm.camerademo/files/Pictures-->
<external-files-path name="hm_external_files" path="Pictures" />
</paths>
my method for providing file provider uri
JavaScript
public Uri getLocalBitmapUri(Bitmap bmp) {
Uri bmpUri = null;
try {
File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "totka_" + System.currentTimeMillis() + ".png");
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
bmpUri = FileProvider.getUriForFile(getApplicationContext(), "com.future_tech.hiravoice.fileprovider", file);
} catch (IOException e) {
e.printStackTrace();
}
return bmpUri;
}
finally the glide with Read URI flag set in intent
JavaScript
Glide.with(this)
.asBitmap()
.load("https://i.imgur.com/lkHKgld.jpeg")
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("image/*");
i.putExtra(Intent.EXTRA_STREAM, getLocalBitmapUri(resource));
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(i, "Share Image"));
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});