#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"
заставляет его запускаться в другом процессе. Удалив его, все начало работать отлично.