Monday, November 9, 2009

MapView to center on the current location from GPS

In the article Read GPS location, LocationManager described how to get current location from GPS.
In the article A minimal Map application using MapActivity, described how to implemented a MapView with MapActiity.

In this article, both exercises are merged to have a MapView, which will center in the current location from GPS.



Please note that the application cannot be run directly, you have to have your own API Key to using the GPS API. Refer to the article A minimal Map application using MapActivity to obtain API Key.

Modify AndroidManifest.xml:
Add <uses-library android:name="com.google.android.maps" /> as a child of the <application> element.
Add <uses-permission android:name="android.permission.INTERNET" />
and <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> as children of the <manifest> element.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.AndroidLocation"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".AndroidLocation"
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:name="com.google.android.maps" />
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-sdk android:minSdkVersion="5" />
</manifest>


Modify main.xml to have a MapView
<?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:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/longitude"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Longitude:"
/>
<TextView
android:id="@+id/latitude"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Latitude:"
/>
</LinearLayout>
<com.google.android.maps.MapView
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="false"
android:apiKey="-----Your Own API Key here-------------"
/>
</LinearLayout>


Finally, modify AndroidLocation.java
package com.AndroidLocation;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.widget.TextView;

public class AndroidLocation extends MapActivity {

private LocationManager myLocationManager;
private LocationListener myLocationListener;
private TextView myLongitude, myLatitude;

private MapView myMapView;

private MapController myMapController;

private void CenterLocatio(GeoPoint centerGeoPoint)
{
myMapController.animateTo(centerGeoPoint);


myLongitude.setText("Longitude: "+
String.valueOf((float)centerGeoPoint.getLongitudeE6()/1000000)
);
myLatitude.setText("Latitude: "+
String.valueOf((float)centerGeoPoint.getLatitudeE6()/1000000)
);
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myMapView = (MapView)findViewById(R.id.mapview);
myLongitude = (TextView)findViewById(R.id.longitude);
myLatitude = (TextView)findViewById(R.id.latitude);
myMapView.setSatellite(true); //Set satellite view
myMapController = myMapView.getController();
myMapController.setZoom(20); //Fixed Zoom Level

myLocationManager = (LocationManager)getSystemService(
Context.LOCATION_SERVICE);

myLocationListener = new MyLocationListener();

myLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0,
myLocationListener);

//Get the current location in start-up
GeoPoint initGeoPoint = new GeoPoint(
(int)(myLocationManager.getLastKnownLocation(
LocationManager.GPS_PROVIDER)
.getLatitude()*1000000),
(int)(myLocationManager.getLastKnownLocation(
LocationManager.GPS_PROVIDER)
.getLongitude()*1000000));
CenterLocatio(initGeoPoint);
}

private class MyLocationListener implements LocationListener{

public void onLocationChanged(Location argLocation) {
// TODO Auto-generated method stub
GeoPoint myGeoPoint = new GeoPoint(
(int)(argLocation.getLatitude()*1000000),
(int)(argLocation.getLongitude()*1000000));

CenterLocatio(myGeoPoint);
}

public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}

public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}

public void onStatusChanged(String provider,
int status, Bundle extras) {
// TODO Auto-generated method stub
}
}

@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
};
}


Download the files.

Also refer Enable "Use wireless networks" and "Use GPS satellites" in Android Emulator and Change GPS location of Android Emulator.





Because te application read location in start-up,
so you have to send GPS Location to Android Emulator
at least once before the application start.

Edited@11-11-2009





8 comments:

giorgos said...

I've downloaded your application but getting following error on Emulator

(process com.AndroidLocation) has stopped unexpectedly. Please try again

Erik said...

hello γιωργος,

Can I know your AVD setting? API level? with Google API?...

Do you have your own Key?

thx.

giorgos said...
This comment has been removed by the author.
Erik said...

hello γιωργος,

Yes, it's a bug here: In the code section commented //Get the current location in start-up in OnCreate(), if there are no LastKnownLocation in GPS, it will be a problem as mentioned by you.

So you can remove the code

GeoPoint initGeoPoint...
...
...
CenterLocatio(initGeoPoint);

Such that the map will start in a unknown location, until location undated by GPS.

Or, you can send a location to Android Emulator using DDMS before the app start.

thx
Eric

RoNaK pAnDyA said...

hi thanks for nice post..but i have a problem, when i install your app into my real device it shows force close msg and if i remove the lines which you have mentioned in above post (GeoPoint initGeoPoint to CenterLocatio(initGeoPoint))it doesnt show any location.displays only blank longitude and latitude...reply as early as possible...i want to show current location with pin pointed to that location...thanks..

Erik said...

hello RoNaK pAnDyA,

Have you enable GPS on your device?

RoNaK pAnDyA said...

yes i have turned on GPS and GPRS both on my mobile. but didnt get anything...how can i get current location and pin on that location..can you help me???

Erik said...

May be you have to wait longer until GPS valid and location changed, because onLocationChanged() will be called ONLY IF LOCATION CHNAGED.