【问题标题】:Glide: load image to push notificationsGlide:加载图像以推送通知
【发布时间】:2017-06-11 04:39:47
【问题描述】:

我正在尝试使用 Glide 将图像加载到推送通知中,但它说:

FATAL EXCEPTION: Thread-9730
Process: com.monkingme.monkingmeapp, PID: 24226
java.lang.IllegalArgumentException: You must call this method on the main thread at com.bumptech.glide.util.Util.assertMainThread(Util.java:135)                                                                                

以及使用的代码:

NotificationTarget notificationTarget = new NotificationTarget(
                context,
                rv,
                R.id.remoteview_notification_icon,
                notification,
                NOTIFICATION_ID);

Glide.with(context.getApplicationContext())
     .load(item.getString("cover_img"))
     .asBitmap()
     .placeholder(placeholder)
     .error(placeholder)
     .into(notificationTarget);

我正在使用 Aerogear 的 MessageHandler --> https://aerogear.org/docs/guides/aerogear-android/push/

问题是在推送通知中应用程序没有运行,所以没有主线程。有什么建议吗?

【问题讨论】:

标签: android notifications push android-glide remoteview


【解决方案1】:

试试这个方法:

    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override 
            public void run() {
                 Glide.with(context.getApplicationContext())
                    .load(item.getString("cover_img"))
                    .asBitmap()
                    .placeholder(placeholder)
                    .error(placeholder)
                    .into(notificationTarget);
        }
    });

【讨论】:

    【解决方案2】:

    这是意料之中的。由于图像是从互联网加载的,它应该始终在 async 调用或后台线程中。您可以使用异步任务或图像加载库,如 Glide。

    要从 url 加载图像通知,您可以使用样式“NotificationCompat.BigPictureStyle()”。这需要一个位图(必须从图片网址中提取)

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

    显示一次图像通知,位图准备就绪。

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

    【讨论】:

    • 每当加载图像失败时,此方法都会导致一些错误。或者在线程终止期间不调用任何回调(例如在广播接收器中),您也应该创建一种方法来处理这些情况。
    【解决方案3】:

    对于那些可能对最新版本的 Glide 和 Kotlin 感到困惑的人:

    val target = NotificationTarget(
                context,
                R.id.iv_image,
                remoteView,
                notification,
                NOTIFICATION_ID)
    
    Glide.with(context.applicationContext)
            .asBitmap()
            .load(url)
            .into(target)
    

    请务必注意,asBitmap() 应该紧跟在 with(context) 之后

    【讨论】:

      【解决方案4】:

      我的解决方案:

      public class NotificationBuilder {
      
        public static void build(Context context) {
          ...
          NotificationCompat.Builder notificationBuilder =
              new NotificationCompat.Builder(context, channelId)
                  .setSmallIcon(R.drawable.app_icon_notification).setContentTitle("Title")
                  .setContentText("Description").setAutoCancel(true).setShowWhen(true)
                  .setWhen(1574521462).setLights(ledColor, 200, 2000)
                  .setPriority(NotificationCompat.PRIORITY_MAX)
                  .setStyle(new NotificationCompat.BigTextStyle().bigText("Description"))
                  .setTicker("Description").setSound(defaultSoundUri).setContentIntent(pendingIntent);
          FutureTarget<Bitmap> futureTarget = GlideApp.with(context).asBitmap()
              .load("http://example.com/myImage.jpg")
              .circleCrop().submit();
          LoadImageTask task = new LoadImageTask(icon -> {
                notificationBuilder.setLargeIcon(icon);
                GlideApp.with(context).clear(futureTarget);
                notificationManager.notify(NotificationsCons.SUPPORT_MESSAGES_NOTIFICATION_ID,
                    notificationBuilder.build());
              });
          task.execute(futureTarget);
        }
      }
      
      private static class LoadImageTask extends AsyncTask<FutureTarget<Bitmap>, Void, Bitmap> {
        private OnSuccess onSuccess;
      
        interface OnSuccess {
          void onSuccess(Bitmap bitmap);
        }
      
        LoadImageTask(OnSuccess onSuccess) {
          this.onSuccess = onSuccess;
        }
      
        @SafeVarargs @Override
        protected final Bitmap doInBackground(FutureTarget<Bitmap>... futureTargets) {
          try {
            return futureTargets[0].get();
          } catch (ExecutionException e) {
            e.printStackTrace();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          return null;
        }
      
        @Override protected void onPostExecute(Bitmap bitmap) {
          super.onPostExecute(bitmap);
          if (bitmap != null)
            onSuccess.onSuccess(bitmap);
        }
      }
      

      效果很好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-23
        • 2017-10-18
        • 2018-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多