Load image from url in notification Android
Solution 1
Changed my code as below and its working now :
private class sendNotification extends AsyncTask<String, Void, Bitmap> {
Context ctx;
String message;
public sendNotification(Context context) {
super();
this.ctx = context;
}
@Override
protected Bitmap doInBackground(String... params) {
InputStream in;
message = params[0] + params[1];
try {
URL url = new URL(params[2]);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setDoInput(true);
connection.connect();
in = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(in);
return myBitmap;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
try {
NotificationManager notificationManager = (NotificationManager) ctx
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(ctx, NotificationsActivity.class);
intent.putExtra("isFromBadge", false);
Notification notification = new Notification.Builder(ctx)
.setContentTitle(
ctx.getResources().getString(R.string.app_name))
.setContentText(message)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(result).build();
// hide the notification after its selected
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(1, notification);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Solution 2
How to implement BigPicture style Notification:
Miracle has been done by .setStyle(new Notification.BigPictureStyle().bigPicture(result))
:
I have done this way with:
Generate notification by AsyncTask:
new generatePictureStyleNotification(this,"Title", "Message",
"http://api.androidhive.info/images/sample.jpg").execute();
AsyncTask:
public class generatePictureStyleNotification extends AsyncTask<String, Void, Bitmap> {
private Context mContext;
private String title, message, imageUrl;
public generatePictureStyleNotification(Context context, String title, String message, String imageUrl) {
super();
this.mContext = context;
this.title = title;
this.message = message;
this.imageUrl = imageUrl;
}
@Override
protected Bitmap doInBackground(String... params) {
InputStream in;
try {
URL url = new URL(this.imageUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
in = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(in);
return myBitmap;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
Intent intent = new Intent(mContext, MyOpenableActivity.class);
intent.putExtra("key", "value");
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 100, intent, PendingIntent.FLAG_ONE_SHOT);
NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notif = new Notification.Builder(mContext)
.setContentIntent(pendingIntent)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(result)
.setStyle(new Notification.BigPictureStyle().bigPicture(result))
.build();
notif.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(1, notif);
}
}
Solution 3
you can do this using Glide like this:
val notificationBuilder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_message)
.setContentTitle("title")
.setContentText("text")
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val futureTarget = Glide.with(this)
.asBitmap()
.load(photoUrl)
.submit()
val bitmap = futureTarget.get()
notificationBuilder.setLargeIcon(bitmap)
Glide.with(this).clear(futureTarget)
notificationManager.notify(0, notificationBuilder.build())
Solution 4
Top answer in Kotlin and with Coroutines. This method applies the bitmap to the builder
instead of a direct assignment, and of course if bitmap available. It's nice because if the url is wrong it will be caught in the try/catch.
fun applyImageUrl(
builder: NotificationCompat.Builder,
imageUrl: String
) = runBlocking {
val url = URL(imageUrl)
withContext(Dispatchers.IO) {
try {
val input = url.openStream()
BitmapFactory.decodeStream(input)
} catch (e: IOException) {
null
}
}?.let { bitmap ->
builder.setLargeIcon(bitmap)
}
}
with Kotlin & RxJava
fun applyImageUrl(
builder: NotificationCompat.Builder,
imageUrl: String
) {
val url = URL(imageUrl)
Single.create<Bitmap> { emitter ->
try {
val input = url.openStream()
val bitmap = BitmapFactory.decodeStream(input)
emitter.onSuccess(bitmap)
} catch (e: Exception) {
emitter.onError(e)
}
}.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{
builder.setLargeIcon(it)
}, {
Timber.e("error generating bitmap for notification")
}
)
}
Solution 5
Since image is loaded from internet, it should be done async in a background thread. Either use async task or Glide (for efficient image loading).
To load image notification, you need to use "NotificationCompat.BigPictureStyle()". This requires a bitmap (which has to be extracted from image url)
Most of the API's and methods of Glide are now deprecated. Below is working with Glide 4.9 and upto Android 10.
// Load bitmap from image url on background thread and display image notification
private void getBitmapAsyncAndDoWork(String imageUrl) {
final Bitmap[] bitmap = {null};
Glide.with(getApplicationContext())
.asBitmap()
.load(imageUrl)
.into(new CustomTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
bitmap[0] = resource;
// TODO Do some work: pass this bitmap
displayImageNotification(bitmap[0]);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
Display the image notification once, the bitmap is ready.
private void displayImageNotification(Bitmap bitmap) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), getChannelId());
builder
.setContentTitle(title)
.setContentText(subtext)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE)
.setSmallIcon(SMALL_ICON)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setColor(getApplicationContext().getColor(color))
.setAutoCancel(true)
.setOngoing(false)
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent)
.setStyle(
new NotificationCompat.BigPictureStyle().bigPicture(bitmap))
.setPriority(Notification.PRIORITY_HIGH);
getManager().notify(tag, id, builder.build());
}
Zankhna
Enthusiastic Software Engineer interested in developing Mobile and Web application that can transform Visualization to the Reality.
Updated on July 05, 2022Comments
-
Zankhna almost 2 years
In my android application, i want to set Notification icons dynamically which will be loaded from URL. For that, i have used
setLargeIcon
property of NotificationBuilder inreceiver
.I reffered many link and tried various solutions but couldn't get desired output. Though i downloaded that image from url and setting that bitmap in notification, it is not being displayed. Instead it displays thesetSmallIcon
image as large icon. I don't know where i am going wrong. Here i am posting my code. Please help me to solve this issue. Thank you.Code:
@SuppressLint("NewApi") public class C2DMMessageReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if ("com.google.android.c2dm.intent.RECEIVE".equals(action)) { Log.e("C2DM", "received message"); final String fullName = intent.getStringExtra("message"); final String payload1 = intent.getStringExtra("message1"); final String payload2 = intent.getStringExtra("message2"); final String userImage = intent.getStringExtra("userImage"); Log.e("userImage Url :", userImage); //it shows correct url new sendNotification(context) .execute(fullName, payload1, userImage); } } private class sendNotification extends AsyncTask<String, Void, Bitmap> { Context ctx; String message; public sendNotification(Context context) { super(); this.ctx = context; } @Override protected Bitmap doInBackground(String... params) { InputStream in; message = params[0] + params[1]; try { in = new URL(params[2]).openStream(); Bitmap bmp = BitmapFactory.decodeStream(in); return bmp; } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); try { NotificationManager notificationManager = (NotificationManager) ctx .getSystemService(Context.NOTIFICATION_SERVICE); Intent intent = new Intent(ctx, NotificationsActivity.class); intent.putExtra("isFromBadge", false); Notification notification = new Notification.Builder(ctx) .setContentTitle( ctx.getResources().getString(R.string.app_name)) .setContentText(message) .setSmallIcon(R.drawable.ic_launcher) .setLargeIcon(result).build(); // hide the notification after its selected notification.flags |= Notification.FLAG_AUTO_CANCEL; notificationManager.notify(1, notification); } catch (Exception e) { e.printStackTrace(); } } }
-
Paresh Mayani over 8 yearsPut some details along with code! It would help someone to understand the APIs, functionality and the implantation exactly!
-
Erum over 7 yearshow to handle image size ??
-
Arpit Patel over 7 yearsi am not able to call this method in FirebaseMessagingService How can i implement it.
-
AxA over 7 years@ArpitPatel May be the service is ending prior to retrieving image asynchronously. Did you try getting the image synchronously? Like here: androidbash.com/firebase-push-notification-android
-
Arpit Patel over 7 yearsya i already solve using this tutorial. It is well explained. thanks by the for guidance @rpattabi
-
Prashant Gosai over 7 years@rpattabi androidbash.com/firebase-push-notification-android I try this tutorial, but there is some restrictions Like Notification with image an fetched from the url is displayed to the user (with BigImage). But if the app is background or killed state, then onMessageReceived () method will not be called. Hence a simple notification containing just a message will be displayed in the notification bar on your Android device.
-
Narendra Singh about 7 yearsIts working, but it takes a few seconds to display the notification, it doesn't display immediately. Is there some way that, notification generate immediately. Is there any way to display notification immediately, and load image from url meanwhile?
-
Tejas Pandya almost 6 years@PrashantGosai is there any way to show image in background state also ?
-
EdgeDev over 5 yearsWhy did you have the notification code in Async Task?
-
Hiren Patel over 5 years@Micklo_Nerd, We are loading image in background thread that's why we've used Async Task. You probably can use Rx java instead to eliminate the code.
-
EdgeDev over 5 yearsOkay, i get it now. Thanks
-
ismail alaoui over 5 yearsyou should call input stream in = new Url .....() in a asynctask , never perform network request in the main thread
-
Juan Mendez almost 5 yearssee my answer in 2019 implementing this answer using Coroutines and Kotlin :)
-
faizanjehangir about 4 yearsVery solid answer! Works as is in Kotlin!
-
Juan Mendez about 4 yearsI have applied this code in two apps and has worked great. Thanks for sharing your experience.
-
skygeek almost 4 yearsThis is more lucrative.
-
Juan Mendez over 3 yearsI edited the answer by appending RxJava solution as well.
-
Rumit Patel about 2 yearsIs there any special purpose to using
setPriority
twice?