Load image from url in notification Android

前端 未结 8 742
北海茫月
北海茫月 2020-11-28 21:48

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 Notificati

相关标签:
8条回答
  • 2020-11-28 22:16

    How to implement BigPicture style Notification:

    Miracle has been done by .setStyle(new Notification.BigPictureStyle().bigPicture(result)) :

    I have done this way with:

    Generate notification by 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);
            }
        }
    
    0 讨论(0)
  • 2020-11-28 22:18

    Since I couldn't find any working solution for Picasso I'm posting my complete and working(July 2020) example using Picasso below.

    It is sending the notification immediately and then updates it when the image for setLargeIcon() has been loaded. Normally this is very quick and the user should only see the updated version of the notification in most cases.

    private void sendNotification(String message, String title, final String photoUrl) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_ONE_SHOT);
    
        final NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(this, CHANNEL_ID)
                        .setSmallIcon(R.drawable.wbib_transp_512)
                        .setContentTitle(title)
                        .setContentText(message)
                        .setAutoCancel(true)
                        .setPriority(NotificationCompat.PRIORITY_HIGH)
                        .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                        .setContentIntent(pendingIntent);
    
        final NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    
        notificationManager.notify(0, notificationBuilder.build());
    
        final Handler uiHandler = new Handler(Looper.getMainLooper());
        uiHandler.post(new Runnable() {
            @Override
            public void run() {
                Picasso.get()
                        .load(photoUrl)
                        .resize(200, 200)
                        .into(new Target() {
                            @Override
                            public void onBitmapLoaded(final Bitmap bitmap, final Picasso.LoadedFrom from) {
                                notificationBuilder.setLargeIcon(bitmap);
                                notificationManager.notify(0, notificationBuilder.build());
                            }
    
                            @Override
                            public void onBitmapFailed(Exception e, final Drawable errorDrawable) {
                                // Do nothing?
                            }
    
                            @Override
                            public void onPrepareLoad(final Drawable placeHolderDrawable) {
                                // Do nothing?
                            }
                        });
            }
        });
    
    
    }
    
    0 讨论(0)
  • 2020-11-28 22:20

    you can do this using Glide like this:

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

    0 讨论(0)
  • 2020-11-28 22:24

    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);
    
    0 讨论(0)
  • 2020-11-28 22:25

    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.

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

    with Kotlin & RxJava

    fun applyImageUrl(
        builder: NotificationCompat.Builder,
        imageUrl: String
    ) {
        val url = URL(imageUrl)
    
        Single.create<Bitmap> { emitter ->
            try {
                val input = url.openStream()
                val bitmap = BitmapFactory.decodeStream(input)
                emitter.onSuccess(bitmap)
            } catch (e: Exception) {
                emitter.onError(e)
            }
        }.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                {
                    builder.setLargeIcon(it)
                }, {
                    Timber.e("error generating bitmap for notification")
                }
            )
    }
    
    0 讨论(0)
  • 2020-11-28 22:28

    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();
                }
            }
        }
    
    0 讨论(0)
提交回复
热议问题