Load image from url in notification Android

旧城冷巷雨未停 提交于 2019-11-26 10:20:52

问题


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.

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

回答1:


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



回答2:


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



回答3:


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




回答4:


Since image is loaded from internet, it should be done async in a background thread. Either use async task or Glide (for efficient image loading).

To load image notification, you need to use "NotificationCompat.BigPictureStyle()". This requires a bitmap (which has to be extracted from image url)

Most of the API's and methods of Glide are now deprecated. Below is working with Glide 4.9 and upto 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());
}



回答5:


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) Get image from a 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

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.

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

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentText("title")
            .setContentText("text goes here")
            .setLargeIcon(bmp)
            .setAutoCancel(true);



回答6:


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



回答7:


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


来源:https://stackoverflow.com/questions/24840282/load-image-from-url-in-notification-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!