2013-01-24 40 views
0

我正在開發一個android應用程序,該應用程序每12小時顯示一次通知,如果時間保存在數據庫中。因此,每次在數據庫中輸入或編輯數據時,我都會取消當前的警報管理器並重新啓動一個新的警報管理器,以便我不會錯過任何警報管理器。同樣在重啓時,我已經調用了警報管理器。在廣播接收機上,檢查數據庫的條目,如果發現設置了通知並且應用程序自動打開。AlarmManager如果應用程序睡眠1天,則不會調用第二天

因此,當我通過手動更改日期來測試應用程序時,該應用程序按預期工作。此外,在重新啓動應用程序時仍然有效。但如果我將應用程序閒置近14個小時,則通知未設置,但如果我打開應用程序並暫停它,然後設置通知。

這就是我所說的警報管理器。 Intent alarmintent = new Intent(context,package.Alarm_Manager.class);

alarmintent.putExtra("note","Notify"); 
    sender = PendingIntent.getBroadcast(context , 0 , alarmintent , PendingIntent.FLAG_CANCEL_CURRENT | Intent.FILL_IN_DATA);    
    alarm_manger = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 
    alarm_manger.cancel(sender); 
    Calendar cal = Calendar.getInstance(); 
    long now = cal.getTimeInMillis(); 
    alarmintent = new Intent(context, package.Alarm_Manager.class); 
    alarmintent.putExtra("note","Notification"); 
    sender = PendingIntent.getBroadcast(context , 0 , alarmintent , PendingIntent.FLAG_CANCEL_CURRENT | Intent.FILL_IN_DATA);    
    alarm_manger = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
    alarm_manger.setRepeating(AlarmManager.RTC_WAKEUP, now, AlarmManager.INTERVAL_HALF_DAY, sender); 

這是廣播接收器

@Override 
public void onReceive(Context context, Intent intent) 
{ 
     NotificationManager manger = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); 
     Calendar cal = Calendar.getInstance(); 
     date = (int)(cal.getTimeInMillis()/1000); 
     Notification notification = new Notification(R.drawable.vlcsnap_396460 , "Notify" , System.currentTimeMillis()); 
     PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, 0); 
     notification.setLatestEventInfo(context, "App", "Notify" , contentIntent); 
     notification.flags = Notification.FLAG_INSISTENT; 
     manger.notify(0 , notification); 
    } 
+0

你能激勵爲什麼你有兩個不同的意圖,其中一個你aapear只用於取消?另外,你是否確定你需要取消明確,儘管FLAG_CANCEL_CURRENT? - 是的,AlarmManager是一項系統服務,並且將始終運行。 - 你確定要使用'now'作爲triggarAtMillis參數嗎? –

+0

每12小時報警一次。因此可能會在上午6點發送1次通知。第二個在今天下午6點。第三個在明天早上6點。第一個鬧鐘可能需要在明天早上6點取消。所以我必須取消所有鬧鐘,並且每次都重新開始。 – viks

+0

我曾嘗試過使用該標誌,但沒有發揮預期的作用。這就是爲什麼我使用另一個鬧鐘取消已設置的鬧鐘。 – viks

回答

0

你並不需要調用alarm_manager.cancel(sender);如果你設置了PendingIntent.FLAG_CANCEL_CURRENT.

您的來電

alarm_manger.setRepeating(AlarmManager.RTC_WAKEUP, now, AlarmManager.INTERVAL_HALF_DAY, sender); 

會觸發報警馬上,因爲現在已經通過設置鬧鐘。

我建議你使用

now + DateUtils.HOUR_IN_MILLIS/2 

爲triggerAtMillis參數

你有沒有嘗試過以安排較小的區間?它會被觸發嗎?

+0

絕對正確(請參閱我的OP評論),但不能解決這個問題,對吧? ;) –

+0

這實際上是一個示例代碼,在我的應用程序的許多類中使用。有時我必須立即開始報警。有時我必須在特定時間後發送通知。 – viks

0

看到您的Alarm_Manager代碼後,我認爲直接在您的BroadcastReceiver對象中執行此操作是非法的。 Quote

如果此BroadcastReceiver是通過標籤啓動的,則此對象在從此函數返回後不再有效。

我相信沒有其他辦法,而不是創建一個由你的廣播接收器通知服務,並確保服務調用setLatestEventInfo()與本身(this)作爲背景。

當您的應用程序運行時,異步廣播失敗的原因可能是您的應用程序無法運行時,向BroadcastReceiver提供的上下文可能只會在調用BroadcastReceiver期間生效。因此,只有在BroadcastReceiver與臨時上下文一起死亡後才運行的Notification服務缺少有效的上下文。

當您的應用程序運行時,廣播可能隨您的活動或應用程序對象一起作爲上下文運行,並且在通知管理器運行時這仍然是vaild。

希望這會有所幫助。

更新:一個`IntentService`會做。你不需要全職的服務。

更新2:一些片段。

<service android:name=".MyIntentService" android:label="@string/my_intent_service_name" /> 

public final class MyIntentService extends IntentService { 
    public MyIntentService() { 
    super("service name"); 
    // set any properties you need 
    } 
    @Override 
    public void onCreate() { 
     super.onCreate(); 
     // do init, e.g. get reference to notification service 
    } 
    @Override 
    protected void onHandleIntent(Intent intent) { 
    // handle the intent 
     // ...especially: 
     notification.setLatestEventInfo(this, "App", "Notify" , contentIntent); 
     // ... 
    } 
} 

public final class MyAlarmReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     context.startService(new Intent(context, MyIntentService.class)); 
    } 
} 
+0

您可以根據您的建議張貼示例或重新編碼我的代碼嗎? – viks

+0

@viks添加了一些片段。 –