2016-10-26 16 views
0

デバイスがスリープモード(十分に文書化されている問題)にある間にアラームを起動すると、この問題が発生し、Androidのアラームマネージャの問題(APIのバッチアラーム)

私のアプリでは、アラームマネージャーを使用して、前のアラームが発生したときに次のアラームの時刻を設定します。ほとんどの場合、アプリはうまく動作しますが、私のASUS TF300t(API 17)のスリープモードでは、アラームは嫌です。

コードアラームを登録する:

  Intent i = new Intent(mContext, OnAlarmReceiver.class); 
     i.putExtra(RReminder.PERIOD_TYPE, type); 
     i.putExtra(RReminder.EXTEND_COUNT, extendCount); 
     i.setAction(RReminder.CUSTOM_INTENT_ALARM_PERIOD_END); 
     pi = PendingIntent.getBroadcast(mContext, (int)when, i, PendingIntent.FLAG_ONE_SHOT); 

     if(buildNumber >= Build.VERSION_CODES.LOLLIPOP){ 
      AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(when, pi); 
      mAlarmManager.setAlarmClock(alarmClockInfo,pi); 
     } else if(buildNumber >= Build.VERSION_CODES.KITKAT){ 
      mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, when, pi); 
     } else { 
      mAlarmManager.set(AlarmManager.RTC_WAKEUP, when, pi); 
     } 

そして、私のWakefulBroadcastReceiverクラス:アラームがないときに、私は見てい

public class OnAlarmReceiver extends WakefulBroadcastReceiver { 
@Override 
public void onReceive(Context context, Intent intent){ 
    int type = intent.getExtras().getInt(RReminder.PERIOD_TYPE); 
    int extendCount = intent.getExtras().getInt(RReminder.EXTEND_COUNT); 
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); 
    Log.d("period type",""+type); 
    Log.d("time",sdf.format(Calendar.getInstance().getTime())); 
    Intent i = new Intent(context, PeriodService.class); 
    i.putExtra(RReminder.PERIOD_TYPE, type); 
    i.putExtra(RReminder.EXTEND_COUNT, extendCount); 
    startWakefulService(context,i); 

} 

}

まず最初は、アラーム、バッチ処理でありますそれが想定されていたときに起動されたが、次のアラームが2番目のアラームと同時に発生したときに起動する。

その他のことは、スリープモードでアラームが時間通りに起動しない場合は、電源ボタンでデバイスを起動した直後に消えます。

私は、API 19と23(ドーズモード)のアラーム動作の変更について認識しています。私は、setExact()を使ってエミュレートされた仮想デバイスで観察された新しいAPIの不正確な問題を解決しました。

私は2つの物理的なアンドロイドデバイス、このTF300tタブレットとギャラクシーS3電話を持っています。 S3では、この問題はごくまれにしか発生しませんが、TF300tの問題の一貫性によって、基本的に私のアプリケーションは役に立たなくなります。

私の質問は、すべてのAPI(多くのソリューション全体を探す必要があります)、またはデバイスやAPIに固有のもので、例外として扱うことができる多くのデバイスに存在しますか?

答えて

0

使用PowerMangerは、この問題を解決するために:

サービスで定義します。サービス・クラスで今すぐ

PowerManager powerManager; 
PowerManager.WakeLock wakeLock; 

、OnCreateイベントMetodでは、これを追加します。

powerManager = (PowerManager) getSystemService(POWER_SERVICE); 
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "NAME"); 

startCommnd方法では、前にこれを追加あなたの仕事を始める:

wakeLock.acquire(); 

あなたのサービスクラスでこれを追加します。

@Override 
    public void onDestroy() { 
     wakeLock.release(); 
     this.isRun=false; 
    } 

最後に、マニフェストファイルに追加します。

<uses-permission android:name="android.permission.WAKE_LOCK"/> 
+0

WakefulBroadcastReceiverが実装ウェイクロックのaquisitionを持っています。 [WakefulBroadcastReceiver](https://developer.android.com/reference/android/support/v4/content/WakefulBroadcastReceiver.html) – aphelion

+0

これはBroadcastReceiver向けです。そのブロードキャストからサービスを開始するので、サービスは正常にタスクを実行するためにウェイクログを必要とします。 –

+0

のリンクからのコメント: "デバイスのウェイクアップイベントを受信したBroadcastReceiverを実装し、そのデバイスをサービスに渡し、移行中にデバイスがスリープ状態に戻らないようにする一般的なパターンのヘルパー。 このクラスは、部分的なウェイクロックの作成と管理を行います。あなたはそれを使用するためにWAKE_LOCKの許可を要求しなければなりません。 – aphelion