I am developing an Android / iOS app from Cordova with some location tracking. To constantly update the location, I use the background geolocation plugin ( https://github.com/mauron85/cordova-plugin-background-geolocation ).
This plugin creates a service that listens for the LocationManager system. When the system receives the location update, the plugin starts the event chain / some calculations until it reaches the final JavaScript callback that I use in my Cordova application.
It works fine on iOS and will never be killed, but I have problems with Android when you put the phone into sleep mode (lock the screen) without an application in the foreground (let's say you switched to another application before blocking), if you moving around (and therefore getting location updates), the process continues to work. But if you have not been working for more than 5 minutes, the background location service stops and my locations are no longer passed to my JS callback. After that, if you move again, the service will remain stopped until you unlock the screen and put the application in the foreground.
This is annoying because my application is completely based on this stop and start pattern, should be run under a locked screen (phone in your pocket), and my server will check the timestamp of the locations to filter out who is considered active and active with a new location and who no. So I basically need 2 things: to be able to restart location tracking when the user is moving again, and to continue sending multiple locations to my server if the user is not in use.
, , 60 , ( JS). , Cordova . 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);
isEnabled = true;
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(){
};
@Override
protected void startRecording(){
};
@Override
protected void stopRecording(){
};
}
, , ...
? , ?