利用手机内置得芯片,实现当前位置的定位,拿到经纬度,定位功能必须要由用户主动去启用才行,不然任何应用程序都无法获取到手机当前的位置信息。进入手机的设置→定位服务,选择定位方式。
拿到经纬度后,根据google提供的API,把经纬度转换成我们看得到的城市名称。
Geocoding API,更详细的用法请参考官方文档:https://developers. google.com/maps/documentation/geocoding/。
详细代码:
public class MainActivity extends Activity {
private LocationManager manager;
private String provider;
private TextView tv;
private static final int MSG_WHAT=111;
Location location;
private String address;//详细地址
protected Address l;
Handler hander=new Handler(){
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_WHAT:
Address location=(Address) msg.obj;
tv.setText(location.guojia+location.province+location.city+location.qu+location.jie+location.jiehao);
break;
default:
break;
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv=(TextView) findViewById(R.id.tv);
manager=(LocationManager) getSystemService(Context.LOCATION_SERVICE);
List<String> providers= manager.getProviders(true);//获取所有可用的位置提供器
// Android中一般有三种位置提供器可供选择,GPS_PROVIDER、NETWORK_PROVIDER和PASSIVE_PROVIDER。
// 其中前两种使用的比较多,分别表示使用GPS定位和使用网络定位。这两种定位方式各有特点,
// GPS定位的精准度比较高,但是非常耗电,而网络定位的精准度稍差,但耗电量比较少。
// 我们应该根据自己的实际情况来选择使用哪一种位置提供器,当位置精度要求非常高的时候,最好使用GPS_PROVIDER,
// 而一般情况下,使用NETWORK_PROVIDER会更加得划算。
// 定位功能必须要由用户主动去启用才行,不然任何应用程序都无法获取到手机当前的位置信息。进入手机的设置→定位服务
//判断哪个位置提供器可用
if(providers.contains(LocationManager.GPS_PROVIDER)){
provider=LocationManager.GPS_PROVIDER;
Toast.makeText(getApplicationContext(), provider, 0).show();
}else if(providers.contains(LocationManager.NETWORK_PROVIDER)){
provider=LocationManager.NETWORK_PROVIDER;
Toast.makeText(getApplicationContext(), provider, 0).show();
}else{
Toast.makeText(getApplicationContext(), "定位功能没有打开,请到设置打开...", 0).show();
return;
}
//获取位置信息
Log.d("provide", provider);
location=manager.getLastKnownLocation(provider);
if(location!=null){
//显示位置信息
showLocation(location);
}
//设备位置发生改变的时候获取到最新的位置信息
// 第一个参数是位置提供器的类型,第二个参数是监听位置变化的时间间隔,以毫秒为单位,
// 第三个参数是监听位置变化的距离间隔,以米为单位,第四个参数则是LocationListener监听器。
// 这样的话,LocationManager每隔5秒钟会检测一下位置的变化情况,当移动距离超过10米的时候,
// 就会调用LocationListener的onLocationChanged()方法,并把新的位置信息作为参数传入。
manager.requestLocationUpdates(provider, 5000, 10, listener);
//谷歌又提供了一套Geocoding API,使用它的话也可以完成反向地理编码的工作
// Geocoding API中规定了很多接口,其中反向地理编码的接口如下:
// http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&sensor=true_or_false
// 我们来仔细看下这个接口的定义,其中http://maps.googleapis.com/maps/api/geocode/是固定的,表示接口的连接地址。
// json表示希望服务器能够返回JSON格式的数据,这里也可以指定成xml。
// latlng=40.714224,-73.96145表示传递给服务器去解码的经纬值是北纬40.714224度,西经73.96145度。
// sensor=true_or_false表示这条请求是否来自于某个设备的位置传感器,通常指定成false即可。
tv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
showLocation(location);
}
});
}
private void showLocation(final Location location) {
// TODO Auto-generated method stub
tv.setText("纬度:"+location.getLatitude()+";经度:"+location.getLongitude());
Log.d("show", location.toString());
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
// 组装反向地理编码的接口地址
StringBuilder url = new StringBuilder();
url.append("http://maps.google.cn/maps/api/geocode/json?latlng=");
url.append(location.getLatitude()).append(",");
url.append(location.getLongitude());
url.append("&sensor=false");
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url.toString());
// 在请求消息头中指定语言,保证服务器会返回中文数据
httpGet.addHeader("Accept-Language", "zh-CN");
HttpResponse httpResponse=null;
try {
httpResponse = httpClient.execute(httpGet);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity, "utf-8");
writeJsonToSDCard(response);
JSONObject jsonObject = new JSONObject(response);
// 获取results节点下的位置信息
JSONArray resultArray = jsonObject.getJSONArray ("results");
if (resultArray.length() > 0) {
JSONObject subObject = resultArray. getJSONObject(0);
// 取出格式化后的位置信息
address = subObject.getString ("formatted_address");
//取出省市区街道地址
JSONArray addArray=subObject.getJSONArray("address_components");
//创建对象放置这些信息
l=new com.example.androidlocation.Address();
//国家
JSONObject guojia=addArray.getJSONObject(5);
l.guojia=guojia.getString("long_name");
//省份
JSONObject province=addArray.getJSONObject(4);
l.province=province.getString("long_name");
//市
JSONObject city=addArray.getJSONObject(3);
l.city=city.getString("long_name");
//区
JSONObject qu=addArray.getJSONObject(2);
l.qu=qu.getString("long_name");
//街道
JSONObject jie=addArray.getJSONObject(1);
l.jie=jie.getString("long_name");
//街道号
JSONObject jiehao=addArray.getJSONObject(0);
l.jiehao=jiehao.getString("long_name");
}
Message message=hander.obtainMessage();
message.what=MSG_WHAT;
message.obj=l;
hander.sendMessage(message);
}
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
protected void onDestroy() {
super.onDestroy();
if (manager != null) {
// 关闭程序时将监听器移除
manager.removeUpdates(listener);
}
}
LocationListener listener=new LocationListener() {
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
// 更新当前设备的位置信息
showLocation(location);
}
};
public void writeJsonToSDCard(String s) {
// TODO Auto-generated method stub
File file=new File(Environment.getExternalStorageDirectory()+File.separator+"json"+File.separator+"json.txt");
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
Log.d("file", file.getAbsolutePath());
PrintStream output=null;
try{
output=new PrintStream(new FileOutputStream(file));
output.print(s);
}catch(Exception e){
e.printStackTrace();
}finally{
if(output!=null){
output.close();
}
}
}
}
保存位置名称的实体类
public class Address {
public String guojia;
public String province;
public String city;
public String qu;
public String jie;
public String jiehao;
}
需要的一些权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>