【问题标题】:Android AlarmManager is not calling PendingIntent at specific timeAndroid AlarmManager 未在特定时间调用 PendingIntent
【发布时间】:2018-04-10 07:56:59
【问题描述】:

我想在特定时间运行服务,为此我正在使用 AlarmManager。我的代码如下。

 public static void setServiceAlarm(Context context, boolean isOn) {
    Intent i = new Intent(context, RefreshingMedicationDataService.class);
    PendingIntent pi = PendingIntent.getService(
            context, 0, i, 0);

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 9);
    calendar.set(Calendar.MINUTE, 51);

    AlarmManager alarmManager = (AlarmManager)
            context.getSystemService(Context.ALARM_SERVICE);
    if (isOn) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP,
                calendar.getTimeInMillis(), pi);
    } else {
        alarmManager.cancel(pi);
        pi.cancel();
    }
}

问题是,AlarmManager 没有调用我在 PendingIntent 中提供的服务。 但是,当我尝试像下面这样调用 AlarmManager 时,它正在工作! 为什么?

 public static void setServiceAlarm(Context context, boolean isOn) {
    Intent i = new Intent(context, RefreshingMedicationDataService.class);
    PendingIntent pi = PendingIntent.getService(
            context, 0, i, 0);

    AlarmManager alarmManager = (AlarmManager)
            context.getSystemService(Context.ALARM_SERVICE);
    if (isOn) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP,
                System.currentTimeMillis(), pi);
    } else {
        alarmManager.cancel(pi);
        pi.cancel();
    }
}

我尝试了几乎所有的 AlarmManager 方法(如 setExact()、set()、setRepeating()、setAlarmClock()),仅当我通过System.currentTimeMillis()时仍然有效@

【问题讨论】:

  • 请在您的清单中发布<service> 声明。
  • 当您使用currentTimeMillis() 时,会立即触发警报。如果您在以后安排闹钟,Android 可能由于某种原因无法启动您的Service。你确定Service 没有开始吗?您是否向Service 构造函数或onCreate() 添加了一些日志记录?你有自定义的Application 类吗?

标签: android alarmmanager android-pendingintent


【解决方案1】:

试试这个代码在AlarmManager中添加PendingIntent

public void addPendingIntentAlarmManager() {
     final PendingIntent pendingIntent = createPendingIntent();
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
         alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, notification.getTime(), pendingIntent);
     } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
         alarmManager.setExact(AlarmManager.RTC_WAKEUP, notification.getTime(), pendingIntent);
     } else {
         alarmManager.set(AlarmManager.RTC_WAKEUP, notification.getTime(), pendingIntent);
     }
}

private PendingIntent pendingIntent() {
    final Intent intent = new Intent(app, NotificationReceiver.class);
    intent.setAction("simplePI 1");
    return PendingIntent.getBroadcast(context, 10, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

在 AndroidManifest 中也添加 PendingIntentReceiver

public class PendingIntentReceiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
        final ComponentName comp = new ComponentName(context.getPackageName(), **YOURSERVICE**.class.getName());
        startWakefulService(context, intent.setComponent(comp));
    }
}

【讨论】:

    【解决方案2】:

    我更高版本的Android你应该使用setAlarmClock

    private void scheduleAlarm(AlarmManager alarmManager, long targetTime, PendingIntent pendingIntent, Intent intent) {
        if(VersionCheckUtils.isLollipopOrLater()) {
            logAlarm(targetTime, pendingIntent, intent, "Lollipop");
            alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(targetTime, pendingIntent),
                    pendingIntent);
        }
        else {
            logAlarm(targetTime, pendingIntent, intent, "Kitkat");
            alarmManager.setExact(AlarmManager.RTC_WAKEUP, targetTime, pendingIntent);
        }
    }
    

    这是您检查版本的方法:

    public class VersionCheckUtils {
    
        private static final int LOLLIPOP = 21;
    
        static final int KITKAT = 20;
    
        private static final int OREO = 26;
    
        public static boolean isKitKatOrLater() {
            return Build.VERSION.SDK_INT >= KITKAT;
        }
    
        public static boolean isLollipopOrLater() {
            return Build.VERSION.SDK_INT >= LOLLIPOP;
        }
    
        public static boolean isOreoOrLater() {
            return Build.VERSION.SDK_INT >= OREO;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多