Android系统GPS定位实现
一、定位方式简介
定位基本分为三种方式,特点如下:
1.wifi定位:IP地址定位,根据ip地址查询实际的地理位置,因为动态获取ip的操作,定位不准确
2.基站定位:根据基站(信号塔)的个数以及手机与基站的距离来实现定位,准确性取决于基站的个数
3.GPS定位:通过光波的形式和Gps定位卫星通讯,返回经纬度坐标,连接时间比较长,在空旷的地方定位比较流畅,不需要联网,agps:通过网络修正gps定位的坐标
二、Android获取定位权限,获取设备所在的经纬度
接下来将讲述一个如何实现获取设备所在的经纬度,并且如果位置改变,如何通过位置的改变,经纬度也发生变化的例子,这里以LocationManager对象为例:
1.获取定位服务
Android为GPS定位提供LocationManager类及其他几个辅助类,开发人员可以非常方便地开发出GPS应用。在程序中,通过getSystemService获得LocationManager对象之后,就可以调用LocationManager提供的常用方法,代码如下:
//获取LocationManager对象
private LocationManager myLocationManager;
//实例化Location应用管理类
myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
2.获取当前位置信息中
在获取到LocationManager对象后,还需要指定LocationManager的定位方法 ,然后才能够调用LocationManager.getLastKnowLocation()方法获取当前位置 ,目前LocationManager主要有两种定位方法
(1)GPS定位:可以提供更加精确的位置信息,但定位速度和质量受到卫星数量和环境情况的影响,需要android.permissions.ACCESS_FINE_LOCATION用户权限。
(2)网络定位:提供的位置信息精度差,但速度较GPS定位要迅速 ,利用基站或WiFi访问的提供近似的位置信息,需要具有如下权限:android.permission.ACCESS_COARSE_LOCATION 或 android.permission.ACCESS_FINE_LOCATION。
并且通过调用Location中的getLatitude()和getLonggitude()方法可以分别获取位置信息中的纬度和经度,代码如下
//使用GPS定位
isOpen = myLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
// 获取GPS信息
String provider = myLocationManager.getBestProvider(criteria, true);
//获取当前位置
Location location = myLocationManager.getLastKnownLocation(provider);
//获取纬度
latitude = location.getLatitude();
//获取经度
longitude = location.getLongitude();
3.监视地理位置变化
在很多提供定位服务的应用程序中,不仅需要获取当前的位置信息,还需要监视位置的变化,在位置改变时调用特定的处理方法 ,其中LocationManager提供了一种便捷、高效的位置监视方法requestLocationUpdates(),可以根据位置的距离变化和时间间隔设定,产生位置改变事件的条件,这样可以避免因微小的距离变化而产生大量的位置改变事件 ,LocationManager中设定监听位置变化的代码如下:
//监视位置的变化
//参数1:定位
//参数2:最小的定位的间隔时间
//参数3:最小的定位的间隔距离
//参数4:定位的回调监听
myLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, myLocationListener);
接下来介绍上面这行代码的各个参数,第一个参数是我们之前指定LocationManager的定位方法,GPS定位或网络定位,第二个参数指的是产生位置改变事件的时间间隔,单位为微秒,第三个参数指的是距离条件,单位为米,第四个参数是回调函数,用于处理位置改变事件,即设置LocationListener监听器。总的来说,那一行代码将产生位置改变事件的条件设定为距离改变0米,时间间隔为0秒,即为无间断刷新位置。
4.实现地理位置变化接口
/**
* 获取GPS位置监听器,包含四个不同触发方式
*/
LocationListener myLocationListener = new LocationListener() {
// Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
// 当位置获取(GPS)打开时调用此方法
@Override
public void onProviderEnabled(String provider) {
Log.d("执行,GPS的打开", provider);
}
// 当位置获取(GPS)关闭时调用此方法
@Override
public void onProviderDisabled(String provider) {
Log.d("执行,GPS关闭", provider);
}
// 当坐标改变时触发此方法,如果获取到相同坐标,它就不会被触发
@Override
public void onLocationChanged(Location location) {
if (location != null) {
latitude = location.getLatitude(); // 经度
longitude = location.getLongitude(); // 纬度
Log.d("执行,坐标发生改变", "Lat: " + location.getLatitude() + " Lng: " + location.getLongitude());
}
}
};
接下来对上面实现LocationListener的代码下的四个方法进行简单介绍:
(1)onLocationChanged()这个方法在位置改变时被调用;
(2)onProviderDisabled()这个方法在用户禁用具有定位功能的硬件时被调用;
(3)onProviderEnabled()这个方法在用户启用具有定位功能的硬件时被调用;
(4)onStatusChanged()这个方法在定位功能硬件状态改变时被调用,例如,从不可获取位置信息状态到可以获取位置信息的状态,反之亦然 。
5.获取经纬度进行显示
实现点击按钮显示经纬度坐标,布局十分简单,一个Button与一个TextView即可。
布局代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/tv_GetGPS"
android:layout_width="match_parent"
android:layout_height="80dp"
android:padding="20dp"
android:text="获取当前经纬度" />
<TextView
android:id="@+id/tv_ShowInfo"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
对于按钮设置点击监听,在点击时检测SD Card读取权限、定位权限是否开启,若未开启则弹出系统提示开启权限界面,若已开启,则在按钮下方显示经纬度坐标。代码如下:
private void myClick() {
tvGetGPS.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
PackageManager pkgManager = getPackageManager();
// 读写 sd card 权限非常重要, android6.0默认禁止的, 建议初始化之前就弹窗让用户赋予该权限
boolean gpsPermission = pkgManager.checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, getPackageName()) == PackageManager.PERMISSION_GRANTED;
if (Build.VERSION.SDK_INT >= 23 && !gpsPermission) {
requestPermission();
} else {
checkGPSIsStart();
}
}
});
}
/**
* 申请权限,6.0之后要动态获取
* 动态权限设置添加多条权限
*/
private void requestPermission() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_PERMISSION);
}
6.权限配置(重要)
为了使GPS定位功能生效,还需要在AndroidManifest.xml文件中加入用户许可,即加入如下代码,加入用户权限:
<!-- 网络和存储 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--获取GPS坐标-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
最终显示界面: