java Cordova 安卓后台插件在5分钟后被杀死
我正在开发一款带有位置跟踪功能的Cordova Android/iOS应用程序。 为了不断更新位置,我使用了一个后台地理位置插件(https://github.com/mauron85/cordova-plugin-background-geolocation)
这个插件创建了一个服务来监听system LocationManager。 当系统得到位置更新时,插件触发事件链/一些计算,直到到达我在cordova应用程序中使用的最后一个JavaScript回调
它在iOS上运行得很好,从来不会被杀死,但我在安卓系统上遇到了麻烦,当你将手机置于睡眠状态(锁定屏幕)而应用程序不在前台时(假设你在锁定前切换到另一个应用程序)。 如果您移动(从而获得位置更新),该过程将保持运行。但是,如果您静止超过5分钟,后台位置服务将停止,不再向我的JS回调传递更多位置。 在此之后,如果您再次移动,服务将保持停止状态,直到您解锁屏幕并将应用程序带到前台
这很烦人,因为我的应用程序完全基于这种“走走停停”模式,需要在锁定的屏幕下运行(手机在口袋里),我的服务器会检查位置的时间戳,以筛选哪些位置被认为是在线的,哪些位置是新位置,哪些位置不是。 因此,我基本上需要两件事:当用户再次移动时,能够重新启动位置跟踪,如果用户空闲,则继续向我的服务器发送几个位置
根据我的研究,我最终创建了一个线程,该线程休眠60秒并循环返回,每分钟调用后台服务的handle position函数(该函数将位置发送到前台JS)。 不幸的是,我是新的科尔多瓦插件,并没有设法让它的工作。尝试访问应用程序上下文的systemService时出现空指针异常:
E/AndroidRuntime( 4627): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object 安卓.content.Context.getSystemService(java.lang.String)' on a null object reference
E/AndroidRuntime( 4627): at 安卓.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 安卓.location.Location;
import 安卓.content.Context;
import 安卓.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 ?
};
}
除此之外,我发现这个解决方案真的很难看
那么,保持此服务运行的最佳方法是什么?是否有在后台保持长时间运行的空闲进程的最佳实践
非常感谢
# 1 楼答案
尝试使用此插件的“stopOnTerminate”和“startOnBoot”选项。 这将帮助你在后台不断获得更新,即使应用程序被操作系统杀死
还请记住,您的callbk函数不会始终执行,因为如果您的应用程序被系统终止,这将终止您的活动和callbk。 因此,尝试使用插件的url选项,即使在后台也可以将您的位置发布到服务器上