2017-11-24 12 views
1

アンドロイドでネイティブコード用のタイマーを実装しようとしています。タイマーは、スリープモードとスリープモードで正確に動作するはずです。タイマーが満了すると、ネイティブコードはDPD(Dead peer detection)ネットワークへのメッセージ 次のアプローチを試みました。Androidのスリープ状態でタイマーが正確に期限切れにならない

ユーザ空間のコードでアラームマネージャのためのAndroidのフレームワークAPIのを使用し、以下の結果である
    • これは2S、3S、5Sのような小さなタイマーのためにも覚醒状態の間に正確な結果を与えるものではありません。
    • スリープモードでも正確に動作しません。
  1. 我々はカーネル空間コードでカーネルタイマーを使用しようと下記の結果である:

      覚醒状態のために完璧に動作
    • スリープ状態のタイマーはまったく期限切れではありません。デバイスを手動でスリープ状態にすると、タイマーの有効期限が切れます。したがって、スリープ状態ではカーネルタイマーは機能しません。

3.Using我々はそれが大幅なパフォーマンスの原因となりウェイクロックの使用を避けるようにしようとしている*ウェイクロック は

PS発行 - でも、オープンソースIPsec実装のstrongSwanのは、DPDメッセージを送信し、正確な時間をしかし、強盗は覚醒ロックを使用していないと思われるので、スリープモード中にどのように動作するか把握しようとしています。この質問に対する回答を探している人は誰でも、そのコードを調べることができます。

誰でもこの問題を解決するために何か提案できますか?

+0

に見える部分ウェイクロックを獲得するために以下のコードを使用します。私が考えている他の方法はありません。 –

+0

Androidのスリープ状態はどういう意味ですか? –

+0

@ Vlad Matvienkoはい、これが最後の選択ですが、電力使用量への影響は認識していません。 – somil

答えて

-1

タイマーを開始し、アプリケーションがバックグラウンドになったら、alarmManagerを起動します。また、アプリケーションがフォアグラウンドになり、タイマーが期限切れになっていない場合は、タイマーがトリガーされ、アラームマネージャーが削除されます。

private int timeToStart; 
private TimerState timerState; 

private static final int MAX_TIME = 60; //Time length is 60 seconds 

private enum TimerState { 
    STOPPED, 
    RUNNING 

} 


private void initTimer() { 
    Log.e(TAG,"initTimer called"); 

    long startTime = mPrefs.getStartedTime(); //here mprefs is your shared preference manager 
    if (startTime > 0) { 
     timeToStart = (int) (MAX_TIME - (getNow() - startTime)); 
     if (timeToStart <= 0) { 
      // TIMER EXPIRED 
      onTimerFinish(); 
     } else { 
      startTimer(); 
      timerState = TimerState.RUNNING; 
     } 
    } else { 
     timeToStart = MAX_TIME; 
     timerState = TimerState.STOPPED; 
    } 
} 

    private long getNow() { 
    Calendar rightNow = Calendar.getInstance(); 
    return rightNow.getTimeInMillis()/1000; 
} 

    private void onTimerFinish() { 
    Log.e(TAG,"onTimerFinish() called"); 

    timerState = TimerState.STOPPED; 
    mPrefs.setStartedTime(0); 
    timeToStart = MAX_TIME; 

} 

private void startTimer() { 
    Log.e(TAG,"startTimer() called"); 

    countDownTimer = new CountDownTimer(timeToStart * 1000, 1000) { 

     @Override 
     public void onTick(long millisUntilFinished) { 
      timeToStart -= 1; 
     } 

     @Override 
     public void onFinish() { 
      onTimerFinish(); 
     } 
    }.start(); 
} 

    public void setAlarmManager() { 
    int wakeUpTime = (mPrefs.getStartedTime() + MAX_TIME) * 1000; 
    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
    Intent intent = new Intent(this, TimeReceiver.class); 
    PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
     am.setAlarmClock(new AlarmManager.AlarmClockInfo(wakeUpTime, sender), sender); 
    } else { 
     am.set(AlarmManager.RTC_WAKEUP, wakeUpTime, sender); 
    } 
} 

    public void removeAlarmManager() { 
    Intent intent = new Intent(this, TimeReceiver.class); 
    PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); 
    AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
    am.cancel(sender); 
} 

    @Override 
    protected void onResume() { 
    super.onResume(); 
     initTimer(); 
     removeAlarmManager(); 

} 
0

Androidがスリープ状態になると、いくつかの状態が発生し、最後のプロセスはすべてのプロセスをフリーズし、CPUをオフにします。 その場合、あなたの時間は始まらないでしょう。カーネルを起動し、CPUが再びオフにならないようにウェイクロックを設定するイベントを作成する必要があります。これはアンドロイドのアラームを使用して行うことができます。

0

タイマーをスリープモードで正確に動作させるには、Wakelockを使用してデバイスを部分的に起動させておくことが唯一の方法です。文書には、

と書かれているため、アプリケーションに実際にタイマーが必要なことを確認してください。の使用によってデバイスのバッテリ寿命が大きく影響を受けます。あなたが本当に必要な場合を除いて、PowerManager.WakeLockを取得しないでください。できるだけ早くリリースしてください。あなたがwakelockを使用して、部分的に目を覚まし、デバイスを維持する必要がありますようにPowerManagerクラスを介して

Goが、

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 
    PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag"); 
    wl.acquire(); 
    ..cpu will stay on during this section.. 
    wl.release(); 
関連する問題