Как запускать сервис каждый день в полдень и при каждой загрузке - PullRequest
15 голосов
/ 21 октября 2011

В моем приложении есть база данных SQLite, в которой есть одна таблица со строками даты в миллисекундах. Я хотел бы, чтобы уведомление отображалось каждый день IF 30 дней прошло с момента последнего значения даты, сохраненного в моей базе данных. Сервис, кажется, хороший способ выполнить эту проверку.

Я столкнулся с WakefulIntentService от Commonsware и подумал, что это может быть ответом, но я действительно не знаю, как мне это реализовать. В демоверсии он запускает службу через 5 минут после завершения загрузки, и это нормально, но что мне нужно добавить, чтобы запускать ее также каждый полдень. (... но только для показа одного уведомления / дня, а не обоих, как при загрузке, так и при регулярной ежедневной проверке)

Я знаю, что это можно решить с помощью AlarmManager, но на самом деле не знаю как. Итак, мне нужна помощь, чтобы дать мне несколько примеров / ключевых моментов, чтобы запускать службу при каждой загрузке и / или каждый день без запуска приложения.

спасибо

Ответы [ 3 ]

41 голосов
/ 21 октября 2011

Android alarmmanager ваш ответ. используйте его с приемником вещания, который также сбрасывает сигналы тревоги при пробуждении телефона.

Теперь с примером кода: Установка будильника внутри метода:

Intent intent = new Intent(context, AlarmReceiver.class);
intent.setAction("packagename.ACTION");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
            0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
        AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pendingIntent);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);

Приемник для вашего интервала:

public class AlarmReceiver extends BroadcastReceiver {
private final String SOMEACTION = "packagename.ACTION"; //packagename is com.whatever.www
@Override
public void onReceive(Context context, Intent intent) {
    Time now = new Time();
    now.setToNow();
    String time = FileHandler.timeFormat(now);

    String action = intent.getAction();
    if(SOMEACTION.equals(action)) {
        // here you call a service etc.
    }

Приемник для сброса сигналов тревоги при каждом отключении телефона.

public class AlarmSetter extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // get preferences
        SharedPreferences preferences = context.getSharedPreferences("name_of_your_pref", 0);
        Map<String, ?> scheduleData = preferences.getAll();

        // set the schedule time
        if(scheduleData.containsKey("fromHour") && scheduleData.containsKey("toHour")) {
            int fromHour = (Integer) scheduleData.get("fromHour");
            int fromMinute = (Integer) scheduleData.get("fromMinute");

            int toHour = (Integer) scheduleData.get("toHour");
            int toMinute = (Integer) scheduleData.get("toMinute");

            //Do some action
        }
    }

}

Манифест очень важен, он добавляется под приложением:

        <receiver android:name="AlarmReceiver">
        <intent-filter>
            <action android:name="packagename.ACTION"/>
            <action android:name="packagename.ACTION2"/>
        </intent-filter>
    </receiver>

    <receiver android:name="AlarmSetter" >
        <intent-filter>
            <action
                android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

Кроме того, чтобы это работало, вам нужно добавить разрешение на получение загрузочной трансляции в манифесте со следующей строкой:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

Надеюсь, что все прояснилось, если какие-либо ошибки, пожалуйста, скажите.

Редактировать (добавлен пример аварийной сигнализации):

public class AlarmSetter extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // Do your stuff
    }
}
5 голосов
/ 08 января 2015

Этот ответ кажется довольно старым. Теперь я настоятельно рекомендую пользователям ознакомиться с платформой SyncAdapter, предоставленной Google. Это на заказ для таких вещей. Вот ссылка: https://developer.android.com/training/sync-adapters/index.html

2 голосов
/ 21 октября 2011

В демонстрационной версии он запускает службу через 5 минут после завершения загрузки, и это просто замечательно, но что мне нужно добавить, чтобы запускать ее также каждый полдень.

Изменение начального времени вызова setRepeating().Пример показывает одну минуту спустя - вам нужно будет выполнить вычисления, чтобы определить, когда наступит следующий полдень.

Пример такого рода вычислений можно увидеть в this OnBootReceiver из другого примера проекта.Здесь я настраиваю будильник так, чтобы он срабатывал каждый день в указанное пользователем время.

...