Несколько распространенный вариант использования приложений для Android — запускать их при запуске телефона и периодически выполнять какой-то фрагмент кода.
Звучит просто, но есть некоторые подводные камни, поэтому вот несколько шагов, которые необходимо предпринять, чтобы достичь этого. Начните с тривиальных вещей:
В вашем манифесте вам нужно следующее, чтобы иметь возможность получить событие загрузки:
1
2
|
< uses-permission android:name = "android.permission.RECEIVE_BOOT_COMPLETED" /> |
Затем, снова в манифесте, вам нужно два получателя:
01
02
03
04
05
06
07
08
09
10
11
12
|
< receiver android:name = ".StartupLauncher" > < intent-filter > < action android:name = "android.intent.action.BOOT_COMPLETED" /> < action android:name = "android.intent.action.QUICKBOOT_POWERON" /> < category android:name = "android.intent.category.DEFAULT" /> </ intent-filter > </ receiver > < receiver android:name = ".Notifier" > < intent-filter > < action android:name = "com.yourpackage.HOURLY_CHECK" /> </ intent-filter > </ receiver > |
Что это все? Вы увидите, что такое HOURLY_CHECK через минуту. Записи в .StartupLauncher
я собрал из нескольких ответов StackOverflow, утверждают, что работают на нескольких устройствах. То, что вы обычно должны потреблять, это просто BOOT_COMPLETED
, но BOOT_COMPLETED
на всякий случай. Обратите внимание на атрибут enabled
приемника — они обычно не нужны, но убедитесь, что получение не отключено родительским приложением. Честно говоря, я бы не советовал ставить бесполезные вещи «на всякий случай», но, учитывая причуды андроид-устройств, я бы их сохранил.
Теперь BOOT_COMPLETED
Сервис, который получит событие BOOT_COMPLETED
:
1
2
3
4
5
6
7
8
9
|
public class StartupLauncher extends BroadcastReceiver { @Override public void onReceive( final Context ctx, Intent intent) { AlarmManager alarmManager = (AlarmManager) ctx.getApplicationContext().getSystemService(Context.ALARM_SERVICE); Intent intent = new Intent( "com.yourpackage.HOURLY_CHECK" ); PendingIntent notificationIntent = PendingIntent.getBroadcast(ctx.getApplicationContext(), 1 , intent, 0 ); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 0 , TimeUnit.MILLISECONDS.convert( 60 , TimeUnit.MINUTES), notificationIntent); } } |
Почему бы не сделать это с ScheduledExecutorService ? Потому что как только вы запланируете Runnable
, ваш BroadcastReceiver
умирает, а исполнитель умирает вместе с ним, поэтому этот runnable никогда не вызывается.
Теперь у вас есть запланированный сигнал тревоги, где вы выполняете свою фактическую логику:
1
2
3
4
5
6
|
public class Notifier extends BroadcastReceiver { @Override public void onReceive(Context ctx, Intent intent) { // ... } } |
Конечно, вы можете иметь один BroadcastReceiver
и различать в зависимости от цели, но я думаю, что это чище.
В целом, этот процесс может быть сложным — как это обычно бывает с Android, к сожалению.
Ссылка: | Планирование повторных задач в Android от нашего партнера по JCG Божидара Божанова в блоге на техническом блоге Божо . |