In “My Seven Wonders” application it was important to know where we are located now in order to correctly calculate bearings of compass targets. Android API makes the interaction with geographical location services an easy task. In this article we will introduce the usage of that API along with some hints we discovered during development.
Android device features two possibilities to obtain current location: from GPS (more accurate) or from Network (less accurate).

The availability of these possibilities is controlled by a user in the Locations menu of a device:

Our example application will:
* retrieve our current location latitude and longitude using GPS or Network Location provider, depending on the current settings
* automatically switch from GPS to Network location provider, if GPS signal is not available.
* display the readable name of the current location using asynchronous call to Geocoder.
* notify the user, if required Location Providers are disabled and automatically display Locations menu so the user be able to enable one.
Firstly in our application activity we will get the android.location.LocationManager service, which will provide us with all the required geographical data.
Now we will check, which of the providers are enabled. This is accomplished using isProviderEnabled method of LocationManager. We try with LocationManager.GPS_PROVIDER and if it is not enabled we try with LocationManager.NETWORK_PROVIDER. If both are disabled, we will display a Locations menu by constructing a new Intent with android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS as a parameter.

As soon as we found an enabled provider we will subscribe to receive updates from it using requestLocationUpdates from LocationManager. The updates will be handled by our custom implementation of android.location.LocationListener which we pass to requestLocationUpdates as a parameter.
Finally we will display received latitude and longitude in onLocationChanged method of our LocationListener.

Currently our application is able get the coordinates from GPS or Network (it depends on which of them are enabled). This is cool. But assume now, user has both providers enabled, but he is located indoors where GPS signal is not available. In that case our application will continuously wait for data from GPS, which actually is impossible to retrieve.
So it would be nice to make our application be smart enough to switch from GPS to Network automatically, when GPS signal is not available. The problem is that GPS signal availability could not be retrieved from Android API, so our aim is to find a workaround for this.
The simple way is to set a predefined delay after which, when no data is received from GPS, we give up. But this may be very inaccurate since the delay, after which the data may be received, may vary depending on different factors, like the time of the day or weather conditions. Sometimes the data could be returned in 2 seconds, but sometimes in 25.
The good thing is Android API can tell us the number of satellites discovered by the GPS receiver of our Android device. The idea is to track the value of available satellites and based on this information predict can we receive GPS data, or we should give up.
Unfortunately there is no predefined value of available satellites after which the coordinates could be potentially received. Depending on the circumstances we can receive coordinates with 3 satellites available, but can receive nothing with 5.
Though the value of available satellites can’t tell us much, the way this value changes over time may become quite handy. If the number of available satellites is increasing, that means we are on the way to signal receiving.

We will introduce a number of wait intervals and a number of satellites, which anyway should become available in these intervals. For example, if during first 5 seconds we will not get at least one satellite available, that surely means, we will not be able to receive the signal later. The same way we can experimentally find other intervals and SATs values (like 3 SATs at 10 seconds, 5 SATs at 18 etc.).
Based on this information we can make an appropriate check by registering our custom GpsStatus.Listener and handle the GpsStatus.GPS_EVENT_SATELLITE_STATUS event. If the minimal required number of satellites will not be available at the predefined time interval we will immediately switch to Network provider.

If GPS signal is not available, but Network provider is disabled we will display Locations menu:

Our application displays the latitude and longitude of the current location in numerical form. To make it more user friendly, we will use these numerical values to get the geographical name of the location associated with these coordinates. To achieve that an android.location.Geocoder.Geocoder class will be used. The data returned by Geocoder will be retrieved from Internet, so there could be some visible delay during that procedure. To avoid our application to stop responding during data retrieval we will call the Geocoder from the android.os.AsyncTask. As a result our application will be able to respond to other actions, while the data is being retrieved asynchronously.

Finally we have a nice application, which automatically chooses available location provider whether we are indoors or outdoors, and displays our current location.
This is one of the genius information.your blog information is quit different compare to other post.
ReplyDeleteAndroid app developers