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>
...

Где я мог сделать ошибку? Может всё связано с тем, что неправильно вызываю сервис? Заранее большое спасибо за ответ


Ответы (0 шт):