Search code examples
androidservicegcm-network-manager

How to create a background Service with a interval time


In my project I need to :

  1. Get the User Location(Lat and Long).
  2. Send it to my API.
  3. Receive the response.

All this between 15 seconds. I already know how to do those things but it has to be on background. I was using JobSchedule which is perfect and it handles everything, Connection, Network State, and time, but the problem is, it's not compatible with old versions > 21! The best approach would be GCMNetworkManager under these conditions(Background request and Location)? Thanks!


Solution

  • This is how you do it:

     <service
            android:name=".GeoLocationService"
            android:exported="false" />
    

    Service:

    import android.Manifest;
    import android.app.Service;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.location.Location;
    import android.location.LocationManager;
    import android.os.Build;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.support.v4.content.ContextCompat;
    import android.support.v4.content.LocalBroadcastManager;
    
    public class GeoLocationService extends Service {
    
    public static final String LOCATION_UPDATE = 
    GeoLocationService.class.getSimpleName();
    public static final String LOCATION_DATA = "location_data";
    
    private static final String TAG = GeoLocationService.class.getSimpleName();
    private LocationManager mLocationManager = null;
    private static final int LOCATION_INTERVAL = 10000; // 30 Seconds
    private static final float LOCATION_DISTANCE = 1f; // meters = 100 m
    
        public static void start(Context context) {
            context.startService(new Intent(context, GeoLocationService.class));
        }
    
        public static void stop(Context context) {
            context.stopService(new Intent(context, GeoLocationService.class));
        }
    
        private class LocationListener implements android.location.LocationListener {
            Location mLastLocation;
    
            public LocationListener(String provider) {
                mLastLocation = new Location(provider);
            }
    
            @Override
            public void onLocationChanged(Location location) {
                mLastLocation.set(location);
    
                Log.i(TAG, "Location Changed! " + location.getLatitude() + " " + location.getLongitude());
                Intent intent = new Intent(LOCATION_UPDATE);
                intent.putExtra(LOCATION_DATA, location);
                LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
            }
    
            @Override
            public void onProviderDisabled(String provider) {
    
            }
    
            @Override
            public void onProviderEnabled(String provider) {
    
            }
    
            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
            }
        }
    
        LocationListener[] mLocationListeners = new LocationListener[]{
                new LocationListener(LocationManager.GPS_PROVIDER),
                new LocationListener(LocationManager.NETWORK_PROVIDER)
        };
    
        @Override
        public IBinder onBind(Intent arg0) {
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            super.onStartCommand(intent, flags, startId);
            return START_STICKY;
        }
    
        @Override
        public void onCreate() {
            initializeLocationManager();
            try {
                mLocationManager.requestLocationUpdates(
                        LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                        mLocationListeners[1]);
            } catch (SecurityException ex) {
    
            } catch (IllegalArgumentException ex) {
    
            }
            try {
                mLocationManager.requestLocationUpdates(
                        LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                        mLocationListeners[0]);
            } catch (SecurityException ex) {
    
            } catch (IllegalArgumentException ex) {
    
            }
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            if (mLocationManager != null) {
                for (int i = 0; i < mLocationListeners.length; i++) {
                    try {
                        if (checkLocationPermission()) {
                            mLocationManager.removeUpdates(mLocationListeners[i]);
                        }
                    } catch (Exception ex) {
    
                    }
                }
            }
        }
    
        private void initializeLocationManager() {
            if (mLocationManager == null) {
                mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
            }
        }
    
        private boolean checkLocationPermission() {
            if (Build.VERSION.SDK_INT < 23)
                return true;
    
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
    
            return ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
        }
    }
    

    And In your Activity:

    private BroadcastReceiver mLocationUpdateMessageReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Location location = intent.getParcelableExtra(GeoLocationService.LOCATION_DATA);
            //SEND LOCATION TO YOUR API HERE
        }
    };
    
    @Override
    protected void onResume() {
        super.onResume();
        GeoLocationService.start(this);
        LocalBroadcastManager.getInstance(context).registerReceiver(mLocationUpdateMessageReceiver,
                new IntentFilter(GeoLocationService.LOCATION_UPDATE));
    }
    
    
    @Override
    protected void onPause() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mLocationUpdateMessageReceiver);
        GeoLocationService.stop(this);
        super.onPause();
    }