web-dev-qa-db-ja.com

Android正確なアラームは常に3分オフです

AlarmManagerを使用して、1時間に定期的に電話を起こし、Android Wear Watchを使用すると、短い振動が発生します。2つあります。在庫のあるSamsungGalaxyS6を使用しているユーザーAndroid 5.1.1および5.1.1を使用しているSonySW 3で、奇妙なバグが発生しています。最初の1時間は、振動は正確な時間ですが、他のすべての振動は3分遅れます。最初の1時間の振動でさえ遅れることがあります。

ここにいくつかのコードがあります:

final Calendar time = Calendar.getInstance();
time.set(Calendar.SECOND, 0);
time.set(Calendar.MILLISECOND, 0);
time.set(Calendar.MINUTE, 0);
time.set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY) + 1);

final Intent hourlyChimeIntent = new Intent(context, HourlyChimeReceiver.class);
hourlyChimeIntent.setAction(key);
final AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
final PendingIntent pi = PendingIntent.getBroadcast(context, 0, hourlyChimeIntent, PendingIntent.FLAG_CANCEL_CURRENT);
am.setExact(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pi);

レシーバーでWakeLockを取得し、スレッドでWearウォッチにメッセージを送信します。振動を逃すことはありません、彼らはわずか3分遅れています。

この問題に関する他の報告はなく、すべてのテストデバイスが正常に機能しています。私はSamsungデバイスを持っていません。

3分の遅延を引き起こす可能性のあるアイデアはありますか? SamsungはsetExactを無視し、アラームを不正確にしますか?サムスンに正確なアラームを強制する方法は?

編集:

これがAndroid Wear固有のコードです。レシーバーのonReceiveメソッドでこれを行います:

final PowerManager mgr = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
final PowerManager.WakeLock lock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID);
lock.acquire(7L * 1000L);

final GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context).addApi(Wearable.API).build();

new Thread(new Runnable() {
    @Override
    public void run() {
        googleApiClient.blockingConnect();

        long pattern[];
        pattern = new long[] {0L, 500L};

        final NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(googleApiClient).await(2000L, TimeUnit.MILLISECONDS);

        if (nodes != null) {
            for (final Node node : nodes.getNodes()) {
                // just send and forget
                Wearable.MessageApi.sendMessage(googleApiClient, node.getId(), "/hourly_chime", Utils.Vibrator.serializeVibratePattern(pattern).getBytes()).await();
            }
        }
    }
}).start();
18
shelll

この問題は、Lollipop(5.0、5.1、5.1.1)を搭載したSamsungデバイス(Galaxy Grand、S4、S5、S6、Note 3、Note 4など)でのみ発生するようです。画面がオフの状態でデバイスのバッテリーがオンの場合、アラームは不正確にスケジュールされているようです。デバイスが充電中であるか、アラームのスケジュール中に画面がオンになっている場合、問題は発生しません。

次のアラームが不正確になるかどうかを確認できます。

adb Shell dumpsys alarm

この問題の完全な解決策は見つかりませんでした。それぞれにいくつかの欠点がある回避策のみです。

  1. 代わりにsetAlarmClocksetExactを使用してください( この回答 を参照)。これは非常にうまく機能します(すべてのデバイスではありません)が、このソリューションの問題は、ステータスバーにアラームアイコンを表示し(誰かがまだ目覚まし時計を設定していない場合)、次のアラームのスケジュール時刻を表示することで、アラームがシステムに影響を与えることです残念ながら、これは5.1.1のGalaxy Grandでは機能しますが、5.0.1のGalaxyS4では機能しません。
  2. アラームをスケジュールする前に画面を有効にします(競合状態を回避するために、次のアラームをスケジュールする前にこの0.5秒を実行します)。もちろん、次のアラームをスケジュールするためだけに画面を有効にすることは、すべてのアプリにとって良い解決策ではありません。
  3. 1つ 同様の問題を説明するバグレポート アプリパッケージ名の長さに接続します!パッケージ名を変更することは、すでに公開されているアプリのオプションではないため、問題が本当に修正されるかどうかは確認しませんでした。
  4. 別のレポート があります。誰かがこれはWakefulBroadcastReceiverを使用して修正できると主張していますが、私の場合は機能しません。

ところで、この問題は私を夢中にさせます:)

編集:アプリパッケージ名にキーワード「alarm」または「alert」がある場合、この問題は発生しないようです(以下のコメントでMathieu H.が指摘しているように)。

また、バッテリー設定(またはSmart Managerアプリ)でアプリの最適化を無効にすることで問題を手動で修正することもできました。プログラムで行うことはできないようですので、ユーザーに質問してみてください...

26
Paweł Nadolski