javaandroidandroid-service

How do I get the last known location for the first time I execute a service?


The thing is that I'm trying on the emulator, and it works but only once I press the "send location to device" on the emulator but before that I don't have the chance to get the location....How do I get the location for the first time using this service?. I don't have a real device right know and the emulator is my only way of testing this for now.....I tried to send a 0,0 at first to see if that would trigger a location update but it's not working as well......any ideas?

@SuppressWarnings("MissingPermission")
public class GPSService extends Service {

    private LocationListener listener;
    private LocationManager locationManager;
    private String lastKnownLatitude;
    private String lastKnownLongitude;
    private Boolean isFirstTime=true;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }

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



        broadcastLocation("0","0");


        listener= new LocationListener() {
            @Override
             public void onLocationChanged(Location location) {

                //To transfer the data to the main activity I use broadcast receiver in the main activity, using an intent filter location_update
                 Intent intentSendLocationMainActivity = new Intent("location_update");
                lastKnownLatitude=""+location.getLatitude();
                lastKnownLongitude=""+location.getLongitude();
                Log.d("LOCATION-UPDATE",lastKnownLatitude+" long:"+lastKnownLongitude);
                broadcastLocation(lastKnownLatitude,lastKnownLongitude);
            }

            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) {
                Log.d("GPS-Stat-Changed",s);
            }

            @Override
            public void onProviderEnabled(String s) {
                Log.d("GPS-Provider-Enabled",s);
            }

            @Override
            public void onProviderDisabled(String s) {
                Intent activateGPSIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                activateGPSIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(activateGPSIntent);

            }
        };

        locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        //noinspection MissingPermission, listen for updates every 3 seconds
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,5000,0,listener);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("ClearFromRecentService", "Service Started");
        Log.d("LAST_LAT_AND_LONG",lastKnownLatitude+" "+lastKnownLongitude);

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("ClearFromRecentService", "Service Destroyed, Removing update location listener");
        //unregistering the listener
        /*if(locationManager != null){
            locationManager.removeUpdates(listener);
        }*/

    }

    public void onTaskRemoved(Intent rootIntent) {
        Log.e("ClearFromRecentService", "END");
        //here you can call a background network request to post you location to server when app is killed
        Toast.makeText(getApplicationContext(), "I'm still getting user coordinates", Toast.LENGTH_LONG).show();
        //stopSelf(); //call this method to stop the service
    }

    public void broadcastLocation(String latitude,String longitude){
        Intent intentSendLocationMainActivity = new Intent("location_update");
        intentSendLocationMainActivity.putExtra("latitude",latitude);
        intentSendLocationMainActivity.putExtra("longitude",longitude);
        //I need to differentiate here if the app is killed or not to send the location to main activity or to a server
        sendBroadcast(intentSendLocationMainActivity);
    }
}

EDIT: This is the complete service working. For the first time it gets the coordinates with the getLastKnownLocation() and the on sucesive times with the listener onLocationChanged()

@SuppressWarnings("MissingPermission")
public class GPSService extends Service {

    private LocationListener listener;
    private LocationManager locationManager;
    private String lastKnownLatitude;
    private String lastKnownLongitude;
    private Boolean isFirstTime=true;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {

        return null;
    }

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

        listener= new LocationListener() {
            @Override
             public void onLocationChanged(Location location) {

                //To transfer the data to the main activity I use broadcast receiver in the main activity, using an intent filter location_update
                 Intent intentSendLocationMainActivity = new Intent("location_update");
                lastKnownLatitude=""+location.getLatitude();
                lastKnownLongitude=""+location.getLongitude();
                Log.d("LOCATION-UPDATE",lastKnownLatitude+" long:"+lastKnownLongitude);
                broadcastLocation(lastKnownLatitude,lastKnownLongitude);
            }

            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) {
                Log.d("GPS-Stat-Changed",s);
            }

            @Override
            public void onProviderEnabled(String s) {
                Log.d("GPS-Provider-Enabled",s);
            }

            @Override
            public void onProviderDisabled(String s) {
                Intent activateGPSIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                activateGPSIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(activateGPSIntent);

            }
        };

        locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        //noinspection MissingPermission, listen for updates every 3 seconds
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,5000,0,listener);


        Map<String, String> coordinates=getLastKnownLocation(locationManager);
        broadcastLocation(coordinates.get("latitude"),coordinates.get("longitude"));
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("ClearFromRecentService", "Service Started");
        Log.d("LAST_LAT_AND_LONG",lastKnownLatitude+" "+lastKnownLongitude);

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d("ClearFromRecentService", "Service Destroyed, Removing update location listener");
        //unregistering the listener
        /*if(locationManager != null){
            locationManager.removeUpdates(listener);
        }*/

    }

    public void onTaskRemoved(Intent rootIntent) {
        Log.e("ClearFromRecentService", "END");
        //here you can call a background network request to post you location to server when app is killed
        Toast.makeText(getApplicationContext(), "I'm still getting user coordinates", Toast.LENGTH_LONG).show();
        //stopSelf(); //call this method to stop the service
    }

    private void broadcastLocation(String latitude,String longitude){
        Intent intentSendLocationMainActivity = new Intent("location_update");
        intentSendLocationMainActivity.putExtra("latitude",latitude);
        intentSendLocationMainActivity.putExtra("longitude",longitude);
        //I need to differentiate here if the app is killed or not to send the location to main activity or to a server
        sendBroadcast(intentSendLocationMainActivity);
    }

    private Map<String, String> getLastKnownLocation(LocationManager lm){

        Location lastKnownLocation=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        String ll=""+lastKnownLocation.getLatitude();
        Map<String, String> coordinates = new HashMap<String, String>();


        // Check everytime this value, it may be null
        if(lastKnownLocation != null){
            coordinates.put("latitude",""+lastKnownLocation.getLatitude());
            coordinates.put("longitude",""+lastKnownLocation.getLongitude());

        }else{
            coordinates.put("latitude","0");
            coordinates.put("longitude","0");
        }

        return coordinates;
    }
}

Solution

  • @Override
    public void onCreate() {
        super.onCreate();
    
        locationManager = (LocationManager) getApplicationContext()
            .getSystemService(Context.LOCATION_SERVICE);
    
        Location lastKnownLocation = locationManager
            .getLastKnownLocation(Locat‌​ionManager.GPS_PROVI‌​DER); 
    
        // Check everytime this value, it may be null
        if(lastKnownLocation != null){
            double latitude = lastKnownLocation.getLatitude();
            double longitude = lastKnownLocation.getLongitude();
            // Use values as you wish
        }
    
        broadcastLocation("0","0");
    
    
        ....
    }