Thursday, April 11, 2013

A GPS Client

This article walks through a basic dot42 code sample that uses the location services such as GPS on an Android device. While this article includes code snippets only, the full code sample is included in dot42 update 1.0.0.62 or higher. See folder [MyDocuments]\dot42\Samples\Sensors\SimpleGps.

Declare permissions

An application that uses location services requires certain permissions. You need INTERNET and ACCESS_COARSE_LOCATION to access the network-based location provider only. For more accurate GPS you need ACCESS_FINE_LOCATION permission. Declaring ACCESS_FINE_LOCATION implies ACCESS_COARSE_LOCATION.
Traditional Android developing declares permissions in AndroidManifest.xml as follows:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  ...
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  <uses-permission android:name="android.permission.INTERNET" />
  ...
</manifest>
However, using dot42 you declare the same set of permissions using the assembly attribute UsesPermission as follows:
[assembly: UsesPermission(Android.Manifest.Permission.ACCESS_COARSE_LOCATION)]
[assembly: UsesPermission(Android.Manifest.Permission.INTERNET)]

LocationManager

Class LocationManager is the starting point for accessing location services. You retrieve an instance as follows:
LocationManager service =
  (LocationManager) GetSystemService(LOCATION_SERVICE);
The next step is to check whether GPS has been enabled on the device:
bool enabled =
  service.IsProviderEnabled(LocationManager.GPS_PROVIDER);
On my Asus Transformer Pad, this corresponds to the following setting:


If GPS is not enabled you may choose to fall back to the network-based location provider. You would check availability as follows:
bool enabled =
  service.IsProviderEnabled(LocationManager.NETWORK_PROVIDER);

Get location provider

After we have determined what provider is enabled, we can retrieve it and ask for the location. Assuming that GPS has been enabled, we would retrieve the provider and location as follows:
// get the provider
Criteria criteria = new Criteria();
criteria.Accuracy = Criteria.ACCURACY_FINE;
provider = service.GetBestProvider(criteria, false);
// request the location (returns null if provider is disabled)
Location location = service.GetLastKnownLocation(provider);
If GPS is not enabled, you may request a provider with course accuracy like this:
criteria.Accuracy = Criteria.ACCURACY_COARSE;

Receive location updates

The above code requests the last known location. The current location may however change and we would like to be notified when it does. This can be done by registering a listener. You typically do this in the OnResume of your activity:
protected override void OnResume()
{
  base.OnResume();
  if (enabled) service.RequestLocationUpdates(
    provider, // as returned by GetBestProvider
    1000, // minimum update period in ms
    1, // minimum update distance in m
    this);
}
In the Activity overridable OnPause, you would remove your listener as follows:
protected override void OnPause()
{
  base.OnPause();
  if (enabled) service.RemoveUpdates(this);
}
Note that this refers to the current Activity and it is therefore required to implement the listener interface ILocationListener:
[Activity]
public class MainActivity : ILocationListener
{
  ...
}
ILocationListener has 4 methods of which OnLocationChanged is the most interesting:
public void OnLocationChanged(Location location)
{
  double latitude = location.GetLatitude();
  double longtitude = location.GetLongitude();
  // update UI
}

The full code

The full code sample is included in dot42 update 1.0.0.62 or higher. See folder [MyDocuments]\dot42\Samples\Sensors\SimpleGps.

No comments:

Post a Comment