16

Hi Iam implementing Push Notifications in Android using GCM. I am trying to set an image for the notification instead of the default app icon. I am able to achieve this using the following code

if(extras.getString("src") != null){
            URL url = new URL(extras.getString("src"));
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap large_icon = BitmapFactory.decodeStream(input);
            mBuilder.setLargeIcon(large_icon);
        }

Typically the image will be from the web(jpg, png etc) and not something in the device. The above code works but the image is either too big or too small. I would like to know the optimum size or aspect ratio for the bitmap so that I can supply an appropriate image

injecteer
  • 16,220
  • 3
  • 39
  • 72
Ram G Athreya
  • 4,604
  • 6
  • 23
  • 57

3 Answers3

42

I was having the same problem. This is how I solve it:

First you need to know the max sizes of the notification icon depending of the device resolution. Searching, I found this:

  • ldpi: 48x48 px *0.75
  • mdpi: 64x64 px *1.00
  • hdpi: 96x96 px *1.50
  • xhdpi: 128x128 px *2.00
  • xxhdpi: 192x192 px *3.00

There are 2 approach:

  • One is having a set of images in those dimension in the server, and get them depending of your device resolution.
  • The other one is having the larger image in the server and resize it in the app depending of your device resolution.

I will explain to you the second one that I implement.

First for get the Image from an URL I use this:

public Bitmap getBitmapFromURL(String strURL) {
    try {
        URL url = new URL(strURL);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.connect();
        InputStream input = connection.getInputStream();
        Bitmap myBitmap = BitmapFactory.decodeStream(input);
        return myBitmap;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

Then I need to know the factor for the new image size. I know that in the server I have the xxhdpi image with a factor of *3.00, I use that for get the global factor:

public static float getImageFactor(Resources r){
      DisplayMetrics metrics = r.getDisplayMetrics();
      float multiplier=metrics.density/3f;
      return multiplier;
  }

Now I have to resize the image size and set the new bitmap in the notification icon:

Bitmap bmURL=getBitmapFromURL(largeIcon);
float multiplier= getImageFactor(getResources());
bmURL=Bitmap.createScaledBitmap(bmURL, (int)(bmURL.getWidth()*multiplier), (int)(bmURL.getHeight()*multiplier), false);
if(bmURL!=null){
    mBuilder.setLargeIcon(bmURL);
}           

This work for me. I hope you can use it.

OscarBudo
  • 451
  • 4
  • 7
  • 2
    @user25 what you are referring to is status bar icons guidelines, but the OP and the answerer are talking about is the size of the image set via [`NotificationCompat.Builder.setLargeIcon()`](https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#setLargeIcon(android.graphics.Bitmap)). – Sufian Sep 17 '16 at 13:20
11

If I understood your problem perfectly, then the below will help you.

If you have the image already.. then you can set it like

  .setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_app_sky))
  .setSmallIcon(R.drawable.ic_aaja_icon_red)

The total one:

 NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
    builder.setNumber(COUNTER)
     .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_app_sky))
     .setSmallIcon(R.drawable.ic_icon_red)
     .setAutoCancel(true)
     .setContentTitle(pushCount > 1 ? "xxx" + pushCount : title)
     .setContentText(pushCount > 1 ? "yyy" : message)
     .setWhen(when)
     .setContentIntent(PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT))
   //.setDeleteIntent(PendingIntent.getBroadcast(context, 0, new Intent(Intent.ACTION_CLEAR_NOTIFICATION), PendingIntent.FLAG_CANCEL_CURRENT))
     .setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE)
     .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));

You can also get help from this tutorial..

EDIT: To change a bitmap size ..taken from here..

Bitmap bitmap = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length)
profileImage.setImageBitmap(Bitmap.createScaledBitmap(bitmap , 64, 64, false));
Community
  • 1
  • 1
Ranjit
  • 4,797
  • 3
  • 28
  • 62
  • Image will be a url like take this for instance http://1.bp.blogspot.com/_rKG-ziTSNUQ/S7H2oaUkKeI/AAAAAAAABTI/DI-jUR-wD1c/s320/blogger-logo.png I have square images i just need to know the optimal size across devices – Ram G Athreya Jul 30 '14 at 07:23
  • @RamGAthreya You can change a bitmap size and put it in notification..no approx needed..it should be 32 px/ 64 px – Ranjit Jul 30 '14 at 07:27
0

The other thing here to know is that the base layouts have margins stated on these images, so if you are trying to mimic the behavior seen by the base layouts in a custom layout make sure to do something similar. Checkout notification_template_icon_group.xml for details.

Here I have computed the math to pixels for you (64dp - 12dp):

ldpi 48 - 9 = 39
mdpi 64 - 12 = 52
hdpi 96 - 18 = 78
xhdpi 128 - 24 = 104
xxhdpi 192 - 36 = 156
Trevor Mack
  • 145
  • 2
  • 6