我有一个应用程序使用AlarmManager
定期唤醒整个小时的电话,并发送消息到Android Wear手表,这是一个短暂的振动。我有两个用户使用三星Galaxy S6和Android 5.1.1,索尼SW 3和5.1.1有一个奇怪的错误。在第一个整小时,振动处于准确的时间,但所有其他振动都延迟了3分钟。有时即使是第一个整小时的振动也会延迟。
这是一些代码:
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分钟。
我没有关于这个问题的其他报告,我的所有测试设备都运行良好。我没有三星设备。
什么可能导致3分钟延迟的想法?三星是否会忽略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();
问题似乎只发生在三星设备上(例如Galaxy Grand,S4,S5,S6,Note 3,Note 4)和Lollipop(5.0,5.1,5.1.1)。当设备处于电池状态且屏幕关闭时,警报似乎不准确。如果设备正在充电或在调度警报期间屏幕亮起,则不会发生此问题。
您可以验证下一个警报是否不准确:
adb shell dumpsys alarm
我找不到解决这个问题的完美解决方案 - 只有每个都有一些缺点的解决方法:
setAlarmClock
而不是setExact
(参见this answer)。这非常有效(不是在所有设备上),但此解决方案的问题是警报会通过在状态栏中显示警报图标(如果有人没有设置闹钟)并显示下一个警报预定时间来影响系统警报小部件等等。不幸的是,虽然这适用于5.1.1的Galaxy Grand,但它不适用于5.0.1的Galaxy S4。WakefulBroadcastReceiver
修复,但它不适用于我的情况。BTW这个问题让我抓狂:)
编辑:当应用程序包名称中存在关键字“alarm”或“alert”时,看起来不会发生此问题(如Mathieu H.在下面的评论中所指出的)。
我还可以通过在电池设置(或智能管理器应用程序)中禁用应用程序优化来手动修复此问题。它似乎无法以编程方式完成,因此您可以尝试询问您的用户......