Как направить уведомление о битве только тогда, когда CheckBoxPreference отмечен?

Я использую уведомления Firebase, чтобы уведомлять пользователей о новых данных, отправленных в приложение. Я следую приведенному здесь примеру: https://github.com/firebase/quickstart-android/tree/master/messaging

Хотя, я также предоставляю предпочтение пользователю. Они должны получать уведомления только тогда, когда они решили получить уведомление, проверив CheckBoxPreference.

Я установил CheckBoxPreference, а также onPreferenceChangeListener. Проблема в том, что пользователь получает уведомление, даже если флажок CheckBox не установлен.

Вот что я сделал в SettingsActivity:

public class SettingsActivity extends PreferenceActivity {

    private AppCompatDelegate mDelegate;

    Preference myPref;

    boolean isChecked = true;

    private static final String TAG = "SettingsActivity";

    public static final String RECEIVE_NOTIFS = "receiveNotifications";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        getDelegate().installViewFactory();
        getDelegate().onCreate(savedInstanceState);
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        myPref = (CheckBoxPreference) findPreference(RECEIVE_NOTIFS);
        myPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object o) {
                isChecked = Boolean.valueOf(o.toString());
                if (isChecked) {
                    Toast.makeText(getBaseContext(), "Checked", Toast.LENGTH_SHORT).show();
                    if (getIntent().getExtras() != null) {
                        String remoteMessage = getIntent().getExtras().getString("remoteMessage");
                        sendNotification(remoteMessage);
                    } else {
                        Toast.makeText(getBaseContext(), "Error!", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(getBaseContext(), "Unchecked", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        });

    }

    public void sendNotification(String messageBody) {
        Intent intent = new Intent(this, SettingsActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("FCM Message")
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

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

Здесь MyFirebaseMessagingService.java код файла:

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    // [START receive_message]
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // TODO(developer): Handle FCM messages here.
        // If the application is in the foreground handle both data and notification messages here.
        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated. See sendNotification method below.
        Log.d(TAG, "From: " + remoteMessage.getFrom());
        Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());

        Intent intent = new Intent(this, SettingsActivity.class);
        intent.putExtra("remoteMessage", remoteMessage.getNotification().getBody());
        startActivity(intent);
    }
    // [END receive_message]

}

Что я делаю здесь, я отправляю remoteMessage в качестве намерения в SettingsActivity и используя его в sendNotification() там.

Итак, ясно, что я хочу, я хочу, чтобы пользователь получал уведомления только тогда, когда они решили, проверив CheckBoxPreference.

Пожалуйста, позвольте мне, что я делаю неправильно здесь.

Ответ 1

При использовании уведомлений Firebase отправленное сообщение является уведомлением. Когда приложение находится на переднем плане, ваш код будет обрабатывать уведомление. Но когда приложение будет заложено, центр уведомлений по умолчанию обработает его. И поскольку центр уведомлений ничего не знает о вашем флажке, он всегда будет отображать уведомление.

См. этот ответ на вопрос о реестре quickstart для лучшего объяснения, которое я видел до сих пор: https://github.com/firebase/quickstart-android/issues/8#issuecomment-221039175

У вас есть несколько вариантов, чтобы заставить вашу логику работать:

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

  • отправить сообщение данных вместо уведомления. Это гарантирует, что ваш код всегда будет вызываться, даже если приложение задумано. См. Документацию по Уведомления и данные в полезной нагрузке сообщения, чтобы узнать больше о различиях между уведомлениями и сообщениями данных.

Похожие вопросы: