【问题标题】:Why AlarmManager fires are inconsistent为什么 AlarmManager 触发不一致
【发布时间】:2014-02-25 16:05:33
【问题描述】:

我在我的 MainActivity.java 中注册一个处于 onResume() 状态的警报管理器(这是程序启动的主要活动)

protected void onResume() {
    super.onResume();
    if (Helper.isNetworkAvailable(this)) {
        Intent intent = new Intent(this, NewsIntentService.class);
        PendingIntent pi = PendingIntent.getService(this, 0, intent, 0);
        AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        am.setRepeating(AlarmManager.RTC, System.currentTimeMillis(),
                10 * 60 * 1000, pi);
    } else {
        // nothing done
    }
}

但是我得到的结果不一致,以下代码运行良好且没有错误,它表明应该每 10 分钟触发一次 PendingIntent,但结果在以下来自 logcat 的示例中:

它开始运作良好:

2:00 pm (fired), 2:10 pm (fired), 2:30 pm (fired), ...

但过了一段时间:

3:20 pm (fired), 3:27 pm (fired), 3:33 pm (fired), 3:38 pm (fired) ...

question is 在活动的哪个生命周期最好注册一个AlarmManager,如果我所做的是正确的,那么运行不一致的原因是什么。

【问题讨论】:

    标签: java android android-alarms


    【解决方案1】:

    使用以下对我有用的代码:

    1-private SharedPreferences prefs;

    2-

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // Launch SharedPreferences
            prefs = getSharedPreferences("Alarm", MODE_PRIVATE);
    

    3-

    protected void onResume() {
            super.onResume();
    
            if(!prefs.getBoolean(Helper.ALARM_SET, false)) {
                Intent intent = new Intent(this, NewsIntentService.class);
                PendingIntent pi = PendingIntent.getService(this, 0, intent, 0);
                AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                am.setRepeating(AlarmManager.RTC, System.currentTimeMillis(),
                        10 * 60 * 1000, pi);
    
                Log.i(Helper.ALARM_SET, "Alarm is set.");
    
                SharedPreferences.Editor editor = prefs.edit();
                editor.putBoolean(Helper.ALARM_SET, true);
                editor.commit();
            }   
        }
    

    说明:

    使用SharedPreferences保存一个布尔值AlARM_SET,简单精确,即使手机重启或关机,此代码也能正常工作。

    【讨论】:

      【解决方案2】:

      您的 onResume 在这些时间被呼叫,因此触发警报并再次将其设置为接下来的十分钟。

      如果您的最终结果是调用警报上的功能,请尝试在那里设置下一个警报,在您的 MainActivity 的 onCreate 中调用一次警报。(检查第一次运行,使用 File 相同或只是Shared Preference) 其余的由触发警报时运行的服务/功能/代码处理。

      Check here for complete implementation.

      流程类似于:

      MainActivity--> onCreate--> 检查是否第一次运行--> 是--> 注册Alarm并立即执行--> Invoke function/code-->让这段代码设置下一个alarm。

      【讨论】:

        【解决方案3】:

        AlarmManager 的文档明确指出重复警报是不准确的——因此您通过 Logcat 观察到的漂移。

        注意:从 API 19 开始,所有重复警报都是不准确的。如果您的应用程序需要精确的交付时间,那么它必须使用一次性精确警报,并如上所述重新安排每次。 targetSdkVersion 早于 API 19 的旧版应用程序将继续将其所有警报(包括重复警报)视为准确。

        【讨论】:

        • 对于 setInexactRepeating 来说确实如此,设置重复应该可以正常工作,并且符合 API 级别 18 的预期。
        【解决方案4】:

        您可以使用的代码块:

        public void schedule(final Context context) {
        
            int alarmCode = YOUR_ALARM_CODE;
            final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, alarmCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        
            final Calendar calendar = yourCalendar();
        
            final AlarmManager alarm = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);
        
            final long time = calendar.getTimeInMillis();
        
            alarm.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-03-23
          • 1970-01-01
          • 1970-01-01
          • 2015-10-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多