Service прекращает свою работу через некоторое время
Для определения геолокации в фоновом режиме решил использовать service, который работает некоторое время(~10-20 секунд), затем его работа прекращается работой метода onDestroy.
MyService.java
package ru.geokrasnodar.gk_tracker;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.GeomagneticField;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.widget.Toast;
public class MyService extends Service {
private static final int MINUTES = 1000 * 60 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
Context mContext;
private boolean isGpsEnabled = false;
private boolean isNetworkEnabled = false;
private GeomagneticField geoField;
private double latitude = 0.0;
private double longitude = 0.0;
@Override
public void onCreate() {
System.out.println("onCreate");
super.onCreate();
mContext = getApplicationContext();
if (locationManager == null) {
locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); //Получить сервис определения местоположения
}
getCurrentLocation();
}
private void getCurrentLocation() { // получить текущее местоположение
System.out.println("getCurrentLocation");
try {
assert locationManager != null;
isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
ex.printStackTrace();
}
if (!isGpsEnabled && !isNetworkEnabled) {
showSettingsAlert();
}
listener = new MyLocationListener();
try {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 0, listener); //обновить данные gps провайдера
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 2000, 0, listener);//обновить данные network провайдера
} catch (SecurityException e) {
e.printStackTrace();
}
}
private void showSettingsAlert() {
System.out.println("showSettAl");
Toast.makeText(mContext, "GPS is disabled in your device. Please Enable it ?", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onStartCommand");
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
System.out.println("onBind");
return null;
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) { //Проверка точности работы определения координат
System.out.println("isBetLoc");
if (currentBestLocation == null) {
return true;
}
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > MINUTES;
boolean isSignificantlyOlder = timeDelta < -MINUTES;
boolean isNewer = timeDelta > 0;
if (isSignificantlyNewer) {
return true;
} else if (isSignificantlyOlder) {
return false;
}
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider());
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
private boolean isSameProvider(String provider1, String provider2) { //Проверка на различия между провайдерами
System.out.println("isSamePr");
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
@Override
public void onDestroy() {
super.onDestroy();
locationManager.removeUpdates(listener);
System.out.println("SERVICE STOPPED");
}
private void setupFinalLocationData(Location mLocation) { // Установка значений широты, долготы и высоты
System.out.println("setFinalLocData");
if (mLocation != null) {
geoField = new GeomagneticField(
Double.valueOf(mLocation.getLatitude()).floatValue(),
Double.valueOf(mLocation.getLongitude()).floatValue(),
Double.valueOf(mLocation.getAltitude()).floatValue(),
System.currentTimeMillis()
);
latitude = mLocation.getLatitude();
longitude = mLocation.getLongitude();
System.out.println(latitude); //Вывод значения широты в консоль
System.out.println(longitude);//Вывод значения долготы в консоль
}
}
public class MyLocationListener implements LocationListener {
public void onLocationChanged(final Location loc) { // При изменении местоположения, данные передаюдся в метод setupFinalLocationData
System.out.println("Location_CHANGED");
if (isBetterLocation(loc, previousBestLocation)) {
setupFinalLocationData(loc);
}
}
public void onProviderDisabled(String provider) {
System.out.println("Prov_disabled");
}
public void onProviderEnabled(String provider) {
System.out.println("prov_enabled");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
System.out.println("statusChanged");
}
}
}
Из активити вызываю таким образом
MainActivity.java
...
@Override
public void onStop() {
super.onStop();
startService(new Intent(this, MyService.class));
}
@Override
protected void onRestart() {
super.onRestart();
stopService(new Intent(this, MyService.class));
}
...
В манифесте прописал так:
AndroidMainfest.XML
...
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
...
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"></service>
...
Где я мог сделать ошибку? Может всё связано с тем, что неправильно вызываю сервис? Заранее большое спасибо за ответ