获得用户位置能让应用程序更加智能。而且能像用户提供更有用的信息。在开发Android位置相关应用时,可以从gps或者网络获得用户位置。通过gps能获得最精确的信息,但是它仅用于户外,不但耗电,而且不能及时返回用户需要的信息。使用网络能从发射塔和WI-FI信号获得用户位置,提供一种适用于户内和户外或得位置信息的方式,不但响应迅速,而且更加省电。为了在应用中获得用户位置,开发人员可以同时使用两种方式,或者使用其中之一。
在Android系统中,开发人员需要使用一下类访问定位服务。
1.LocationManager:该类提供系统定位服务访问功能。
2.LocationListener:当位置发生变化时,该接口从LocationManager中获得通知。
3.Location:该类表示特定时间地理位置信息,位置由经度,维度、UTC时间戳以及可选的高度,速度,方向灯组成。
1.获得位置源
private LocationListener locationListener = new LocationListener(){
/**
* 手机位置发生变动
*/
@Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
location.getAccuracy();//精确度
latitude = String.valueOf(location.getLatitude());
longitude = String.valueOf(location.getLongitude());
Editor edit = sp.edit();
edit.putString("latitude",latitude);
edit.putString("longitude", longitude);
edit.commit();
}
/**
* 当某个位置提供者的状态发生改变时
*/
@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
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_getlocation=(Button)findViewById(R.id.btn_getlocation);
btn_getcity=(Button)findViewById(R.id.btn_getcity);
tv_latitude=(TextView)findViewById(R.id.tv_latitude);
tv_longitude=(TextView)findViewById(R.id.tv_longitude);
tv_city=(TextView)findViewById(R.id.tv_city);
btn_getlocation.setOnClickListener(this);
btn_getcity.setOnClickListener(this);
manager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
sp = getSharedPreferences("config", MODE_APPEND);
List<String> providers = manager.getAllProviders();
int i =0;
for(String provider:providers){
Editor edit = sp.edit();
edit.putString("provider_"+i, provider);
edit.commit();
i++;
}
//获取条件
criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);//获取精准位置
criteria.setCostAllowed(true);// 允许开销
criteria.setPowerRequirement(Criteria.POWER_HIGH);//设置消耗频率,越高准确度越高
criteria.setSpeedRequired(true);//手机位置移动
criteria.setAltitudeRequired(true);//设置海拔
//获取最佳provider(gps)
bestProvider = manager.getBestProvider(criteria, true);//使用gps卫星?
// bestProvider = "network";
System.out.println("最好的位置提供者是"+bestProvider);
Editor edit = sp.edit();
edit.putString("best_provider", bestProvider);
edit.commit();
//parameter: 1. provider 2. 每隔多少时间获取一次 3.每隔多少米 4.监听器触发回调函数
manager.requestLocationUpdates(bestProvider, 1000, 1, locationListener);
}
如果希望通过经纬度确定城市位置,需要调用百度,或谷歌地图api
下面说百度地图的:http://api.map.baidu.com/geocoder?output=json&location=纬度,经度&key=百度开发者apiID
返回数据可为json,或者xml。自己解析内容即可。
Criteria类定义的经度和耗电信息如下
常量 | 说明 |
ACCURACY_COARSE | 中等精度 |
ACCURACY_FINE | 低等精度 |
ACCURACY_HIGH | 高等精度 |
ACCURACY_MEDIUM | 中等精度 |
ACCURACY_LOW | 低等精度 |
PWOER_HIGH | 高耗电量 |
PWOER_MEDIUM | 中耗电量 |
PWOER_LOW | 低耗电量 |
1.2 监听位置变化事件
对于位置发生变化的用户,可以再变化后接收到相关的通知。在LocationManager类中,定义了多个requestLocationUpdates()方法,用来为当前activity注册位置变化通知事件。该方法的声明如下:
<span style="font-size:14px;">public void requestLocationUpdates(String provider,long minTime,float minDistance,LocationListener listener);</span>
参数说明如下:
1.provider:注册的provider的名称,可以是gps,或者network等。
2.minTime:通知间隔的最小时间,单位是毫秒。系统可能为了省电而延长该时间。
3.minDistance:更新通知的最小变化距离,单位是米。
4.listener:用于处理通知的监听器。
LocationListener接口中的4个方法上面有注释。