我在我的应用中加入了oreo支持。现在编译和目标SDK版本是27.我创建了一个通道来获取我的通知。我从应用程序类调用create channel方法。当应用程序处于前台时,通知看起来很好。但是当我在应用程序处于后台时收到通知时,会创建默认通道,以便在通知托盘中显示1个默认通知和1个自定义通知。我正在使用广播接收器来获取通知。以下是我的代码。
的Manifest.xml
<receiver
android:name=".receiver.PushMessageReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter android:priority="999">
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.caps" />
</intent-filter>
</receiver>
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="com.caps" />
Broadcast Receiver.java
public class PushMessageReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
abortBroadcast();
Logger.d(Logger.TAG, "notification received");
if (intent != null) {
NotificationHandler.handleNotification(context, formNotificationObject(intent));
}
}
private Notification formNotificationObject(Intent intent) {
Notification notification = new Notification();
notification.setMessageId(TextUtils.isEmpty(intent.getStringExtra("messageid")) ?
0 : Integer.parseInt(intent.getStringExtra("messageid")));
notification.setTitle(intent.getStringExtra("title"));
notification.setBody(intent.getStringExtra("body"));
notification.setImage(intent.getStringExtra("image"));
notification.setType(intent.getStringExtra("type"));
notification.setUrl(intent.getStringExtra("url"));
notification.setExpiry(intent.getStringExtra("expiry"));
if (intent.hasExtra("param")) {
String data = intent.getStringExtra("param");
ObjectMapper mapper = new ObjectMapper();
try {
CFLProduct product = mapper.readValue(data, CFLProduct.class);
notification.setParam(product);
} catch (IOException e) {
e.printStackTrace();
}
}
return notification;
}
}
NotificationHandler.java
public class NotificationHandler {
private static final CharSequence ANDROID_CHANNEL_NAME = "Promotions";
private static final String ANDROID_CHANNEL_ID = "com.caps";
private static NotificationManager mNotificationManager;
public static void handleNotification(Context context, Notification notification) {
if (notification != null) {
Logger.d(Logger.TAG, notification.toString());
showNotification(context, notification);
} else {
Logger.e(Logger.TAG, "notification is null");
}
}
private static NotificationCompat.Builder getNotificationBuilder(Context context) {
if (CommonUtils.isOreoOrAbove()) {
return new NotificationCompat.Builder(context, ANDROID_CHANNEL_ID);
} else {
return new NotificationCompat.Builder(context);
}
}
private static void showNotification(final Context context, final Notification notification) {
final NotificationCompat.Builder builder = getNotificationBuilder(context);
builder.setContentTitle(notification.getTitle());
builder.setContentText(notification.getBody());
NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
bigTextStyle.setBigContentTitle(notification.getTitle());
bigTextStyle.bigText(notification.getBody());
builder.setStyle(bigTextStyle);
// Playing notification sound
builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
getNotificationIcon(context, builder);
builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),
R.mipmap.ic_launcher));
builder.setAutoCancel(true);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
Intent resultIntent = new Intent(context, HomeActivity.class);
resultIntent.putExtra(AppConstants.BundleKeys.NOTIFICATION, notification);
stackBuilder.addParentStack(HomeActivity.class);
final int id = new Random().nextInt(1000);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(id, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(resultPendingIntent);
if (CommonUtils.isValidUrl(notification.getImage())) {
/* DownLoadBitMap downLoadBitMap = new DownLoadBitMap(context, builder, id, notification);
downLoadBitMap.execute(notification.getImage());*/
DownLoadBitmap downLoadBitmap = new DownLoadBitmap(context, builder, id, notification);
downLoadBitmap.loadFromGlide();
} else {
showSmallNotification(context, builder, id);
}
}
private static void getNotificationIcon(Context context, NotificationCompat.Builder notificationBuilder) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notificationBuilder.setSmallIcon(R.drawable.ic_notification_small_icon);
notificationBuilder.setColor(ContextCompat.getColor(context, R.color.colorPrimary));
} else {
notificationBuilder.setSmallIcon(R.mipmap.ic_launcher);
}
}
private static void showSmallNotification(Context context, NotificationCompat.Builder builder, int id) {
if (AppData.getInstance().getNotificationCount() == 0) {
AppData.getInstance().setNotificationCount(1);
}
getManager(context).notify(id, builder.build());
}
private static void showBigNotification(Context context, NotificationCompat.Builder builder, Bitmap bitmap, int id, Notification notification) {
if (AppData.getInstance().getNotificationCount() == 0) {
AppData.getInstance().setNotificationCount(1);
}
NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle();
bigPictureStyle.bigPicture(bitmap);
bigPictureStyle.setBigContentTitle(notification.getTitle());
bigPictureStyle.setSummaryText(notification.getBody());
builder.setStyle(bigPictureStyle);
getManager(context).notify(id, builder.build());
}
@RequiresApi(api = Build.VERSION_CODES.O)
public static void createChannels(Context context) {
// create android channel
NotificationChannel androidChannel = new NotificationChannel(ANDROID_CHANNEL_ID,
ANDROID_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
// Sets whether notifications posted to this channel should display notification lights
androidChannel.enableLights(true);
// Sets whether notification posted to this channel should vibrate.
androidChannel.enableVibration(true);
// Sets the notification light color for notifications posted to this channel
androidChannel.setLightColor(android.app.Notification.DEFAULT_LIGHTS);
// Sets whether notifications posted to this channel appear on the lockscreen or not
androidChannel.setLockscreenVisibility(android.app.Notification.VISIBILITY_PRIVATE);
getManager(context).createNotificationChannel(androidChannel);
}
private static NotificationManager getManager(Context context) {
if (mNotificationManager == null) {
mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
return mNotificationManager;
}
/**
* Downloading push notification image before displaying it in
* the notification tray
*/
private static class DownLoadBitmap {
private Context mContext;
private NotificationCompat.Builder mBuilder;
private int mId;
private Notification mNotification;
private SimpleTarget target = new SimpleTarget<Bitmap>(1024, 512) {
@Override
public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
Logger.d(Logger.TAG, "I got the bitmap");
showBigNotification(mContext, mBuilder, resource, mId, mNotification);
}
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
Logger.d(Logger.TAG, "FAILED TO DOWNLOAD RESOURCE"+e.getMessage());
}
};
private DownLoadBitmap(final Context context, final NotificationCompat.Builder builder, final int id, final Notification notification) {
mContext = context;
mBuilder = builder;
mId = id;
mNotification = notification;
}
public void loadFromGlide() {
Glide.with(mContext)
.load(mNotification.getImage())
.asBitmap()
.into(target);
}
}
}
我不明白为什么在我创建频道并将其设置为默认频道时创建默认频道。这也只有在应用程序处于后台时才会发生。可能是什么问题?我该如何解决?
答案 0 :(得分:1)
您正在使用通知和数据,但在showNotification
中您正在执行此操作:
bigTextStyle.setBigContentTitle(notification.getTitle());
bigTextStyle.bigText(notification.getBody())
在上面,您会收到通知有效负载并将其添加到BigContentTitle
和BigText
,而数据有效负载未添加,因此在后台(因为通知有效负载仅在前台触发) ),您收到默认通知。
您需要接收数据有效负载,因为如果应用程序位于后台和前台,它将被触发。
所以你可以这样做:
bigTextStyle.setBigContentTitle(notification.getData().get("title")); //title name in the data payload
bigTextStyle.bigText(notification.getData().get("body")); //body name in the data payload
还需要相应更改setSummaryText(..)
,setContentTitle(..)
和setContentText(..)
之类的其他内容。