代码之家  ›  专栏  ›  技术社区  ›  Mahmoud Hashim

AlarmManager激发不一致的原因

  •  2
  • Mahmoud Hashim  · 技术社区  · 11 年前

    我正在 onResume() 我的MainActivity.java中的状态 (这是程序开始的主要活动)

    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
        }
    }
    

    然而,我得到了不一致的结果,下面的代码运行良好,没有错误,它显示 PendingIntent 应每10分钟发射一次,但结果如下:

    它开始运作良好:

    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 如果我所做的是正确的,那么不一致运行的原因是什么。

    4 回复  |  直到 11 年前
        1
  •  3
  •   Mahmoud Hashim    11 年前

    使用以下代码:

    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
  •  1
  •   Community Mohan Dere    5 年前

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

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

    Check here for complete implementation.

    流程大致如下:

    主活动-->on创建-->检查是否首次运行-->是-->注册报警并立即执行-->调用函数/代码-->让此代码设置下一个警报。

        3
  •  1
  •   Thorn G    11 年前

    的文档 AlarmManager 清楚地说明重复报警是不准确的,因此您可以通过Logcat观察到漂移。

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

        4
  •  1
  •   Douglas Frari    11 年前

    您可以使用的代码块:

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