3 回答

TA貢獻1783條經驗 獲得超4個贊
您需要創建一個單獨的類,該類是該類的子Service類。
您的主要應用程序應該可以調用startService并stopService啟動后臺進程。還有上下文類中的一些其他有用的調用來管理服務:

TA貢獻1780條經驗 獲得超4個贊
我最近寫了其中一個,并認為讓后臺服務運行不是一個好主意。它可能會被操作系統關閉,或者可能是。我所做的是使用過濾器作為啟動意圖,然后使用警報管理器設置警報,以便我的應用程序定期重新啟動,然后發送數據。您可以在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。

TA貢獻1798條經驗 獲得超7個贊
另外我認為可以更好地擴展你的BroadcastReceiver中的WakefulBroadcastReceiver并使用它的靜態方法startWakefulService(android.content.Context context,android.content.Intent intent),因為它保證你的服務不會被os關閉。
public class YourReceiver extends WakefulBroadcastReceiver {
? ? @Override
? ? public void onReceive(Context context, Intent intent) {
? ? ? ? Intent service = new Intent(context, YourService.class);
? ? ? ? startWakefulService(context, service);
? ? }
}
- 3 回答
- 0 關注
- 734 瀏覽
添加回答
舉報