0

在我的android應用程序中,我有一個「全局」應用程序類,其中包含一個靜態BlockingQueue,用於存儲信息。當隊列滿時,我將其刷新到文件。我有多個生產者,服務,BroadcastReceivers和一切工作正常。現在我必須添加一個警報,每30分鐘觸發一個PendingIntent,我必須從中寫入此BlockingQueue,這不起作用!我看到調用了適當的函數,但數據沒有寫入。如果我Log.d()它之前blockingQueue.put()我可以看到數據,然後它會丟失。我在我的應用程序中從任何地方執行相同的過程,並且它只在警報的PendingIntent的BroadcastReceiver中不起作用。當然,我錯過了一些東西。我能做什麼?從AlarmManager觸發的PendingIntent中修改靜態BlockingQueue

下面是如何觸發從服務報警(和它的作品):

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

這是廣播接收器:

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

}

因爲我希望我的鬧鐘在棉花糖打盹模式下工作我必須使用setExactAndAllowWhileIdle(),並在每次觸發廣播時調用該方法。

+0

據我所知,你不能在這些接收器中做長時間的操作。調用阻塞方法將被視爲一個長操作。 – Joakim

回答

0

問題在於PendingIntent。在清單我宣佈它是這樣的:

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

android:process=":remote"強制它在不同的進程中運行。通過刪除它,一切都開始完美。