2015-05-10 41 views
7

我正在開發一個應每60秒執行一次特定任務的應用程序。由於Android 4.4+中的報警存在一些準確性問題,在所有報警都不準確的情況下,我選擇了鏈接模式:A BroadcastReceiver觸發第一個報警,每個報警依次設置下一個報警。Android設置()和setExact()報警以不正確的時間間隔觸發

問題是,即使我以60秒(60000毫秒)的間隔設置警報,警報以5秒爲間隔觸發,有時甚至更少。我測試了我的Nexus 5(Android 5.1.1)和Android 5.0.1模擬器上的代碼,兩者都給出了相同的結果。 我應該指出兩個接收器都在AndroidManifest上註冊,我的應用程序具有RECEIVE_BOOT_COMPLETED權限。

編輯:setExact()導致完全相同的問題

StartupReceiver.java(廣播接收器用於BOOT_COMPLETED):

public class StartupReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     Log.d(TAG, "Got the BOOT_COMPLETED signal"); 
     // Get the first alarm to be invoked immediately 
     AlarmReceiver.setNextScanAlarm(context, 0); 
    } 
} 

AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     // Start the service 
     Intent startServiceIntent = new Intent(context, BackgroundService.class); 
     startServiceIntent.putExtra("interval", 60000); 
     startServiceIntent.putExtra("action", "scan"); 
     context.startService(startServiceIntent); 

     // Schedule the next alarm 
     setNextScanAlarm(context, 60000); 
    } 

    public static void setNextScanAlarm(Context context, int interval) { 
     Intent scanIntent = new Intent(context, AlarmReceiver.class); 
     scanIntent.putExtra("interval", interval); 
     scanIntent.putExtra("action", "scan"); 
     PendingIntent pendingIntent = PendingIntent.getBroadcast(
       context, 
       0, 
       scanIntent, 
       PendingIntent.FLAG_ONE_SHOT); 


     AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
     alarmManager.set(
       AlarmManager.ELAPSED_REALTIME_WAKEUP, 
       interval, 
       pendingIntent); 
    } 
} 

有什麼事情是問題嗎?

+0

只是一個簡單的問題,你實際上是在做什麼與警報或只是試圖在後臺或主界面每60秒運行一些代碼? – napkinsterror

回答

0

我相信,因爲這是調用

alarmManager.set(
       AlarmManager.ELAPSED_REALTIME_WAKEUP, 
       interval, 
       pendingIntent); 

您呼叫interval變量當鬧鐘是要經過,直到下一個報警的時間,但是當你想這樣做時,它知道開始?更何況,時間何時實際上等於零?

當你創建它?號碼
當您撥打.set()?第

它實際上在啓動時爲零。所以你要求它在啓動60秒後啓動,並且每次都要求這個,這個時間已經過去了。

這是混淆的地方,你應該使用像new Handler.postDelayed(Runnnable r, 60000)這樣的電話而不是鬧鐘管理器。它會更加準確,並且不會在理解Android操作系統及其鬧鐘/時鐘/ etc /等等時遇到一些問題。

但是對於您的具體情況,我相信您可以通過訪問System函數調用/變量來解決它。所以,你的功能setNextScanAlarm()裏面我相信它應該是這樣的:

public static void setNextScanAlarm(Context context, int interval) { 
     //create the intent the same way as before 
     Intent scanIntent = new Intent(context, AlarmReceiver.class); 
     scanIntent.putExtra("interval", interval); 
     scanIntent.putExtra("action", "scan"); 
     PendingIntent pendingIntent = PendingIntent.getBroadcast(
       context, 
       0, 
       scanIntent, 
       PendingIntent.FLAG_ONE_SHOT); 

     //create new variables to calculate the correct time for this to go off 
     long timeRightNow = System.elapsedRealTime() //use something else if you change AlarmManager type 
     long timeWhenIShouldGoOff = timeRightNow + interval; 

     //use the new timeWhenIShouldGoOff variable instead of interval 
     AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
     alarmManager.set(
       AlarmManager.ELAPSED_REALTIME_WAKEUP, 
       timeWhenIShouldGoOff, 
       pendingIntent); 
    } 
0

my answer到類似的問題。 我使用postDelayed()而不是AlarmManager爲短時間間隔(少於1分鐘)和AlarmManager長。

相關問題