2015-09-10 46 views
34

私はGoogle Playで2つの目覚まし時計アプリを開発しています。私は彼らにAndroid 6.0で作業させようとしています。しかし、ドーズモードでは、リングしないようにします。私はそれらをホワイトリストに載せ、フォアグラウンドの通知アイコンを上にして、何ができるか分かりません。Dozeモードでは、Alarm Managerのアラームは無視されます。ただし、時計アプリ(AOSPアプリではなくGoogle Play)は異なります。時計アプリでアラームが有効になっている場合、「adb deviceidle step」は常に「アクティブ」と表示され、「アイドル」、「idle_pending」などは表示されません。Android 6.0がDozeモードのときにAlarm Managerを動作させるにはどうすればいいですか?

Androidはここで不正行為をしていますが、自分のアプリにもっと力を与えています。 "リンゴを引っ張る"? Google Playのすべての目覚まし時計アプリが機能しなくなる予定ですか?ここで心配しているのは、パートタイムの開発時間を1年要した高品質のアプリで、私の大きな収入源です。どのように私はこれらを動作させることができるかについての手がかりは、大きな助けになるだろう。

 Intent intent = new Intent(context, ReceiverAlarm.class); 
     if (android.os.Build.VERSION.SDK_INT >= 16) { 
      intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 
     } 
     amSender = PendingIntent.getBroadcast(context, 1, intent, PendingIntent.FLAG_CANCEL_CURRENT); //FLAG_CANCEL_CURRENT seems to be required to prevent a bug where the intent doesn't fire after app reinstall in KitKat 
     am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
     am.set(AlarmManager.RTC_WAKEUP, scheduleToTime+1, amSender); 

とReceiverAlarmクラス:

public class ReceiverAlarm extends BroadcastReceiver{ 

@Override 
public void onReceive(Context context, Intent intent) { 
    if (wakeLock == null) { 
     PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 
     wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Theme.appTitle); 
     wakeLock.acquire(); 
    } 
    X.alarmMaster.startRingingAlarm(true); 
} 

とX.alarmMaster.startRingingAlarmの関連部分()メソッド:

if (wakeLock == null) { 
     PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 
     wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Theme.appTitle); 
     wakeLock.acquire(); 
    } 

    if (screenWakeLock == null) { 
     PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 
     screenWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, Theme.appTitle+" scr"); 
     screenWakeLock.acquire(); 
    } 

    Intent alarmIntent = new Intent(Intent.ACTION_VIEW); 
    alarmIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    alarmIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
    alarmIntent.setClass(context, ActivityAlarmAlarm.class); 

    context.startActivity(alarmIntent); 

AlarmManager意図を設定

いくつかのメソッドは、読みやすくするためにインラインで貼り付けられています。

+0

他の人が何が起こっているか見るのを助けることができるいくつかのスニペットを持っています。してください:-) – Nabin

+1

確かに、私は私の応答を編集します。それらは両方とも20k +コード行ですので、私はそれらの1つの関連する行を投稿しようとします。 – user1908060

答えて

30

DozeとApp Standbyは、アラームとウォークロックに関する動作を間違いなく変更しますが、間違いなくあなたのために世界の終わりではありません!

set()の代わりにsetAlarmclock()を使用してみましたか? これは目覚まし時計用に特別に設計されており、ドーズをカットすることができます。 https://developer.android.com/preview/features/power-mgmt.html

あなたのアプリを起きさせることができない場合は、確実な方法setExactAndAllowWhileIdle()が携帯電話をスリープ状態から復帰させるように設計されています。何があってもドーズ。最悪のシナリオでは、この方法でアプリケーションを起動させ、ウェイクアップを使用して次のアラームをスケジュールすることができます。

読む価値は別のページには、バックグラウンドの仕事とアラーム用のフローチャートで、このブログの記事です:https://plus.google.com/+AndroidDevelopers/posts/GdNrQciPwqo

+4

これは、setAlarmClock()を使用して動作しているようです。 "adb shell deviceidle step"を使用してアプリケーションをドーズモードに設定しようとすると、すぐにアラームが鳴り、ACTIVEモードになります。 – user1908060

+2

これは役に立ちます!しかし、 'セット[実寸] AndAllowWhileIdle()'メソッドは動作しないことをこのレポートhttps://code.google.com/p/android-developer-preview/issues/detail?id=2225を参照してください。 :-(https://plus.google.com/+AndroidDevelopers/posts/94jCkmG4jffイアン湖は、あなたが開発者向けプレビューに比べて期待通りはるかドーズ中の 'AndAllowWhileIdle()'メソッド火災、内部に構築することを報告して – Jerry101

+0

開発者向けプレビュー3と 'setExactAndAllowWhileIdle両方()'と 'setAndAllowWhileIdle()'メソッド、ネットワーク接続の約10秒の持続時間の間アイドル状態時とアラーム_will_トリガーを使用して私のテスト3. – Jerry101

1

は、ホワイトリストにアプリケーションを入れのみ居眠りモードでネットワークすることができます。 AlarmManagerはホワイトリストの影響を受けません。

setExactAndAllowWhileIdle()メソッドについては、SDKの下記の説明をご確認ください。それはドーズから電話を目覚めさせません。

アラームがディスパッチされると、アプリはまた、アプリケーションが その作業を完了するために、さらなるウェイクロックを取得すること を可能にするために約10秒間 システムの一時的なホワイトリストに追加されます。

+1

そうです。ドキュメントから:「ホワイトリストに登録されたアプリケーションのジョブと同期は延期され、通常のAlarmManagerアラームは起動しません。」 –

+0

@UncaughtExceptionどうすればこのアンドロイド6と7の今日の対応ができますか?どんな実装例も提供できますか? – ray20

9

おそらくあなたを助ける:

我々のアプリケーションが19以下のAPIレベル(キットカット)をターゲットにしている場合、予定のアラームがアラーム時刻に正確に を実行します。KitKat以降を対象とするアプリケーションでは、スケジュール が不正確であるとみなされ、 ウェイクアップを最小限に抑えてバッテリを節約するために、アラームの並べ替えやグループ化が行われる可能性があります。

はAPIレベル23の後、Androidの開発チームは、さらに少し行って、デバイスを すると、電源アダプタ、動かから抜くと、バッテリーの消費を減らすためにAndroidのシステムに導入されました モードをDoze状態、および で使用されていません長期間使用することはできません。 デバイスはDozeモードを終了するか、定期的なメンテナンスウィンドウが 保留中のジョブを実行するために実行されるまで

ドーズシステムは バックグラウンドジョブ、ネットワークの更新、同期を延期デバイスのウェイクアップ頻度、そして私たちの貴重な警報を減少しようとします、特定のアラーム、またはネットワークとの同期。 メンテナンスウィンドウfnishesした後、それがその間に使用されなかった場合、デバイスは再び Dozeモードを入力します。

enter image description here

Dozeモードは、アプリケーションに影響を与える可能性があり、メンテナンスまで、あなたのアラーム を延期します深いアイドル状態でアラームの実行を のsetAndAllowWhileIdle()およびsetExactAndAllowWhileIdle()メソッドを使用しない限り、ウィンドウが表示されます。また

、ドーズモードメンテナンスウィンドウの実行が 長期非アクティブの場合にはそれほど頻繁になり、したがって我々のスケジューリングに関するこの新しいメカニズム の影響が大きくなり、それゆえに、より予測不可能なジッタを引き起こした回数 アラーム時刻。

dozeモードでは、アプリケーションもネットワークにアクセスできません。 WakeLockは無視され、Wi-Fiスキャンは実行されません。

我々は、精密なスケジューリングを必要とし、あなたはマシュマロをターゲットに以降している、 なら、私たちは APIレベル23で導入された新setExactAndAllowWhileIdle()メソッドを使用しなければならない。注意事項

am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, time, pending); 

を:

Androidシステムは、あまりにも頻繁にフリーオフする正確な アラームの悪用を防ぐ保護を備えています。 AlarmManagerはデバイスを だけ起動し、毎分1つのアラームを送出し、低電力では モードでは15分ごとに1にすることができます。

アプリケーションはキットカット(APIレベル19)と マシュマロ(APIレベル23)との間にバージョンをターゲットにしている場合、setExact方法は、精度のタイミングのために十分である:

am.setExact(AlarmManager.RTC_WAKEUP, time, pending); 

しかし、我々はそれをチェックする必要がありますメソッドを呼び出す前に存在します。それ以外の場合は、以前のAPIレベルで実行するとアプリケーションがクラッシュします。

これは、すべてのプラットフォームで正確に指定された時刻にアラームを送信します。

Asynchronous android programming

+1

"これは、すべてのプラットフォーム上の特定の時刻にアラームを送信します。いいえ – PrisonMike

+0

setExactAndAllowWhileIdleメソッドは完全に役に立たないです。いくつかの状況で2つのアラームを15分以内に処理できないリマインダアプリケーションは、アプリケーションの悪い駄目です。してください、制限なくアラームをトリガするための良い方法はありませんか?リマインダーアプリケーションが必要です! – user3289695

関連する問題