Intent .putExtra возвращает null с PendingIntent

Это приложение позволяет мне запустить службу, которая напомнит мне о питье. Если я нажимаю на уведомление, я хочу увидеть, запущена служба или нет, но я не получаю никаких результатов с помощью метода Intent.putExtra.

Мой класс MainActivity:

Boolean isServiceRunning = false;
AlarmManager alarmManager;
PendingIntent pendingIntent;
TextView mainText;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mainText = findViewById(R.id.mainTextView);

    Bundle extras = getIntent().getExtras();
    if (extras == null) {
            mainText.setText("Service is paused");
    } else {
        mainText.setText("Service is running");
    }

}

public void sendNotification(View view) {

    if (!isServiceRunning) {
        isServiceRunning = true;
        Toast.makeText(this, "Reminder service started.", Toast.LENGTH_SHORT).show();
        alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

        mainText.setText("Service is running.");
        Intent i = new Intent(this, reciever.class);
        i.putExtra("isServiceRunning", isServiceRunning.booleanValue());

        pendingIntent = PendingIntent.getBroadcast(this, 100, i, PendingIntent.FLAG_UPDATE_CURRENT);

        Calendar calendar = Calendar.getInstance();
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 10, pendingIntent);
    } else {
        isServiceRunning = false;
        Toast.makeText(this, "Reminder service ended.", Toast.LENGTH_SHORT).show();
        mainText.setText("Service paused.");
        alarmManager.cancel(pendingIntent);
    }
}

Я думаю, что эту проблему можно решить с помощью общих предпочтений, но это не должно быть хорошим решением.

Обновлено:

Мой класс радиоприемника:

public class reciever BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    Intent notificationIntent = new Intent(context, drinkReminder.class);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    stackBuilder.addParentStack(drinkReminder.class);
    stackBuilder.addNextIntent(notificationIntent);

    PendingIntent pendingIntent = stackBuilder.getPendingIntent(100, PendingIntent.FLAG_UPDATE_CURRENT);


    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
    Notification notification = new NotificationCompat.Builder(context, CHANNEL_1_ID)
            .setContentTitle("Title")
            .setContentText("description")
            .setSmallIcon(R.drawable.icon_waterdrop)
            .setTimeoutAfter(30000)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .build();

    notificationManager.notify(0, notification);

}

}

Непонятно, что вы пытаетесь сделать. В любом случае вы устанавливаете будильник с помощью AlarmManager и передаете ему широковещательный Intent для запуска MainActivity. Это не работает. Широковещательный Intent будет виден только BroadcastReceiver, и при срабатывании тревоги он не запустит ни один Activity. Также вы говорите о Service, но здесь нет кода, который имел бы дело с каким-либо Service. Вы также упоминаете Notification, но здесь также нет кода, который мог бы справиться с ними. Пожалуйста, объясните подробнее, что вы пытаетесь сделать.

David Wasser 10.12.2018 23:38

Извините, у меня уже есть класс широковещательного приемника, он также работает нормально (остановка и возобновление программы), но если широковещательный приемник отправляет мне уведомление, и если я нажимаю на него, он должен проверить, запущена ли служба или нет. В этом-то и дело. Я только что добавил класс радиоприемника.

Oliver Weidner 11.12.2018 11:13

Вы добавляете "дополнительный" к Intent, который вы передаете AlarmManager. Этот «лишний» будет в Intent, который будет доставлен на ваш BroadcastReceiver в onReceive(), но вы там ничего с ним не делаете.

David Wasser 11.12.2018 21:48

Когда вы нажимаете на Notification, он запускает drinkReminder, который, я надеюсь, является Activity.

David Wasser 11.12.2018 21:50

Спасибо, Дэвид, я просто добавил дополнительную информацию к намерению в BroadcastReciever, и это решило проблему!

Oliver Weidner 11.12.2018 22:28

Подскажите, пожалуйста, еще кое-что. Иногда, если я нажимаю кнопку, чтобы запустить службу, уведомление появляется примерно через 10 секунд, после этого оно показывает все 10 минут, как должно. Как я могу это исправить?

Oliver Weidner 11.12.2018 22:52

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

David Wasser 13.12.2018 10:09
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
7
286
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вместо кода в onCreate () и putExtra () вы можете создать два ожидающих намерения в каждом случае, и каждое намерение использует другой широковещательный приемник. В этом широковещательном приемнике вы можете распечатать отдельные всплывающие сообщения.

MyBroadcastRecieverStart.java

 public class MyBroadcastReceiverStart extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

Toast.makeText(this, "Reminder service started.", Toast.LENGTH_SHORT).show();

}
}

MyBroadcastReceiverStop.java

public class MyBroadcastReceiverStop extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

Toast.makeText(this, "Reminder service ended.", Toast.LENGTH_SHORT).show();

}
}

SendNotification метод -

public void sendNotification(View view) {

if (!isServiceRunning) {
    isServiceRunning = true;

    alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    mainText.setText("Service is running.");
    Intent i = new Intent(this, MyBroadcastReceiverStart.class);


    pendingIntent = PendingIntent.getBroadcast(this, 100, i, PendingIntent.FLAG_UPDATE_CURRENT);

    Calendar calendar = Calendar.getInstance();
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 10, pendingIntent);
} else {
    isServiceRunning = false;

    mainText.setText("Service paused.");
    Intent i = new Intent(this, MyBroadcastReceiverStop.class);


    pendingIntent = PendingIntent.getBroadcast(this, 100, i, PendingIntent.FLAG_UPDATE_CURRENT);

    Calendar calendar = Calendar.getInstance();
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 10, pendingIntent);
    alarmManager.cancel(pendingIntent);
}
}

Если вы пишете alarmManager.cancel (pendingIntent) в блоке else, он отменяет намерение, которое не существует, поскольку вы создали намерение в блоке if, и оно не создается, если выполняется else, поэтому я создал намерение в else блок также.

Спасибо за ответ, но запуск и приостановка службы работали нормально, потому что я объявил PendingIntent перед методом onCreate (). Раньше у меня тоже был радиоприемник, я только что отредактировал свой вопрос.

Oliver Weidner 11.12.2018 11:16
Ответ принят как подходящий

Вы добавляете "дополнительный" к Intent, который вы передаете AlarmManager. Этот «лишний» будет в намерении, которое будет доставлено на ваш BroadcastReceiver в onReceive(), но вы там ничего с ним не делаете.

Когда вы нажимаете на Notification, он запускает drinkReminder, который, я надеюсь, является Activity.


Вы также сказали в комментарии:

Could you tell me please one more thing. Sometimes if i press the button to start the service, a notification appers after about 10 seconds, after this it shows all 10 minutes like it should. How can i fix this?

Вот ваш код для установки будильника:

Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 
    calendar.getTimeInMillis(), 1000 * 60 * 10, pendingIntent);

Когда вы вызываете setRepeating(), 2-й параметр указывает, когда в первый раз должен сработать сигнал тревоги, а 3-й параметр определяет интервал повтора. Вы сказали диспетчеру сигналов тревоги, что хотите, чтобы первый сигнал тревоги срабатывал немедленно, а затем каждые 10 минут после этого.

Если вы хотите, чтобы первый сигнал тревоги срабатывал через 10 минут после нажатия кнопки, вам необходимо настроить второй параметр так, чтобы он представлял время на 10 минут в будущем, например:

Calendar calendar = Calendar.getInstance();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 
    calendar.getTimeInMillis() + (1000 * 60 * 10), 1000 * 60 * 10, pendingIntent);

Это происходит, если вы копируете и вставляете код и не думаете об этом. Спасибо!

Oliver Weidner 14.12.2018 16:45

Другие вопросы по теме