Изменение статической очереди блокировки из PendingIntent, запускаемой AlarmManager

#android #alarmmanager #android-pendingintent #blockingqueue

#Android #alarmmanager #android-pendingintent #blockingqueue

Вопрос:

В моем приложении для Android у меня есть «глобальный» класс приложения, а внутри него, среди прочего, у меня есть статический BlockingQueue, в котором я храню информацию. Когда очередь заполнена, я сбрасываю ее в файл. У меня есть несколько производителей, служб, приемников вещания, и все работает нормально. Теперь мне нужно добавить сигнал тревоги, который каждые 30 минут запускает PendingIntent, из которого я должен записать в этот BlockingQueue, и это не работает! Я вижу, что вызываются соответствующие функции, но данные не записываются. Если я зарегистрирую.d() это перед BlockingQueue.put() Я вижу данные, а затем они теряются. Я выполняю ту же процедуру отовсюду в своем приложении, и она не работает только с BroadcastReceiver PendingIntent тревоги. Конечно, я что-то упускаю. Что я могу сделать?

Вот как я вызываю тревогу из службы (и это работает):

 alarmNotificationIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, QuestionnaireNotificationReceiver.class), 0);
            if(alarmNotificationIntent!=null) {
                if (alarmManager != null) {
                    if (iLogApplication.isAtLeastMarshmallow()) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()   Constants.NOTIFICATION_INTERVAL, alarmNotificationIntent);
                    } else {
                        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()   Constants.NOTIFICATION_INTERVAL, alarmNotificationIntent);
                    }
                }
            }
  

И это BroadcastReceiver:

 public class QuestionnaireNotificationReceiver extends BroadcastReceiver {

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

    Log.d(context.toString(), "Questionnaire notification");

    //this method does blockingQueue.put(answer.toString());
    iLogApplication.persistInMemoryAnswerQuestionnaireEvent(new Answer(new Question(666)));

    System.out.println(iLogApplication.questionnaire.toString());

    SharedPreferences sharedPreferences = context.getSharedPreferences(Constants.PACKAGE_NAME, Context.MODE_PRIVATE);

    Intent notificationIntent = new Intent(context, NotificationActivity.class);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    PendingIntent pendingIntent = PendingIntent.getActivity(context, (int) System.currentTimeMillis(), notificationIntent, 0);
    iLogApplication.questionnaireBuilder.setContentTitle("Nuova domanda disponibile")
            .setContentIntent(pendingIntent)
            .setSmallIcon(R.drawable.ic_notification_bar)
            .setAutoCancel(false)
            .setOngoing(true);

    String notificationText = "Hai %d domand%c a cui rispondere";

    if (iLogApplication.questionnaireBuilder != null) {
        iLogApplication.questionnaireBuilder.setWhen(System.currentTimeMillis());
        if(iLogApplication.questionnaire.getNumberOfQuestions()>2) {
            iLogApplication.questionnaireBuilder.setContentText(String.format(notificationText, iLogApplication.questionnaire.getNumberOfQuestions(), 'e'));
        }
        else {
            iLogApplication.questionnaireBuilder.setContentText(String.format(notificationText, iLogApplication.questionnaire.getNumberOfQuestions(), 'a'));
        }
    }
    if (iLogApplication.notificationManager != null) {
        iLogApplication.notificationManager.notify(Constants.QUESTIONNAIRENOTIFICATIONID, iLogApplication.questionnaireBuilder.build());
    }

    PendingIntent alarmNotificationIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, QuestionnaireNotificationReceiver.class), 0);
    if(alarmNotificationIntent!=null) {
        if(iLogApplication.alarmManager!=null) {
            if (iLogApplication.isAtLeastMarshmallow()) {
                iLogApplication.alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()  Constants.NOTIFICATION_INTERVAL, alarmNotificationIntent);
            } else {
                iLogApplication.alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()  Constants.NOTIFICATION_INTERVAL, alarmNotificationIntent);
            }
        }
    }
}
  

}

Поскольку я хочу, чтобы мой будильник работал также в режиме ожидания Marshmallow, я должен использовать setExactAndAllowWhileIdle() и вызывать этот метод каждый раз, когда запускается трансляция.

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

1. Насколько я знаю, вам не разрешено выполнять длительные операции в этих приемниках. Вызов метода блокировки будет считаться длительной операцией.

Ответ №1:

Проблема заключалась в PendingIntent . В манифесте я объявил это так:

 <receiver android:process=":remote" android:name=".broadcastreceivers.QuestionnaireNotificationRunnable"></receiver>
  

флаг android:process=":remote" заставляет его запускаться в другом процессе. Удалив его, все начало работать отлично.