android定位
开头
此文档主要介绍在android中的基本定位方式。
如何偷偷打开GPS
偷偷把GPS打开,这样就可以用GPS定位了。
当然不用GPS也可以通过网络或者基站信息等定位。
/**
* Toggles the state of GPS. Actually turn on the gps
*
* @param context
*/
private void toggleGps(Context context, boolean flag) {
ContentResolver resolver = context.getContentResolver();
boolean enabled = getGpsState(context);
if (enabled ^ flag) {
Settings.Secure.setLocationProviderEnabled(resolver,
LocationManager.GPS_PROVIDER, flag);
}
}
/**
* get the state of GPS location.
*
* @param context
* @return true if enabled.
*/
private static boolean getGpsState(Context context) {
ContentResolver resolver = context.getContentResolver();
boolean open = Settings.Secure.isLocationProviderEnabled(resolver,
LocationManager.GPS_PROVIDER);
if (originGpsState == null) {
originGpsState = open ? "open" : "close";
}
return open;
}
监听地理位置变化
这里主要介绍使用GPS和NET的方式。
这两种方式基本是一样的。
LocationManager locationManager;
locationManager = (LocationManager) mContext
.getSystemService(contextService);
String provider = LocationManager.GPS_PROVIDER;
// 5000: every 5 seconds
// 1: every 1 meters change.
locationManager.requestLocationUpdates(provider, 5000, 1,
gpsLocationListener, Looper.myLooper());
// Add NETWORK_PROVIDER
provider = LocationManager.NETWORK_PROVIDER;
locationManager.requestLocationUpdates(provider, 5000, 1,
netLocationListener, Looper.myLooper());
Looper.loop();
通过LocationManager的requestLocationUpdates进行监听。
如果看过一些网络攻略,可能会了解到使用Criteria和LocationManager的getBestProvider方法来获取最优provider。我们这里直接两种定位方式同进行。简单粗暴!
private final LocationListener gpsLocationListener = new LocationListener() {
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onLocationChanged(Location location) {
updateNewLocation(location);
}
};
private final LocationListener netLocationListener = new LocationListener() {
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onLocationChanged(Location location) {
Log.d(TAG, "newLocationListener > onLocationChanged");
updateNewLocation(location);
}
};
将经纬度转为地址信息
通过LocationListener中的onLocationChanged获取到位置信息。
private static final String LOCATION_URI_PART1 =
"http://maps.googleapis.com/maps/api/geocode/json?latlng=";
private static final String LOCATION_URI_PART2 = "&sensor=false&language=";
private void updateNewLocation(Location location) {
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
String lan = Locale.getDefault().getLanguage();
String locationUriStr = LOCATION_URI_PART1 + lat + "," + lng
+ LOCATION_URI_PART2 + lan;
if (mCm.getActiveNetworkInfo() == null) {
} else {
new ReadHttpGet().execute(locationUriStr);
}
}
}
方法一:
拿到Location中的经纬度信息,通过google地图api转换为具体的位置信息。
ReadHttpGet extends AsyncTask<Object, Object, Object> {
@Override
protected Object doInBackground(Object... params) {
HttpGet httpRequest = new HttpGet(params[0].toString());
try {
HttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpRequest);
if (httpResponse.getStatusLine().getStatusCode()
== HttpStatus.SC_OK) {
Log.d(TAG, "HttpStatus.SC_OK");
String strResult = EntityUtils.toString(httpResponse
.getEntity());
return strResult;
} else {
return "request error";
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onCancelled(Object result) {
super.onCancelled(result);
}
@Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
try {
if (result != null) {
JSONObject jsonObject = new JSONObject(result.toString());
JSONArray jsonArray = jsonObject.getJSONArray("results");
JSONObject placemarkObj = jsonArray.getJSONObject(0);
JSONArray adressArray = placemarkObj
.getJSONArray("address_components");
locationStr = adressArray.getJSONObject(3).getString(
"long_name")
+ adressArray.getJSONObject(2).getString(
"long_name")
+ adressArray.getJSONObject(1).getString(
"long_name")
+ adressArray.getJSONObject(0).getString(
"long_name");
// locationStr 位置信息
} else {
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
}
}
方法二:
这里也可以直接用Geocoder的getFromLocation拿到Address列表。
通过解析Address内容来实现。
private Geocoder mGeocoder;
mGeocoder = new Geocoder(this, Locale.getDefault());
public class ReverseGeocoderTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... arg0) {
try {
android.util.Log.i(TAG,"1");
List<Address> address = mGeocoder.getFromLocation(31.22, 121.48, 1);
android.util.Log.i(TAG,"address:" + address.size());
StringBuilder sb = new StringBuilder();
for (Address addr : address) {
android.util.Log.i(TAG,"addr:" + addr);
sb.append(addr.getAdminArea());
}
android.util.Log.i(TAG,"sb:" + sb.toString());
Bundle data = new Bundle();
data.putString("address", sb.toString());
Message msg = mHandler.obtainMessage();
msg.setData(data);
mHandler.sendMessage(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
}
最后
用好之后把资源释放。
如果实现过程中用到其他东西也别忘记释放了。
if (locationManager != null) {
locationManager.removeUpdates(gpsLocationListener);
locationManager.removeUpdates(netLocationListener);
locationManager = null;
}