我正在開發一個科爾多瓦Android/iOS應用程序與一些位置跟蹤。 要不斷更新位置,我使用背景地理位置插件(https://github.com/mauron85/cordova-plugin-background-geolocation)。科爾多瓦Android背景插件5分鐘後死亡
這個插件創建一個服務,該服務監聽系統LocationManager。 當系統獲得位置更新時,插件會觸發一個事件鏈/一些計算,直到它達到我在我的cordova應用程序中使用的最終JavaScript回調。
它可以在iOS上正常工作,並且永遠不會被殺死,但是當您將手機置於睡眠狀態(鎖定屏幕)而未在前臺顯示應用時,我遇到了Android的問題(假設您切換到另一個鎖定前的應用程序)。 如果您移動(從而獲取位置更新),則此過程將繼續運行。但是如果你靜置超過5分鐘,後臺位置服務停止,並且沒有更多位置傳遞給我的JS回調。 在此之後,如果您再次移動服務停止,直到您解鎖屏幕並將應用程序放到前臺。
這很煩人,因爲我的應用程序完全基於此停止和去模式,需要在鎖定屏幕(口袋裏的電話)下運行,並且我的服務器檢查位置的時間戳以過濾誰被視爲在線和活躍在一個新的地點,誰不是。 所以我基本上需要2件事:當用戶再次移動時能夠重新啓動位置跟蹤,並且如果用戶空閒,則繼續向我的服務器發送一些位置。
從我的研究中,我最終創建了一個睡眠時間爲60s並回退的線程,每分鐘調用我的後臺服務(將位置發送給前端JS)的句柄位置函數。 不幸的是,我是Cordova Plugin的新手,並沒有設法讓它工作。我有一個空指針異常,同時試圖訪問該應用上下文的systemService:
E/AndroidRuntime(4627): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
E/AndroidRuntime(4627): at android.content.ContextWrapper.getSystemService(ContextWrapper.java:583)
E/AndroidRuntime(4627): at com.tenforwardconsulting.cordova.bgloc.ForcedUpdateLocation.handleLocationFromOutside(ForcedUpdateLocation.java:12)
E/AndroidRuntime(4627): at com.tenforwardconsulting.cordova.bgloc.BackgroundGeolocationPlugin$3.run(BackgroundGeolocationPlugin.java:266)
E/AndroidRuntime(4627): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
E/AndroidRuntime(4627): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
E/AndroidRuntime(4627): at java.lang.Thread.run(Thread.java:818)
插件的啓動功能:
public ComponentName startBackgroundService() {
if (isEnabled) { return null; }
Class serviceProviderClass = null;
try {
serviceProviderClass = ServiceProvider.getClass(config.getServiceProvider());
} catch (ClassNotFoundException e) {
callbackContext.error("Configuration error: provider not found");
return null;
}
Activity activity = this.cordova.getActivity();
Log.d(TAG, "Starting bg service");
registerActionReceiver();
locationServiceIntent = new Intent(activity, serviceProviderClass);
locationServiceIntent.addFlags(Intent.FLAG_FROM_BACKGROUND);
// locationServiceIntent.putExtra("config", config.toParcel().marshall());
locationServiceIntent.putExtra("config", config);
isEnabled = true;
//Start a thread to send a position every 60s
final ForcedUpdateLocation ful = new ForcedUpdateLocation();
cordova.getThreadPool().execute(new Runnable(){
public void run(){
try {
while(isEnabled){
Thread.sleep(3000);
Log.d(TAG, "Force location sent");
ful.handleLocationFromOutside();
}
} catch (InterruptedException e){
Log.d(TAG, "EXCEPTION ! Force location sent", e);
}
}
});
return activity.startService(locationServiceIntent);
}
我的存根「ForcedUpdateLocation」服務,擴展了該插件的LocationService(呼籲handleLocation):
package com.tenforwardconsulting.cordova.bgloc;
import android.location.Location;
import android.content.Context;
import android.location.LocationManager;
public class ForcedUpdateLocation extends com.tenforwardconsulting.cordova.bgloc.AbstractLocationService {
public void handleLocationFromOutside(){
LocationManager locationMangerWakeThread = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location location = locationMangerWakeThread.getLastKnownLocation(locationMangerWakeThread.GPS_PROVIDER);
handleLocation(location);
}
@Override
protected void cleanUp(){
//Stub
};
@Override
protected void startRecording(){
//Duh
};
@Override
protected void stopRecording(){
//Wouf ?
};
}
除了事實我堅持這一點,我覺得這個解決方案真的很醜...
那麼保持此服務運行的最佳方式是什麼?有沒有最佳做法,以保持長時間在後臺運行閒置進程?
非常感謝