init commit

This commit is contained in:
2011-12-17 15:43:48 +00:00
parent eeb14e8bb7
commit 4a0469abf7
190 changed files with 21930 additions and 0 deletions

View File

@@ -0,0 +1,146 @@
/**
* AndroidGPS.java
* @date Feb 3, 2011
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.location;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import com.TwentyCodes.android.SkyHook.SkyHook;
import com.TwentyCodes.android.debug.Debug;
import com.google.android.maps.GeoPoint;
/**
* This class will be used for gathering location using android's location services
* @author ricky barrette
*/
public class AndroidGPS implements LocationListener {
private static final String TAG = "AndroidGPS";
private LocationManager mLocationManager;
private GeoPointLocationListener mListener;
private LocationListener mLocationListener;
/**
* Creates a new SkyHookFallback
* @author ricky barrette
*/
public AndroidGPS(Context context) {
mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
}
/**
* Remove updates from androids location services
* @author ricky barrette
*/
public void disableLocationUpdates(){
if(Debug.DEBUG)
Log.d(TAG, "disableLocationUpdates()");
mListener = null;
mLocationManager.removeUpdates(this);
}
/**
* Attempts to enable periodic location updates
* @param listener
* @author ricky barrette
*/
public void enableLocationUpdates(LocationListener listener) {
if(Debug.DEBUG)
Log.d(SkyHook.TAG, "enableLocationUpdates()");
if(mLocationListener == null){
mLocationListener = listener;
requestUpdates();
}
}
/**
* request periodic location updates from androids location services
* @author ricky barrette
*/
public void enableLocationUpdates(GeoPointLocationListener listener) {
if(Debug.DEBUG)
Log.d(SkyHook.TAG, "enableLocationUpdates()");
if (mListener == null) {
mListener = listener;
requestUpdates();
}
}
/**
* (non-Javadoc)
* @see android.location.LocationListener#onLocationChanged(android.location.Location)
* @param location
* @author ricky barrette
*/
@Override
public void onLocationChanged(Location location) {
if(mListener != null)
mListener.onLocationChanged(new GeoPoint( (int) (location.getLatitude() * 1e6), (int) (location.getLongitude() * 1e6)), (int) location.getAccuracy());
if(mLocationListener != null){
mLocationListener.onLocationChanged(location);
}
}
/**
* (non-Javadoc)
* @see android.location.LocationListener#onProviderDisabled(java.lang.String)
* @param arg0
* @author ricky barrette
*/
@Override
public void onProviderDisabled(String arg0) {
// UNUSED
}
/**
* (non-Javadoc)
* @see android.location.LocationListener#onProviderEnabled(java.lang.String)
* @param arg0
* @author ricky barrette
*/
@Override
public void onProviderEnabled(String arg0) {
// UNUSED
}
/**
* (non-Javadoc)
* @see android.location.LocationListener#onStatusChanged(java.lang.String, int, android.os.Bundle)
* @param arg0
* @param arg1
* @param arg2
* @author ricky barrette
*/
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// UNUSED
}
/**
* Request updates from android location services
* @author ricky barrette
*/
private void requestUpdates() {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this);
try {
mLocationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, 0, 0, this);
} catch (IllegalArgumentException e) {
e.printStackTrace();
/* We do no handle this exception as it is caused if the android version is < 1.6. since the PASSIVE_PROVIDER call is not required
* to function we can ignore it.
*/
}
}
}

View File

@@ -0,0 +1,234 @@
/**
* CompasOverlay.java
* @date Mar 9, 2011
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.location;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Point;
import com.TwentyCodes.android.SkyHook.R;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
/**
* A Simple compass overlay that will be used to point towards a destination or north
* @author ricky barrette
*/
public class CompasOverlay extends Overlay implements CompassListener {
private float mBearing;
private Context mContext;
private GeoPoint mDestination;
private GeoPoint mLocation;
private boolean isEnabled;
private CompassSensor mCompassSensor;
private int mNeedleResId = R.drawable.needle;
private int mBackgroundResId = R.drawable.compass;
private int mX = 100;
private int mY = 100;
private CompassListener mListener;
/**
* Creates a new CompasOverlay
* @author ricky barrette
*/
public CompasOverlay(Context context) {
mContext = context;
mCompassSensor = new CompassSensor(context);
}
/**
* Creates a new CompasOverlay
* @param context
* @param destination
* @author ricky barrette
*/
public CompasOverlay(Context context, GeoPoint destination){
this(context);
mDestination = destination;
}
/**
* Creates a new CompasOverlay
* @param context
* @param needleResId
* @param backgroundResId
* @param x
* @param y
* @author ricky barrette
*/
public CompasOverlay(Context context, int needleResId, int backgroundResId, int x, int y){
this(context, null, needleResId, backgroundResId, x, y);
}
/**
* Creates a new CompasOverlay
* @param context
* @param destination
* @param needleResId
* @param backgroundResId
* @param x
* @param y
* @author ricky barrette
*/
public CompasOverlay(Context context, GeoPoint destination, int needleResId, int backgroundResId, int x, int y){
this(context, destination);
mX = x;
mY = y;
mNeedleResId = needleResId;
mBackgroundResId = backgroundResId;
}
/**
* Calculated the bearing from the current location to the current destination, or returns the bearing for north if there is no destination
* @return bearing
* @author ricky barrette
*/
private float calculateBearing() {
if( (mLocation == null) || (mDestination == null) )
return mBearing;
float bearing = mBearing - GeoUtils.bearing(mLocation, mDestination).floatValue();
if (bearing != 0)
bearing = 360 - bearing;
return bearing;
}
/**
* Disables the compass overlay
* @author ricky barrette
*/
public void disable(){
isEnabled = false;
mCompassSensor.disable();
mListener = null;
}
/**
* (non-Javadoc)
* @see com.google.android.maps.Overlay#draw(android.graphics.Canvas, com.google.android.maps.MapView, boolean)
* @author ricky barrette
*/
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
if(isEnabled){
//set the center of the compass in the top left corner of the screen
Point point = new Point();
point.set(mX, mY);
//draw compass background
Bitmap compass = BitmapFactory.decodeResource( mContext.getResources(), mBackgroundResId);
canvas.drawBitmap(compass,
point.x - (compass.getWidth() / 2),
point.y - (compass.getHeight() / 2),
null
);
//draw the compass needle
Bitmap arrowBitmap = BitmapFactory.decodeResource( mContext.getResources(), mNeedleResId);
Matrix matrix = new Matrix();
matrix.postRotate(calculateBearing());
Bitmap rotatedBmp = Bitmap.createBitmap(
arrowBitmap,
0, 0,
arrowBitmap.getWidth(),
arrowBitmap.getHeight(),
matrix,
true
);
canvas.drawBitmap(
rotatedBmp,
point.x - (rotatedBmp.getWidth() / 2),
point.y - (rotatedBmp.getHeight() / 2),
null
);
mapView.invalidate();
}
super.draw(canvas, mapView, shadow);
}
/**
* Enables the compass overlay
* @author ricky barrette
*/
public void enable(){
if(! isEnabled){
isEnabled = true;
mCompassSensor.enable(this);
}
}
/**
* Enables the compass overlay
* @param listener
* @author ricky barrette
*/
public void enable(CompassListener listener){
mListener = listener;
enable();
}
/**
* @return the current bearing
* @author ricky barrette
*/
public float getBearing(){
return mBearing;
}
/**
* Called from the compass Sensor to update the current bearing
* (non-Javadoc)
* @see com.TwentyCodes.android.location.CompassListener#onCompassUpdate(float)
* @author ricky barrette
*/
@Override
public void onCompassUpdate(float bearing) {
mBearing = bearing;
/*
* pass it down the chain
*/
if(mListener != null)
mListener.onCompassUpdate(bearing);
}
/**
* @param destination
* @author ricky barrette
*/
public void setDestination(GeoPoint destination){
mDestination = destination;
}
/**
* @param needleResId
* @param backgroundResId
* @author ricky barrette
*/
public void setDrawables(int needleResId, int backgroundResId, int x, int y){
mX = x;
mY = y;
mNeedleResId = needleResId;
mBackgroundResId = backgroundResId;
}
/**
* @param location
* @author ricky barrette
*/
public void setLocation(GeoPoint location){
mLocation = location;
}
}

View File

@@ -0,0 +1,21 @@
/**
* CompassListener.java
* @date Mar 2, 2011
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.location;
/**
* A simple listener interface to get updates from CompassSensor
* @author ricky barrette
*/
public interface CompassListener {
/**
* Called when there is an update from the Compass Sensor
* @param bearing
* @author ricky barrette
*/
public void onCompassUpdate(float bearing);
}

View File

@@ -0,0 +1,138 @@
/**
* CompassSensor.java
* @date Mar 2, 2011
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.location;
import android.content.Context;
import android.content.res.Configuration;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Handler;
import android.os.Message;
import com.TwentyCodes.android.debug.Debug;
/**
* A simple convince class that accesses the compass sensor on another thread
* @author ricky barrette
*/
public class CompassSensor{
private static final int BEARING = 0;
private SensorManager mSensorManager;
private Context mContext;
private CompassListener mListener;
private Handler mHandler;
private SensorCallBack mCallBack;
/**
* A convince callback class for the compass sensor
* @author ricky barrette
*/
private class SensorCallBack implements SensorEventListener {
/**
* (non-Javadoc)
* @see android.hardware.SensorEventListener#onAccuracyChanged(android.hardware.Sensor, int)
* @author ricky barrette
*/
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// NOT USED
}
/**
* (non-Javadoc)
* @see android.hardware.SensorEventListener#onSensorChanged(android.hardware.SensorEvent)
* @author ricky barrette
*/
@Override
public void onSensorChanged(SensorEvent event) {
float myAzimuth = event.values[0];
// myPitch = event.values[1];
float roll = event.values[2];
if (mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
boolean isNormal = false;
if (roll <= -25)
isNormal = false;
if (roll >= 25)
isNormal = true;
if (isNormal)
myAzimuth = myAzimuth + 90;
else
myAzimuth = myAzimuth - 90;
}
mHandler.sendMessage(mHandler.obtainMessage(BEARING, myAzimuth));
}
}
/**
* Creates a new CompassSensor
* @author ricky barrette
*/
public CompassSensor(Context context) {
mContext = context;
setUiHandler();
//start getting information from the compass sensor
new Thread(new Runnable(){
@Override
public void run() {
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
}
}).start();
mCallBack = new SensorCallBack();
}
/**
* Disables compass updates
* @author ricky barrette
*/
public void disable(){
mListener = null;
mSensorManager.unregisterListener(mCallBack);
}
/**
* Attempts to register the listener for compass updates
* @param listener
* @author ricky barrette
*/
public void enable(CompassListener listener){
if(mListener == null) {
mListener = listener;
if(mSensorManager == null)
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
mSensorManager.registerListener(mCallBack, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), Debug.COMPASS_UPDATE_INTERVAL);
}
}
/**
* Sets up the UI handler
* @author ricky barrette
*/
private void setUiHandler() {
mHandler = new Handler(){
@Override
public void handleMessage(Message msg){
System.out.print((Float) msg.obj);
if(mListener != null)
if(msg.what == BEARING)
mListener.onCompassUpdate((Float) msg.obj);
}
};
}
}

View File

@@ -0,0 +1,23 @@
/**
* @author Twenty Codes, LLC
* @author ricky barrette
* @date Oct 2, 2010
*/
package com.TwentyCodes.android.location;
import com.google.android.maps.GeoPoint;
/**
* this interface will be used to interface with skyhook sdk with the rest of the application
* @author ricky barrette
*/
public interface GeoPointLocationListener {
/**
* Called when the location has changed
* @param point
* @param accuracy
* @author ricky barrette
*/
public void onLocationChanged(GeoPoint point, int accuracy);
}

View File

@@ -0,0 +1,232 @@
/**
* @author Twenty Codes, LLC
* @author Google Inc.
* @author ricky barrette
* @date Oct 2, 2010
*
* Some Code here is Copyright (C) 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.TwentyCodes.android.location;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Point;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
/**
* This class contains common tools for computing common geological problems
* @author ricky barrette
* @author Google Inc.
*/
public class GeoUtils {
public static final int EARTH_RADIUS_KM = 6371;
public static final double MILLION = 1000000;
/**
* computes the bearing of lat2/lon2 in relationship from lat1/lon1 in degrees East
* @param lat1 source lat
* @param lon1 source lon
* @param lat2 destination lat
* @param lon2 destination lon
* @return the bearing of lat2/lon2 in relationship from lat1/lon1 in degrees East
* @author Google Inc.
*/
public static double bearing(double lat1, double lon1, double lat2, double lon2) {
double lat1Rad = Math.toRadians(lat1);
double lat2Rad = Math.toRadians(lat2);
double deltaLonRad = Math.toRadians(lon2 - lon1);
double y = Math.sin(deltaLonRad) * Math.cos(lat2Rad);
double x = Math.cos(lat1Rad) * Math.sin(lat2Rad) - Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLonRad);
return radToBearing(Math.atan2(y, x));
}
/**
* computes the bearing of lat2/lon2 in relationship from lat1/lon1 in degrees East
* @param p1 source geopoint
* @param p2 destination geopoint
* @return the bearing of p2 in relationship from p1 in degrees East
* @author Google Inc.
*/
public static Double bearing(GeoPoint p1, GeoPoint p2) {
double lat1 = p1.getLatitudeE6() / MILLION;
double lon1 = p1.getLongitudeE6() / MILLION;
double lat2 = p2.getLatitudeE6() / MILLION;
double lon2 = p2.getLongitudeE6() / MILLION;
return bearing(lat1, lon1, lat2, lon2);
}
/**
* Calculates a geopoint x meters away of the geopoint supplied. The new geopoint
* shares the same latitude as geopoint point, this way they are on the same latitude arc.
*
* @param point central geopoint
* @param distance in meters from the geopoint
* @return geopoint that is x meters away from the geopoint supplied
* @author ricky barrette
*/
public static GeoPoint distanceFrom(GeoPoint point, double distance){
//convert meters into kilometers
distance = distance / 1000;
// convert lat and lon of geopoint to radians
double lat1Rad = Math.toRadians((point.getLatitudeE6() / 1e6));
double lon1Rad = Math.toRadians((point.getLongitudeE6() / 1e6));
/*
* kilometers = acos(sin(lat1Rad)sin(lat2Rad)+cos(lat1Rad)cos(lat2Rad)cos(lon2Rad-lon1Rad)6371
*
* we are solving this equation for lon2Rad
*
* lon2Rad = lon1Rad+acos(cos(meters/6371)sec(lat1Rad)sec(lat2Rad)-tan(lat1Rad)tan(lat2Rad))
*
* NOTE: sec(x) = 1/cos(x)
*
* NOTE: that lat2Rad is = lat1Rad because we want to keep the new geopoint on the same lat arc
* therefore i saw no need to create a new variable for lat2Rad,
* and simply inputed lat1Rad in place of lat2Rad in the equation
*
* NOTE: this equation has be tested in the field against another gps device, and the distanceKm() from google
* and has been proven to be damn close
*/
double lon2Rad = lon1Rad + Math.acos( Math.cos((distance/6371)) * (1 / Math.cos(lat1Rad))
* (1 / Math.cos(lat1Rad)) - Math.tan(lat1Rad) * Math.tan(lat1Rad));
//return a geopoint that is x meters away from the geopoint supplied
return new GeoPoint(point.getLatitudeE6(), (int) (Math.toDegrees(lon2Rad) * 1e6));
}
/**
* computes the distance between to lat1/lon1 and lat2/lon2 based on the curve of the earth
* @param lat1 source lat
* @param lon1 source lon
* @param lat2 destination lat
* @param lon2 destination lon
* @return the distance between to lat1/lon1 and lat2/lon2
* @author Google Inc.
*/
public static double distanceKm(double lat1, double lon1, double lat2, double lon2) {
double lat1Rad = Math.toRadians(lat1);
double lat2Rad = Math.toRadians(lat2);
double deltaLonRad = Math.toRadians(lon2 - lon1);
return Math.acos(Math.sin(lat1Rad) * Math.sin(lat2Rad) + Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.cos(deltaLonRad)) * EARTH_RADIUS_KM;
}
/**
* a convince method for testing if 2 circles on the the surface of the earth intersect.
* we will use this method to test if the users accuracy circle intersects a marked locaton's radius
* if ( (accuracyCircleRadius + locationRadius) - fudgeFactor) > acos(sin(lat1Rad)sin(lat2Rad)+cos(lat1Rad)cos(lat2Rad)cos(lon2Rad-lon1Rad)6371
* @param userPoint
* @param accuracyRadius in KM
* @param locationPoint
* @param locationRadius in KM
* @param fudgeFactor how many KM the circles have to intersect
* @return true if the circles intersect
* @author ricky barrette
*/
public static boolean isIntersecting(GeoPoint userPoint, float accuracyRadius, GeoPoint locationPoint, float locationRadius, float fudgeFactor){
if(((accuracyRadius + locationRadius) - fudgeFactor) > distanceKm(locationPoint, userPoint))
return true;
return false;
}
/**
* computes the distance between to p1 and p2 based on the curve of the earth
* @param p1
* @param p2
* @return the distance between to p1 and p2
* @author Google Inc.
*/
public static double distanceKm(GeoPoint p1, GeoPoint p2) {
//if we are handed a null, return -1 so we don't break
if(p1 == null || p2 == null)
return -1;
double lat1 = p1.getLatitudeE6() / MILLION;
double lon1 = p1.getLongitudeE6() / MILLION;
double lat2 = p2.getLatitudeE6() / MILLION;
double lon2 = p2.getLongitudeE6() / MILLION;
return distanceKm(lat1, lon1, lat2, lon2);
}
/**
* determines when the specified point is off the map
* @param point
* @return true is the point is off the map
* @author ricky barrette
*/
public static boolean isPointOffMap(MapView map , GeoPoint point){
if(map == null)
return false;
if (point == null)
return false;
GeoPoint center = map.getMapCenter();
double distance = GeoUtils.distanceKm(center, point);
double distanceLat = GeoUtils.distanceKm(center, new GeoPoint((center.getLatitudeE6() + (int) (map.getLatitudeSpan() / 2)), center.getLongitudeE6()));
double distanceLon = GeoUtils.distanceKm(center, new GeoPoint(center.getLatitudeE6(), (center.getLongitudeE6() + (int) (map.getLongitudeSpan() / 2))));
if (distance > distanceLat || distance > distanceLon){
return true;
}
return false;
}
/**
* computes a geopoint the is the central geopoint between p1 and p1
* @param p1 first geopoint
* @param p2 second geopoint
* @return a MidPoint object
* @author ricky barrette
*/
public static MidPoint midPoint(GeoPoint p1, GeoPoint p2) {
int minLatitude = (int)(+81 * 1E6);
int maxLatitude = (int)(-81 * 1E6);
int minLongitude = (int)(+181 * 1E6);
int maxLongitude = (int)(-181 * 1E6);
List<Point> mPoints = new ArrayList<Point>();
int latitude = p1.getLatitudeE6();
int longitude = p1.getLongitudeE6();
if (latitude != 0 && longitude !=0) {
minLatitude = (minLatitude > latitude) ? latitude : minLatitude;
maxLatitude = (maxLatitude < latitude) ? latitude : maxLatitude;
minLongitude = (minLongitude > longitude) ? longitude : minLongitude;
maxLongitude = (maxLongitude < longitude) ? longitude : maxLongitude;
mPoints.add(new Point(latitude, longitude));
}
latitude = p2.getLatitudeE6();
longitude = p2.getLongitudeE6();
if (latitude != 0 && longitude !=0) {
minLatitude = (minLatitude > latitude) ? latitude : minLatitude;
maxLatitude = (maxLatitude < latitude) ? latitude : maxLatitude;
minLongitude = (minLongitude > longitude) ? longitude : minLongitude;
maxLongitude = (maxLongitude < longitude) ? longitude : maxLongitude;
mPoints.add(new Point(latitude, longitude));
}
return new MidPoint(new GeoPoint((maxLatitude + minLatitude)/2, (maxLongitude + minLongitude)/2 ), minLatitude, minLongitude, maxLatitude, maxLongitude);
}
/**
* converts radians to bearing
* @param rad
* @return bearing
* @author Google Inc.
*/
public static double radToBearing(double rad) {
return (Math.toDegrees(rad) + 360) % 360;
}
}

View File

@@ -0,0 +1,46 @@
/**
* @author Twenty Codes, LLC
* @author ricky barrette
* @date Oct 18, 2010
*/
package com.TwentyCodes.android.location;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
/**
* this abstract class will be used as a for classes wishing to be a receiver of location updates from the location services
* @author ricky barrette
*/
public abstract class LocationReceiver extends BroadcastReceiver {
public static final String INTENT_EXTRA_ACTION_UPDATE = "TwentyCodes.intent.action.LocationUpdate";
public static final String INTENT_EXTRA_LOCATION_PARCEL = "location_parcel";
public Context mContext;
/**
* (non-Javadoc)
* @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
* @param contextonBind
* @param intent
* @author ricky barrette
*/
@Override
public void onReceive(Context context, Intent intent) {
mContext = context;
if(intent.getParcelableExtra(INTENT_EXTRA_LOCATION_PARCEL) != null){
Location location = intent.getParcelableExtra(INTENT_EXTRA_LOCATION_PARCEL);
onLocationUpdate(location);
}
}
/**
* called when a location update is received
* @param parcelableExtra
* @author ricky barrette
*/
public abstract void onLocationUpdate(Location location);
}

View File

@@ -0,0 +1,255 @@
/**
* @author Twenty Codes, LLC
* @author ricky barrette
* @date Oct 28, 2010
*/
package com.TwentyCodes.android.location;
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;
import com.TwentyCodes.android.debug.Debug;
/**
* This service class will be used broadcast the users location either one time, or periodically.
* To use as a one shot location service:
* <blockquote><pre>PendingIntent pendingIntent = PendingIntent.getService(context, 0, LocationService.startService(context), 0);
* or
* Intent service = new Intent(context, LocationService.class);
* context.startService(service);<pre></bloackquote>
* To use as a recurring service:
* <blockquote>LocationService.startService(this, (60000 * Integer.parseInt(ringer.getString(UPDATE_INTVERVAL , "5")))).run();</bloackquote>
* @author ricky barrette
*/
public class LocationService extends Service implements LocationListener {
/**
* Used to tell the service how frequently it needs to run. This is required if you want a multishot service
*/
public static final String INTENT_EXTRA_PERIOD_BETWEEN_UPDATES = "period_beween_updates";
/**
* Used to tell the service how accurate of a location you want reported
*/
public static final String INTENT_EXTRA_REQUIRED_ACCURACY = "required_accuracy";
/**
* Used to tell the service the update action to broadcast. If this is not supplied, {@link LocationReceiver.INTENT_EXTRA_ACTION_UPDATE } will be used.
* @see LocationReceiver.INTENT_EXTRA_ACTION_UPDATE
*/
public static final String INTENT_EXTRA_ACTION_UPDATE = "action_update";
public static final String TAG = "LocationService";
private static final int REQUEST_CODE = 7893749;
private WakeLock mWakeLock;
private long mPeriod = -1;
private Location mLocation;
private int mStartId;
private AndroidGPS mLocationManager;
private int mRequiredAccuracy;
private Intent mIntent;
/*
* this runnable will be qued when the service is created. this will be used as a fail safe
*/
private Runnable failSafe = new Runnable() {
@Override
public void run(){
stopSelf(mStartId);
}
};
/**
* registers this service to be waken up by android's alarm manager
* @author ricky barrette
*/
private void registerwakeUp(){
Log.d(TAG, "registerwakeUp()");
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + this.mPeriod, PendingIntent.getService(this, REQUEST_CODE, this.mIntent, 0));
}
/**
* broadcasts location to anything listening for updates,
* since this is the last function of the service, we call finish()u
* @author ricky barrette
*/
private void broadcastLocation() {
Log.d(TAG, "broadcastLocation()");
if (mLocation != null) {
Intent locationUpdate = new Intent();
if(mIntent.getAction() != null)
locationUpdate.setAction(mIntent.getAction());
else
locationUpdate.setAction(LocationReceiver.INTENT_EXTRA_ACTION_UPDATE);
locationUpdate.putExtra(LocationReceiver.INTENT_EXTRA_LOCATION_PARCEL, mLocation);
sendBroadcast(locationUpdate);
stopSelf(mStartId);
}
}
/**
* called when the service is created. this will initialize the location manager, and acquire a wakelock
* (non-Javadoc)
* @see android.app.Service#onCreate()
* @author ricky barrette
*/
@Override
public void onCreate(){
mLocationManager = new AndroidGPS(this);
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
mWakeLock.acquire();
/*
* que the fail safe runnable to kill the report location and kill it self after the MAX_RUN_TIME has been meet
*/
new Handler().postDelayed(failSafe, Debug.MAX_LOCATION_SERVICE_RUN_TIME);
super.onCreate();
}
/**
* called when the service is destroyed.
* this will remove any wakelock or location service running, and register to be waken back up
* (non-Javadoc)
* @see android.app.Service#onDestroy()
* @author ricky barrette
*/
@Override
public void onDestroy(){
broadcastLocation();
mLocationManager.disableLocationUpdates();
if(mWakeLock.isHeld())
mWakeLock.release();
if(mPeriod > -1)
registerwakeUp();
}
/**
* To keep backwards compatibility we override onStart which is the equivalent of onStartCommand in pre android 2.x
* @author ricky barrette
*/
@Override
public void onStart(Intent intent, int startId) {
if(Debug.DEBUG)
Log.i(TAG, "onStart.Service started with start id of: " + startId);
mStartId = startId;
parseIntent(intent);
mLocationManager.enableLocationUpdates(this);
}
/**
* This method is called when startService is called. only used in 2.x android.
* @author ricky barrette
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(Debug.DEBUG)
Log.i(TAG , "onStartCommand.Service started with start id of: " + startId);
mStartId = startId;
parseIntent(intent);
mLocationManager.enableLocationUpdates(this);
return START_STICKY;
}
/**
* Parses the incoming intent for the service options
*
* @author ricky barrette
*/
private void parseIntent(Intent intent){
this.mIntent = intent;
if (intent.hasExtra(INTENT_EXTRA_PERIOD_BETWEEN_UPDATES))
mPeriod = intent.getLongExtra(INTENT_EXTRA_PERIOD_BETWEEN_UPDATES, 60000L);
if (intent.hasExtra(INTENT_EXTRA_REQUIRED_ACCURACY))
mRequiredAccuracy = intent.getIntExtra(INTENT_EXTRA_REQUIRED_ACCURACY, -1);
}
/**
* (non-Javadoc)
* @see android.app.Service#onBind(android.content.Intent)
* @param arg0
* @return
* @author ricky barrette
*/
@Override
public IBinder onBind(Intent arg0) {
// UNUSED
return null;
}
/**
*a convince method for getting an intent to start the service
* @param context
* @return a intent that will start the service
* @author ricky barrette
*/
public static Intent getStartServiceIntent(final Context context){
return new Intent(context, LocationService.class);
}
/**
* a convince method for stopping the service and removing it's alarm
* @param context
* @return a runnable that will stop the service
* @author ricky barrette
*/
public static Runnable stopService(final Context context){
return new Runnable(){
@Override
public void run(){
context.stopService(new Intent(context, LocationService.class));
((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).cancel(PendingIntent.getService(context, REQUEST_CODE, new Intent(context, LocationService.class), 0));
}
};
}
@Override
public void onLocationChanged(Location location) {
if(Debug.DEBUG)
Log.d(TAG, "got location +- "+ location.getAccuracy() +"m");
mLocation = location;
if(location.getAccuracy() <= (mRequiredAccuracy > -1 ? mRequiredAccuracy : Debug.MINIMUM_REQUIRED_ACCURACY) || Debug.REPORT_FIRST_LOCATION){
stopSelf(mStartId);
}
}
@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
}
}

View File

@@ -0,0 +1,110 @@
/**
* @author Twenty Codes, LLC
* @author ricky barrette
* @date Oct 10, 2010
*/
package com.TwentyCodes.android.location;
import com.TwentyCodes.android.debug.Debug;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
/**
* We use this MapView Because it has double tap zoom capability and exception handling
* @author ricky barrette
*/
public class MapView extends com.google.android.maps.MapView {
private static final String TAG = "MapView";
private long mLastTouchTime;
private boolean mDoubleTapZoonEnabled = true;
/**
* @param context
* @param apiKey
* @author ricky barrette
*/
public MapView(Context context, String apiKey) {
super(context, apiKey);
}
/**
* @param context
* @param attrs
* @author ricky barrette
*/
public MapView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* @param context
* @param attrs
* @param defStyle
* @author ricky barrette
*/
public MapView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
long thisTime = System.currentTimeMillis();
if (this.mDoubleTapZoonEnabled && thisTime - mLastTouchTime < 250) {
// Double tap
this.getController().zoomInFixing((int) ev.getX(), (int) ev.getY());
mLastTouchTime = -1;
} else {
// Too slow
mLastTouchTime = thisTime;
}
}
return super.onInterceptTouchEvent(ev);
}
/**
* We will override the draw method to help prevent issues
* (non-Javadoc)
* @see android.view.View#draw(android.graphics.Canvas)
* @author ricky barrette
*/
@Override
public void draw(Canvas canvas) {
try {
if(this.getZoomLevel() >= 21) {
this.getController().setZoom(20);
}
super.draw(canvas);
}
catch(Exception ex) {
// getController().setCenter(this.getMapCenter());
// getController().setZoom(this.getZoomLevel() - 2);
if(Debug.DEBUG)
Log.d(TAG, "Internal error in MapView:" + Log.getStackTraceString(ex));
}
}
/**
* @param isDoubleTapZoonEnabled the isDoubleTapZoonEnabled to set
* @author ricky barrette
*/
public void setDoubleTapZoonEnabled(boolean isDoubleTapZoonEnabled) {
this.mDoubleTapZoonEnabled = isDoubleTapZoonEnabled;
}
/**
* @return the isDoubleTapZoonEnabled
* @author ricky barrette
*/
public boolean getDoubleTapZoonEnabled() {
return mDoubleTapZoonEnabled;
}
}

View File

@@ -0,0 +1,51 @@
/**
* @author Twenty Codes, LLC
* @author ricky barrette
* @date Nov 30, 2010
*/
package com.TwentyCodes.android.location;
import com.google.android.maps.GeoPoint;
/**
* This MidPoint object will hold the information form the calculations performed by GeoUtils.midPoint().
* @author ricky barrette
*/
public class MidPoint {
private int mMinLatitude;
private int mMaxLatitude;
private int mMinLongitude;
private int mMaxLongitude;
private GeoPoint mMidPoint;
/**
* Creates a new MidPoint
* @author ricky barrette
*/
public MidPoint(GeoPoint midPoint, int minLatitude, int minLongitude, int maxLatitude, int maxLongitude) {
mMinLatitude = minLatitude;
mMaxLatitude = maxLatitude;
mMinLongitude = minLongitude;
mMaxLongitude = maxLongitude;
mMidPoint = midPoint;
}
/**
* zooms the provided map view to the span of this mid point
* @param mMapView
* @author ricky barrette
*/
public void zoomToSpan(com.google.android.maps.MapView mMapView){
mMapView.getController().zoomToSpan((mMaxLatitude - mMinLatitude), (mMaxLongitude - mMinLongitude));
}
/**
* returns the calculated midpoint
* @return
* @author ricky barrette
*/
public GeoPoint getMidPoint(){
return mMidPoint;
}
}

View File

@@ -0,0 +1,149 @@
/**
* ReverseGeocoder.java
* @date Jan 31, 2011
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.location;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.location.Location;
import android.util.Log;
import com.TwentyCodes.android.debug.Debug;
/**
* Due to this bug http://code.google.com/p/android/issues/detail?id=8816 google's Geocoder class does not function in android 2.2+.
* I found this source in one of the comments mentioning that it is a work around.
*
* @author ricky barrette
*/
public class ReverseGeocoder {
private static final String TAG = "ReverseGeocoder";
/**
* Performs a google maps search for the address
* @param location
* @return JSON Array on google place marks nearby
* @author ricky barrette
* @throws IOException
* @throws JSONException
*/
public static JSONArray getFromLocation(Location location) throws IOException, JSONException {
String urlStr = "http://maps.google.com/maps/geo?q=" + location.getLatitude() + "," + location.getLongitude() + "&output=json&sensor=false";
StringBuffer response = new StringBuffer();
HttpClient client = new DefaultHttpClient();
if(Debug.DEBUG)
Log.d(TAG, urlStr);
HttpResponse hr = client.execute(new HttpGet(urlStr));
HttpEntity entity = hr.getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));
String buff = null;
while ((buff = br.readLine()) != null)
response.append(buff);
if(Debug.DEBUG)
Log.d(TAG, response.toString());
return new JSONObject(response.toString()).getJSONArray("Placemark");
}
/**
* Performs a google maps search for the closest address to the location
* @param lat
* @param lon
* @return string address, or lat, lon if search fails
* @author ricky barrette
*/
public static String getAddressFromLocation(Location location) {
String urlStr = "http://maps.google.com/maps/geo?q=" + location.getLatitude() + "," + location.getLongitude() + "&output=json&sensor=false";
StringBuffer response = new StringBuffer();
HttpClient client = new DefaultHttpClient();
if(Debug.DEBUG)
Log.d(TAG, urlStr);
try {
HttpResponse hr = client.execute(new HttpGet(urlStr));
HttpEntity entity = hr.getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));
String buff = null;
while ((buff = br.readLine()) != null)
response.append(buff);
} catch (IOException e) {
e.printStackTrace();
}
if(Debug.DEBUG)
Log.d(TAG, response.toString());
JSONArray responseArray = null;
try {
responseArray = new JSONObject(response.toString()).getJSONArray("Placemark");
} catch (JSONException e) {
return location.getLatitude() +", "+ location.getLongitude() +" ± "+ location.getAccuracy()+"m";
}
if(Debug.DEBUG)
Log.d(TAG,responseArray.length() + " result(s)");
try {
JSONObject jsl = responseArray.getJSONObject(0);
return jsl.getString("address");
} catch (JSONException e) {
e.printStackTrace();
}
return location.getLatitude() +", "+ location.getLongitude() +" ± "+ location.getAccuracy()+"m";
}
/**
* Performs a google maps search for the address
* @param address to search
* @return JSON Array of google place marks
* @throws IOException
* @throws JSONException
* @author ricky barrette
*/
public static JSONArray addressSearch(String address) throws IOException, JSONException {
String urlStr = "http://maps.google.com/maps/geo?q=" + address + "&output=json&sensor=false";
urlStr = urlStr.replace(' ', '+');
StringBuffer response = new StringBuffer();
HttpClient client = new DefaultHttpClient();
if(Debug.DEBUG)
Log.d(TAG, urlStr);
HttpResponse hr = client.execute(new HttpGet(urlStr));
HttpEntity entity = hr.getEntity();
BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));
String buff = null;
while ((buff = br.readLine()) != null)
response.append(buff);
if(Debug.DEBUG)
Log.d(TAG, response.toString());
return new JSONObject(response.toString()).getJSONArray("Placemark");
}
}

View File

@@ -0,0 +1,351 @@
/**
* @author Twenty Codes, LLC
* @author ricky barrette
* @date Dec 28, 2010
*/
package com.TwentyCodes.android.location;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.location.Location;
import android.os.Handler;
import android.os.SystemClock;
import com.TwentyCodes.android.SkyHook.R;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Projection;
/**
* This is the standard version of the UserOverlay.
* @author ricky barrette
*/
public class UserOverlay extends MyLocationOverlay {
private Context mContext;
private MapView mMapView;
private ProgressDialog mGPSprogress;
private boolean isFirstFix = true;
private GeoPointLocationListener mListener;
private boolean isFollowingUser = true;
private float myAzimuth;
private GeoPoint mUser;
private GeoPoint mDest;
private boolean isShowingCompass;
private AnimationDrawable mUserArrow;
/**
* Creates a new UserOverlay
* @param context
* @param mapView
* @author ricky barrette
*/
public UserOverlay(Context context, MapView mapView) {
super(context, mapView);
mMapView = mapView;
mContext = context;
mUserArrow = (AnimationDrawable) mContext.getResources().getAnimation(R.drawable.userarrow);
mUserArrow.start();
}
/**
* disables the compass view
* (non-Javadoc)
* @see com.google.android.maps.MyLocationOverlay#disableCompass()
* @author ricky barrette
*/
@Override
public void disableCompass(){
isShowingCompass = false;
}
/**
* called when the overlay is disabled. this will disable all progress dialogs, and location based servicess
* (non-Javadoc)
* @see com.google.android.maps.MyLocationOverlay#disableMyLocation()
* @author ricky barrette
*/
@Override
public void disableMyLocation(){
super.disableCompass();
super.disableMyLocation();
mGPSprogress.dismiss();
}
/**
* draws an accuracy circle onto the canvas supplied
* @param center point of the circle
* @param left point of the circle
* @param canvas to be drawn on
* @return modified canvas
* @author ricky barrette
*/
private Canvas drawAccuracyCircle(Point center, Point left, Canvas canvas) {
Paint paint = new Paint();
/*
* get radius of the circle being drawn by
*/
int circleRadius = center.x - left.x;
if(circleRadius <= 0){
circleRadius = left.x - center.x;
}
/*
* paint a blue circle on the map
*/
paint.setAntiAlias(true);
paint.setStrokeWidth(2.0f);
paint.setColor(Color.BLUE);
paint.setStyle(Style.STROKE);
canvas.drawCircle(center.x, center.y, circleRadius, paint);
/*
* fill the radius with a alpha blue
*/
paint.setAlpha(30);
paint.setStyle(Style.FILL);
canvas.drawCircle(center.x, center.y, circleRadius, paint);
/*
* for testing
* draw a dot over the left geopoint
*/
// paint.setColor(Color.RED);
// RectF oval = new RectF(left.x - 1, left.y - 1, left.x + 1, left.y + 1);
// canvas.drawOval(oval, paint);
return canvas;
}
/**
* computes bearing to geopoint based on device oriantaion and draws the compass of what you want really really badly on screen
* @param - canvas - the canvas to draw on
* @param - bearing - bearing of user based on magnetic compass
* @author ricky barrette
*/
@Override
protected void drawCompass(Canvas canvas, float bearing){
myAzimuth = bearing;
mMapView.invalidate();
if (isShowingCompass) {
/*
* if the dest and user geopoint are not null, then draw the compass point to the dest geopoint
*
* else draw the compass to point north
*/
if (mUser != null && mDest != null){
Double d = GeoUtils.bearing(mUser, mDest);
bearing = bearing - d.floatValue();
} else if (bearing != 0){
bearing = 360 - bearing;
}
super.drawCompass(canvas, bearing);
}
}
/**
* we override this methods so we can provide a drawable and a location to draw on the canvas.
* (non-Javadoc)
* @see com.google.android.maps.Overlay#draw(android.graphics.Canvas, com.google.android.maps.MapView, boolean)
* @param canvas
* @param mapView
* @param shadow
* @author ricky barrette
*/
@Override
protected void drawMyLocation(Canvas canvas, MapView mapView, Location lastFix, GeoPoint point, long when){
if (point != null) {
Point center = new Point();
Point left = new Point();
Projection projection = mapView.getProjection();
GeoPoint leftGeo = GeoUtils.distanceFrom(point, lastFix.getAccuracy());
projection.toPixels(leftGeo, left);
projection.toPixels(point, center);
canvas = drawAccuracyCircle(center, left, canvas);
canvas = drawUser(center, myAzimuth, canvas);
/*
* the following log is used to demonstrate if the leftGeo point is the correct
*/
// Log.d(SkyHook.TAG, (GeoUtils.distanceKm(mPoint, leftGeo) * 1000)+"m");
}
}
/**
* draws user arrow that points north based on bearing onto the supplied canvas
* @param point to draw user arrow on
* @param bearing of the device
* @param canvas to draw on
* @return modified canvas
* @author ricky barrette
*/
private Canvas drawUser(Point point, float bearing, Canvas canvas){
Bitmap arrowBitmap = ((BitmapDrawable)mUserArrow.getCurrent()).getBitmap();
Matrix matrix = new Matrix();
matrix.postRotate(bearing);
Bitmap rotatedBmp = Bitmap.createBitmap(
arrowBitmap,
0, 0,
arrowBitmap.getWidth(),
arrowBitmap.getHeight(),
matrix,
true
);
canvas.drawBitmap(
rotatedBmp,
point.x - (rotatedBmp.getWidth() / 2),
point.y - (rotatedBmp.getHeight() / 2),
null
);
return canvas;
}
/**
* enables the compass view
* (non-Javadoc)
* @see com.google.android.maps.MyLocationOverlay#enableCompass()
* @author ricky barrette
*/
@Override
public boolean enableCompass(){
isShowingCompass = true;
return isShowingCompass;
}
/**
* called when the user overlay is enabled, this will display the progress dialog
* (non-Javadoc)
* @see com.google.android.maps.MyLocationOverlay#enableMyLocation()
* @author ricky barrette
*/
@Override
public boolean enableMyLocation(){
mGPSprogress = ProgressDialog.show(mContext, "", mContext.getText(R.string.gps_fix), true, true);
isFirstFix = true;
super.enableCompass();
/**
* this is a message that tells the user that we are having trouble getting an GPS signal
*/
new Handler().postAtTime(new Runnable() {
@Override
public void run() {
if (mGPSprogress.isShowing()) {
mGPSprogress.cancel();
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage(
mContext.getText(R.string.sorry_theres_trouble))
.setCancelable(false)
.setPositiveButton(mContext.getText(android.R.string.ok),
new DialogInterface.OnClickListener() {
public void onClick( DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder.show();
}
}
}, SystemClock.uptimeMillis()+90000L);
return super.enableMyLocation();
}
/**
* Allows the map to follow the user
* @param followUser
* @author ricky barrette
*/
public void followUser(boolean followUser){
isFollowingUser = followUser;
}
/**
* called when the SkyHook location changes, this method is resposiable for updating the overlay location and accuracy circle.
* (non-Javadoc)
* @see com.TwentyCodes.android.SkyHook.GeoPointLocationListener.location.LocationListener#onLocationChanged(com.google.android.maps.GeoPoint, float)
* @param point
* @param accuracy
* @author ricky barrette
*/
@Override
public void onLocationChanged(Location location) {
GeoPoint point = new GeoPoint((int) (location.getLatitude() *1e6), (int) (location.getLongitude() *1e6));
/*
* if this is the first fix
* set map center the users location, and zoom to the max zoom level
*/
if(point != null && isFirstFix){
mMapView.getController().setCenter(point);
mMapView.getController().setZoom(mMapView.getMaxZoomLevel()+3);
mGPSprogress.dismiss();
isFirstFix = false;
}
//pan to user if off map
if (isFollowingUser) {
panToUserIfOffMap(point);
}
mListener.onLocationChanged(point, (int) location.getAccuracy());
super.onLocationChanged(location);
}
/**
* pans the map view if the user is off screen.
* @author ricky barrette
*/
private void panToUserIfOffMap(GeoPoint user) {
GeoPoint center = mMapView.getMapCenter();
double distance = GeoUtils.distanceKm(center, user);
double distanceLat = GeoUtils.distanceKm(center, new GeoPoint((center.getLatitudeE6() + (int) (mMapView.getLatitudeSpan() / 2)), center.getLongitudeE6()));
double distanceLon = GeoUtils.distanceKm(center, new GeoPoint(center.getLatitudeE6(), (center.getLongitudeE6() + (int) (mMapView.getLongitudeSpan() / 2))));
double whichIsGreater = (distanceLat > distanceLon) ? distanceLat : distanceLon;
/**
* if the user is one the map, keep them their
* else don't pan to user unless they pan pack to them
*/
if( ! (distance > whichIsGreater) )
if (distance > distanceLat || distance > distanceLon){
mMapView.getController().animateTo(user);
}
}
/**
* Attempts to register the listener for location updates
* @param listener
* @author Ricky Barrette
*/
public void registerListener(GeoPointLocationListener listener){
if (mListener == null){
mListener = listener;
}
}
/**
* UnResgisters the listener. after this call you will no longer get location updates
* @author Ricky Barrette
*/
public void unRegisterListener(){
mListener = null;
}
}