1. 写一个获取GPS信息的处理类,这个类用到的知识基本就是LocationManager的CallBack和系统提供的NetworkProvider 和GPSProvider, 代码如下:
public class MyLocationListener implements LocationListener {
private static final String TAG = "BestLocationListener";
private static final boolean DEBUG = true;
public static final long LOCATION_UPDATE_MIN_TIME = 0;
public static final long LOCATION_UPDATE_MIN_DISTANCE = 0;
public static final long SLOW_LOCATION_UPDATE_MIN_TIME = 1000 * 60 * 5;
public static final long SLOW_LOCATION_UPDATE_MIN_DISTANCE = 50;
public static final float REQUESTED_FIRST_SEARCH_ACCURACY_IN_METERS = 100.0f;
public static final int REQUESTED_FIRST_SEARCH_MAX_DELTA_THRESHOLD = 1000 * 60 * 5;
public static final long LOCATION_UPDATE_MAX_DELTA_THRESHOLD = 1000 * 60 * 5;
private Location mLastLocation;
private LocationObservable mObservable;
public MyLocationListener(LocationObservable observable) {
super();
mObservable = observable;
}
@Override
public void onLocationChanged(Location location) {
if (DEBUG) Log.d(TAG, "onLocationChanged: " + location);
updateLocation(location);
}
@Override
public void onProviderDisabled(String provider) {
// do nothing.
}
@Override
public void onProviderEnabled(String provider) {
// do nothing.
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// do nothing.
}
synchronized public void onBestLocationChanged(Location location) {
if (DEBUG) Log.d(TAG, "onBestLocationChanged: " + location);
mLastLocation = location;
//setChanged();
//notifyObservers(location);
if (mObservable != null){
mObservable.updateLocation(location);
}
}
synchronized public Location getLastKnownLocation() {
return mLastLocation;
}
public void updateLocation(Location location) {
if (DEBUG) {
Log.d(TAG, "updateLocation: Old: " + mLastLocation);
Log.d(TAG, "updateLocation: New: " + location);
}
// Cases where we only have one or the other.
if (location != null && mLastLocation == null) {
if (DEBUG) Log.d(TAG, "updateLocation: Null last location");
onBestLocationChanged(location);
return;
} else if (location == null) {
if (DEBUG) Log.d(TAG, "updated location is null, doing nothing");
return;
}
long now = new Date().getTime();
long locationUpdateDelta = now - location.getTime();
long lastLocationUpdateDelta = now - mLastLocation.getTime();
boolean locationIsInTimeThreshold = locationUpdateDelta <= LOCATION_UPDATE_MAX_DELTA_THRESHOLD;
boolean lastLocationIsInTimeThreshold = lastLocationUpdateDelta <= LOCATION_UPDATE_MAX_DELTA_THRESHOLD;
boolean locationIsMostRecent = locationUpdateDelta <= lastLocationUpdateDelta;
boolean accuracyComparable = location.hasAccuracy() || mLastLocation.hasAccuracy();
boolean locationIsMostAccurate = false;
if (accuracyComparable) {
// If we have only one side of the accuracy, that one is more
// accurate.
if (location.hasAccuracy() && !mLastLocation.hasAccuracy()) {
locationIsMostAccurate = true;
} else if (!location.hasAccuracy() && mLastLocation.hasAccuracy()) {
locationIsMostAccurate = false;
} else {
// If we have both accuracies, do a real comparison.
locationIsMostAccurate = location.getAccuracy() <= mLastLocation.getAccuracy();
}
}
if (DEBUG) {
Log.d(TAG, "locationIsMostRecent:\t\t\t" + locationIsMostRecent);
Log.d(TAG, "locationUpdateDelta:\t\t\t" + locationUpdateDelta);
Log.d(TAG, "lastLocationUpdateDelta:\t\t" + lastLocationUpdateDelta);
Log.d(TAG, "locationIsInTimeThreshold:\t\t" + locationIsInTimeThreshold);
Log.d(TAG, "lastLocationIsInTimeThreshold:\t" + lastLocationIsInTimeThreshold);
Log.d(TAG, "accuracyComparable:\t\t\t" + accuracyComparable);
Log.d(TAG, "locationIsMostAccurate:\t\t" + locationIsMostAccurate);
}
// Update location if its more accurate and w/in time threshold or if
// the old location is
// too old and this update is newer.
if (accuracyComparable && locationIsMostAccurate && locationIsInTimeThreshold) {
onBestLocationChanged(location);
} else if (locationIsInTimeThreshold && !lastLocationIsInTimeThreshold) {
onBestLocationChanged(location);
}
}
public boolean isAccurateEnough(Location location) {
if (location != null && location.hasAccuracy()
&& location.getAccuracy() <= REQUESTED_FIRST_SEARCH_ACCURACY_IN_METERS) {
long locationUpdateDelta = new Date().getTime() - location.getTime();
if (locationUpdateDelta < REQUESTED_FIRST_SEARCH_MAX_DELTA_THRESHOLD) {
if (DEBUG) Log.d(TAG, "Location is accurate: " + location.toString());
return true;
}
}
if (DEBUG) Log.d(TAG, "Location is not accurate: " + String.valueOf(location));
return false;
}
public void register(LocationManager locationManager, boolean gps) {
if (DEBUG) Log.d(TAG, "Registering this location listener: " + this.toString());
long updateMinTime = SLOW_LOCATION_UPDATE_MIN_TIME;
long updateMinDistance = SLOW_LOCATION_UPDATE_MIN_DISTANCE;
if (gps) {
updateMinTime = LOCATION_UPDATE_MIN_TIME;
updateMinDistance = LOCATION_UPDATE_MIN_DISTANCE;
}
List<String> providers = locationManager.getProviders(true);
int providersCount = providers.size();
for (int i = 0; i < providersCount; i++) {
String providerName = providers.get(i);
if (locationManager.isProviderEnabled(providerName)) {
updateLocation(locationManager.getLastKnownLocation(providerName));
}
// Only register with GPS if we've explicitly allowed it.
if (gps || !LocationManager.GPS_PROVIDER.equals(providerName)) {
locationManager.requestLocationUpdates(providerName, updateMinTime,
updateMinDistance, this);
}
}
}
public void unregister(LocationManager locationManager) {
if (DEBUG) Log.d(TAG, "Unregistering this location listener: " + this.toString());
locationManager.removeUpdates(this);
}
/**
* Updates the current location with the last known location without
* registering any location listeners.
*
* @param locationManager the LocationManager instance from which to
* retrieve the latest known location
*/
synchronized public void updateLastKnownLocation(LocationManager locationManager) {
List<String> providers = locationManager.getProviders(true);
for (int i = 0, providersCount = providers.size(); i < providersCount; i++) {
String providerName = providers.get(i);
if (locationManager.isProviderEnabled(providerName)) {
updateLocation(locationManager.getLastKnownLocation(providerName));
}
}
}
private Criteria getCriteria(){
Criteria cr = new Criteria();
// query precision
cr.setAccuracy(Criteria.ACCURACY_FINE);
// whether query altitude
cr.setAltitudeRequired(false);
// whether query direction
cr.setBearingRequired(false);
// whether desire cost
cr.setCostAllowed(true);
// power requirement is low
cr.setPowerRequirement(Criteria.POWER_LOW);
return cr;
}
}
2. UI类用于反编译Location地址成物理地址(我这儿使用的反编用的是高德的库,如果是用SDK默认的接口,也就是我注释起来的部分来反编译出来的定位只能定位到区,而用Google API来编译就需要上传基站地址到Google,然后Google会返回一个JSON文件,Google返回的数据可以定位到街道,它就没有POI部分的数据,这种上传基站定们的方式又叫AGPS, 除这三种方法还可以用百度的GPS API效果和高德差不多)
http://ouyangfeng521.iteye.com/blog/1064382
http://topic.csdn.net/u/20110110/23/C2F6524A-8746-4C1B-914E-57C7C9CCED02.html
public class GPSLib extends Activity implements LocationObservable{
private LocationManager mLocationManager;
private MyLocationListener mLocationListener;
// view
private TextView mShowInfo;
private Handler mHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
if (msg.what == 1){
mShowInfo.setText((String)msg.obj);
}
};
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mLocationListener = new MyLocationListener(this);
((Button)findViewById(R.id.get_location)).setOnClickListener(
new OnClickListener(){
@Override
public void onClick(View v) {
mLocationListener.register(mLocationManager, true);
}
});
mShowInfo = (TextView)findViewById(R.id.show_gps_info);
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
mLocationListener.unregister(mLocationManager);
super.onDestroy();
}
@Override
public void updateLocation(final Location location) {
if (location != null){
mHandler.post(new Runnable() {
@Override
public void run() {
callGaoWithGeo(location, getApplicationContext());
}
});
//String address = getStreetAddress(location);
//if (address != null){
// mShowInfo.setText(address);
//}
}
}
//Android sdk 返编辑
// private String getStreetAddress(Location location){
// String addressString=null;
//
// if (location != null){
// double latitude = location.getLatitude();
// double longitude = location.getLongitude();
//
// Geocoder gc = new Geocoder(this, Locale.getDefault());
//
// try{
// List<Address> addresses = gc.getFromLocation(latitude, longitude, 8);
// StringBuilder sb = new StringBuilder();
//
// for(int j=0; j <addresses.size(); j++){
// Address address = addresses.get(j);
// sb.append(address.getCountryName());
// sb.append(address.getLocality());
// for (int i = 0; i < address.getMaxAddressLineIndex(); i++)
// sb.append(address.getAddressLine(i));
// sb.append("\n");
// }
//
// addressString = sb.toString();
// }
// catch (IOException e) {
// // TODO: handle exception
// e.printStackTrace();
// }
// }
//
// return addressString;
// }
//高德反编码方式
synchronized public Location callGaoWithGeo(Location location,Context context) {
double mLat = location.getLatitude();
double mLon = location.getLongitude();
// 用给定的经纬度构造一个GeoPoint,单位是微度 (度 * 1E6)
GeoPoint geo = new GeoPoint((int) (mLat * 1E6),
(int) (mLon * 1E6));
try {
if (geo.toString() != "") {
Geocoder mGeocoder01 = new Geocoder(context, Locale.getDefault().toString());
int x = geo.getLatitudeE6(); // 得到geo纬度,单位微度 (度 * 1E6)
double x1 = ((double) x) / 1000000;
int y = geo.getLongitudeE6(); // 得到geo经度,单位微度 (度 * 1E6)
double y1 = ((double) y) / 1000000;
//得到逆理编码,参数分别为:纬度,经度,最大结果集
List<Address> lstAddress = mGeocoder01.getFromRawGpsLocation(x1, y1, 3);
if (lstAddress.size()!=0) {
Location loc = new Location(location);
Address adsLocation = null;
for (int i = 0; i < lstAddress.size(); ++i) {
adsLocation = lstAddress.get(i);
String pr = adsLocation.getPremises();
//Log.i("joseph", "Address found = "+ adsLocation.toString());
if(pr.equals(Geocoder.POI)){
loc.setLongitude(adsLocation.getLongitude());
loc.setLatitude(adsLocation.getLatitude());
break;
}
}
if (adsLocation != null){
mShowInfo.setText(adsLocation.getAddressLine(0) + " "
+ adsLocation.getLocality() + " "
+ adsLocation.getAdminArea()+" "
+ adsLocation.getCountryName() + "\n"
+ adsLocation.getLatitude() + "," + adsLocation.getLongitude());
}
else{
mShowInfo.setText("获取数据失败!");
}
return loc;
} else {
Log.i("joseph", "Address GeoPoint NOT Found.");
}
}
} catch (Exception e) {
e.printStackTrace();
}
return location;
}
}
3. 一个CallBack的接口类,到LocationManager类获取到Location数据时, 通知给UI类
public interface LocationObservable {
public void updateLocation(Location location);
}
4. 添加permission
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"></uses-permission>