How can I get continuous location updates in Android like in Google Maps?

To get continiuos location update, you can refer to the above provided answers .

But You can also make use of LocationServices which is faster than other approaches and much easy and efficient to get location.

This approach is quit long but kindly follow all the provided steps

So let me provide a brief working :

  1. Add these two dependencies in your gradle app file

    implementation 'com.google.android.gms:play-services-maps:17.0.0' implementation 'com.google.android.gms:play-services-location:17.0.0'

  2. Add these permissions in the manifest file outside applicationtag

  3. Declare variable outside onCreate

    private FusedLocationProviderClient fusedLocationClient; private LocationRequest mLocationRequest; private LocationCallback mlocationCallback; private LocationSettingsRequest.Builder builder; private static final int REQUEST_CHECK_SETTINGS = 102;

  4. Now inside onCreate :

    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this); fetchLastLocation(); mlocationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { if (locationResult == null) { return; } for (Location location : locationResult.getLocations()) { // Update UI with location data // ... Log.e("CONTINIOUSLOC: ", location.toString()); } }; };

    mLocationRequest = createLocationRequest(); builder = new LocationSettingsRequest.Builder() .addLocationRequest(mLocationRequest); checkLocationSetting(builder);

  5. No define fetchLastLocation method

    private void fetchLastLocation() {

         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                 // TODO: Consider calling
                 //    Activity#requestPermissions
                 // here to request the missing permissions, and then overriding
                 //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                 //                                          int[] grantResults)
                 // to handle the case where the user grants the permission. See the documentation
                 // for Activity#requestPermissions for more details.
    

    // Toast.makeText(MainActivity.this, "Permission not granted, Kindly allow permission", Toast.LENGTH_LONG).show(); showPermissionAlert(); return; } } fusedLocationClient.getLastLocation() .addOnSuccessListener(this, new OnSuccessListener() { @Override public void onSuccess(Location location) { // Got last known location. In some rare situations this can be null. if (location != null) { // Logic to handle location object Log.e("LAST LOCATION: ", location.toString()); // You will get your last location here } } });

     }
    
  6. Now define other two method for permission request

    @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case 123: { // If request is cancelled, the result arrays are empty. if (grantResults[0] == PackageManager.PERMISSION_DENIED) { // permission was denied, show alert to explain permission showPermissionAlert(); }else{ //permission is granted now start a background service if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) { fetchLastLocation(); } } } } }

     private void showPermissionAlert(){
         if (ActivityCompat.checkSelfPermission(MainHomeActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                 && ActivityCompat.checkSelfPermission(MainHomeActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
             ActivityCompat.requestPermissions(MainHomeActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 123);
         }
     }
    
  7. now define createLocationRequest method and checkLocationSetting method :

    protected LocationRequest createLocationRequest() { LocationRequest mLocationRequest = LocationRequest.create(); mLocationRequest.setInterval(30000); mLocationRequest.setFastestInterval(10000); mLocationRequest.setSmallestDisplacement(30); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); return mLocationRequest; }

    private void checkLocationSetting(LocationSettingsRequest.Builder builder) {

         SettingsClient client = LocationServices.getSettingsClient(this);
         Task<LocationSettingsResponse> task = client.checkLocationSettings(builder.build());
    
         task.addOnSuccessListener(this, new OnSuccessListener<LocationSettingsResponse>() {
             @Override
             public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
                 // All location settings are satisfied. The client can initialize
                 // location requests here.
                 // ...
                 startLocationUpdates();
                 return;
             }
         });
    
         task.addOnFailureListener(this, new OnFailureListener() {
             @Override
             public void onFailure(@NonNull final Exception e) {
                 if (e instanceof ResolvableApiException) {
                     // Location settings are not satisfied, but this can be fixed
                     AlertDialog.Builder builder1 = new AlertDialog.Builder(mContext);
                     builder1.setTitle("Continious Location Request");
                     builder1.setMessage("This request is essential to get location update continiously");
                     builder1.create();
                     builder1.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                         @Override
                         public void onClick(DialogInterface dialog, int which) {
                             ResolvableApiException resolvable = (ResolvableApiException) e;
                             try {
                                 resolvable.startResolutionForResult(MainHomeActivity.this,
                                         REQUEST_CHECK_SETTINGS);
                             } catch (IntentSender.SendIntentException e1) {
                                 e1.printStackTrace();
                             }
                         }
                     });
                     builder1.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                         @Override
                         public void onClick(DialogInterface dialog, int which) {
                             Toast.makeText(mContext, "Location update permission not granted", Toast.LENGTH_LONG).show();
                         }
                     });
                     builder1.show();
                 }
             }
         });
    
     }
    
     @Override
     protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
         if (requestCode == REQUEST_CHECK_SETTINGS) {
             if (resultCode == RESULT_OK) {
                 // All location settings are satisfied. The client can initialize
                 // location requests here.
                  startLocationUpdates();
             }
             else {
                 checkLocationSetting(builder);
             }
         }
     }
    
  8. now atlast define startLocationUpdates and stopLocationUpdates method :

    public void startLocationUpdates() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // Activity#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for Activity#requestPermissions for more details. return; } } fusedLocationClient.requestLocationUpdates(mLocationRequest, mlocationCallback, null /* Looper */); }

    private void stopLocationUpdates() { fusedLocationClient.removeLocationUpdates(mlocationCallback); }

Note : Replace context with your class context and call stopLocationUpdates() inside onDestroy method of your class

Note : For any futher information or doubt you can refer to :

https://developer.android.com/training/location/retrieve-current https://developer.android.com/training/location/change-location-settings https://developer.android.com/training/location/receive-location-updates

You will get your location in Logcat.

Hope this will hope you or somebody else !


I believe rather than reinventing the wheel, you can use one of the third party libraries that are easy to implement and in this case, battery efficient. One of the library I found is SmartLocation. You can add the following dependency in your build.gradle (app) to start using the library.

compile 'io.nlopez.smartlocation:library:3.2.9'

After adding the dependency, you should rebuild the project to get the references.

As an example you can try the following code in your Activity.

Button start_btn=(Button)findViewById(R.id.start_location_streaming);

Context context = start_btn.getContext();

Handler handler = new Handler();

start_btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        SmartLocation.with(context).location().start(locationListener);
    }
});

OnLocationUpdatedListener locationListener = new OnLocationUpdatedListener({
    @Override
    public void onLocationUpdated(Location location) {
        double lat = location.getLatitude();
        double lng = location.getLongitude();
        handler.postDelayed(locationRunnable,8000);
    }
});

Runnable locationRunnable = new Runnable({
    @Override
    public void run() {
        SmartLocation.with(context).location().start(locationListener);
    }
});

You can stop location tracking in onStop() method

@Override
public void onStop() {
    SmartLocation.with(context).location().stop();
    super.onStop();
}

SmartLocation library will give you more than what is expected, just try that once.

Note: Make sure your application does have ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION (both) to have accurate results. Don't forget to ask for permissions at runtime for Android 6.0 and above.


Use Fused location provider in Android set your interval in that:

For an example create your activity like this:

public class LocationActivity extends Activity implements
        LocationListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    private static final String TAG = "LocationActivity";
    private static final long INTERVAL = 1000 * 10;
    private static final long FASTEST_INTERVAL = 1000 * 5;
    Button btnFusedLocation;
    TextView tvLocation;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Location mCurrentLocation;
    String mLastUpdateTime;

    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate ...............................");
        //show error dialog if GoolglePlayServices not available
        if (!isGooglePlayServicesAvailable()) {
            finish();
        }
        createLocationRequest();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();

        setContentView(R.layout.activity_main);
        tvLocation = (TextView) findViewById(R.id.tvLocation);

        btnFusedLocation = (Button) findViewById(R.id.btnShowLocation);
        btnFusedLocation.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                updateUI();
            }
        });

    }

    @Override
    public void onStart() {
        super.onStart();
        if (mGoogleApiClient.isConnected()) {
            startLocationUpdates();
            Log.d(TAG, "Location update resumed .....................");
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "onStop fired ..............");
        mGoogleApiClient.disconnect();
        Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected());
    }

    private boolean isGooglePlayServicesAvailable() {
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == status) {
            return true;
        } else {
            GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
            return false;
        }
    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
        startLocationUpdates();
    }

    protected void startLocationUpdates() {
        PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
        Log.d(TAG, "Location update started ..............: ");
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.d(TAG, "Connection failed: " + connectionResult.toString());
    }

    @Override
    public void onLocationChanged(Location location) {
        Log.d(TAG, "Firing onLocationChanged..............................................");
        mCurrentLocation = location;
        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
        updateUI();
    }

    private void updateUI() {
        Log.d(TAG, "UI update initiated .............");
        if (null != mCurrentLocation) {
            String lat = String.valueOf(mCurrentLocation.getLatitude());
            String lng = String.valueOf(mCurrentLocation.getLongitude());
            tvLocation.setText("At Time: " + mLastUpdateTime + "\n" +
                    "Latitude: " + lat + "\n" +
                    "Longitude: " + lng + "\n" +
                    "Accuracy: " + mCurrentLocation.getAccuracy() + "\n" +
                    "Provider: " + mCurrentLocation.getProvider());
        } else {
            Log.d(TAG, "location is null ...............");
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopLocationUpdates();
    }

    protected void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient, this);
        Log.d(TAG, "Location update stopped .......................");
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mGoogleApiClient.isConnected()) {
            startLocationUpdates();
            Log.d(TAG, "Location update resumed .....................");
        }
    }
}

Google play services required: