从通知 Android 中的 url 加载图像
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24840282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Load image from url in notification Android
提问by Zankhna
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 in receiver
.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 the setSmallIcon
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.
在我的 android 应用程序中,我想动态设置将从 URL 加载的通知图标。为此,我setLargeIcon
在receiver
.I 中使用了 NotificationBuilder 的属性。我引用了许多链接并尝试了各种解决方案,但无法获得所需的输出。尽管我从 url 下载了该图像并在通知中设置了该位图,但它并未显示。相反,它将setSmallIcon
图像显示为大图标。我不知道我哪里出错了。我在这里发布我的代码。请帮我解决这个问题。谢谢你。
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();
}
}
}
采纳答案by Zankhna
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();
}
}
}
回答by Hiren Patel
How to implement BigPicturestyle Notification:
如何实现BigPicture风格的通知:
Miracle has been done by .setStyle(new Notification.BigPictureStyle().bigPicture(result))
:
奇迹是由.setStyle(new Notification.BigPictureStyle().bigPicture(result))
:
I have done this way with:
我已经这样做了:
Generate notificationby AsyncTask:
通过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);
}
}
回答by Dan Alboteanu
you can do this using Glide like this:
你可以像这样使用 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())
回答by Mayuri Khinvasara
Since image is loaded from internet, it should be done asyncin a background thread. Either use async task or Glide (for efficient image loading).
由于图像是从 Internet 加载的,因此应该在后台线程中异步完成。使用异步任务或 Glide(为了高效的图像加载)。
To load image notification, you need to use "NotificationCompat.BigPictureStyle()". This requires a bitmap(which has to be extracted from image url)
要加载图像通知,您需要使用“NotificationCompat.BigPictureStyle()”。这需要一个位图(必须从图像 url 中提取)
Most of the API's and methods of Glideare now deprecated. Below is working with Glide 4.9 and upto Android 10.
Glide 的大部分 API 和方法现在都已弃用。下面是使用 Glide 4.9 和高达 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());
}
回答by Juan Mendez
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.
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)
}
}
回答by user10475447
I know a good answer has been given so let's see if we can make it easier to understand and implement.
---------------------Theory------------------------
The problem can be abstracted in two step solution namely
1) Get image from a URL
2) Decode image and pass to notification builder
我知道已经给出了一个很好的答案,所以让我们看看我们是否可以让它更容易理解和实施。
---------------------理论------------------------
问题可以抽象为两步解决方案,即
1) 从 URL 获取图像
2) 解码图像并传递给通知生成器
1) Get image from a URLInputStream in = new URL("Img URL goes here eg. http://gg.com/profile.jpg").openStream();
1) 从 URL 获取图像InputStream in = new URL("Img URL goes here eg. http://gg.com/profile.jpg").openStream();
2) Decode and pass to notification Bitmap bmp = null;
#create a null bmp container that will be used to hold decoded img bmp = BitmapFactory.decodeStream(in);
# save the image into container
2) 解码并传递给通知Bitmap bmp = null;
#创建一个空的 bmp 容器,用于保存解码后的 img bmp = BitmapFactory.decodeStream(in);
# 将图像保存到容器中
Voila!
once you build the image and save it in the variable bmp, you can call it on notification builder
.setLargeIcon(bmp)
--------Implementation---------------
Android studio will encourage you to wrap your code with try catch so the end product will look like this.
瞧!一旦您构建了图像并将其保存在变量 bmp 中,您就可以在通知构建器上调用它
.setLargeIcon(bmp)
--------Implementation---------------
Android studio 将鼓励您用 try catch 包装你的代码,这样最终产品看起来像这样。
Bitmap bmp = null;
try {
InputStream in = new URL("url goes here").openStream();
bmp = BitmapFactory.decodeStream(in);
} catch (IOException e) {
e.printStackTrace();
}
Once you have the bmp you can call it in notification builder as
拥有 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);
回答by Sunil Soni
Using Picasso Library.
使用毕加索图书馆。
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);