0

In my android application I have a "global" application class and inside it, among others, I have a static BlockingQueue in which I store information. When the queue is full I flush it to file. I have multiple producers, Services, BroadcastReceivers and everything works fine. Now I have to add an alarm that every 30 minutes triggers a PendingIntent from which I have to write to this BlockingQueue and this doesn't work! I see that the appropriate functions are called but the data is not written. If I Log.d() it before blockingQueue.put() I can see the data and then it get lost. I do the same procedure from everywhere in my app and it only does not work from the BroadcastReceiver of the PendingIntent of the Alarm. For sure I'm missing something. What can I do?

Here's how I trigger the Alarm from a Service (and it works):

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);
                    }
                }
            }

And this is the 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);
            }
        }
    }
}

}

Since I want my alarm to work also in Marshmallow Doze mode I have to use setExactAndAllowWhileIdle() and recall the method every time the Broadcast is triggered.

phcaze
  • 1,707
  • 5
  • 27
  • 58
  • As far as I know, you are not allowed to do long operations in these receivers. Calling a blocking method would count as a long operation. – Joakim Oct 18 '16 at 14:32

1 Answers1

0

The problem was the PendingIntent. In the manifest I declared it like this:

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

the flag android:process=":remote" forces it to run on a different process. By removing it everything started working perfectly.

phcaze
  • 1,707
  • 5
  • 27
  • 58