2016-03-27 12 views
0

私は1,510分ごとに位置更新を送信する必要があるアプリケーションを作成しようとしています。アラームマネージャーが時間通りに起動しない

アプリが実行されている場合、それは正確に動作しますが、それは背景/スリープモードに移行するときそれが正確に動作しません。

私は両方の方法を試みましたsetRepeating/setInExactRepeatingしかし、どれもバックグラウンドモードでは動作しません。

public static void startSensorAlaram(Context ctx, long minutes) { 

    AlarmManager alarmManager = (AlarmManager) ctx 
      .getSystemService(Context.ALARM_SERVICE); 

    // Alarm_Receiver is a broadcast receiver. 

    Intent intent = new Intent(ctx, Alaram_Receiver.class); 

    intent.setAction(Utility.SENSOR_ACTION); 

    PendingIntent pi = PendingIntent.getBroadcast(ctx, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),minutes,pi); 

// alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), minutes, pi); 

} 

public static void stopAlaramSensor(Context ctx) { 

    Intent intent = new Intent(ctx, Alaram_Receiver.class); 
    PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 1, 
      intent, 0); 
    AlarmManager alarmManager = (AlarmManager) ctx 
      .getSystemService(Context.ALARM_SERVICE); 
    alarmManager.cancel(pendingIntent); 

} 

Alarm Receiver - Broadcast receiver

public class Alaram_Receiver extends WakefulBroadcastReceiver { 

private SharedPreferences sp; 

@Override 
public void onReceive(Context context, Intent intent) { 
    // TODO Auto-generated method stub 

    sp = context.getSharedPreferences(Utility.SHARED_PREFS, 0); 

    if (intent.getAction().equalsIgnoreCase(Utility.SENSOR_ACTION)) { 

     if (sp.getBoolean("logged_in", false)) { 

     // context.startService(new Intent(context,SensorService.class)); 

     startWakefulService(context,new Intent(context,SensorService.class)); 

     } else 
      Utility.stopAlaramSensor(context); 
    } 
    } 
} 

Note:-分のAPIのバージョンは15で、バージョンをコンパイルする2つの問題があります。23

+0

どのバージョンテストデバイス上で実行されているここで入手できますか? – nuuneoi

+0

これはアンドロイド5.1と6.0です@nuuneoi – moDev

+1

['AlarmManager'](http://developer.android.com/reference/android/app/AlarmManager.html)のドキュメントを参照してください。 KitKatの 'targetSdkVersion'> = 19の場合、' setRepeating() 'は不正確です。あなたは 'setExact()'を使う必要があり、起動するたびに必要な間隔でアラームを再設定する必要があります。 –

答えて

2

です。 AndroidのAPI> = 19のよう

1)、あなたの代わりにset()またはsetRepeating()の新しいAlarmManager.setExact()メソッドを使用する必要があります。ここに公式文書からの引用があります。 API 19(キットカット)警報の配信を皮切り

は不正確です:OSは ウェイクアップし、バッテリーの使用を最小限にするために、アラームをシフトします。厳密な配信が必要なアプリケーションをサポートするための新しいAPIは です。 保証があります。 setWindow(int、long、long、PendingIntent)および setExact(int、long、PendingIntent)を参照してください。

2)Android 6.0以降では、Dozeと呼ばれるディープスリープモードが導入されています。

これは、デバイスがスタンバイ状態のときのバッテリ消費を抑えるように設計されています。非常に多くの制限があり、そのモードでできることは非常に限られています。新しいAlarmManager.setExactAndAllowWhileIdle()を使用して、希望の時間にDozeモードでAlarmを起動させる必要があります。 Dozeモードについて

詳しい情報は、AndroidのOptimizing for Doze and App Standby

+0

Dozeモードでhandler.postDelayed()を使用できますか? @ nuuneoi – moDev

+0

いいえ。それはいけません。ほとんどのプロセスは、ハンドラのようなスレッドジョブを含むスリープモードに強制されます。 – nuuneoi

+0

私は、アラームマネージャを使用してデバイスの場所を取得し、私たちのサーバーに常に送信したいと思います。今は夢中では可能ではないのですか?アラームマネージャの精度が機能しているように見えます。あなたがここで助けることができるものですか? – moDev

関連する問題