📜 ⬆️ ⬇️

Locating a user using Google Play Services

Good afternoon friends!

The question of determining the location of the user on the maximum number of devices tormented me for about six months. It came even to the bikes described here and here . The point was that there were devices on which the location was not determined, for an unknown reason, but other applications worked quite well. Once again, digging through the code and roving in the expanses of the hum in search of what I was missing, and the implementation, which I have not tried, I came across a fresh article from google manual and, oh gods (!), It worked.

In this article I want to tell you how I used it for my own purposes and give a simple example.
I want the source


The official example shows how to do all this in one activity, since it is important for them to show only the capabilities, and I needed convenience, so I carried everything into a separate class.
')
To get started, you must initialize the instances of the LocationClient and LocationRequest classes. The first is responsible for accessing the main methods of the location API and Geofence, the second serves the LocationClient and is responsible for updating, that is, callbacks are performed through it. Using LocationRequest, as in the example below, you can set update intervals, priority for positioning accuracy, and update intervals.

private LocationRequest mLocationRequest; private LocationClient mLocationClient; private LocationListenerGPServices(final Context context) { mLocationRequest = LocationRequest.create(); mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest.setFastestInterval(FAST_INTERVAL_CEILING_IN_MILLISECONDS); mLocationClient = new LocationClient(context, this, this); } 


Then there are two scenarios: we can take the last known location or request a search for a new one.
In my case, I combine these two options, that is, at the beginning I get the last known location and, if it suits me, I use it, otherwise I request updates. In the code below, after calling the mLocationClient.connect () method, the onConnected (final Bundle bundle) method should work on the GooglePlayServicesClient.ConnectionCallbacks interface, which means that we were able to connect to Google Play Services, i.e. we can now subscribe to a location update.

 public void enableMyLocation() { log("enableMyLocation"); mLocation = null; mLocationClient.connect(); } private boolean useCurrentLocation() { final Location location = mLocationClient.getLastLocation(); if (System.currentTimeMillis() - location.getTime() < HALF_MINUTE) { log("useCurrentLocation"); disableMyLocation(); if (locationRunnable != null) locationRunnable.locationUpdate(location); return true; } return false; } 


When we requested a location to pass as a time and not load the UI stream, I use AsynkTask as a timeout that runs for a given time, and upon completion returns the application to the location and unsubscribes from the location updates.

  @Override public void onConnected(final Bundle bundle) { if (!useCurrentLocation()) { mLocationClient.requestLocationUpdates(mLocationRequest, this); if (findLocation != null && !findLocation.isCancelled()) findLocation.cancel(true); findLocation = new FindLocation(); findLocation.execute(); } } private Location endFind() { long sec = System.currentTimeMillis(); while (this.mLocation == null && System.currentTimeMillis() - sec < TIME_OUT) {} return this.mLocation; } private class FindLocation extends AsyncTask<Void, Void, Location> { @Override protected Location doInBackground(final Void... params) {return endFind();} @Override protected void onPostExecute(final Location location) { if (locationRunnable != null) locationRunnable.locationUpdate(location); disableMyLocation(); } } @Override public void disableMyLocation() { if (mLocationClient.isConnected()) mLocationClient.removeLocationUpdates(this); mLocationClient.disconnect(); } public interface LocationRunnable { public void locationUpdate(Location location);} 


Actually how to use this example with github:
First you need to get an instance of the class, for myself I implemented singletone, since it is more suitable for my case
 locationListener = LocationListenerGPServices.getInstance(this); 

Then sign up for a location and do whatever you want with it.
 locationListener.setLocationRunnable(new ILocationListener.LocationRunnable() { @Override public void locationUpdate(final Location location) {}}); 


Actually, that's all I wanted to tell about this topic. Then I tried to tell in brief, and gave a minimum of code by text, in the source code on github, I showed an example of how to find the user's location and sort the list of metro stations by distance from the user.

Thank you for your attention, I hope someone will help and relieve from torment.

Source: https://habr.com/ru/post/191290/


All Articles