【问题标题】:How to use Android AlarmManager with small intervals like 1 minute?如何以 1 分钟的小间隔使用 Android AlarmManager?
【发布时间】:2014-08-07 11:34:42
【问题描述】:

我想建立一些外部服务监控器,并尽快收到有关问题的通知。

我尝试设置 AlarmManager 间隔 1-2 分钟,但它看起来每隔几分钟随机触发一次。

当然,我希望避免被android杀死我的后台任务,如果我只使用Service,它将停止监控。

是否可以以小而准确的间隔使用AlarmManager

Facebook、Gmail 等应用程序使用哪些方法来通知新消息?

ServicestartForeground 和部分WakeLock 一起制作会更好吗?

【问题讨论】:

    标签: android timer alarmmanager background-service


    【解决方案1】:

    我尝试以 1-2 分钟的间隔设置 AlarmManager,但它看起来每隔几分钟随机触发一次。

    由于您决定不展示如何“以 1-2 分钟的间隔设置 AlarmManager”,因此任何人都很难帮助您。请阅读 the documentation for AlarmManager 并注意 Android 4.4 新增的默认不精确行为。

    我希望避免被 android 杀死我的后台任务,如果我只使用 Service,它将停止监控。

    AlarmManager 并没有解决这方面的所有问题。例如,如果用户选择强制停止您的应用(例如,通过设置),您的警报将被移除。

    是否可以在小而准确的间隔内使用 AlarmManager?

    在 Android 1.0-4.3 上使用 setRepeating(),在 Android 4.4+ 上使用 setExact()。使用setExact(),作为处理一个警报事件的一部分,您需要安排下一个警报事件。

    用 startForeground 和部分 WakeLock 做 Service 会更好吗?

    仅当您的设备始终插入电源时(例如,工业过程监视器)。

    【讨论】:

    • 如果您将目标版本设置为低于 4.4,您无需担心 4.4 及以上版本。
    • @Eu.Dr.:正确。但是,选择targetSdkVersion 涉及许多因素。精明的程序员会考虑到,总有一天,他们将需要提高他们的targetSdkVersion 并且会忘记它对警报的影响。因此,此类程序员将在开发新的AlarmManager 代码时选择使用setExact(),此时需要准确的警报。 targetSdkVersion 主要是为了简化现有代码的转换,而不是作为在编写新代码时忽略更改的许可。
    • 会接受这一点,但我根本无法达到 1 分钟的间隔,即使在 adroid 3 目标 SDK 上也是如此。这可能与我使用的是MIUI Android有关,看起来有一些内部限制等于5分钟作为最小的警报间隔
    • @killer_PL:我使用AlarmManager 进行了低至五秒的演示,所以它当然可以做到。但是AlarmManager 是设备制造商进行更改以尝试延长电池寿命的领域,因此如果您的设备是问题的根源,我不会感到惊讶。您可以与 x86 模拟器或其他设备或其他设备进行比较。
    • setRepeating() 在某些设备上无法在 Android 5 及更高版本上可靠运行,即使您将 targetSdk 设置为 8 (Android 2.2)。大多数较新的设备似乎都忽略了targetSdk 设置并使用自己的电源管理算法。不幸的是。
    【解决方案2】:
    Calendar cal = Calendar.getInstance();
                cal.add(Calendar.SECOND, 30);
                Intent intent = new Intent(MainActivity.this, YourClass.class);
                PendingIntent pintent = PendingIntent.getService(MainActivity.this,
                        0, intent, 0);
                AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
                        60* 1000, pintent);
    

    【讨论】:

    • 在我的情况下,这恰好是每 5 分钟一次。
    【解决方案3】:

    发布我们使用的代码sn-p。请根据您的要求进行修改。我们每 15 秒使用一次,它就可以工作。

    public class AlarmManagerBroadcastReceiver extends BroadcastReceiver  
    {
    private static final int _REFRESH_INTERVAL = 60 * 1; // 1 minutes
    // Alarm id
        private static final int ALARM_ID = 102; // This can be any random integer.
    
        PendingIntent pi = null;
        AlarmManager am= null;
    
    @Override
        public void onReceive(Context context, Intent intent) 
        {
            /* All actions to be handled here.. */
            }
    
    
        // This is to initialize the alarmmanager and the pending intent. It is done in separate method because, the same alarmmanager and
        // pending intent instance should be used for setting and cancelling the alarm.
    
        public void SetContext(Context context)
        {
            this.context = context;
            am=(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
            pi = PendingIntent.getBroadcast(context, ALARM_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        }
    
        // Setting the alarm to call onRecieve every _REFRESH_INTERVAL seconds
        public void SetAlarm()
        {
            // am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * _REFRESH_INTERVAL , pi);
            try
            {
                am.cancel(pi);
            }catch (Exception ignored){}
            am.setRepeating(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime(), 1000 * _REFRESH_INTERVAL , pi);
        }
    
        // Cancel the alarm.
        public void CancelAlarm()
        {
            am.cancel(pi);
        }
    
    }
    

    【讨论】:

    • 这个解决方案和我的一样 - 它每 5 分钟启动一次。
    • 注意两点:1)从API 19开始,所有的报警都是不准确的; 2)为了让它长时间工作,广播接收器必须在清单中注册,而不是动态地
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多