MyLocationManager.java :  » App » vanbus » org » niclab » vanbus » gps » Android Open Source

Android Open Source » App » vanbus 
vanbus » org » niclab » vanbus » gps » MyLocationManager.java
/*******************************************************************************
 * Copyright (c) 2010 liw.
 * All rights reserved. 
 * 
 * This file is part of VanBus.
 * 
 *     VanBus is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     VanBus is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with VanBus.  If not, see <http://www.gnu.org/licenses/>.
 * Contributors:
 *     liw - initial API and implementation
 ******************************************************************************/
package org.niclab.vanbus.gps;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.niclab.vanbus.application.VanBusApplication;

import android.app.Application;
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.util.Log;

public class MyLocationManager {
  
  private static String LOG_TAG="MyLocationManager";
  
  private Application appContext;
  private Timer timer;
  private LocationManager locationManager;
  private LocationListener coarseLocationListener;
  private LocationListener fineLocationListener;
  
  private static final long coarseLocUpdateInterval = 500; //ms
  private static final long fineLocUpdateInterval = 500; //ms
  
  private static final long coarseLocUpdateDistance = 1000; //meters
  private static final long fineLocUpdateDistance = 50; //meters
  private static final int TWO_MINUTES = 1000 * 60 * 2;
  private static final int HALF_A_MINUTE = 1000*30;
  private Location currentBestLocation;
//  boolean gps_enabled=false;
//  boolean network_enabled=false;

  
  
  public MyLocationManager(Application app){
    appContext = app;
    locationManager = (LocationManager) appContext.getSystemService(Context.LOCATION_SERVICE);
    currentBestLocation = getLastKnownLocation();
  }
  
  public boolean isGPSEnabled(){
    return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
  }
  
  public boolean isNetworkEnabled(){
    return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    
  }
  public boolean isGPSandNetworkEnabled(){
    return isGPSEnabled() && isNetworkEnabled();
    
  }
  
  public boolean isOnlyGPSEnabled(){
    return isGPSEnabled() && !isNetworkEnabled();
  }
  
  public boolean isOnlyNetworkEnabled(){
    return isNetworkEnabled() && !isGPSEnabled();
  }
  
  public boolean isGPSorNetworkEnabled(){
    return isGPSEnabled() || isNetworkEnabled();
  }
  
  public void startPinDownMyLocation(){
    
    //clear all the old listeners
    if(coarseLocationListener !=null)
      locationManager.removeUpdates(coarseLocationListener);
    if(fineLocationListener !=null)
      locationManager.removeUpdates(fineLocationListener);
    
    // Initialize criteria for location providers
    Criteria fine = new Criteria();
    fine.setAccuracy(Criteria.ACCURACY_FINE);
       
    Criteria coarse = new Criteria();
    coarse.setAccuracy(Criteria.ACCURACY_COARSE);
       
       
    creatLocationListeners();
    // Will keep updating about every 500 ms until accuracy is about 1000 meters to get quick fix.
    locationManager.requestLocationUpdates(locationManager.getBestProvider(coarse, true),0, 0, coarseLocationListener);
    // Will keep updating about every 500 ms until accuracy is about 50 meters to get accurate fix.
    locationManager.requestLocationUpdates(locationManager.getBestProvider(fine, true),0, 0, fineLocationListener);
    
  }
  
  private void creatLocationListeners(){
    coarseLocationListener = new LocationListener(){
  
      @Override
      public void onLocationChanged(Location location) {
        
         Log.v(LOG_TAG,"Location updated in coarseLocListener");
         if(isBetterLocation(location, currentBestLocation))
           currentBestLocation = location;
         
         if (location.getAccuracy() < coarseLocUpdateDistance && location.hasAccuracy()){
           locationManager.removeUpdates(this);
           coarseLocationListener = null;
         }
    
            
      }
  
      @Override
      public void onProviderDisabled(String provider) {
            
      }
  
      @Override
      public void onProviderEnabled(String provider) {
          
      }
  
      @Override
      public void onStatusChanged(String provider, int status,
          Bundle extras) {
            
      }
      
    };
    
  
    fineLocationListener = new LocationListener(){
  
      @Override
      public void onLocationChanged(Location location) {
         Log.v(LOG_TAG,"Location updated in fineLocListener");
         if(isBetterLocation(location, currentBestLocation))
           currentBestLocation = location;
            if (location.getAccuracy() <fineLocUpdateDistance   && location.hasAccuracy()){
                 locationManager.removeUpdates(this);
                 fineLocationListener = null;
               }
    
    
        
      }
  
      @Override
      public void onProviderDisabled(String provider) {
        
      }
  
      @Override
      public void onProviderEnabled(String provider) {
      
      }
  
      @Override
      public void onStatusChanged(String provider, int status,
          Bundle extras) {
              
      }
      
    };
    
  }
  
  public Location getLastKnownLocation(){
    if(isGPSEnabled())
      return locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    else if(isNetworkEnabled())
      return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    else return null;
    
    
  }
  
  /**
   * get current location. If ms >0, then this starts a new search location process and 
   * blocks the current thread for that long, then return a new location.
   * If ms ==0, then return the current best location immediately.
   *
   * @param ms how long it waits to get the current location;
   * @return the current best location
   */
  
  public Location getCurrentBestLocation(long ms){
    if(ms==0)
      return currentBestLocation;
    
    
    //if current best location is updated within 30seconds, we return it immediately.
    if(currentBestLocation!=null){
      if(System.currentTimeMillis()-currentBestLocation.getTime()<HALF_A_MINUTE)
        return currentBestLocation;
    }
    //if the current listeners haven't been all removed, we do not start new listeners.
    if(coarseLocationListener == null && fineLocationListener ==null)
      this.startPinDownMyLocation();
    
    VanBusApplication app = (VanBusApplication) appContext;
    
    ScheduledFuture<Location> futureLoc= app.getScheduledExecutorService().schedule(new Callable<Location>(){

      @Override
      public Location call() throws Exception {
        
        return currentBestLocation;
      }
      
      
    }, ms, TimeUnit.MILLISECONDS);
    
    
    try {
      return futureLoc.get();
    } catch (Exception e) {
      e.printStackTrace();
      return currentBestLocation;
      
    }
    
  }
  
  
  
  
  /** Determines whether one Location reading is better than the current Location fix
    * @param location  The new Location that you want to evaluate
    * @param currentBestLocation  The current Location fix, to which you want to compare the new one
    */

  private boolean isBetterLocation(Location location, Location currentBestLocation) {
      if (currentBestLocation == null) {
          // A new location is always better than no location
          return true;
      }

      // Check whether the new location fix is newer or older
      long timeDelta = location.getTime() - currentBestLocation.getTime();
      boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
      boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
      boolean isNewer = timeDelta > 0;

      // If it's been more than two minutes since the current location, use the new location
      // because the user has likely moved
      if (isSignificantlyNewer) {
          return true;
      // If the new location is more than two minutes older, it must be worse
      } else if (isSignificantlyOlder) {
          return false;
      }

      // Check whether the new location fix is more or less accurate
      int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
      boolean isLessAccurate = accuracyDelta > 0;
      boolean isMoreAccurate = accuracyDelta < 0;
      boolean isSignificantlyLessAccurate = accuracyDelta > 200;

      // Check if the old and new location are from the same provider
      boolean isFromSameProvider = isSameProvider(location.getProvider(),
              currentBestLocation.getProvider());

      // Determine location quality using a combination of timeliness and accuracy
      if (isMoreAccurate) {
          return true;
      } else if (isNewer && !isLessAccurate) {
          return true;
      } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
          return true;
      }
      return false;
  }

  /** Checks whether two providers are the same */
  private boolean isSameProvider(String provider1, String provider2) {
      if (provider1 == null) {
        return provider2 == null;
      }
      return provider1.equals(provider2);
  }
  


  

}

/*public class MyLocation {
    Timer timer1;
    LocationManager lm;
    LocationResult locationResult;
    boolean gps_enabled=false;
    boolean network_enabled=false;

    public boolean getLocation(Context context, LocationResult result)
    {
        //I use LocationResult callback class to pass location value from MyLocation to user code.
        locationResult=result;
        if(lm==null)
            lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);

        //exceptions will be thrown if provider is not permitted.
        try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
        try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}

        //don't start listeners if no provider is enabled
        if(!gps_enabled && !network_enabled)
            return false;

        if(gps_enabled)
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
        if(network_enabled)
            lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
        timer1=new Timer();
        timer1.schedule(new GetLastLocation(), 20000);
        return true;
    }

    LocationListener locationListenerGps = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerNetwork);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    LocationListener locationListenerNetwork = new LocationListener() {
        public void onLocationChanged(Location location) {
            timer1.cancel();
            locationResult.gotLocation(location);
            lm.removeUpdates(this);
            lm.removeUpdates(locationListenerGps);
        }
        public void onProviderDisabled(String provider) {}
        public void onProviderEnabled(String provider) {}
        public void onStatusChanged(String provider, int status, Bundle extras) {}
    };

    class GetLastLocation extends TimerTask {
        @Override
        public void run() {
             lm.removeUpdates(locationListenerGps);
             lm.removeUpdates(locationListenerNetwork);

             Location net_loc=null, gps_loc=null;
             if(gps_enabled)
                 gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
             if(network_enabled)
                 net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

             //if there are both values use the latest one
             if(gps_loc!=null && net_loc!=null){
                 if(gps_loc.getTime()>net_loc.getTime())
                     locationResult.gotLocation(gps_loc);
                 else
                     locationResult.gotLocation(net_loc);
                 return;
             }

             if(gps_loc!=null){
                 locationResult.gotLocation(gps_loc);
                 return;
             }
             if(net_loc!=null){
                 locationResult.gotLocation(net_loc);
                 return;
             }
             locationResult.gotLocation(null);
        }
    }

    public static abstract class LocationResult{
        public abstract void gotLocation(Location location);
    }
}*/
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.