当前位置: 首页 > 科技观察

关于如何在Android上做GPS相关的定位服务

时间:2023-03-13 23:37:31 科技观察

今天因为工作需要,把之前写的一个GPS测试程序拿出来重新修改。这个程序有一些历史。是我11年写的。那时候,我刚学Android开发没多久。它被认为是一项实验性工作。现在需要再次取出工件进行修整。同时发现自己对android的GPS服务了解的还不是很深,所以今天看了一些关于GPS服务的资料,把相关的知识点记录下来。本人从事GPS相关嵌入式软件多年,所以一提到测试GPS定位模块的程序,第一反应就是通过串口读取GPS模块的数据,然后分析NMEAGPS的格式数据。NMEA是一种标准化的数据格式,不仅应用于GPS,还用于其他一些工业通信。解析出相关数据并展示后,一个基本的GPS定位测试功能就完成了。查看后发现Android上GPS相关定位服务不需要读取NMEA数据分析。Android已经封装了相关服务,你只需要调用API即可。不知道这应该是觉得爽还是纠结。(Android也提供了读取NMEA的接口,下面会讲到)1.Android定位服务先来看看Android对定位服务的支持:Android定位服务位于location下,上面有相关说明,这里就不详细分析了。有一点需要说明一下:GpsStatus.NmeaListener官方说可以读取NMEA数据,但是我这里测试发现它并没有读取NMEA数据。查阅了一些资料,据说谷歌并没有在底层实现数据反馈的功能。如果你有时间,你需要查看源代码。2.LocationManager定位//获取位置服务LocationManagerlocationManager=(LocationManager)this.getSystemService(Context.LOCATION_SERVICE);//判断GPS模块是否开启if(locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)){//GPS模块开启,可以进行定位操作}//通过GPS定位StringLocateType=locationManager.GPS_PROVIDER;Locationlocation=locationManager.getLastKnownLocation(LocateType);//设置监听器,设置自动更新间隔,这里设置1000ms,移动距离:0米。locationManager.requestLocationUpdates(provider,1000,0,locationListener);//设置状态监听回调函数。statusListener是监听的回调函数。locationManager.addGpsStatusListener(statusListener);//另外通过网络设置位置StringLocateType=locationManager.NETWORK_PROVIDER;Locationlocation=locationManager.getLastKnownLocation(LocateType);知道GPS卫星定时广播数据,也就是说会定时接收卫星的GPS数据。我们不能主动向卫星申请数据,只能被动接收数据。(中国的北斗二号可以给卫星发卫星信息)所以我们需要注册一个listener来处理卫星返回的数据。privatefinalGpsStatus.ListenerstatusListener=newGpsStatus.Listener(){publicvoidonGpsStatusChanged(inevent){//GPS状态变化时的回调,获取当前状态GpsStatusstatus=locationManager.getGpsStatus(null);//自己写的方法,获取卫星状态相关数据GetGPSStatus(event,status);}};4.获取搜索到的卫星privatevoidGetGPSStatus(inevent,GpsStatusstatus){Log.d(TAG,"entertheupdateGpsStatus()");if(status==null){}elseif(event==GpsStatus.GPS_EVENT_SATELLITE_STATUS){//获取最大数量satellites(这只是一个预设值)intmaxSatellites=status.getMaxSatellites();Iteratorit=status.getSatellites().iterator();numSatelliteList.clear();//记录实际的卫星数intcount=0;while(it.hasNext()&&count<=maxSatellites){//保存卫星数据到队列刷新界面GpsSatellites=it.next();numSatelliteList.add(s);count++;Log.d(TAG,"updateGpsStatus----count="+count);}mSatelliteNum=numSatelliteList.size();}elseif(event==GpsStatus.GPS_EVENT_STARTED){//定位开始}elseif(event==GpsStatus.GPS_EVENT_STOPPED){//定位结束}}以上是从status值中获取搜索到的卫星数量,主要是通过status.getSatellites()。将获取到的GpsSatellite对象保存在一个队列中,以供后续刷新界面使用。以上是获取GPS状态监听器。除了GPS状态,我们还需要监听一个服务,即:LocationListener,一个位置监听器,用来监听位置的变化。这对于做位置服务的应用程序来说非常重要。5.LocationListenerlistenerprivatefinalLocationListenerlocationListener=newLocationListener(){publicvoidonLocationChanged(Locationlocation){//坐标变化时触发该函数,如果Provider传入相同坐标则不会触发updateToNewLocation(location);Log.d(TAG,"LocationListeneronLocationChanged");}publicvoidonProviderDisabled(Stringprovider){//Provider关闭时触发该函数,比如GPS关闭Log.d(TAG,"LocationListeneronProviderDisabled");}publicvoidonProviderEnabled(Stringprovider){//当Provider开启时触发该功能,比如GPS开启//Provider的transition可用,暂时不可用这个函数在service和noservice三种状态直接切换时触发if(status==LocationProvider.OUT_OF_SERVICE||status==LocationProvider.TEMPORARILY_UNAVAILABLE)      {}}};位置监听回调用于处理GPS定位时间的变化,自动回调的方法,我们可以从这里获取当前的GPS数据。另外,我们可以通过回调函数提供的location参数获取GPS的地理位置信息,包括经纬度、速度、高度等信息。 6.获取地理位置信息(经纬度、卫星数、高度、定位状态)//从上面定位服务回调函数的参数中获取位置对象。mLatitude=location.getLatitude();   //经度mLongitude=location.getLongitude(); //纬度mAltitude=location.getAltitude();  //海拔mSpeed=location.getSpeed();     //速度mBearing=location.getBearing();   //Direction7.获取指定卫星信息(方向角,高度角,信噪比)//temgGpsSatellite就是我们上面保存的搜索到的卫星//方位角floatazimuth=temgGpsSatellite.getAzimuth();//仰角floatelevation=temgGpsSatellite.getElevation();//信噪比floatsnr=temgGpsSatellite.getSnr();我们可以利用方位角和高度角绘制一个二维图,表示卫星在地球上的位置,信噪比的影响更大。一般的卫星定位测试软件都会提供信噪比的状态图,它是GPS模块搜星能力的一个代表。8.绘制二维卫星位置图下面是我做的GPS测试效果图:下面是根据方位角和高度角计算卫星二维图中位置的方法。上图左侧的绿点代表卫星位置。右边的信噪比直方图代表卫星接收信号的能力。//根据方位角和高度角计算出卫星显示的位置Pointpoint=newPoint();intx=mEarthHeartX;//左边地球圆心位置的X坐标inty=mEarthHeartY;//左边地球圆心位置Y坐标intr=mEarthR;x+=(int)((r*elevation*Math.sin(Math.PI*azimuth/180)/90));y-=(int)((r*elevation*Math.cos(Math.PI*azimuth/180)/90));point.x=x;point.y=y;//点是信噪比的绘图需要绘制卫星图的起始坐标,是单位换算,这里不再赘述。9、总结:Android为我们提供了非常方便的位置服务,主要是通过GpsStatus、LocationManager、GpsSatellite来实现相关的服务和监控。不过个人觉得直接读取NMEA数据还是很方便的,至少对于一些应用来说,可以获得更多的信息。