Загрузить изображение с url в уведомлении Android
В моем приложении для Android я хочу динамически устанавливать значки уведомлений, которые будут загружаться с URL. Для этого я использовал свойство setLargeIcon
NotificationBuilder в receiver
Я ссылался на многие ссылки и пробовал различные решения, но не смог получить желаемый результат. Хотя я загрузил это изображение с URL и установил это растровое изображение в уведомлении, оно не отображается. Вместо этого он отображает изображение setSmallIcon
виде большого значка. Я не знаю, где я иду не так. Здесь я публикую свой код. Пожалуйста, помогите мне решить эту проблему. Спасибо.
Код:
@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();
}
}
}
Ответы
Ответ 1
Изменен мой код ниже и его работа сейчас:
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();
}
}
}
Ответ 2
Как реализовать уведомление в стиле BigPicture:
Чудо было сделано .setStyle(new Notification.BigPictureStyle().bigPicture(result))
:
Я сделал это с:
![enter image description here]()
Создать уведомление от 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);
}
}
Ответ 3
Вы можете сделать это с помощью Glide следующим образом:
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())
![preview]()
Ответ 4
Я знаю, что был дан хороший ответ, так что давайте посмотрим, сможем ли мы облегчить понимание и реализацию.
--------------------- Теория ------------------------
Проблема может быть разделена на два этапа, а именно:
1) Получить изображение с URL
2) Расшифруйте изображение и передайте построителю уведомлений
1) Получить изображение с URL
InputStream in = new URL("Img URL goes here eg. http://gg.com/profile.jpg").openStream();
2) Расшифровать и перейти к уведомлению
Bitmap bmp = null;
# Создайте пустой BMP-контейнер, который будет использоваться для хранения декодированного img
bmp = BitmapFactory.decodeStream(in);
# сохранить изображение в контейнер
Вуаля! как только вы .setLargeIcon(bmp)
образ и сохраните его в переменной bmp, вы можете вызвать его в построителе уведомлений .setLargeIcon(bmp)
--------Реализация---------------
Студия Android предложит вам обернуть ваш код в try catch, чтобы конечный продукт выглядел следующим образом.
Bitmap bmp = null;
try {
InputStream in = new URL("url goes here").openStream();
bmp = BitmapFactory.decodeStream(in);
} catch (IOException e) {
e.printStackTrace();
}
Если у вас есть bmp, вы можете вызвать его в уведомителе как
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher)
.setContentText("title")
.setContentText("text goes here")
.setLargeIcon(bmp)
.setAutoCancel(true);
Ответ 5
Использование библиотеки Пикассо.
Target target = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
largeIcon=bitmap;
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
Picasso.with(this).load("url").into(target);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.icon)
.setContentTitle(msg.getString("title"))
.setContentText(msg.getString("msg"))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setLargeIcon(largeIcon)
.setContentIntent(pendingIntent);
Ответ 6
Используя Glide lib, вы можете использовать
Bitmap bitmapImage = Glide.with(this).asBitmap().centerCrop().load(imageUrl).submit(imageSize, imageSize).get();
Ответ 7
Лучший ответ в Kotlin и с сопрограммами. Этот метод применяет растровое изображение к builder
вместо прямого назначения и, конечно, если доступно растровое изображение. Это хорошо, потому что если URL неверный, он будет пойман в 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)
}
}