哎,这几天有点偷懒,博客几天没有更新啦,自己攒了一大堆知识没有整理,今天要抓紧调整状态,恢复之前的状态哦, 哦哦,不扯了,下面说今天总结的内容是基于位置服务的用户定位。
这项功能在手机应用中在常见不过了啦,QQ空间发状态有定位,微信有定位,滴滴打车更不用说,各种地图还有等等好多的应用都有定位的功能,那么这些为用户定位的功能是如何实现的呢,下面我们首先来看与用户定位有关的API。
User Location API
LocationManager:主要用于管理用户定位服务。
LocationProvider:主要用于管理设备获取用户位置所使用定位服务。现在目前的手机有三种定位功能:GPS, NETWORK,PASSIVE。
- GPS是我们很熟悉的卫星定位,通常我们的位置都是有三个卫星确定的。GPS的精度比较高,但是慢而且消耗电力,而且可能因为天气原因或者障碍物而无法获取卫星信息,另外有些设备可能没有GPS模块
- NETWORK是通过网络定位。就像现在的联通和移动在各地都设置了信号塔,为我们提供手机信号,它的定位就是通过确定我们使用的哪个信号塔,然后通过确定信号谈的位置来估算我们的位置。精度低,耗电少,获取信息速度较快,不依赖GPS模块。
- PASSIVE是一种被动的定位。现在很少使用这种定位方式,大多是使用前两种。
LocationListener:该类重要用于监听定位,当用户的位置发生改变或其他,我们想要对其进行操作时,我们可以使用该监听器。
获取用户Location
获取用户的位置信息,这里我们获取用户的经纬度。我们还是按照步骤讲解:
1. 添加权限。
注意:这里声明了两个权限:ACCESS_FINE_LOCATION,声明定位精度高的权限,一般是用于GPS,也可以是NETWORK;ACCESS_COARSE_LOCATION,声明定位精度低的权限,可以是NETWORK。
<!--声明定位的权限-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
2. 创建LocationManager的对象通过getSystemService(Context.LOCATION_SERVICE)
//这里要强制造型,因为getSystemService()方法返回的是一个Object的对象。
LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
3. 绑定一个监听器,通过监听器中闯入的LocationListener来获取经纬度信息。
//绑定一个监听器
manager.requestLocationUpdates(provider, 0, 0, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
//该方法当用户位置改变时调用
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
//当定位功能提供发生改变时调用
}
@Override
public void onProviderEnabled(String provider) {
//当定位提供器可用时调用
}
@Override
public void onProviderDisabled(String provider) {
//当定位提供器不可用时调用
}
});
获取移动用户Location
有时候我们想定位位置不断改变的用户,这时我们该如何做呢?
还记的我们在上一节中注册监听器的方法么requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)
,这个方法传入四个参数:
provider:定位功能的提供类型。分为GPS_PROVIDER, NETWORK_PROVIDER, PASSIVE_PROVIDER。
minTime:两次定位之间的时间间隔,单位是ms。
minDistance:两次定位的最小距离,单位是m。
listener:我们定义的LocationListener 定位监听器对象。
如果我们想每隔10s,以及每隔10m给用户定位一次,我们可以书写如下:
public class MainActivity extends Activity implements LocationListener {
private TextView mTextViewLongtitude;
private TextView mTextViewLatitude;
private LocationManager manager;//定义LocationManager的对象
private String provider;//定义位置提供者的类型
private List<String> providers;//获取定位提供者的对象
private double longitute;//用户的经度
private double latitude;//用户的纬度
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextViewLongtitude = (TextView) findViewById(R.id.textview_longtitude);
mTextViewLatitude = (TextView) findViewById(R.id.textview_latitude);
//步骤一:获取位置LocationManager对象
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//获得所有的位置提供器
providers=manager.getProviders(true);
if(providers.contains(LocationManager.GPS_PROVIDER)){
provider=LocationManager.GPS_PROVIDER;
}else if(providers.contains(LocationManager.NETWORK_PROVIDER)){
provider=LocationManager.NETWORK_PROVIDER;
}else {
Toast.makeText(getApplicationContext(), "没有相应的位置提供器!", Toast.LENGTH_SHORT).show();
}
manager.requestLocationUpdates(provider, 10000, 10, this);
}
@Override
public void onLocationChanged(Location location) {
longitute = location.getLongitude();
mTextViewLongtitude.setText(""+longitute);
latitude = location.getLatitude();
mTextViewLatitude.setText(""+latitude);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
获取LocationProvider
获取所有的LocationProvider
一直说我们的手机上有三种位置提供器也不太靠谱,下面我们来获得一下这三种位置提供器。
我们通过LocationManager对象调用getProviders(true)方法可以获得所有已开启的位置提供器,通过调用getAllProviders()方法可以获得所有的设备中的位置提供器。这里我们通过该方法获得设备的位置提供器,然后循环输出下:
List<String> pros = manager.getAllProviders();
for (String pro:pros) {
Log.d("data", ""+pro);//输出所有的位置提供器
}
获取最好的LocationProvider
有时候家人问我们晚饭吃什么,我们可能不清楚自己到底具体想吃什么,但是我们清楚的知道我们不吃什么,我们可以通过告诉家人我们不喜欢吃什么,然后他们依据这些来给我们做最适合的晚餐。
在使用位置提供器是我们想要最好最适合的,我们如何获得呢?
想要筛选出最适合的位置提供器,我们就要使用一个类Criteria。先看这个类的相关介绍:
A class indicating the application criteria for selecting a location provider. Providers maybe ordered according to accuracy, power usage, ability to report altitude, speed, and bearing, and monetary cost.
Criteria是一个通过设定相关的信息,例如:精度,电量使用, 海拔高度是否提供,速度,方位以及是否收费等功能来筛选出Provider。
- setAccuracy(int accuracy):设置精度要求,有两种:ACCURACY_COARSE,ACCURACY_FINE。
- setPowerRequirement(int level):设置电量水平。
- setAltitudeRequired(boolean altitudeRequired):设置是否提供海拔。
- setSpeedRequired(boolean speedRequired):设置是否需要速度。
setCostAllowed(boolean costAllowed):设置是否产生费用。
除此之外还有很多方法,这里我们只列举这些,具体可以去API查询。
//首先生成一个Criteria的对象
Criteria criteria = new Criteria();
//设置查询的条件
criteria.setAccuracy(Criteria.ACCURACY_FINE);//设置精度要求为高
criteria.setPowerRequirement(Criteria.POWER_LOW);//设置电量要求为低
criteria.setAltitudeRequired(false);//不需要还把要求
criteria.setSpeedRequired(false);//不需要速度
criteria.setCostAllowed(false);//不需要产生费用
//第二个参数传入false代表从没打开的定位设备选取,为true则要从已经打开的定位设备中选取。
String bestProvider = manager.getBestProvider(criteria, false);
Log.d("data", ""+bestProvider);