我正在寻找一种简单的方法来使用Picasso加载一个说明图标(这是一个远程网页上的URL)。在以前版本的应用程序我正在研究这个代码似乎工作:
Bitmap speakerPic = null;
try {
speakerPic = new AsyncTask<Void, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(Void... params) {
try {
return Picasso.with(c).load(session.getSpeaker().getPhotoUrl()).get();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}.execute().get(1500, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
if (speakerPic != null) {
builder.setLargeIcon(speakerPic);
} else {
builder.setLargeIcon(BitmapFactory.decodeResource(c.getResources(), R.drawable.ic_launcher));
}
但是现在我每次都得到一个TimeOutException(我回退到res文件夹中的默认图标)。我必须使用这个AsyncTask,因为Picasso(/ network)可能不会在UI线程上发生。 (虽然我在这里阻止了1.5秒的UI线程..)。
我知道Picasso可以处理远程视图,但我不想使用自定义视图来表示我的意见。另外,我找不到一种方法来获取NoticifationIcon的RemoteView。
有没有办法只使用Picasso来设置我的通知图标?
答案 0 :(得分:17)
I'll answer the question myself because I've found a decent way, using Picasso and RemoteViews. Tested and working with Picasso 2.5.2 :
// Default stuff; making and showing notification
final Context context = getApplicationContext();
final NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
final Notification notification = new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher) // Needed for the notification to work/show!!
.setContentTitle("Title of notification")
.setContentText("This is the description of the notification")
// Uncomment if you want to load a big picture
//.setStyle(new NotificationCompat.BigPictureStyle())
.build();
final int notifId = 1337;
notificationManager.notify(notifId, notification);
// Get RemoteView and id's needed
final RemoteViews contentView = notification.contentView;
final int iconId = android.R.id.icon;
// Uncomment for BigPictureStyle, Requires API 16!
//final RemoteViews bigContentView = notification.bigContentView;
//final int bigIconId = getResources().getIdentifier("android:id/big_picture", null, null);
// Use Picasso with RemoteViews to load image into a notification
Picasso.with(getApplicationContext()).load("http://i.stack.imgur.com/CE5lz.png").into(contentView, iconId, notifId, notification);
// Uncomment for BigPictureStyle
//Picasso.with(getApplicationContext()).load("http://i.stack.imgur.com/CE5lz.png").into(bigContentView, iconId, notifId, notification);
//Picasso.with(getApplicationContext()).load("http://i.stack.imgur.com/CE5lz.png").into(bigContentView, bigIconId, notifId, notification);
答案 1 :(得分:6)
不确定为什么你的代码不能正常工作,但它的编译很适合我,在API级别21和Android Studio上进行了测试。
我做了一些改动以满足我的需求,例如:消除了时间延迟。
唯一明显的区别是我的logcat中的以下输出:
Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, returning read-only value.
我的更新代码是:
Bitmap contactPic = null;
final String getOnlinePic = GET_AVATAR;
try {
contactPic = new AsyncTask<Void, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(Void... params) {
try {
return Picasso.with(ctx).load(getOnlinePic)
.resize(200, 200)
.placeholder(R.drawable.ic_action_user_purple_light)
.error(R.drawable.ic_action_user_purple_light)
.get();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}.execute().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
if (contactPic != null) {
builder.setLargeIcon(contactPic);
} else {
builder.setLargeIcon(BitmapFactory.decodeResource(ctx.getResources(), R.drawable.ic_action_user_purple_light));
}
答案 2 :(得分:5)
我建议用最简单的方法将通知中的远程图片与毕加索的大图标集成。
// your notification builder
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(getString(R.string.app_name))
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
String picture = "http://i.stack.imgur.com/CE5lz.png";
Bitmap bmp = Picasso.with(getApplicationContext()).load(picture).get();
notificationBuilder.setLargeIcon(bmp);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
答案 3 :(得分:2)
如果你不想等到毕加索在发送通知之前提取图片,一个解决方案就是用相同的身份发送两次通知,这样NotificationManager
就会第二次发送时更新现有通知。
在实践中,第一次使用setLargeIcon()
的占位符,第二次使用毕加索Bitmap
中的Target
。
例如,来自您的Activity
:
final Notification.Builder builder = new Notification.Builder(this);
final int id = 0; // change this w/ your notification id
Bitmap placeholder = BitmapFactory.decodeResource(getResources(), R.drawable.your_placeholder_icon);
builder.setContentTitle(title)
.yourFavoriteBuilderMethods(...)
.setLargeIcon(placeholder)
.setDefaults(0); // so that it doesn't ring twice
// mTarget should an instance variable of your class so it doesn't get GC'ed
mTarget = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
builder.setLargeIcon(bitmap)
.setDefaults(Notification.DEFAULT_ALL);
// send the notification again to update it w/ the right image
((NotificationManager) (getSystemService(NOTIFICATION_SERVICE)))
.notify(id, builder.build());
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {}
};
Picasso.with(this).load(your_image_url_here).into(mTarget);
// send notification for the first time here, w/ placeholder:
((NotificationManager) (getSystemService(NOTIFICATION_SERVICE)))
.notify(id, builder.build());
由于Picasso需要访问互联网,因此不要忘记在清单中设置正确的权限以使其正常工作:
<uses-permission android:name="android.permission.INTERNET" />
答案 4 :(得分:0)
使用Picaso 2.5.2的图像加载代码在此方法的中间开始,除了所有内容都是简单的通知代码,只需复制和粘贴,替换&#34; image_url&#34;与实际图像网址。
private Notification notification;
public void genrateNewsNotification(String title, final int id) {
try {
final Context context=GcmService.this;
final NotificationCompat.Builder mBuilder;
final NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(id);
Intent notificationIntent = new Intent(context, YourActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(notificationIntent);
final PendingIntent contentIntent =
stackBuilder.getPendingIntent(
id,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle("Custom Notification");
mBuilder.setAutoCancel(true);
mBuilder.setPriority(Notification.PRIORITY_MAX);
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= Build.VERSION_CODES.LOLLIPOP) {
mBuilder.setSmallIcon(R.drawable.launch_lolipop);
} else {
mBuilder.setSmallIcon(R.drawable.launcher_icon);
}
mBuilder.setContentText(title);
mBuilder.setContentIntent(contentIntent);
notification= mBuilder.build();
// image code starts from here
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
try{
Picasso.with(context).load("image_url")
.into(target);
notificationManager.notify(id, notification);
}
catch (Exception e){
// notification without image in case of Exception
notificationManager.notify(id, notification);
}
}else{
notificationManager.notify(id, notification);
}
} catch (Exception e) {
e.printStackTrace();
}
}
**// main stuff goes here ,it is an inner class**
private Target target = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
if (bitmap != null) {
RemoteViews views;
views = new RemoteViews(getPackageName(), R.layout.custom_notification);
views.setTextViewText(R.id.title, "Daily Notification");
views.setTextColor(R.id.title,getResources().getColor(R.color.black));
views.setImageViewBitmap(R.id.big_picture, bitmap);
views.setImageViewBitmap(R.id.big_icon, BitmapFactory.decodeResource(getResources(), R.drawable.launcher_icon));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
notification.bigContentView = views;
}
}
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
Log.i("errorDrawable","errorDrawable");
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};