Значок Bigmap отображается как белый квадрат в уведомлении?
У меня возникает эта проблема, когда я генерирую Bitmap
из URL-адреса, который я использую в своем уведомлении. Однако, на моем телефоне, Bitmap
появляется как маленький белый квадрат. Я заглянул в него и нашел много сообщений, рассказывающих об этом: Значок не отображается в уведомлении: вместо этого показан белый квадрат
и я точно знаю, что мой Small Icon
для уведомления действительно прозрачен. Однако для Large Icon
я понимаю, что Large Icon
не может быть прозрачным, потому что на самом деле это Bitmap
, который я генерирую из URL. Как я могу обойти это и убедиться, что изображение отображается правильно, вместо того, чтобы Large Icon
отображался как белый квадрат? Вот моя попытка:
NotificationService.java:
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
.setContentTitle(getString(R.string.app_name))
.setContentText(remoteMessage.getNotification().getBody())
.setTicker(remoteMessage.getFrom() + " has responded!")
.setLargeIcon(AndroidUtils.getBitmapFromURL(remoteMessage.getNotification().getIcon()))
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setStyle(new NotificationCompat.BigTextStyle().bigText(remoteMessage.getNotification().getBody()))
.setSmallIcon(R.drawable.ic_tabs_notification_transparent);
AndroidUtils.java:
public static Bitmap getBitmapFromURL(String userId) {
try {
URL imgUrl = new URL("https://graph.facebook.com/" + userId + "/picture?type=large");
InputStream in = (InputStream) imgUrl.getContent();
Bitmap bitmap = BitmapFactory.decodeStream(in);
Bitmap output;
Rect srcRect;
if (bitmap.getWidth() > bitmap.getHeight()) {
output = Bitmap.createBitmap(bitmap.getHeight(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
srcRect = new Rect((bitmap.getWidth()-bitmap.getHeight())/2, 0, bitmap.getWidth()+(bitmap.getWidth()-bitmap.getHeight())/2, bitmap.getHeight());
} else {
output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getWidth(), Bitmap.Config.ARGB_8888);
srcRect = new Rect(0, (bitmap.getHeight()-bitmap.getWidth())/2, bitmap.getWidth(), bitmap.getHeight()+(bitmap.getHeight()-bitmap.getWidth())/2);
}
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
float r;
if (bitmap.getWidth() > bitmap.getHeight()) {
r = bitmap.getHeight() / 2;
} else {
r = bitmap.getWidth() / 2;
}
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawCircle(r, r, r, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, srcRect, rect, paint);
return output;
} catch (IOException e) {
FirebaseCrash.report(e);
return null;
}
Изображение, показывающее мою проблему:
![введите описание изображения здесь]()
EDIT: файл Build.gradle показывает:
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
defaultConfig {
applicationId '<ID>'
multiDexEnabled true
minSdkVersion 21
targetSdkVersion 23
versionCode 12
versionName ".12"
signingConfig signingConfigs.Tabs
}
buildTypes {
release {
minifyEnabled false
shrinkResources false
zipAlignEnabled true
debuggable false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.Tabs
}
debug {
applicationIdSuffix ".debug"
debuggable true
minifyEnabled false
signingConfig signingConfigs.Tabs
}
}
//DatabaseReference stuff
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE-FIREBASE.txt'
exclude 'META-INF/NOTICE'
}
dexOptions {
javaMaxHeapSize "4g"
}
productFlavors {
}
}
Ответы
Ответ 1
try {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setSmallIcon(getNotificationIcon());
Bitmap icon = BitmapFactory.decodeResource(CXGcmListenerService.this.getResources(), R.drawable.ic_launcher);
mBuilder.setLargeIcon(icon);
//Define sound URI
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
mBuilder.setContentIntent(pendingIntent);
mBuilder.setContentText(msg);
mBuilder.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg));
mBuilder.setContentTitle(getString(R.string.app_name));
mBuilder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
mBuilder.setAutoCancel(true);
mBuilder.setSound(soundUri); //This sets the sound to play
Intent intent = new Intent(CXGcmListenerService.this, CXMainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent notificationIntent = PendingIntent.getActivity(this, 0, intent, 0);
mBuilder.setContentIntent(notificationIntent);
NotificationManager notifyManager = (NotificationManager) CXGcmListenerService.this.getSystemService(Context.NOTIFICATION_SERVICE);
NOTIFICATION_ID++;
notifyManager.notify("" + System.currentTimeMillis(), NOTIFICATION_ID, mBuilder.build());
} catch (Resources.NotFoundException e) {
CXLog.e(TAG, "" + e.getLocalizedMessage(), e);
}
Попробуйте это, чтобы получить значок в уведомлении.
Ответ 2
Вы можете использовать другой значок для другой версии:
int bigIcon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.drawable.logo_who_is_not_white: R.drawable.logo_who_is_in_whit_tint;
Ответ 3
Я думаю, что вы правильно загрузили изображение с URL-адреса. Итак, разместите Asynctask, чтобы загрузить изображение с URL-адреса, а затем используйте конструктор уведомлений, чтобы показать уведомление как подобное сообщение SO: fooobar.com/questions/239193/...
Ответ 4
У Lilipop есть эта проблема, вы просто смотрите на другой телефон до Lolipop, у которого нет проблем.
см. следующие ссылки
https://material.google.com/style/icons.html
https://developer.android.com/about/versions/android-5.0-changes.html
в противном случае вы можете изменить скомпилированный SDK
Ответ 5
Изменения в уведомлении для Lollipop, а затем и на уровнях API Android. Чтобы устранить эту проблему, вы можете выполнить следующие действия:
Way1: Либо измените цель targetSdkVersion с 23 до 19 в build.gradle вашего модуля приложения.
Это решит проблему для этого.
Примечание. Возможно, это решение создаст проблему в вашей системе сборки (я предпочитаю, чтобы вы не пошли таким образом, но вы можете проверить свою проблему таким образом)
Way2: Измените значок уведомления с черно-белым значком. Поскольку создатель уведомлений не поддерживает значки цветов с уровня API леденца.
Как получить черно-белый значок в Android Studio:
-
Папка с правой кнопкой мыши > Добавить ресурс изображения (любая папка ресурсов должна делать)
![введите описание изображения здесь]()
-
Нажмите на значок уведомлений из верхнего раскрывающегося списка (по умолчанию - значок Launcher) ![введите описание изображения здесь]()
-
Выберите изображение > Обзор для изображения > нажмите ok ![введите описание изображения здесь]()
Это нормально, так как Lollipop SDK (API 21 - Вер. 5.0.1) допускает только этот тип цветовой схемы
Или вы можете создать здесь: http://romannurik.github.io/AndroidAssetStudio/icons-notification.html
Ответ 6
Я думаю, что проблема связана с размером изображения, размер значков строки состояния следует ниже:
ldpi - 18 x 18 px
mdpi - 24 x 24 px
hdpi - 36 x 36 px
xhdpi - 48 x 48 px
вы также можете взглянуть на этот документ разработчика
вам нужно изменить размер полученного растрового изображения на вышеупомянутые размеры, и он должен работать.
Ответ 7
Хорошо, потому что Google изменил стиль уведомлений в API 21+ и рекомендовал использовать белый значок уведомления
Хотя вы можете использовать значок силуэта на значке 21+ и старше на всех других устройствах, что-то вроде ниже
private int getNotificationIcon() {
boolean icon = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP);
return icon ? R.drawable.silhouette : R.drawable.ic_launcher;
}
и вот фактический код построителя уведомлений:
Notification builder = new Notification.Builder(context)
.setSmallIcon(getNotificationIcon())
.build();
Ответ 8
В документация setColor()
Параметры
argb -The accent color to use
Вы проходите через 2, что не является допустимым цветом ARGB, поэтому цвет фона вашего маленького значка отображается неправильно. Вместо этого выберите допустимый цвет ARGB.
Если у вас есть ресурс цвета, который вы хотите использовать, вы можете использовать код, например
.setColor(context.getResources().getColor(R.color.notification_color))
Кроме того, обратите внимание на состояние изменений Android 5.0:
Обновите или удалите активы, которые включают цвет. Система игнорирует все не-альфа-каналы в значках действий и в главном значке уведомления. Вы должны предположить, что эти значки будут только альфа-. Система рисует значки уведомлений в белом цвете и значках действий в темно-сером цвете.
Ваш маленький значок должен быть полностью белым и прозрачным - вы можете использовать такие инструменты, как Notification Icon Generator, чтобы создать соответствующий значок.
или вы можете попробовать следующее:
int icon = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP ? R.drawable.your_logo_for_Kitkat : R.mipmap.your_logo_for_Lolipop_and_uper_version;
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(icon)
.setContentTitle(remoteMessage.getData().get("title"))
.setContentText(remoteMessage.getData().get("shortDescription"))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setColor(Color.RED)
.setStyle(notiStyle)
.setContentIntent(pendingIntent);
Для изображения Url Load:
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();
}
}
}