在通知中使用毕加索最简单的方法(图标)

我正在寻找一种简单的方法来使用毕加索加载一个通知图标(这是一个远程网页上的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线程上发生。 (尽pipe我在这里封锁了1.5秒的UI线程..)。

我知道毕加索可以处理远景,但我不想用自定义的观点来expression我的意见。 此外,我无法find一个方法来获取NoticifationIcon的RemoteView。

有没有办法简单地使用毕加索设置我的通知图标?

Solutions Collecting From Web of "在通知中使用毕加索最简单的方法(图标)"

我会自己回答这个问题,因为我find了一个体面的方式,使用毕加索和RemoteViews。 经过testing并与毕加索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://img.androidcookie.com/android/CE5lz.png").into(contentView, iconId, notifId, notification); // Uncomment for BigPictureStyle //Picasso.with(getApplicationContext()).load("http://img.androidcookie.com/android/CE5lz.png").into(bigContentView, iconId, notifId, notification); //Picasso.with(getApplicationContext()).load("http://img.androidcookie.com/android/CE5lz.png").into(bigContentView, bigIconId, notifId, notification); 

不知道为什么你的代码不能正常工作,但是它的编译对我来说很好,在API级别21和Android Studio上testing过。

我做了一些改变,以适应我的需要,例如,消除了时间延迟。

唯一明显的区别是我的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)); } 

如果您不想等到毕加索在发送通知之前获取图像,则一种解决方法是使用相同的ID发送两次通知,以便NotificationManager在第二次发送时更新现有通知。

实际上,第一次使用setLargeIcon()的占位符,第二次使用从毕加索Target获得的Bitmap

例如,从您的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()); 

由于毕加索将需要访问互联网,不要忘记在您的清单中设置正确的权限,以使其工作:

 <uses-permission android:name="android.permission.INTERNET" /> 

我build议一个最简单的方法来将您的通知中的远程图片与毕加索的大图标集成在一起。

 // 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://img.androidcookie.com/android/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()); 
 Image loading code using Picaso 2.5.2 starts in middle of this method,besides that all stuff is simple notification code 

只需复制并粘贴,将“image_url”replace为实际的图片url

  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) { } };