2

私はAlarmManagerを実装して、アプリの更新を要求しています。これは1日に1回だけ発生するはずです。アラームが作成されたらすぐにアラームを鳴らしたくありません。このために、カレンダーオブジェクトを作成しました。

また、アラームが作成されるたびに起動します。これは常に発生するとは限らないことに注意してください。この問題は1日の特定の時間にのみ発生することに注意しました。私は香港に住んでいますが、タイムゾーンの関係で問題がないことを願っています。AlarmManager.INTERVAL_DAYを使用する代わりに、24 * 60 * 60*1000も使用してみました。これは、カレンダーミルが現在のミルよりも古い場合にのみ発生します。この質問を削除する前に、現在の時刻が新しいかどうかを確認し、カレンダーオブジェクトに24 * 60 * 60*1000を追加します。

これがAlarmManagerを作成するサービスです。このサービスも起動時に開始されます。dataPreferenceObjについて確認するために、これはアプリケーションのDataPreferenceクラスのインスタンスであり、アプリケーションのSharedPreferences関連の呼び出しを処理します。また、ACTION_SCHEDULE_ALARMは、すべての文字列を一定に保持するKeysENUMクラスの一部です。

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

1 に答える 1

4

私は今この問題を解決しました。triggerAtMillis が currentMillis よりも古い場合、いつ設定してもアラームが発生するようです。triggerAtMillis が currentMillis よりも古いかどうかを確認する次のコードを作成しました。それより古い場合は、triggerAtMillis に 1 日間隔を追加します。いつアラームを設定しても、常に正確な時刻に起動し、アラーム時刻が過ぎている場合は翌日同時に起動します。そのためのコードは次のとおりです。

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

誰かがこれよりも優れた解決策を指摘できれば、それは素晴らしいことです。

于 2013-02-21T08:07:09.710 に答える