我最近寫了其中一個,並決定它是不是一個好主意離開後臺服務運行。無論如何,它可能會被操作系統關閉,或者它可能會被操作系統關閉。我所做的是爲引導意圖使用過濾器,然後使用警報管理器設置警報,以便我的應用程序定期重新啓動,然後發送數據。您可以在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()'的評論。
萬分感謝。我已經能夠建立服務,啓動和停止它。我現在必須確保系統不會殺死它,並且根據需要調用它。 – Mark 2010-05-06 15:45:02
請記住,操作系統會定期停止(並重新啓動)您認爲合適的服務:http://developer.android.com/reference/android/app/Service.html#ProcessLifecycle – jscharf 2010-05-06 17:47:56
jscharf,我如何確保該服務被保證被定期調用,並且只在那時運行,直到用戶執行特定的操作來停止呼叫爲止?我正在尋找使用警報,並通過文檔瞭解如何使用它們...... – Mark 2010-05-06 18:25:08