Android GPS应用开发

发布时间:2025-12-10 11:36:17 浏览次数:4

Android GPS应用开发

文章目录

    • Android GPS应用开发
      • 一、支持GPS的核心AP
        • 1、android 定位的几种方式介绍
        • 2、GPS定位相关类
        • 2.1、LocationManager
        • 2.2、LocationProvider
        • 2.3、Location
        • 2.4、LocationListener位置监听接口
        • 2.5、LocationListener需要实现的方法:
        • 2.6、GpsStatus.Listener:GPS状态监听的一个接口
        • 2.7、Criteria:用于选择位置信息提供者的辅助类
      • 3、GPS定位流程
        • 3.1、通过指定名称获取
        • 3.2、获取可使用的LocationProvider 实例列表
        • 3.3、根据Criteria 获取符合条件的 LocationProvider 实例
      • 二、 Android GPS 临近警告
        • 1、临近警告就是固定一个点,当手机与该点的距离少于指定范围时,可以触发对应的处理
        • 2、调用LocationManager的addProximityAlert() 方法添加临近警告
      • 三、Android 9利用 Wi-Fi RTT 进行室内定位
        • 1、实现RTT要求:
        • 2、应用使用WLAN RTT,需要完成:
          • 1、 请求权限
          • 2.、检查设备是否支持 WLAN RTT
          • 3、 检查 WLAN RTT 是否可用
        • 3、 获得WifiRttManager的实例对象
          • 3.1、创建测距请求
          • 3.2、请求测距
          • 3.3、识别请求

一、支持GPS的核心AP

在Android开发中常常须要用到定位功能,尤其是依赖于地理位置功能的应用。大家首先想到的是使用百度地图、高德地图提供的sdk,但是在只须要经纬度或者城市、街道地址等信息并不须要提供预览地图时我们考虑使用Android系统提供的API来实现。

Android SDK 提供了 android.location 包和 Google Maps API 支持位置服务功能,开发人员可以方便地开发自己的位置服务应用程序。

1、android 定位的几种方式介绍

android 定位一般有四种方法,这四种方式分别是:GPS定位,WIFI定准,基站定位,AGPS定位

2、GPS定位相关类

在开发过程中主要使用android.location包中的LocationManager和LocationProviders对象。

2.1、LocationManager

LocationManager 类用于管理 Android 用户位置服务信息,提供确定用户位置的 API,通过这个类可以实现定位、跟踪和目标趋近等功能。

LocationManager 对象可以完成以下三个方面的任务:

  • 从用户的位置查询所有可用的 LocationProvider 列表。

  • 从特定的 LocationProvider 周期性获取用户当前位置的功能。

  • 当用户位置接近某个特定区域时,启动相关任务。

⭐️ LocationManager 对象不能直接实例化,可以通过 Context.getSystemService(Context. LOCATION_SERVICE) 方法获得。

常用方法:

  • boolean addGpsStatusListener(GpsStatus.Listener listener):添加一个监听GPS状态的监听器

  • void removeGpsStatusListener(GpsStatus.Listener listener):删除Gps状态监听器

  • List getAllProviders():获得所有LocationProvider列表

  • String getBestProvider(Criteria criteria,Boolean enabldOny):根据 criteria 返回最合适的 LocationProvider,其中 criteria 指定了一系列条件

  • Location getLastKnownLocation (String provider):获取缓存中的位置信息, 该方法不会发起监听,返回的是上一次的位置信息,但此前如果没有位置更新的话,返回的位置信息可能是错误的

  • LocationProvider getProvider (String name):获得指定名称的 LocationProvider

  • List getProviders (boolean enabledOnly):获得可用的 LocationProvider 列表

  • addProximityAlert (double latitude, double longitude, float radius, long expiration, PendingIntent intent):添加一个邻近警告

  • removeProximityAlert (PendingIntent intent):删除趋近警告

  • void requestLocationUpdates(String provider, long minTime, float minDistance, PendingIntent intent): 通过指定的LoactionProvider周期性地获取定位信息,并通过intent启动相应的组件

  • void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener): 通过指定的LocationProvider周期性地获取定位信息,并触发listener所对应的触发器3

  • requestSingleUpdate(String provider, LocationListener listener, Looper looper):获取一次定位结果,如果不想一直监听位置信息,那么可以用requestSingleUpdate来实现只请求一次定位,该方法也要在主线程上执行

  • isProviderEnabled(String provider):判断provider是否可用

2.2、LocationProvider

⭐️ LocationProvider 为位置提供者的抽象类,位置提供者提供手机设备周期性的地理位置报告。

常用方法:

? int getAccuracy():获取LocationProvider提供位置信息的精度

? String getName():获得LocationProvider的名称

? int getPowerRequirement():获得LocationProvider 对电源的需求

? boolean hasMonetaryCost():获取当前LocationProvider 是免费的还是收费的

? boolean meetsCriteria(Criteria criteria):确定当前 LocationProvider 是否符合特定条件

? boolean requiresCell():LocationProvider定位是否需要访问基站网络

? boolean requiresNetwork():LocationProvider定位是否需要 Internet 网络数据

?boolean requiresSatellite():LocationProvider定位是否需要获取卫星数据

? boolean supportsAltitude():LocationProvider提供的位置信息是否包含高度信息

? boolean supportsBearing():是否能够提供方向信息

? boolean supportsAltitude():LocationProvider是否能够提供速度信息

2.3、Location

⭐️ Location它就是一个代表位置信息的抽象类,记录了经纬度、海拔高度、获取坐标时间、速度、方位等

⭐️ 不过很多时候得到的Location对象为null;实时动态坐标可以在监听器locationListener的onLocationChanged(Location location)方法中来获取。

常用方法:

?float getAccuracy():获得定位信息的精度

?double getAltitude():获得定位信息的高度

?float getBearing():获得定位信息的方向

?double getLatitude():获得定位信息的纬度

?double getLongitude():获得定位信息的精度

?String getProvider():获得提供该定位信息的LocationProvider

?float getSpeed():获得定位信息的速度

?boolean hasAccuracy ():判断该定位信息是否含有精度信息

2.4、LocationListener位置监听接口

用于监听位置(包括GPS、网络、基站等所有提供位置的)变化,监听设备开关与状态。实时动态获取位置信息,首先要实现该接口,在相关方法中添加实现功能的代码,实现该接口可以使用内部类或者匿名实现。

注册监听:LocationManger.requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)。

?provider:注册的provider的名称,可以是GPS_PROVIDER等。

?minTime:通知间隔的最小时间,单位是毫秒。系统可能为了省电而延长该时间。

?minDistance:更新通知的最小变化距离,单位是米。

?listener:用于处理通知的监听器。

n 使用完之后需要在适当的位置移除监听:LocationManager .removeUpdates(LocationListener listener)

2.5、LocationListener需要实现的方法:

?onLocationChanged(Location location):当位置发生变化的时候会自动调用该方法,参数location记录了最新的位置信息(经纬度)。Location表示位置发生变化后的新位置。

?onStatusChanged(String provider, int status, Bundle extras):当位置提供者的状态发生改变(可用到不可用、不可用到可用)时自动调用该方法;参数provider为位置提供者的名称,status为状态信息:OUT_OF_SERVICE(0,无服务)、AVAILABLE(2,provider可用) 、TEMPORARILY_UNAVAILABLE(1,不可用),extras为附加数据:key/value,如satellites;

?onProviderEnabled(String provider):当provider可用时被触发,比如定位模式切换到了使用精确位置时GPSProvider就会回调该方法;

?onProviderDisabled(String provider):当provider不可用时被触发,比如定位模式切换到了使用使用网络定位时GPSProvider就会回调该方法。

2.6、GpsStatus.Listener:GPS状态监听的一个接口

n 使用方法与locationListener接口类似,先实现接口并创建对象,实现接口中的方法:onGpsStatusChanged(int event);在方法中实现对卫星状态信息变化的监听,根据event的类型编写逻辑代码。

n 创建对象后再注册监听:LocationManager .addGpsStatusListener(GpsStatus.Listener listener);使用后在合适的位置释放监听:LocationManager .removeGpsStatusListener(GpsStatus.Listener listener)。

2.7、Criteria:用于选择位置信息提供者的辅助类

创建LocationProvider对象时会使用到该类。定位信息提供者会根据精度、电量、是否提供高度、速度、方位、服务商付费等信息进行排序选择定位提供者。

3、GPS定位流程

(1)配置权限:

添加如下权限

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />是粗略位置,该权限只针对NETWORK_PROVIDER。<uses-permission android:name="android.permission..ACCESS_FINE_LOCATION" />是精确位置,如果使用GPS_PROVIDER或者同时使用GPS_PROVIDER和NETWORK_PROVIDER,需声明该权限,它对于这两个provider都是有效的;

(2)获取LocationManager类型对象

(3)获取LocationProvider

根据设备的不同可以使用不同的定位技术来实现位置服务,也就是获取不同的 LocationProvider,以下是 3 种获取LocationProvider 实例的方法。

3.1、通过指定名称获取

getProvider(LocationManager.GPS_PROVIDER)

根据 LocationManager 中的静态常量 GPS_PROVIDER 和 NETWORK_PROVIDER 来分别获得 GPS Provider 和 Network Provider

GPS_PROVIDER:这个就是手机里有GPS芯片,然后利用该芯片就能利用卫星获得自己的位置信息。可是在室内,GPS定位基本没用,非常难定位的到。

优点:获取地理位置信息精确度高;

缺点:只能在户外使用,获取经纬度信息耗时,耗电;

NETWORK_PROVIDER:这个就是利用网络定位,一般是利用手机基站和WIFI节点的地址来大致定位位置,这样的定位方式取决于server,即取决于将基站或WIFI节点信息翻译成位置信息的server的能力。因为眼下大部分Android手机没有安装google官方的location manager库。大陆网络也不同意。即没有server来做这个事情,自然该方法基本上没法实现定位。

优点:只要有网络,就可以快速定位,室内室外都可;

缺点:精确度不高;

PASSIVE_PROVIDER:被动定位方式。被动接收更新地理位置信息,而不用自己请求地理位置信息。 PASSIVE_PROVIDER 返回的位置是通过其他 providers 产生的,可以查询 getProvider() 方法决定位置更新的由来,需要 ACCESS_FINE_LOCATION 权限,但是如果未启用 GPS,则此 provider 可能只返回粗略位置匹配;

这个意思也比較明显。就是用现成的,当其它应用使用定位更新了定位信息。系统会保存下来。该应用接收到消息后直接读取就能够了。比方假设系统中已经安装了百度地图,高德地图(室内能够实现精确定位)。你仅仅要使用它们定位过后。再使用这样的方法在你的程序肯定是能够拿到比較精确的定位信息。

3.2、获取可使用的LocationProvider 实例列表

通过调用 locationManager.getProviders(true) 方法就可以获得可利用的 LocationProvider 实例列表

3.3、根据Criteria 获取符合条件的 LocationProvider 实例

?每个 LocationProvider 都有一个条件集合,以便于应用程序可以选择合适的位置提供者。

?例如有的 LocationProvider 要求设备本身具有 GPS 模块,并且要求看见卫星的数量,有的要求手机设备能够接入 Internet 或者特定网络等。Criteria 类被用于为 LocationProvider 设置相关条件。

?Criteria 对象封装了获得 LocationProvider 实例的条件,可以根据指定的 Criteria 条件来过滤 LocationProvider 列表,以得到符合条件的 LocationProvider 实例。

Criteria 的常用方法

⭐️isAltitudeRequired():返回 Provider 是否需要高度信息

⭐️isBearingRequired():返回 Provider 是否需要方向信息

⭐️isSpeedRequired():返回 Provider 是否需要速度信息

⭐️isCostAllowed():标识是否允许产生费用

⭐️setAccuracy(int accuracy):设置 Provider 的精确度

⭐️setAltitudeRequired (boolean altitudeRequired):设置 Provider 是否需要高度信息

⭐️setBearingRequired (boolean bearingRequired):设置 Provider 是否需要方位信息

⭐️setSpeedRequired (boolean speedRequired):设置 Provider 是否需要速度信息

⭐️setCostAllowed (boolean cost Allowed):设置是否需要产生费用

⭐️getAccuracy():获取位置信息的准确度

(4)实现LocationListener接口:可以采用内部类(MyLocationListener)或匿名类方式实现,重写接口方法

(5)使用完释放监听:

mLocationManager.removeUpdates(mLocationListener);

该方法执行的位置需要特别注意,如果是在Activity对象中,则需要考虑Activity的生命周期,onPause方法中比较合适,因为onStop、onDestroy两个方法在异常情况下不会被执行。

(6)如果需要监听GPS卫星状态,则需要实现GpsStatus.Listener接口,并创建对象、添加监听、使用完后释放监听

private class MyGpsStatusListener implements GpsStatus.Listener;

二、 Android GPS 临近警告

1、临近警告就是固定一个点,当手机与该点的距离少于指定范围时,可以触发对应的处理

2、调用LocationManager的addProximityAlert() 方法添加临近警告

addProximityAlert(double latitude,double longitude,float radius,long expiration,PendingIntent intent)

⭐️ latitude指定固定点的经度

⭐️ longitude指定固定点的纬度

⭐️ radius指定半径长度

⭐️ expiration指定经过多少毫秒后该临近警告就会过期失效,-1 表示永不过期

⭐️ intent该参数指定临近该固定点时触发该 intent 对应的组件

三、Android 9利用 Wi-Fi RTT 进行室内定位

Android 9 中的 WLAN 往返时间 (RTT) 功能允许设备测量与其他支持设备的距离:无论它们是接入点 (AP) 还是 WLAN 感知对等设备(如果设备支持 WLAN 感知功能)。此功能基于 IEEE 802.11mc 协议,使应用能够使用准确性更高的定位功能和增强的感知功能。

用户可以利用 WLAN RTT(往返时间)API 提供的 WLAN 定位功能,测量距附近支持 RTT 的 WLAN 接入点和 WLAN 感知对等设备的距离。

请求发出设备无需连接到接入点即可通过 WLAN RTT 测量距离。为维护隐私,只有发出请求的设备能够确定距接入点的距离,接入点没有此信息。前台应用执行 WLAN RTT 操作不受限制,但后台应用执行此类操作时会受限。

1、实现RTT要求:

​1、测距请求发出设备的硬件必须实现 802.11mc FTM 标准。

​2、测距请求发出设备必须运行 Android 9(API 级别 28)或更高版本的操作系统。

​3、测距请求发出设备必须启用位置服务并打开 WLAN 扫描(Settings > Location)。

​4、测距请求发出设备必须拥有 ACCESS_FINE_LOCATION 权限。

​5、接入点必须实现 IEEE 802.11mc FTM 标准。

2、应用使用WLAN RTT,需要完成:

1、 请求权限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />//ACCESS_WIFI_STATE权限可以获取使用Wi-Fi等WLAN无线网络<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />//CHANGE_WIFI_STATE是改变WLAN状态的开关,如果开或关闭Wi-Fi必需加入android.permission.CHANGE_WIFI_STATE的声明.<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>//android.permission.ACCESS_FINE_LOCATION允许一个程序访问精良位置(如GPS)
2.、检查设备是否支持 WLAN RTT
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI_RTT);
3、 检查 WLAN RTT 是否可用

⭐️ 设备上可能存在 WLAN RTT,但由于用户已禁用 WLAN,该功能目前或不可用。如果 SoftAP 或网络共享处于使用状态,则某些设备可能不支持 WLAN RTT,具体视设备的硬件和固件功能而定。

⭐️ 如要检查 WLAN RTT 当前是否可用,请调用 isAvailable()。

⭐️ WLAN RTT 的可用性随时可能发生变化。所以应注册一个 BroadcastReceiver,以接收 ACTION_WIFI_RTT_STATE_CHANGED(系统会在可用性发生变化时发送该内容)。当应用收到广播 Intent 时,其应检查可用性的当前状态,并对其行为进行相应调整。

IntentFilter filter =new IntentFilter(WifiRttManager.ACTION_WIFI_RTT_STATE_CHANGED);BroadcastReceiver myReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {​ if (wifiRttManager.isAvailable()) {​ …​ } else {​ …​ }}};context.registerReceiver(myReceiver, filter);

3、 获得WifiRttManager的实例对象

WifiRttManager mWifiRttManager=getSystemService(Context.WIFI_RTT_RANGING_SERVICE);
3.1、创建测距请求

通过指定请求范围的 AP 或 WLAN 感知对等设备的列表,即可创建测距请求 (RangingRequest)。可以在单个测距请求中指定多个接入点或 WLAN 感知对等设备,然后测量并返回与所有设备的距离。

  • 请求可以使用 addAccessPoint() 方法指定要测量距离的接入点:

  • 接入点由其 ScanResult 对象标识,该对象可通过调用 WifiManager.getScanResults() 获得。可以使用 addAccessPoints(List) 批量添加多个接入点。

  • 可以通过以下两种途径添加 WLAN 感知对等设备:使用 addWifiAwarePeer(MacAddress 对等点) 方法利用请求的 MAC 地址,或者使用 addWifiAwarePeer(PeerHandle 对等点) 方法利用请求的 PeerHandle。

3.2、请求测距
  • 应用使用 WifiRttManager.startRanging() 方法发出测距请求,并提供以下内容:用于指定操作的 RangingRequest、用于指定回调上下文的 Executor,以及用于接收结果的 RangingResultCallback。

  • 测距操作以异步方式执行;测距结果在 RangingResultCallback 的某个回调中返回:

  • 如果整个测距操作失败,则会触发 onRangingFailure 回调,并返回 RangingResultCallback 中描述的状态代码。如果该服务当时出于某些原因(例如 WLAN 遭到禁用、应用请求的测距操作过多并受到限制,或者存在权限问题)无法执行测距操作,则可能会发生此类失败。

  • 测距操作完成后,会触发 onRangingResults 回调,并返回与请求列表匹配的结果列表(每个请求匹配一个结果)。结果的顺序不一定与请求的顺序一致。请注意,测距操作可能已经完成,但每个结果仍有可能提示该特定测量失败,

mgr.startRanging(request, executor, new RangingResultCallback() {@Overridepublic void onRangingFailure(int code) { … }@Overridepublic void onRangingResults(List<RangingResult> results) { … }});

onRangingResults 回调返回的每个结果均由 RangingResult 对象指定。请对每个请求执行以下操作。

3.3、识别请求
  • 根据创建 RangingRequest 时提供的信息来识别请求。该信息通常是在 ScanResult中提供的 MAC 地址,用于识别接入点。可以使用 getMacAddress()方法从测距结果中获得 MAC 地址。

  • 测距结果列表的顺序可能与测距请求中指定的对等设备(接入点)的顺序不同,因此应使用 MAC 地址而非结果的顺序来识别对等设备。

  • 确定每个测量是否成功

如要确定测量是否成功,请使用 getStatus() 方法。STATUS_SUCCESS 以外的任何值都表示失败。失败意味着此结果的所有其他字段(上述请求标识除外)均为无效字段,相应的 get* 方法也将失败,并显示 IllegalStateException 异常。

  • 获取每个成功测量的结果

对于每个成功的测量,可以使用相应的 get 方法检索结果值:

  • 距离(单位为毫米)和测量的标准偏差:getDistanceMm()和getDistanceStdDevMm()

  • 用于测量的数据包的 RSSI:getRssi()

  • 测量所用时间(以毫秒为单位;表示自启动以来的时间):getRangingTimestampMillis()

  • 尝试的测量个数和成功的测量个数(以及距离测量的依据):getNumAttemptedMeasurements()和

getNumSuccessfulMeasurements()

需要做网站?需要网络推广?欢迎咨询客户经理 13272073477