Android完全闹钟始终关闭3分钟 [英] Android exact Alarm is always 3 minutes off

查看:92
本文介绍了Android完全闹钟始终关闭3分钟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,该应用程序使用 AlarmManager 定期整小时唤醒手机,并向Android Wear手表发送消息,这会引起短暂的震动。我有两个用户在使用带有Android 5.1.1的三星Galaxy S6和5.1.1的Sony SW 3,它们遇到了一个奇怪的错误。在最初的整整一个小时内,振动是在准确的时间进行的,但所有其他振动都延迟了3分钟。有时甚至第一个小时的振动也会被延迟。

I have an app which uses the AlarmManager to regularly wake up the phone at full hour and send a message to an Android Wear watch which than makes a short vibration. I have two users with a Samsung Galaxy S6 with stock Android 5.1.1 and the Sony SW 3 with 5.1.1 who experience a weird bug. At the very first full hour the vibration is at the exact time but all other vibrations are 3 minutes delayed. Sometimes even the first full hour vibration is delayed.

这里是一些代码:

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分钟。

I acquire a WakeLock in the receiver and then send a message to the Wear watch in a thread. No vibration is missed, they are just 3 minutes late.

我没有关于此问题的其他报告,并且我的所有测试设备都运行良好。我没有三星设备。

I have no other reports about this issue and all my testing devices are working good. I have no Samsung device though.

任何想法可能导致3分钟的延迟吗?三星会忽略 setExact 并使我的闹钟不准确吗?如何在Samsung上强制发出确切警报?

Any ideas what could cause the 3 minutes delay? Does Samsung ignore setExact and makes my alarm an inexact? How to force exact alarms on Samsungs?

编辑:

这里是Android Wear专用代码。在接收方的 onReceive 方法中,我这样做:

Here is the Android Wear specific code. In the receiver's onReceive method I do this:

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();


推荐答案

问题似乎仅发生在三星设备上(例如Galaxy Grand,S4,S5,S6,Note 3,Note 4和Lollipop(5.0、5.1、5.1.1)。当设备由电池供电且屏幕关闭时,警报调度的时间似乎不准确。如果设备正在充电或在计划警报期间打开屏幕,则不会发生此问题。

The issue seems to occur only on Samsung devices (e.g. Galaxy Grand, S4, S5, S6, Note 3, Note 4) with Lollipop (5.0, 5.1, 5.1.1). It seems that alarms are scheduled inexact when device is on battery with screen off. If device is charging or has screen on during scheduling alarm the issue will not occur.

您可以通过以下方式验证下一个警报是否不准确:

You can verify if next alarm will be inexact with:

adb shell dumpsys alarm

我没有找到解决此问题的完美解决方案-只是每个都有一些缺点的解决方法:

I didn't find perfect solution for this problem - only workarounds where each has some drawbacks:


  1. 使用 setAlarmClock 代替 setExact (请参阅此答案)。此方法效果很好(并非在所有设备上都适用),但是此解决方案的问题在于,警报将通过在状态栏中显示警报图标(如果某人尚未设置闹钟)并显示下一个警报预定时间来影响系统不幸的是,虽然这在5.1.1的Galaxy Grand上可以使用,但在5.0.1的Galaxy S4上却不可用。

  2. 在安排警报之前启用屏幕(我做了一半在安排下一个警报之前,避免发生竞争情况。当然,并不是每个应用程序都启用屏幕只是为了调度下一个警报是一个好的解决方案。

  3. 一个描述类似问题的错误报告将其与应用程序包名称的长度连接起来!我没有验证它是否真的可以解决问题,因为更改软件包名称不是已发布应用程序的选项。

  4. 另一份报告,其中有人声称可以使用 WakefulBroadcastReceiver 来解决此问题。 ,但在我的情况下不起作用。

  1. Use setAlarmClock instead setExact (see this answer). This works very well (not on all devices), but the issue with this solution is that the alarm will affect the system by showing alarm icon in status bar (if someone doesn't have alarm clock set already) and displaying next alarm scheduled time on alarm widgets etc. Unfortunately while this works on Galaxy Grand with 5.1.1 it doesn't on Galaxy S4 with 5.0.1.
  2. Enable screen before scheduling the alarm (I do this half second before scheduling next alarm to avoid race condition). Of course it is not good solution for every app to enable screen just to schedule next alarm.
  3. One bug report describing similar issue connects it with app package name length! I didn't verify if it really fixes the issue, because changing package name is not an option for already published app.
  4. There is another report where someone claims this can be fixed by using WakefulBroadcastReceiver, but it doesn't work in my case.

BTW这个问题使我发疯:)

BTW This issue drives me crazy :)

编辑:当应用包名称中有关键字 alarm或 alert时,看来不会发生此问题(如Mathieu H.在下面的评论中所指出的那样) )。

Looks like this issue does not occur when there is keyword "alarm" or "alert" in the app package name (as pointed out by Mathieu H. in comments below).

我还可以通过在电池设置(或Smart Manager应用)中禁用应用优化来手动解决此问题。似乎无法通过编程方式完成,因此您可以尝试询问用户...

I was also able to fix the issue manually by disabling App optimization in Battery settings (or in Smart Manager app). It seems it cannot be done programmatically, so you can try asking your users...

这篇关于Android完全闹钟始终关闭3分钟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆