调度任务时,Alarm Manager无法按预期工作

时间:2017-04-04 11:45:12

标签: android alarmmanager

我目前正在使用Android Alarm Manager并找到了一个有效的示例。但它在我的情况下不能正常工作。让我解释。基本上我的目标是每5分钟从MainActivity执行一个方法。为此,我使用Alarm Manager来安排该任务。

基本上这是工作原理:

AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        context.sendBroadcast(new Intent("SERVICE_TEMPORARY_STOPPED"));
    }
}

MainActivity.java

public class MainActivity extends Activity{
    private PendingIntent pendingIntent;
    private AlarmManager manager;

    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
        }
    };


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent alarmIntent = new Intent(this, AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
        registerReceiver(broadcastReceiver, new IntentFilter("SERVICE_TEMPORARY_STOPPED"));

        Button button = (Button) findViewById(R.id.button);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startAlarm();
            }
        });
    }


    public void startAlarm() {
        manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
        int interval = 300000;
        manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
        Log.d(TAG, "Alarm Set");
    }
}

一切都很好。 "我正在跑步"吐司每300毫秒(5分钟)执行一次。 AlarmReceiver类通过消息" SERVICE_TEMPORARY_STOPPED"向我的主Activity发送广播。我已经通过registerReceiver(broadcastReceiver, new IntentFilter("SERVICE_TEMPORARY_STOPPED"));在我的MainActivity中注册了该消息。但是,当我添加另一种方法时,让我们在broadcastReceiver中说stopAlarm(),它将在5分钟后停止警报,时间间隔(5分钟)不再适用。在10秒内,它会调用广播接收器并停止闹钟。这就是问题所在。请查看stop()方法以及我如何在broadcastReceiver上调用它:

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
        stopAlarm();
    }
};

public void stopAlarm() {
    Intent alarmIntent = new Intent(this, AlarmReceiver.class);
    pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
    manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    manager.cancel(pendingIntent);
    Log.d(TAG, "Alarm Cancelled");
}

有任何线索吗?

1 个答案:

答案 0 :(得分:0)

AlarmManager.setRepeating 在不同的Android版本上无法正常工作。

尝试 setExact 。它不会重复,但您可以实现如下所述的重复功能:

更新了AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        context.sendBroadcast(new Intent("SERVICE_TEMPORARY_STOPPED"));

        long repeatCount = PreferenceManager.getDefaultSharedPreferences(context).getLong("REPEAT_COUNT", 0L);

        repeatCount++;

        PreferenceManager.getDefaultSharedPreferences (context).edit().putLong("REPEAT_COUNT", repeatCount).apply()

        AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

        Intent alarmIntent = new Intent(this, AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
        manager.setExact(AlarmManager.RTC_WAKEUP, (repeatCount *System.currentTimeMillis()),pendingIntent);
    }
}

我们维持一个repeatCount&变量(基于偏好)并在AlarmReceiver&中增加它。通过使用repeatCount * System.currentTimeMillis();

计算nextAlarmTime来再次计划警报