Saturday, May 12, 2012

Location updates from GPS_PROVIDER and NETWORK_PROVIDER

Last exercise demonstrate how "Obtaining user location" using LocationListener. Actually, you can equest location updates from both the GPS and the Network Location Provider by calling requestLocationUpdates() twice—once for NETWORK_PROVIDER and once for GPS_PROVIDER.

But please note that there may be a case: the new location come from NETWORK_PROVIDER have lower accuracy than the old location come from GPS_PROVIDER. The Location passed to onLocationChanged() of LocationListener not only have Latitude and Longitude, it also provide more useful information such as time, accuracy, provider...etc. You can define your own logic to determine accept/reject the new location base on the time, provider, accuracy...etc.

It's a example to retrieve various information from Location passed to onLocationChanged().

Location log from GPS_PROVIDER and NETWORK_PROVIDER


package com.exercise.AndroidLocation;

import java.text.SimpleDateFormat;
import java.util.LinkedList;
import android.app.Activity;
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 AndroidLocationActivity extends Activity {
 
 LocationManager locationManager;
 double myLatitude, myLongitude;
 
 TextView textLatitude, textLongitude, textLog;
 
 LinkedList<Location> locList;
 final static int LOG_SIZE = 5;
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        textLatitude = (TextView)findViewById(R.id.Latitude);
        textLongitude = (TextView)findViewById(R.id.Longitude);
        textLog = (TextView)findViewById(R.id.Log);
        
        locList = new LinkedList<Location>();
        
        locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        
        //for demo, getLastKnownLocation from GPS only, not from NETWORK
        Location lastLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if(lastLocation != null){
         updateLoc(lastLocation);
        }
    }
    
    private void updateLoc(Location loc){
     textLatitude.setText("Latitude: " + loc.getLatitude());
     textLongitude.setText("Longitude: " + loc.getLongitude());
     
     locList.add(loc);
     
     //maintain the LOG_SIZE
     if (locList.size() > LOG_SIZE){
      locList.remove();
     }
     
     String locLog = "\n LOCATION LOG (last " + LOG_SIZE + " logs)\n";
     for(int i = 0; i < locList.size(); i++){
      if(locList.get(i) != null){
       
       String formatedTime = (new SimpleDateFormat("mm:ss:SSS")).format(locList.get(i).getTime());
       
       locLog += "\n--- " + i + " ---\n"
         + "@ " + formatedTime + "\n"
         + "Latitude: " + locList.get(i).getLatitude() + "\n"
         + "Longitude: " + locList.get(i).getLongitude() + "\n"
         + "Time: " +  String.valueOf(locList.get(i).getTime()) + "\n"
         + "Provider: " + locList.get(i).getProvider() + "\n";
       
       if(locList.get(i).hasAltitude()){
        locLog += "Altitude: " + locList.get(i).getAltitude() + "\n";
       }
       
       if(locList.get(i).hasAccuracy()){
        locLog += "Accuracy: " + locList.get(i).getAccuracy() + "(m)\n";
       }
       
       if(locList.get(i).hasBearing()){
        locLog += "Bearing: " + locList.get(i).getBearing() + "(m)\n";
       }
       
       if(locList.get(i).hasSpeed()){
        locLog += "Speed: " + locList.get(i).getSpeed() + "(m)\n";
       }
       
      }
      
     }

     textLog.setText(locLog);
    }
    
 @Override
 protected void onResume() {
  // TODO Auto-generated method stub
  super.onResume();
  locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, myLocationListener);
  locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, myLocationListener);
 }
    
    @Override
 protected void onPause() {
  // TODO Auto-generated method stub
  super.onPause();
  locationManager.removeUpdates(myLocationListener);
 }

    private LocationListener myLocationListener
    = new LocationListener(){

  @Override
  public void onLocationChanged(Location location) {
   updateLoc(location);
   
  }

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

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

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


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    <TextView
        android:id="@+id/Latitude"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/Longitude"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
    <ScrollView 
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
     <TextView
         android:id="@+id/Log"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"/>
 </ScrollView>
</LinearLayout>


Note: permission of "android.permission.ACCESS_FINE_LOCATION"is needed.

Download the files.

Next:
- Update location on OpenStreetMap


1 comment:

Unknown said...

All is worthless on GPS state off, it keep return the lastKnowLocation.
Is der any trick to turn GPS on n get location and then off it even on ICS version??