4

I have an application which is using location service in background at every 5 minute of interval. We are using Fusedlocationproviderclient in foreground service. It is working fine when app is in open.

When I put application in background or swipe to kill from background , Foreground service is automatically killed by OS on android 8.0 and higher version.

We are facing problem in samsung note 8 , one plus 5t and red mi devices.

Please let me know How can I implement service which is compatible for all devices.

This is my location service class.

    public class TrackingForgroundService extends Service {


    private final long UPDATE_INTERVAL = (long) 2000;
    private static final long FASTEST_INTERVAL = 2000;

    public BookingTrackingForgroundService() {

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }


    @Override
    public void onCreate() {
        super.onCreate();
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null) {
            String action = intent.getAction();

            switch (action) {
                case ACTION_START_FOREGROUND_SERVICE:
                    startForegroundService();

                    break;
                case ACTION_STOP_FOREGROUND_SERVICE:
                    stopForegroundService();

                    break;
            }
        }
        return START_STICKY;
    }


    private class TimerTaskToGetLocation extends TimerTask {
        @Override
        public void run() {

            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    // Call webservice evry 5 minute
                }
            });

        }
    }


    private void startForegroundService() {

        Log.d(TAG_FOREGROUND_SERVICE, "Start foreground service.");

        context = this;
        startLocationUpdates();
        notify_interval1 = Prefs.with(this).readLong("notify_interval1", 5000);
        mTimer = new Timer();
        mTimer.scheduleAtFixedRate(new TimerTaskToGetLocation(), 15000, notify_interval1);
        mTimer.scheduleAtFixedRate(new TimerTaskToSendCsvFile(), 60000, 1200000);
        prefsPrivate = getSharedPreferences(Constants.prefsKeys.PREFS_PRIVATE, Context.MODE_PRIVATE);
        internet = new NetConnectionService(context);


        Intent notificationIntent = new Intent(this, ActTherapistDashboard.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle(getString(R.string.app_name))
                .setContentText("Geolocation is running")
                .setTicker("Geolocation").setSmallIcon(R.drawable.app_small_icon_white)
                .setContentIntent(pendingIntent);
        Notification notification = builder.build();
        if (Build.VERSION.SDK_INT >= 26) {
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
            channel.setDescription(CHANNEL_DESCRIPTION);
            NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            notificationManager.createNotificationChannel(channel);
        }
        startForeground(SERVICE_ID, notification);
    }

    private void stopForegroundService() {
        stopLocationUpdates();
        Log.d(TAG_FOREGROUND_SERVICE, "Stop foreground service.");
        if (mTimer != null) {
            mTimer.cancel();
        } else {
            mTimer = null;
        }
        // Stop foreground service and remove the notification.
        stopForeground(true);

        // Stop the foreground service.
        stopSelf();
    }




    public static boolean isServiceRunningInForeground(Context context, Class<?> serviceClass) {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (serviceClass.getName().equals(service.service.getClassName())) {
                if (service.foreground) {
                    return true;
                }

            }
        }
        return false;
    }


    private void startLocationUpdates() {
        // create location request object
        mLocationRequest = LocationRequest.create();

        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);


        // initialize location setting request builder object
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        LocationSettingsRequest locationSettingsRequest = builder.build();


        // initialize location service object
        SettingsClient settingsClient = LocationServices.getSettingsClient(this);
        Task<LocationSettingsResponse> task = settingsClient.checkLocationSettings(locationSettingsRequest);
        task.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
            @Override
            public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                registerLocationListner();
            }
        });


    }


    private void registerLocationListner() {
        locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                super.onLocationResult(locationResult);
                onLocationChanged(locationResult.getLastLocation());
            }
        };

      //location permission
        LocationServices.getFusedLocationProviderClient(this).requestLocationUpdates(mLocationRequest, locationCallback, null);

    }


    private void onLocationChanged(Location location) {

        if (location != null) {
            latitude = location.getLatitude();
            longitude = location.getLongitude();
            latitudeTemp = latitude;
            longitudeTemp = longitude;
        }

    }



}       
  • Why cannot you use JobSchedulers ? For service to keep running in Android Oreo we need to show notifications – Rahul Patil Dec 11 '18 at 05:53
  • @Rahul Patil JobSchedulers is not work in when the device is in sleep mode or doze mode. – Jenis Kasundra Dec 11 '18 at 05:58
  • A foreground service is not assured to keep the Service resident forever. It just puts it lower on the to-kill priority chain. – Gabe Sechan Dec 11 '18 at 06:01
  • @RahulPatil Thank for quick response. Previously we have used jobschduler but it was not working in Locking screen and Doze mode. That is the reason we switched from job scheduler to Foreground service with Notification. – user2617850 Dec 11 '18 at 06:02
  • @GabeSechan - Thanks for sharing knowledge. Which is best solution to fix my issue except foreground service? – user2617850 Dec 11 '18 at 06:04
  • there is alarm manager , work manager – Rahul Patil Dec 11 '18 at 06:07
  • @RahulPatil - We have used alarm manager with JobSchedulers but not working in lock screen and doze mode. We need to uninstall application and start again to release from Doze mode. – user2617850 Dec 11 '18 at 06:11

1 Answers1

1

Please see answer here to a similar question and the linked site dontkillmyapp which provides a very useful summary for developers to help understand this issue across different handset manufacturers and Android OS versions.

Jadent
  • 974
  • 8
  • 14