亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Android:如何定期向服務器發送位置

Android:如何定期向服務器發送位置

皈依舞 2019-09-19 10:52:42
我正在運行一項Web服務,允許用戶記錄他們的旅行(有點像Google的MyTracks)作為更大的應用程序的一部分。問題在于,當用戶開始旅行或結束旅行時,很容易將數據(包括坐標和其他項目)傳遞到服務器。作為一個新手,我不知道如何設置一個后臺服務,每隔(預定)一段時間(最少3分鐘,最多1小時)發送一次位置更新,直到用戶標記旅行結束,或直到預設的時間量過去了。一旦從電話開始旅行,服務器將以電話的輪詢周期作為響應,作為更新之間的間隔。這部分工作,因為我可以在手機上顯示響應,我的服務器注冊用戶的操作。類似地,在關閉行程請求時,行程在服務器端關閉。但是,當我嘗試從StartTrack活動內部啟動定期跟蹤方法時,使用requestLocationUpdates(String provider,long minTime,float minDistance,LocationListener listener),其中minTime是來自服務器的輪詢周期,它只是不起作用,我'我沒有得到任何錯誤。所以這意味著我在這一點上一無所知,從來沒有使用過Android。我在這里看到很多關于使用后臺服務與處理程序,待定意圖和其他類似東西的帖子,但我真的不明白該怎么做。我希望用戶在更新過程中在手機上做其他的事情,所以如果你們可以指點我的教程,說明如何實際編寫后臺服務(也許這些作為單獨的類運行?)或其他方式這樣做,那將是偉大的。
查看完整描述

3 回答

?
慕娘9325324

TA貢獻1783條經驗 獲得超4個贊

您需要創建一個單獨的類,該類是該類的子Service類。

您的主要應用程序應該可以調用startService并stopService啟動后臺進程。還有上下文類中的一些其他有用的調用來管理服務:


查看完整回答
反對 回復 2019-09-19
?
Helenr

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。


查看完整回答
反對 回復 2019-09-19
?
元芳怎么了

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);

? ? }

}


查看完整回答
反對 回復 2019-09-19
  • 3 回答
  • 0 關注
  • 734 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號