Version 1.4
Copyright © 2010 - 2011 Lars Vogel
15.06.2011
Revision History | ||
---|---|---|
Revision 0.1 | 15.06.2010 | Lars Vogel |
created | ||
Revision 0.2 - 1.4 | 18.06.2010 - 15.06.2011 | Lars Vogel |
bugfixes and enhancements |
Table of Contents
Most Android devices allow to determine the current geolocation. This can be done via a GPS (Global Positioning System) device, via cell tower triangulation or via wifi networks for which the geolocation is known. Android provides the package "android.location" which provides the API to determine the current geo position.
The class "LocationManager" provides access to the location service . The Android device might have several providers available and you can select one of them. For a flexible selection of the best location provider use a "Criteria" object in which you can define how the provider should be selected.
You can register a "LocationListener" with the "LocationManager" and will receive periodic updates about the geoposition. The class "LocationProvider" is the superclass of the different location providers which deliver the information about the current location.
You can also register an Intent also allows to define a proximity alert, this alert will be triggered if the device enters a area given by a longitude, latitude and radius (proximity alert).
The class "LocationManager" provides access to the location service . The Android device might have several providers available and you can select one of them. For a flexible selection of the best location provider use a "Criteria" object in which you can define how the provider should be selected.
You can register a "LocationListener" with the "LocationManager" and will receive periodic updates about the geoposition. The class "LocationProvider" is the superclass of the different location providers which deliver the information about the current location.
You can also register an Intent also allows to define a proximity alert, this alert will be triggered if the device enters a area given by a longitude, latitude and radius (proximity alert).
Google provides in the package "com.google.android.maps" a library for using Google Maps in Android. Google Maps is not part of the standard Open Source Platform Android and you require an additional key to use them. This key will be specified in the view which will be used to display the map.
To use Google Maps in your application you need to add the following uses-library statement to your AndroidManifest.xml file. The project creation wizard allow to do this automatically.
The class "MapActivity" extends the class "Activity" and provides the life-cycle management and the services for displaying a Map in a "MapView". MapActivity is for maps what ListActivity is for lists.
A "MapView" is typically defined in the layout for the MapActivity and requires the API key in the attribute android:apiKey. A MapView can be used with other UI components in the same layout.
The class "MapController" can be used to interact with the "MapView", e.g. by moving it. A "Geopoint" is a position described via latitude and longitude and the class "Overlay" can be used to drawn on the map, for example position markers.
The usage of Google Maps also requires the permission to access the internet as the Google Maps data is read from it.
To use Google Maps in your application you need to add the following uses-library statement to your AndroidManifest.xml file. The project creation wizard allow to do this automatically.
<uses-library android:required="true" android:name="com.google.android.maps"></uses-library>
The class "MapActivity" extends the class "Activity" and provides the life-cycle management and the services for displaying a Map in a "MapView". MapActivity is for maps what ListActivity is for lists.
A "MapView" is typically defined in the layout for the MapActivity and requires the API key in the attribute android:apiKey. A MapView can be used with other UI components in the same layout.
The class "MapController" can be used to interact with the "MapView", e.g. by moving it. A "Geopoint" is a position described via latitude and longitude and the class "Overlay" can be used to drawn on the map, for example position markers.
The usage of Google Maps also requires the permission to access the internet as the Google Maps data is read from it.
The class "Geocoder" allow to determine the geo-coordinates (longitude, laditude) for a given address and vice versa.
The following assumes that you have already basic knowledge in Android development . Please check the Android development tutorialfor the basics.
To use Google Maps you need an additional key. See Obtaining a Maps API Key to learn how to get an Google Maps API key. This process is a little bit time consuming and involves creating a value on the command line as well as a webpage to get the key.
In case you want to use Google Maps in your emulator you have to create a device which supports the Google API's. This requires that you also install the "Google API" (see Android development tutorial ). During device creation select the target Google API's in the version of your SDK.
You can set the geoposition the the Android emulator via telnet. Open a console and connect to your device. The port number of your device can be seen in the title area of your emulator.
Set the position via the following command.
telnet localhost 5554
Set the position via the following command.
geo fix 13.24 52.31
You also need to activate the GPS module in the emulator. If you do not activate it you receive "null" the first time you try to use. The Google Map activity should automatically activate the GPS device in the emulator but if you want to use the location manager directly you need to do this yourself. Currently their seems to be an issue with this. Just start Google Maps on the emulator, this will activate the GPS provider.
Create a new project "de.vogella.android.locationapi.simple" with the Activity "ShowLocation". This example will not use the Google Map therefore select an Android target.
Define your view layout "main.xml" to the following.
Define your view layout "main.xml" to the following.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:id="@+id/linearLayout1" android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="horizontal" android:layout_marginTop="40dip"> <TextView android:text="Latitude: " android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/TextView01" android:layout_marginLeft="10dip" android:layout_marginRight="5dip" android:textSize="20dip"></TextView> <TextView android:text="unknown" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/TextView02" android:textSize="20dip"></TextView> </LinearLayout> <LinearLayout android:id="@+id/linearLayout2" android:layout_height="wrap_content" android:layout_width="match_parent"> <TextView android:text="Longitute: " android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/TextView03" android:layout_marginLeft="10dip" android:layout_marginRight="5dip" android:textSize="20dip"></TextView> <TextView android:text="unknown" android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/TextView04" android:textSize="20dip"></TextView> </LinearLayout> </LinearLayout>
Add the following permissions to your application in Android.xml.
- INTERNET
- ACCESS_FINE_LOCATION
- ACCESS_COARSE_LOCATION
Create the following activity. This activity will query the location manager and display the queried values in the activity.
package de.vogella.android.locationsapi.simple; import android.app.Activity; import android.content.Context; import android.location.Criteria; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.widget.TextView; import android.widget.Toast; public class ShowLocation extends Activity implements LocationListener { private TextView latituteField; private TextView longitudeField; private LocationManager locationManager; private String provider; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); latituteField = (TextView) findViewById(R.id.TextView02); longitudeField = (TextView) findViewById(R.id.TextView04); // Get the location manager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); // Define the criteria how to select the locatioin provider -> use // default Criteria criteria = new Criteria(); provider = locationManager.getBestProvider(criteria, false); Location location = locationManager.getLastKnownLocation(provider); // Initialize the location fields if (location != null) { System.out.println("Provider " + provider + " has been selected."); int lat = (int) (location.getLatitude()); int lng = (int) (location.getLongitude()); latituteField.setText(String.valueOf(lat)); longitudeField.setText(String.valueOf(lng)); } else { latituteField.setText("Provider not available"); longitudeField.setText("Provider not available"); } } /* Request updates at startup */ @Override protected void onResume() { super.onResume(); locationManager.requestLocationUpdates(provider, 400, 1, this); } /* Remove the locationlistener updates when Activity is paused */ @Override protected void onPause() { super.onPause(); locationManager.removeUpdates(this); } @Override public void onLocationChanged(Location location) { int lat = (int) (location.getLatitude()); int lng = (int) (location.getLongitude()); latituteField.setText(String.valueOf(lat)); longitudeField.setText(String.valueOf(lng)); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { Toast.makeText(this, "Enabled new provider " + provider, Toast.LENGTH_SHORT).show(); } @Override public void onProviderDisabled(String provider) { Toast.makeText(this, "Disenabled provider " + provider, Toast.LENGTH_SHORT).show(); } }
Create a new project "de.vogella.android.locationapi.maps" with the activity "ShowMapActivity". Make sure to select the "Google API" als Target. Add also the same permissions as in the last example to your application.
You need to add the Google maps library to your application. Add "uses library" to "AndroidManifest.xml".
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="de.vogella.android.locationapi.maps" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="10" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ShowMap" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <uses-library android:required="true" android:name="com.google.android.maps"></uses-library> </application> </manifest>
The next step requires that you have generated your Google Map key . Change the "main.xml" layout to the following. Replace "Your Maps API Key" with your Google API key.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainlayout" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.google.android.maps.MapView android:id="@+id/mapview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" android:apiKey="Your Maps API Key" /> </RelativeLayout>
Create the following activity. This activity use an LocationListner to update the map with the current location.
package de.vogella.android.locationapi.maps; import android.content.Context; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.widget.RelativeLayout; import com.google.android.maps.GeoPoint; import com.google.android.maps.MapActivity; import com.google.android.maps.MapController; import com.google.android.maps.MapView; public class ShowMap extends MapActivity { private MapController mapController; private MapView mapView; private LocationManager locationManager; public void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.main); // bind the layout to the activity // create a map view RelativeLayout linearLayout = (RelativeLayout) findViewById(R.id.mainlayout); mapView = (MapView) findViewById(R.id.mapview); mapView.setBuiltInZoomControls(true); mapView.setStreetView(true); mapController = mapView.getController(); mapController.setZoom(14); // Zoon 1 is world view locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new GeoUpdateHandler()); } @Override protected boolean isRouteDisplayed() { return false; } public class GeoUpdateHandler implements LocationListener { @Override public void onLocationChanged(Location location) { int lat = (int) (location.getLatitude() * 1E6); int lng = (int) (location.getLongitude() * 1E6); GeoPoint point = new GeoPoint(lat, lng); mapController.animateTo(point); // mapController.setCenter(point); } @Override public void onProviderDisabled(String provider) { } @Override public void onProviderEnabled(String provider) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } } }
Run and test your application. You should be able to zoon in and out and send new geocoordinates to your Maps via the Emulator console.
No comments:
Post a Comment