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>