Уведомления не поступают на устройство, но при успешном запуске FCM, в чем проблема

#android #push-notification #intentservice

#Android #push-уведомление #intentservice

Вопрос:

Когда я пытаюсь получить уведомление на устройстве, когда я открываю приложение, я получаю уведомление, и после закрытия я также получаю уведомление, но оно будет работать примерно 40-60 секунд, после чего оно выдаст эту ошибку —

 W/ActivityManager: Background start not allowed: service Intent 
{ act=com.google.firebase.MESSAGING_EVENT pkg=packagename cmp=packageName/.Services.MyFirebaseMessagingService (has extras) } to packageName/.Services.MyFirebaseMessagingService from pid=1990 uid=10541 pkg=packageName
2019-03-20 17:25:15.158 1990-1990/packageName E/FirebaseInstanceId: Error while delivering the message: ServiceIntent not found.`
  

Я получаю уведомление на переднем плане, но когда я на какое-то время отключу приложение, я получу примерно через 40-60 секунд, через некоторое время я не буду получать уведомления

Примечание: Это не проблема с Android v8 или Orio , я пытаюсь с Android v7 или v9 , так что это проблема со всеми устройствами

я перепробовал все возможные решения, но у меня ничего не получалось. Поэтому я буду рад, если кто-нибудь сможет мне с этим помочь

Вот мой класс firbaseMessaging:

 public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "FirebaseService";

    UserSessionManager session;
    private NotificationUtils notificationUtils;


    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.e(TAG, "NBody: "   remoteMessage.getFrom()  ", " remoteMessage.getData()  ", "  remoteMessage.getNotification());
        if (remoteMessage == null) {
            Log.e("TAGGG","Nothing to recieve");
            return;
        }
        /* Check if message contains a notification payload. */
        if (remoteMessage.getNotification() != null) {
            Log.e(TAG, "Notification Body: "   remoteMessage);
            handleNotification(remoteMessage.getNotification().getBody());
        }
        /* Check if message contains a data payload.*/
        if (remoteMessage.getData().size() > 0) {
            Log.e(TAG, "Data Payload: "   remoteMessage.getData().toString());
            try {
                JSONObject json = new JSONObject(remoteMessage.getData().toString());

                handleDataMessage(json);
            } catch (Exception e) {
                Log.e(TAG, "Exception: "   e.getMessage());
            }
        }
    }

    private void handleNotification(String message) {
        if (NotificationUtils.isAppIsInBackground(getApplicationContext())) {
            /* app is in foreground, broadcast the push message */
            Intent pushNotification = new  Intent(Config.PUSH_NOTIFICATION);
            pushNotification.putExtra("message", message);
            LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);

            /* play notification sound */
            NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
            notificationUtils.playNotificationSound();
        } else {
            Log.d("INBACKGROUND","Not is background");
        }
    }


    private void handleDataMessage(JSONObject json) {
        try {
            JSONObject data = json.getJSONObject("data");
            String title = data.getString("title");
            String message = data.getString("message");
            String action = data.getString("action");
            String destination = data.getString("action_destination");
            Preference.storeLoadStatus("UnDone");
            Preference.storeNotificationType(action);

            if (NotificationUtils.isAppIsInBackground(getApplicationContext())) {
                /* app is in foreground, broadcast the push message */
                Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION);
                pushNotification.putExtra("message", message);

                pushNotification.putExtra("action", action);
                pushNotification.putExtra("destination", destination);
                LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);

                /* play notification sound */
                NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
                notificationUtils.playNotificationSound();
            } else {
               /* app is in background, show the notification in notification tray*/
                session = new UserSessionManager(getApplicationContext());
                Intent resultIntent;
                if (!session.checkLogin()) {
                    resultIntent = new Intent(getApplicationContext(), NewHomeActivity.class);
                } else {
                    resultIntent = new Intent(getApplicationContext(), Main2Activity.class);
                }
                resultIntent.putExtra("message", message);
                resultIntent.putExtra("action", action);
                resultIntent.putExtra("destination", destination);
                Timestamp timestamp = new Timestamp(System.currentTimeMillis());
                String ts = timestamp.toString();
                showNotificationMessage(getApplicationContext(), title, message, ts, resultIntent);
                // check for image attachment
            }
        } catch (Exception e) {
            Log.e(TAG, "Exception: "   e.getMessage());
        }
    }

    /**
     * Showing notification with text only
     */
    private void showNotificationMessage(Context context, String title, String message, String timeStamp, Intent intent) {
        notificationUtils = new NotificationUtils(context);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction("android.intent.action.MAIN");
        intent.addCategory("android.intent.category.LAUNCHER");
        notificationUtils.showNotificationMessage(title, message, timeStamp, intent); ;
    }

    /**
     * Showing notification with text and image
     */
    private void showNotificationMessageWithBigImage(Context context, String title, String message, String timeStamp, Intent intent, String imageUrl) {
        notificationUtils = new NotificationUtils(context);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        notificationUtils.showNotificationMessage(title, message, timeStamp, intent, imageUrl);
    }
}
  

Вот утилиты уведомлений

 public class NotificationUtils {
    private static final int NOTIFICATION_ID = 1;
    private static String TAG = NotificationUtils.class.getSimpleName();
    private Context mContext;
    public NotificationUtils(Context mContext) {
        this.mContext = mContext;
    }

    /**
     * Method checks if the app is in background or not
     */
    public static boolean isAppIsInBackground(Context context) {
        boolean isInBackground = true;
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
            List<ActivityManager.RunningAppProcessInfo> runningProcesses = null;
            if (am != null) {
                runningProcesses = am.getRunningAppProcesses();
            }
            if (runningProcesses != null) {
                for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
                    if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                        for (String activeProcess : processInfo.pkgList) {
                            if (activeProcess.equals(context.getPackageName())) {
                                isInBackground = false;
                            }
                        }
                    }
                }
            }
        } else {
            List<ActivityManager.RunningTaskInfo> taskInfo = null;
            if (am != null) {
                taskInfo = am.getRunningTasks(1);
            }
            ComponentName componentInfo = null;
            if (taskInfo != null) {
                componentInfo = taskInfo.get(0).topActivity;
            }
            if (componentInfo != null amp;amp; componentInfo.getPackageName().equals(context.getPackageName())) {
                isInBackground = false;
            }
        }

        return !isInBackground;
    }

    // Clears notification tray messages
    public static void clearNotifications(Context context) {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancelAll();
    }

    public static long getTimeMilliSec(String timeStamp) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        try {
            Date date = format.parse(timeStamp);
            return date.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return 0;
    }

    public void showNotificationMessage(String title, String message, String timeStamp, Intent intent) {
        showNotificationMessage(title, message, timeStamp, intent, null);
    }

    public void showNotificationMessage(final String title, final String message, final String timeStamp, Intent intent, String imageUrl) {
        Log.d("ShowNotification1", "Message");
        // Check for empty push message
        if (TextUtils.isEmpty(message))
            return;

        // notification icon
        final int icon = R.mipmap.ic_launcher;

        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        final PendingIntent resultPendingIntent =
                PendingIntent.getActivity(
                        mContext,
                        0,
                        intent,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );

        final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
                mContext);
        final Uri alarmSound = Uri.parse(PreferenceManager.getDefaultSharedPreferences(mContext).
                getString("pref_tone", "content://settings/system/notification_sound"));

        if (!TextUtils.isEmpty(imageUrl)) {

            if (imageUrl != null amp;amp; imageUrl.length() > 4 amp;amp; Patterns.WEB_URL.matcher(imageUrl).matches()) {

                Bitmap bitmap = getBitmapFromURL(imageUrl);

                if (bitmap != null) {
                    showBigNotification(bitmap, mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
                } else {
                    showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
                }
            }
        } else {
            showSmallNotification(mBuilder, icon, title, message, timeStamp, resultPendingIntent, alarmSound);
            playNotificationSound();
        }
    }

    private void showSmallNotification(NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {

        Notification notification;
        //notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
        notification = new NotificationCompat.Builder(mContext)
                .setAutoCancel(true)
                .setContentTitle(title)
                .setContentIntent(resultPendingIntent)
                .setSound(alarmSound)
                // .setStyle(inboxStyle)
                .setStyle(new NotificationCompat.BigTextStyle()
                        .bigText(message))
                .setWhen(getTimeMilliSec(timeStamp))
                .setSmallIcon(R.drawable.mtruck_new_logo)
                .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.mtruck_new_logo))
                .setContentText(message)
                .build();

        // startForeground(NOTIFICATION_ID, notification);

        NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(Config.NOTIFICATION_ID, notification);
    }

    private void showBigNotification(Bitmap bitmap, NotificationCompat.Builder mBuilder, int icon, String title, String message, String timeStamp, PendingIntent resultPendingIntent, Uri alarmSound) {
        NotificationCompat.BigPictureStyle bigPictureStyle = new NotificationCompat.BigPictureStyle();
        bigPictureStyle.setBigContentTitle(title);
        bigPictureStyle.setSummaryText(Html.fromHtml(message).toString());
        bigPictureStyle.bigPicture(bitmap);
        Notification notification;
        notification = mBuilder.setSmallIcon(icon).setTicker(title).setWhen(0)
                .setAutoCancel(true)
                .setContentTitle(title)
                .setContentIntent(resultPendingIntent)
                .setSound(alarmSound)
                .setStyle(bigPictureStyle)
                .setWhen(getTimeMilliSec(timeStamp))
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), icon))
                .setContentText(message)
                .build();

        NotificationManager notificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(Config.NOTIFICATION_ID_BIG_IMAGE, notification);
    }

    /**
     * Downloading push notification image before displaying it in
     * the notification tray
     */
    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;
        }
    }

    // Playing notification sound
    public void playNotificationSound() {
        try {
            Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            Ringtone r = RingtoneManager.getRingtone(mContext, notification);
            r.play();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  

Вот класс MyFirebaseInstance

 public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
    private static final String TAG = MyFirebaseInstanceIDService.class.getSimpleName();

    @Override
    public void onTokenRefresh() {
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        // Saving reg id to shared preferences
        storeRegIdInPref(refreshedToken);

        sendRegistrationToServer(refreshedToken);
        // Notify UI that registration has completed, so the progress indicator can be hidden.
        Intent registrationComplete = new Intent(Config.REGISTRATION_COMPLETE);
        registrationComplete.putExtra("token", refreshedToken);
        LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);

    }


    private void sendRegistrationToServer(String refreshToken) {
        // sending gcm token to server
        Log.d("TOKEN: ", refreshToken);
    }

    private void storeRegIdInPref(String token) {
        SharedPreferences pref = getApplicationContext().getSharedPreferences(Config.SHARED_PREF, 0);
        SharedPreferences.Editor editor = pref.edit();
        editor.putString("regId", token);
        editor.commit();
    }
}
  

Вот разрешение манифеста и библиотека firebase:

 <service android:name=".Services.MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
        <action android:name="com.google.android.c2dm.intent.RECEIVE" />
    </intent-filter>
</service>

<!--<service android:name=".Services.BackgroundServices" />-->
<service android:name=".Services.MyFirebaseInstanceIDService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
    </intent-filter>
</service>
  

Библиотеки Firbase

 implementation 'com.google.firebase:firebase-messaging:17.4.0'
implementation 'com.google.firebase:firebase-core:16.0.8'
  

Спасибо

Комментарии:

1. можете ли вы упомянуть класс FirebaseMessageService?

2. @Abhinav Gupta Я добавил классы, которые я использую

3. Вы проверили какие-либо требуемые разрешения, службы и meta -ы в соответствии с документами Firebase? Похоже, это вызвано тем, что он находится в фоновом режиме.

4. Я добавил манифест и fcm @ Meow Cat 2012

Ответ №1:

Сделайте это :

 if (remoteMessage.getData().size() > 0) {
    Log.e(TAG, "Data Payload: "   remoteMessage.getData().get("body"));
    try {
        JSONObject json = new JSONObject(remoteMessage.getData().get("body"));
        handleDataMessage(json);
    } catch (Exception e) {
        Log.e(TAG, "Exception: "   e.getMessage());
    }
}
  

вместо :

 if (remoteMessage.getData().size() > 0) {
    Log.e(TAG, "Data Payload: "   remoteMessage.getData().toString());
    try {
        JSONObject json = new JSONObject(remoteMessage.getData().toString()); // this can be null that's why you are not receiving notification 
        handleDataMessage(json);
    } catch (Exception e) {
        Log.e(TAG, "Exception: "   e.getMessage());
    }
}
  

в mainfest файле сделайте это :

 <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
  

тогда

 <service android:name=".service.MyFirebaseMessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT" />
        </intent-filter>
    </service>
    <service android:name=".service.MyFirebaseInstanceIDService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
    </intent-filter>
</service>
  

В gradle :

 implementation 'com.google.firebase:firebase-messaging:17.4.0'
implementation 'com.google.firebase:firebase-core:16.0.7'
  

Комментарии:

1. Я попробовал это, и это тоже не работает, это не проблема, поскольку он даже не вызывает onMessage, это проблема с ActivityManager: фоновый запуск не разрешен: намерение службы

2. @Govind пожалуйста, проверьте и обновите ответ в данных удаленного сообщения, сделайте то, что я упомянул, потому что я также получаю эту ошибку.

3. Попробовал ваше решение, но не работает, та же проблема @Abhinav Gupta

4. Есть ли кто-нибудь, кто может мне помочь с этим?

5. Кто-нибудь, кто может помочь? Пожалуйста