Thursday, January 24, 2013

Implement LocationSource and LocationListener for Google Maps Android API v2

Example to Implement LocationSource and LocationListener for Google Maps Android API v2.

Implement LocationSource and LocationListener for Google Maps Android API v2


package com.example.androidmapsv2;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.LocationSource;
import com.google.android.gms.maps.MapFragment;

import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity 
  implements LocationSource, LocationListener{
 
 final int RQS_GooglePlayServices = 1;
 private GoogleMap myMap;
 TextView tvLocInfo;
 
 LocationManager myLocationManager = null;
 OnLocationChangedListener myLocationListener = null;
 Criteria myCriteria;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvLocInfo = (TextView)findViewById(R.id.locinfo);
        
        FragmentManager myFragmentManager = getFragmentManager();
        MapFragment myMapFragment 
         = (MapFragment)myFragmentManager.findFragmentById(R.id.map);
        myMap = myMapFragment.getMap();
        
        myMap.setMyLocationEnabled(true);
        
        myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        
        myCriteria = new Criteria();
        myCriteria.setAccuracy(Criteria.ACCURACY_FINE);
        myLocationManager = (LocationManager)getSystemService(LOCATION_SERVICE);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  switch (item.getItemId()) {
  case R.id.menu_legalnotices:
   String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
     getApplicationContext());
   AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(MainActivity.this);
   LicenseDialog.setTitle("Legal Notices");
   LicenseDialog.setMessage(LicenseInfo);
   LicenseDialog.show();
   return true; 
  }
  return super.onOptionsItemSelected(item); 
 }

 @Override
 protected void onResume() {
  super.onResume();
  
  int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
  
  if (resultCode == ConnectionResult.SUCCESS){
   Toast.makeText(getApplicationContext(), 
     "isGooglePlayServicesAvailable SUCCESS", 
     Toast.LENGTH_LONG).show();
   
   //Register for location updates using a Criteria, and a callback on the specified looper thread.
   myLocationManager.requestLocationUpdates(
     0L,    //minTime
     0.0f,    //minDistance
     myCriteria,  //criteria
     this,    //listener
     null);   //looper
   
   //Replaces the location source of the my-location layer.
      myMap.setLocationSource(this);
   
  }else{
   GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices); 
  }
  
 }

 @Override
 protected void onPause() {
  myMap.setLocationSource(null);
  myLocationManager.removeUpdates(this);
     
  super.onPause();
 }

 @Override
 public void activate(OnLocationChangedListener listener) {
  myLocationListener = listener;
 }

 @Override
 public void deactivate() {
  myLocationListener = null;
 }

 @Override
 public void onLocationChanged(Location location) {
  if (myLocationListener != null) {
   myLocationListener.onLocationChanged(location);
   
   double lat = location.getLatitude();
   double lon = location.getLongitude();
   
   tvLocInfo.setText(
     "lat: " + lat + "\n" +
     "lon: " + lon);
  }
 }

 @Override
 public void onProviderDisabled(String arg0) {
  // TODO Auto-generated method stub
  
 }

 @Override
 public void onProviderEnabled(String arg0) {
  // TODO Auto-generated method stub
  
 }

 @Override
 public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
  // TODO Auto-generated method stub
  
 }

}


download filesDownload the files.

Next:
- Detect and animate to user location


The series:
A simple example using Google Maps Android API v2, step by step.

7 comments:

Việt Anh Nguyễn said...

Hi,
Thanks for your post.
But i have an issue: I download your project and change a little bit of code to compatible with Android API 2.3.3.
And when running, it only show the blank map instead of a map with blue arrow (current location) like in your capture.
Please help me to fix this, thanks in advance!

Andr.oid Eric said...

Hello Việt Anh Nguyễn,

You have to use your own API Key, read here.

Việt Anh Nguyễn said...

I already change API Key and displayed maps. But current location icon is a blue dot, instead of an arrow like in your photo.
So please help me to show the current location as a flashing arrow like default navigation app.
Thanks!

Andr.oid Eric said...

hello Việt Anh Nguyễn,

Yes, the blur dot is the default indicator of setMyLocationEnabled(true), like Display my location on Google Maps Android API v2.

As I remember, the arrow will appear once your location updated, such as location changed. So please make sure your GPS is turned on, and may be you have to wait longer.

Việt Anh Nguyễn said...

Hi Eric,

You're right. I just go out with this app. The arrow appear when i move, but it disappear when i stand (even stand and rotate device).

I already turn on GPS in Setting. And in default Map app of android, the arrow still appear when i stand.

I have run your app with other device but the result is same.

So please help me.

Thanks so much!

Rash727 said...

Thanks a lot for all your post... :)
very helpful and easy to understand...

Anonymous said...

do i have to make a new activity for this?
this is my java code
package com.example.map1;

import android.support.v4.app.FragmentActivity;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;


public class MainActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}