无法在后台和被杀死状态下触发推送通知
Unable to trigger Push Notification in background and killed state
我正在开发一个基于设备到设备推送通知的应用程序。当应用程序处于前台时,我的通知工作正常。但是当应用程序处于后台或终止状态时,它不能按要求工作。 onMessageReceived()
在这种情况下不会被调用。我有一个自定义通知,它有两个按钮(接受和拒绝)。当应用程序处于后台或处于终止状态时,我能够收到通知,但不会出现操作按钮。但是当应用程序处于前台时,它可以完美运行。你们能帮我这个吗?我被困在这个很长一段时间了。
注意:我正在使用 FCM
生成推送通知。有效载荷在 index.js 文件中。有效负载包含 'data' 和 'notification',因为需要在 Android 和 iOS 中生成通知。我在某处读到,从有效负载中删除 'notification' 将使它在前台、后台和终止状态下都能完美运行,它也是如此,但这不符合我的要求,因为我需要 'data' 和 'notifications'.
请帮帮我!!
public class FirebaseNotifications extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> remoteMessageData = remoteMessage.getData();
String remoteMessageType = remoteMessageData.get(REMOTE_TYPE);
/*E-Intercom Notification requires Users Action*/
if (remoteMessageType.equals(getString(R.string.e_intercom))) {
String message = remoteMessageData.get(REMOTE_MESSAGE);
String profilePhoto = remoteMessageData.get(REMOTE_PROFILE_PHOTO);
String notificationUID = remoteMessageData.get(REMOTE_NOTIFICATION_UID);
String userUID = remoteMessageData.get(REMOTE_USER_UID);
String visitorType = remoteMessageData.get(REMOTE_VISITOR_TYPE);
String visitorMobileNumber = remoteMessageData.get(REMOTE_VISITOR_MOBILE_NUMBER);
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_custom_notification);
remoteViews.setTextViewText(R.id.textNotificationMessage, message);
/*We don't want to show Profile image if cabs and packages enter into society*/
if (visitorType.equals(FIREBASE_CHILD_CABS) || visitorType.equals(FIREBASE_CHILD_PACKAGES)) {
remoteViews.setViewVisibility(R.id.eIntercomProfilePic, View.GONE);
} else {
remoteViews.setImageViewBitmap(R.id.eIntercomProfilePic, getBitmapFromURL(profilePhoto));
}
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
String channelId;
/*To support Android Oreo Devices and higher*/
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
getString(R.string.default_notification_channel_id), getString(R.string.namma_apartments_channel), NotificationManager.IMPORTANCE_HIGH);
Objects.requireNonNull(notificationManager).createNotificationChannel(mChannel);
channelId = mChannel.getId();
IntentFilter actionIntents = new IntentFilter();
actionIntents.addAction(ACCEPT_BUTTON_CLICKED);
actionIntents.addAction(REJECT_BUTTON_CLICKED);
getApplicationContext().registerReceiver(new ActionButtonListener(), actionIntents);
} else {
channelId = getString(R.string.default_notification_channel_id);
}
Notification notification = new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.namma_apartment_notification)
.setContentTitle(NOTIFICATION_EXPAND_TITLE)
.setContentText(NOTIFICATION_EXPAND_MSG)
.setAutoCancel(true)
.setCustomBigContentView(remoteViews)
.setSound(RingtoneManager.getDefaultUri(Notification.DEFAULT_SOUND))
.setPriority(PRIORITY_DEFAULT)
.build();
int mNotificationID = (int) System.currentTimeMillis();
Intent acceptButtonIntent = new Intent(ACCEPT_BUTTON_CLICKED);
acceptButtonIntent.putExtra(NOTIFICATION_ID, mNotificationID);
acceptButtonIntent.putExtra(NOTIFICATION_UID, notificationUID);
acceptButtonIntent.putExtra(USER_UID, userUID);
acceptButtonIntent.putExtra(MESSAGE, message);
acceptButtonIntent.putExtra(VISITOR_TYPE, visitorType);
acceptButtonIntent.putExtra(VISITOR_PROFILE_PHOTO, profilePhoto);
acceptButtonIntent.putExtra(VISITOR_MOBILE_NUMBER, visitorMobileNumber);
PendingIntent acceptPendingIntent = PendingIntent.getBroadcast(this, 123, acceptButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.buttonAccept, acceptPendingIntent);
Intent rejectButtonIntent = new Intent(REJECT_BUTTON_CLICKED);
rejectButtonIntent.putExtra(NOTIFICATION_ID, mNotificationID);
rejectButtonIntent.putExtra(NOTIFICATION_UID, notificationUID);
rejectButtonIntent.putExtra(USER_UID, userUID);
rejectButtonIntent.putExtra(VISITOR_TYPE, visitorType);
PendingIntent rejectPendingIntent = PendingIntent.getBroadcast(this, 123, rejectButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.buttonReject, rejectPendingIntent);
Objects.requireNonNull(notificationManager).notify(mNotificationID, notification);
} else {
/*General Notification - These do not require any user actions*/
String message = remoteMessageData.get(REMOTE_MESSAGE);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
int mNotificationID = (int) System.currentTimeMillis();
/*To support Android Oreo Devices and higher*/
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
getString(R.string.default_notification_channel_id), getString(R.string.namma_apartments_channel), NotificationManager.IMPORTANCE_HIGH);
Objects.requireNonNull(notificationManager).createNotificationChannel(mChannel);
}
/*After the Admin adds a notice and user receives notification, making sure user is navigated
* to 'Notice Board' screen on press of notification in notification panel*/
if (remoteMessageType.equals(getString(R.string.notice_board_notification))) {
Intent noticeBoardIntent = new Intent(this, NoticeBoard.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, Constants.NEW_NOTICE_CODE,
noticeBoardIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification noticeBoardNotification = new NotificationCompat.Builder(this, getString(R.string.default_notification_channel_id))
.setSmallIcon(R.drawable.namma_apartment_notification)
.setAutoCancel(true)
.setContentTitle(getString(R.string.app_name))
.setContentText(message)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setPriority(PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.build();
Objects.requireNonNull(notificationManager).notify(mNotificationID, noticeBoardNotification);
} else {
Notification notificationDefault = new NotificationCompat.Builder(this, getString(R.string.default_notification_channel_id))
.setSmallIcon(R.drawable.namma_apartment_notification)
.setAutoCancel(true)
.setContentTitle(getString(R.string.app_name))
.setContentText(message)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setPriority(PRIORITY_DEFAULT)
.build();
Objects.requireNonNull(notificationManager).notify(mNotificationID, notificationDefault);
}
}
}
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 getCircleBitmap(myBitmap);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private Bitmap getCircleBitmap(Bitmap bitmap) {
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final int color = Color.RED;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
bitmap.recycle();
return output;
}
}
为此,您可以试试这个技巧。当您将 FCM 令牌存储在数据库中时,在用于存储设备类型的数据库中添加一个位或变量(device_type),如果 FCM 令牌来自 IOS,则在 device_type 并且如果它来自 android 对 android 设备执行相同的操作,那么在发送通知时您可以检查 FCM 令牌是否为 android 类型,仅发送数据有效负载以及是否它是 IOS 发送通知和数据负载的类型。
我正在开发一个基于设备到设备推送通知的应用程序。当应用程序处于前台时,我的通知工作正常。但是当应用程序处于后台或终止状态时,它不能按要求工作。 onMessageReceived()
在这种情况下不会被调用。我有一个自定义通知,它有两个按钮(接受和拒绝)。当应用程序处于后台或处于终止状态时,我能够收到通知,但不会出现操作按钮。但是当应用程序处于前台时,它可以完美运行。你们能帮我这个吗?我被困在这个很长一段时间了。
注意:我正在使用 FCM
生成推送通知。有效载荷在 index.js 文件中。有效负载包含 'data' 和 'notification',因为需要在 Android 和 iOS 中生成通知。我在某处读到,从有效负载中删除 'notification' 将使它在前台、后台和终止状态下都能完美运行,它也是如此,但这不符合我的要求,因为我需要 'data' 和 'notifications'.
请帮帮我!!
public class FirebaseNotifications extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> remoteMessageData = remoteMessage.getData();
String remoteMessageType = remoteMessageData.get(REMOTE_TYPE);
/*E-Intercom Notification requires Users Action*/
if (remoteMessageType.equals(getString(R.string.e_intercom))) {
String message = remoteMessageData.get(REMOTE_MESSAGE);
String profilePhoto = remoteMessageData.get(REMOTE_PROFILE_PHOTO);
String notificationUID = remoteMessageData.get(REMOTE_NOTIFICATION_UID);
String userUID = remoteMessageData.get(REMOTE_USER_UID);
String visitorType = remoteMessageData.get(REMOTE_VISITOR_TYPE);
String visitorMobileNumber = remoteMessageData.get(REMOTE_VISITOR_MOBILE_NUMBER);
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_custom_notification);
remoteViews.setTextViewText(R.id.textNotificationMessage, message);
/*We don't want to show Profile image if cabs and packages enter into society*/
if (visitorType.equals(FIREBASE_CHILD_CABS) || visitorType.equals(FIREBASE_CHILD_PACKAGES)) {
remoteViews.setViewVisibility(R.id.eIntercomProfilePic, View.GONE);
} else {
remoteViews.setImageViewBitmap(R.id.eIntercomProfilePic, getBitmapFromURL(profilePhoto));
}
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
String channelId;
/*To support Android Oreo Devices and higher*/
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
getString(R.string.default_notification_channel_id), getString(R.string.namma_apartments_channel), NotificationManager.IMPORTANCE_HIGH);
Objects.requireNonNull(notificationManager).createNotificationChannel(mChannel);
channelId = mChannel.getId();
IntentFilter actionIntents = new IntentFilter();
actionIntents.addAction(ACCEPT_BUTTON_CLICKED);
actionIntents.addAction(REJECT_BUTTON_CLICKED);
getApplicationContext().registerReceiver(new ActionButtonListener(), actionIntents);
} else {
channelId = getString(R.string.default_notification_channel_id);
}
Notification notification = new NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.namma_apartment_notification)
.setContentTitle(NOTIFICATION_EXPAND_TITLE)
.setContentText(NOTIFICATION_EXPAND_MSG)
.setAutoCancel(true)
.setCustomBigContentView(remoteViews)
.setSound(RingtoneManager.getDefaultUri(Notification.DEFAULT_SOUND))
.setPriority(PRIORITY_DEFAULT)
.build();
int mNotificationID = (int) System.currentTimeMillis();
Intent acceptButtonIntent = new Intent(ACCEPT_BUTTON_CLICKED);
acceptButtonIntent.putExtra(NOTIFICATION_ID, mNotificationID);
acceptButtonIntent.putExtra(NOTIFICATION_UID, notificationUID);
acceptButtonIntent.putExtra(USER_UID, userUID);
acceptButtonIntent.putExtra(MESSAGE, message);
acceptButtonIntent.putExtra(VISITOR_TYPE, visitorType);
acceptButtonIntent.putExtra(VISITOR_PROFILE_PHOTO, profilePhoto);
acceptButtonIntent.putExtra(VISITOR_MOBILE_NUMBER, visitorMobileNumber);
PendingIntent acceptPendingIntent = PendingIntent.getBroadcast(this, 123, acceptButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.buttonAccept, acceptPendingIntent);
Intent rejectButtonIntent = new Intent(REJECT_BUTTON_CLICKED);
rejectButtonIntent.putExtra(NOTIFICATION_ID, mNotificationID);
rejectButtonIntent.putExtra(NOTIFICATION_UID, notificationUID);
rejectButtonIntent.putExtra(USER_UID, userUID);
rejectButtonIntent.putExtra(VISITOR_TYPE, visitorType);
PendingIntent rejectPendingIntent = PendingIntent.getBroadcast(this, 123, rejectButtonIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.buttonReject, rejectPendingIntent);
Objects.requireNonNull(notificationManager).notify(mNotificationID, notification);
} else {
/*General Notification - These do not require any user actions*/
String message = remoteMessageData.get(REMOTE_MESSAGE);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
int mNotificationID = (int) System.currentTimeMillis();
/*To support Android Oreo Devices and higher*/
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(
getString(R.string.default_notification_channel_id), getString(R.string.namma_apartments_channel), NotificationManager.IMPORTANCE_HIGH);
Objects.requireNonNull(notificationManager).createNotificationChannel(mChannel);
}
/*After the Admin adds a notice and user receives notification, making sure user is navigated
* to 'Notice Board' screen on press of notification in notification panel*/
if (remoteMessageType.equals(getString(R.string.notice_board_notification))) {
Intent noticeBoardIntent = new Intent(this, NoticeBoard.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, Constants.NEW_NOTICE_CODE,
noticeBoardIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification noticeBoardNotification = new NotificationCompat.Builder(this, getString(R.string.default_notification_channel_id))
.setSmallIcon(R.drawable.namma_apartment_notification)
.setAutoCancel(true)
.setContentTitle(getString(R.string.app_name))
.setContentText(message)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setPriority(PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
.build();
Objects.requireNonNull(notificationManager).notify(mNotificationID, noticeBoardNotification);
} else {
Notification notificationDefault = new NotificationCompat.Builder(this, getString(R.string.default_notification_channel_id))
.setSmallIcon(R.drawable.namma_apartment_notification)
.setAutoCancel(true)
.setContentTitle(getString(R.string.app_name))
.setContentText(message)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setPriority(PRIORITY_DEFAULT)
.build();
Objects.requireNonNull(notificationManager).notify(mNotificationID, notificationDefault);
}
}
}
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 getCircleBitmap(myBitmap);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private Bitmap getCircleBitmap(Bitmap bitmap) {
final Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final int color = Color.RED;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawOval(rectF, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
bitmap.recycle();
return output;
}
}
为此,您可以试试这个技巧。当您将 FCM 令牌存储在数据库中时,在用于存储设备类型的数据库中添加一个位或变量(device_type),如果 FCM 令牌来自 IOS,则在 device_type 并且如果它来自 android 对 android 设备执行相同的操作,那么在发送通知时您可以检查 FCM 令牌是否为 android 类型,仅发送数据有效负载以及是否它是 IOS 发送通知和数据负载的类型。