I'm trying to build an app that uses some packages as Location (https://pub.dev/packages/location) and Compass (https://pub.dev/packages/flutter_compass) and keep a background service tracking user location. Everything works fine until I start the service to track the location.
With the service active the whole app never stops, for example, when I close the app without service the compass stops too, but with the service running, compass keeps running too. Actually it returns a error "Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: hemanthraj/flutter_compass". The same thing happens with location: "Tried to send a platform message to Flutter, but FlutterJNI was detached from native C++. Could not send. Channel: lyokone/locationstream". After this even if I open again the project it don't work anymore... I'm trying to make a service totally independent from rest of project.
I'll show you the service implementation (Android)
public class CompassApplication extends FlutterApplication {
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("messages", "Messages", NotificationManager.IMPORTANCE_LOW);
NotificationManager manager = getSystemService(NotificationManager.class);
if (manager != null) {
manager.createNotificationChannel(channel);
}
}
}
}
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine)
val intent = Intent(this, LocationService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent)
} else {
startService(intent)
}
}
}
public class LocationService extends Service {
static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10 * 60 * 1000; // 10 minutes
static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;
private LocationRequest mLocationRequest;
private FusedLocationProviderClient mFusedLocationClient;
private LocationCallback mLocationCallback;
@Override
public void onCreate() {
super.onCreate();
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mLocationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
onNewLocation(locationResult.getLastLocation());
}
};
createLocationRequest();
getLastLocation();
requestLocationUpdates();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "messages")
.setSmallIcon(R.mipmap.ic_launcher_foreground);
startForeground(101, builder.build());
}
}
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private void getLastLocation() {
try {
mFusedLocationClient.getLastLocation()
.addOnCompleteListener(task -> {
if (task.isSuccessful() && task.getResult() != null) {
onNewLocation(task.getResult());
}
});
} catch (SecurityException ignored) {}
}
public void requestLocationUpdates() {
Utils.setRequestingLocationUpdates(this, true);
startService(new Intent(getApplicationContext(), LocationUpdatesService.class));
try {
mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
} catch (SecurityException unlikely) {
Utils.setRequestingLocationUpdates(this, false);
}
}
private void onNewLocation(Location location) {
// TODO: deal with current location
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Another problem is even when I don't close the app, it is draining a lot of battery. Thanks!