简体   繁体   English

闹钟服务在手机的省电模式下不起作用

[英]alarm service not working in power saver mode of phone

I have a app which using alarm service.Using the alarm service i am setting 我有一个使用警报服务的应用程序。使用我正在设置的警报服务

PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
                new Intent("com.mindedges.pkg.intent.action.NEW_HOUR"),
                PendingIntent.FLAG_UPDATE_CURRENT);

alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, AlarmSheduleHelper
                .getImmediateNextHour().getTimeInMillis(),
                AlarmManager.INTERVAL_HOUR, pendingIntent);

And then there is a receiver for this and then it plays some sound. 然后有一个接收器,然后播放一些声音。

Evertthing works fine for on my phone and with most of the users , but some customers complain. Evertthing适用于我的手机以及大多数用户,但有些客户抱怨。 " most of the time app fails to show alarm and Its either few minutes late or only when I press power button to unlock the phone" “大多数情况下,应用程序无法显示警报,或者延迟几分钟,或者仅当我按下电源按钮以解锁手机时才显示”

NOTE that this customer have turned on power saver and have have also included the app to be active on standby mode 请注意,该客户已打开省电功能,并且还包括该应用程序以在待机模式下处于活动状态

What could be the possible reason?Does alarm service not work in power saver mode? 可能的原因是:警报服务在省电模式下不起作用?

Related post : Android AlarmManager.set(...): notification never received when battery low 相关文章: Android AlarmManager.set(...):电池电量不足时永远不会收到通知

I've empirically found that the timing for repeating alarms to be wildly unpredictable. 从经验上我发现,重复警报的时间非常难以预测。 For instance, when I've asked for a 35 minute period, I'll get some alarms at about 35 minutes intervals, some hours apart, and some within a few minutes of each other. 例如,当我要求35分钟的时间时,我将以大约35分钟的间隔,相隔几个小时的间隔以及彼此之间几分钟的间隔得到一些警报。

I've found it much more predictable to just ask for a one-shot alarm and then resubmit a new one each time the alarm fires. 我发现只需要发出一次警报,然后在每次触发警报时重新提交一个新警报,就可以预测得多了。

That approach has apparently become a Google recommendation. 这种方法显然已成为Google的推荐。 The AlarmManager page now has the following added to the description of SetRepeating: "Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact." 现在, AlarmManager页面SetRepeating的描述中添加了以下内容:“注意:从API 19开始,所有重复的警报都是不精确的。如果您的应用程序需要精确的交付时间,则它必须使用一次性精确的警报,并按所述重新安排每次时间targetSdkVersion早于API 19的旧版应用程序将继续将其所有警报(包括重复警报)视为精确警报。”

I work on an application that heavily relies on reminders to notify users when to take their medication. 我在一个严重依赖提醒来通知用户何时服药的应用程序上工作。 Samsung devices that have PowerSave mode enabled will consistently not fire alarms at the correct time . 启用了PowerSave模式的Samsung设备将始终不会在正确的时间发出警报 I have seen instances where it fires one hour early. 我见过一些情况,它会提前一小时触发。 So for example users that want to be reminded at 8:00am to take there medication receive notifications at 7:00am. 因此,例如,想要在8:00 am提醒他们服用药物的用户在7:00 am收到通知。

Note: It doesn't matter how you set it. 注意:设置方式无关紧要。 As usual Samsung does their own thing and all logic goes out the window. 像往常一样,三星做自己的事,所有逻辑都无法实现。

Basically, ensure that the trigger time that was set is close enough to the current time: 基本上,请确保设置的触发时间与当前时间足够接近:

public class AlarmReceiver extends BroadcastReceiver {

  @Override public void onReceive(
      final Context context,
      final Intent intent) {

    // Sanity check on the received intent.
    if ((intent == null) || (intent.getAction() == null)) {
      Log.v(TAG, "Alarm received but the extra doesn't contain valid informations");
      return;
    }

      if (!validAlarmReceived(alarm)) {
        //try to set alarm again, use the same request code to cancel the pending intent
        AlarmManager.rescheduleCurrentAlarm(alarm, context);
        return;
      }
    }
  }

  /**
   * Sanity check to see if alarm has been prematurely triggered
   * due to odd behavior with PowerSave on some devices.
   */
  private boolean validAlarmReceived(
      final Alarm alarm) {

    if (alarm.isSnoozed()) {
      //avoid time check for snoozed alarms
      return true;
    }

    final long alarmMillis = alarm.getCurrentTriggerTime();
    final long currentMillis = System.currentTimeMillis();
    final long difference = (currentMillis - alarmMillis);
    final long THRESHOLD = TimeUnit.MINUTES.toMillis(1);

    // Allow the notification to show under the following scenarios:
    // 1. The alarm triggered late (i.e. current millis > alarm millis)
    // 2. OR the alarm triggered within the threshold value
    if (difference > 0 || Math.abs(difference) < THRESHOLD) {
      return true;

    } else {
      // otherwise reschedule the alarm
      return false;
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM