Я недавно написал один из них и решил, что не стоит оставлять фоновую службу запущенной. Возможно, он все равно будет отключен операционной системой, или это может быть так. Я использовал фильтр для цели загрузки, а затем установил тревогу с помощью диспетчера тревог, чтобы мое приложение перезапускалось через равные промежутки времени, а затем оно отправляло данные. Хорошую информацию об услугах и диспетчере аварийных сигналов вы можете найти в документации Android.
Сначала я создал широковещательный приемник, который просто запускает мой сервис при открытии интернет-соединения (мне интересно только, если есть соединение - вы можете также захотеть отфильтровать событие загрузки). Приемник запуска должен быть недолговечным, поэтому просто запустите свой сервис:
public class LaunchReceiver extends BroadcastReceiver {
public static final String ACTION_PULSE_SERVER_ALARM =
"com.proofbydesign.homeboy.ACTION_PULSE_SERVER_ALARM";
@Override
public void onReceive(Context context, Intent intent) {
AppGlobal.logDebug("OnReceive for " + intent.getAction());
AppGlobal.logDebug(intent.getExtras().toString());
Intent serviceIntent = new Intent(AppGlobal.getContext(),
MonitorService.class);
AppGlobal.getContext().startService(serviceIntent);
}
}
В манифесте у меня есть:
<receiver
android:name="LaunchReceiver"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
<intent-filter>
<action android:name="com.proofbydesign.homeboy.ACTION_PULSE_SERVER_ALARM" />
</intent-filter>
</receiver>
Обратите внимание, что у меня есть фильтр для моей собственной тревоги, который позволяет мне отключить службу и перезапустить ее после того, как она выполнит свою работу.
Верх моей службы мониторинга выглядит так:
public class MonitorService extends Service {
private LoggerLoadTask mTask;
private String mPulseUrl;
private HomeBoySettings settings;
private DataFile dataFile;
private AlarmManager alarms;
private PendingIntent alarmIntent;
private ConnectivityManager cnnxManager;
@Override
public void onCreate() {
super.onCreate();
cnnxManager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
alarms = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intentOnAlarm = new Intent(
LaunchReceiver.ACTION_PULSE_SERVER_ALARM);
alarmIntent = PendingIntent.getBroadcast(this, 0, intentOnAlarm, 0);
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// reload our data
if (mPulseUrl == null) {
mPulseUrl = getString(R.string.urlPulse);
}
AppGlobal.logDebug("Monitor service OnStart.");
executeLogger();
}
executeLogger запускает asyncTask, что, вероятно, является излишней осторожностью (это было только мое третье приложение для Android). AsyncTask захватывает данные GPS, отправляет их в Интернет и, наконец, устанавливает следующий сигнал тревоги:
private void executeLogger() {
if (mTask != null
&& mTask.getStatus() != LoggerLoadTask.Status.FINISHED) {
return;
}
mTask = (LoggerLoadTask) new LoggerLoadTask().execute();
}
private class LoggerLoadTask extends AsyncTask<Void, Void, Void> {
// TODO: create two base service urls, one for debugging and one for live.
@Override
protected Void doInBackground(Void... arg0) {
try {
// if we have no data connection, no point in proceeding.
NetworkInfo ni = cnnxManager.getActiveNetworkInfo();
if (ni == null || !ni.isAvailable() || !ni.isConnected()) {
AppGlobal
.logWarning("No usable network. Skipping pulse action.");
return null;
}
// / grab and log data
} catch (Exception e) {
AppGlobal.logError(
"Unknown error in background pulse task. Error: '%s'.",
e, e.getMessage());
} finally {
// always set the next wakeup alarm.
int interval;
if (settings == null
|| settings.getPulseIntervalSeconds() == -1) {
interval = Integer
.parseInt(getString(R.string.pulseIntervalSeconds));
} else {
interval = settings.getPulseIntervalSeconds();
}
long timeToAlarm = SystemClock.elapsedRealtime() + interval
* 1000;
alarms.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, timeToAlarm,
alarmIntent);
}
return null;
}
}
Я заметил, что я не вызываю stopSelf () после установки будильника, поэтому моя служба будет бездействовать, если не отключена операционной системой. Поскольку я единственный пользователь этого приложения, это не имеет значения, кроме общедоступного приложения, идея заключается в том, что вы устанавливаете будильник на следующий интервал, а затем StopSelf закрывается.
Обновление См. Комментарий @juozas об использовании 'alarms.setRepeating ()'.