web-dev-qa-db-ja.com

Android 5.1で毎秒アラームをスケジュールする


アプリケーションで毎秒アラームサービスを実行したい。5.1バージョン以下では正常に動作しています。ただし、5.1デバイスではトリガーされません。 commonsware wakeful intentサービスを使用しています。logcatメッセージは、「疑わしいほど短い間隔1000ミリ秒、60秒に拡張 "」と言っています。 5.1で毎秒ポーリングするにはどうすればよいですか?誰かがこれを達成する方法を私に提案できますか?

もう少し説明:

私のユースケースは、30分間隔ごとに何らかの操作を行う必要があるというものです。 AFAIKこのためにアラームマネージャーを使用することは効率的な方法ですが、ここに

1)カウントダウンタイマーをユーザーに表示する必要があります。 (タイマータスク、カウントダウンタイマー、ScheduledExecutorServiceはこれに非常に役立ちます)
2)アプリがバックグラウンドであっても、30分ごとに(通知を介して)ユーザーに通知する必要があります(これにはアラームサービスで十分です)

しかし、ここでの私の問題は、アプリがバックグラウンドにあるとき、最近からアプリケーションをスワイプしたとき(つまり、アプリケーションプロセスが強制終了されたとき)、サービスまたはタイマー、ハンドラー、エグゼキューターサービスのいずれも機能しないことです)。この場合、30分が経過した後にユーザーに通知するにはどうすればよいですか。私が間違った考えをしているなら、私を導いてください。

ありがとう、
チャイタンヤ

13
Chaitu

これは、Android Lollipopの正常な動作です。

疑わしいほど短い間隔1000ミリ; 60秒に拡張

システムがこれらの短い時間間隔をもう気に入らないことを通知します。

問題 #161244 次のように文書化されています:

これは意図したとおりに機能していますが、現時点では十分に文書化されていません(そして、問題のその側面を認識しています)。

非常に一般的に言えば、短期および近未来のアラームは、バッテリーのコストが驚くほど高くなります。短期または近い将来の作業が必要なアプリは、他のメカニズムを使用してアクティビティをスケジュールする必要があります。

したがって、これにはAlarmServiceを使用しないでください。スレッドまたはExecutorsまたはTimerTaskまたは他のものを優先します:

// Using Handler
new Handler().postDelayed(runnable, TimeUnit.SECONDS.toMillis(1));

// Using Executors
Executors.newSingleThreadScheduledExecutor().schedule(runnable, 1, TimeUnit.SECONDS);
8
shkschneider

どうしてそうするか?
代わりにハンドラーを使用してください:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        // do your stuff here, called every second
        mHandler.postDelayed(this, 1000);
    }
};

// start it with:
mHandler.post(runnable);

そして、以下を使用して1秒のタイマーを停止します。

mHandler.removeCallbacks(runnable);
5
Lazy Ninja

1 および 2の両方を使用します:

  • 1分を超える間隔(要求された30分など)でユーザーに警告する役割には、AlarmManagerを使用します。

  • If通知により、更新がフォアグラウンドにあることを示す必要があるアクティビティがトリガーされます。thenpostDelayed()などの安価な処理も実行して、ユーザーに提供します。その活動の定期的な更新

1
CommonsWare

これらの手順を試してください。

  1. 1分後に定期的にAlarmmaagerを使用する
  2. そのアラームマネージャー内で、数秒後に呼び出してタスクを実行するハンドラーを使用します。

覚えておいてください

アラームマネージャはデバイスの現在の状況を認識していないため、たとえば、デバイスが電源プラグに接続されているか、アイドル状態であるか、ネットワークに接続されているかを考慮しません。また、アラームマネージャはリソースを浪費します。デバイスに利用可能なリソースがいつあるかは気にしないためです。

0
Fasiha

私はあなたのユースケースを正確に理解していませんが、毎秒アラームを設定するのはやり過ぎです。 タイマー を使用できます。このクラスを見てください。

0
Riyaz Ahamed

これは報告された issue for Android 5.1で、60000ミリ秒未満の間隔でアラームを設定しようとすると発生します。

この警告は、このように非常に低い間隔を設定すると、バッテリーの消耗が非常に速くなるために発生します。

プラットフォームのプロジェクトメンバーは次のように述べています。

非常に一般的に言えば、短期および近未来のアラームは、バッテリーのコストが驚くほど高くなります。短期または近い将来の作業が必要なアプリは、他のメカニズムを使用してアクティビティをスケジュールする必要があります。

そのため、この場合はAlarmを使用することはお勧めしません。

質問の更新によると。ユーザーが最近のアプリリストから手動でスワイプした場合でも、バックグラウンドサービスを起動したままにしておきたい。これは、次のようなSTART_STICKYフラグを使用して簡単に実行できます。このコードをonStartCommandメソッドでサービスに追加します。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
} 

出典: 回答

0
Sami Eltamawy