为什么下面的实现是在警报不应该关闭时触发警报?

时间:2013-02-20 13:20:02

标签: android alarmmanager repeatingalarm

我正在实施一个AlarmManager来请求我的应用程序的更新,这应该每天只发生一次。警报创建后,我不希望警报响起。为此,我创建了一个日历对象。

每当创建警报时,它也会触发。请注意,这并不总是发生。 我注意到这个问题只在一天中的某个时间发生。我住在香港,我希望我的时区没有任何问题。我没有使用AlarmManager.INTERVAL_DAY,而是尝试使用24 * 60 * 60 * 1000。仅当日历工厂比当前工厂更旧时才会发生这种情况。我将检查时间当前时间是否较新,并在日历对象中添加24 * 60 * 60 * 1000,然后再删除此问题。

这是一个创建AlarmManager的服务。此服务也在启动时启动。为了确保dataPreferenceObj,它是我的应用程序中DataPreference类的一个实例,它处理与我的应用程序相关的SharedPreferences相关调用。 ACTION_SCHEDULE_ALARM是Keys ENUM类的一部分,它保存所有字符串常量。

public class TukiService extends Service {

private static AlarmManager calendarAlarmManager;
private static PendingIntent calendarPendingIntent;
private static final int SCHEDULE_REQUEST_CODE = 1001;

@Override
public void onCreate() {
    super.onCreate();

    updateScheduleUpdate();
}

private static void updateScheduleUpdate() {

    if (dataPreferenceObj.getEnabledUpdate() == true) {
        cancelScheduleUpdate();
        requestScheduleUpdate();
    } else if (dataPreferenceObj.getEnabledUpdate() == false) {
        cancelScheduleUpdate();
    }
}

private static void requestScheduleUpdate() {
    setScheduleAlarmParamaters();

    Calendar calendar = new GregorianCalendar();
    calendar.set(Calendar.HOUR_OF_DAY, 9);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    scheduleAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
            calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
            schedulePendingIntent);
}

/*
 * Cancels an existing alarm if user doesn't want to auto update.
 */
private static void cancelScheduleUpdate() {
    setScheduleAlarmParamaters();
    scheduleAlarmManager.cancel(schedulePendingIntent);
}

private static void setScheduleAlarmParamaters() {
    Intent intent = new Intent(Keys.ACTION_SCHEDULE_ALARM.toString(),
            Uri.parse(Long.toString(SCHEDULE_REQUEST_CODE)), context,
            AlarmReceiver.class);

    schedulePendingIntent = PendingIntent.getBroadcast(mContext,
            SCHEDULE_REQUEST_CODE, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);

    scheduleAlarmManager = (AlarmManager) mContext
            .getSystemService(Context.ALARM_SERVICE);
}

}

这是接收广播的广播接收器:

public class ScheduleReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

    if (intent.getAction().equals(Keys.ACTION_SCHEDULE_ALARM.toString())) {

        if (TukiService.SCHEDULE_REQUEST_CODE == Long.parseLong(intent
                .getData().getSchemeSpecificPart())) {
            new NetworkHandler(context).fetchAutoEnabledUpdate();
        }
    } 
}

}

这是主要节日中的接收者声明:

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <receiver
        android:name="com.milanix.tuki.service.ScheduleReceiver"
        android:enabled="true" >
    </receiver>
    <service android:name="com.milanix.tuki.service.TukiService" >
    </service>

1 个答案:

答案 0 :(得分:4)

我现在已经解决了这个问题。看起来如果triggerAtMillis比currentMillis旧,则无论何时设置它都会触发警报。我编写了以下代码,用于检查triggerAtMillis是否比currentMillis旧。如果它比我们旧,我们将在triggerAtMillis中添加一天的间隔。现在,无论何时设置闹钟,它都会在确切的时间点亮,如果闹钟时间过去,它将在第二天同时点火。这是代码:

public static final int INTERVAL_DAY = 24 * 60 * 60 * 1000;

private static void requestScheduleUpdate() {
    setScheduleAlarmParamaters();

    Calendar calendar = new GregorianCalendar();
    calendar.set(Calendar.HOUR_OF_DAY, 15);
    calendar.set(Calendar.MINUTE, 55);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    long triggerMillis = calendar.getTimeInMillis();

    if (calendar.getTimeInMillis() < Calendar.getInstance()
            .getTimeInMillis()) {
        triggerMillis = calendar.getTimeInMillis() + INTERVAL_DAY;

        System.out.println("Alarm will go off next day");
    }

    scheduleAlarmManager
            .setRepeating(AlarmManager.RTC_WAKEUP, triggerMillis,
                    AlarmManager.INTERVAL_DAY, schedulePendingIntent);
}

如果有人能指出比这个更好的解决方案,那就太好了。