无法在后台和被杀死状态下触发推送通知

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 发送通知和数据负载的类型。