Heute habe ich aus beruflichen Gründen ein GPS-Testprogramm herausgenommen, das ich zuvor geschrieben hatte, und es überarbeitet. Dieses Programm hat eine gewisse Geschichte. Ich habe es 2011 geschrieben, nicht lange nachdem ich die Android-Entwicklung gelernt hatte, und es galt als experimentelle Arbeit. Jetzt erfordert die Arbeit es, also muss ich es wieder herausnehmen und reparieren. Gleichzeitig stellte ich fest, dass ich nicht viel über den GPS-Dienst von Android weiß, deshalb habe ich heute einige Informationen über den GPS-Dienst gelesen und die relevanten Wissenspunkte aufgezeichnet.
Ich entwickle seit mehreren Jahren GPS-bezogene eingebettete Software. Wenn es also darum geht, ein Programm zum Testen des GPS-Positionierungsmoduls zu erstellen, besteht meine erste Reaktion darin, die Daten des GPS-Moduls über die serielle Schnittstelle zu lesen , und analysieren Sie dann das NMEA der GPS-Formatdaten. NMEA ist ein standardisiertes Datenformat, das nicht nur im GPS, sondern auch in der anderen industriellen Kommunikation verwendet wird. Durch das Parsen der relevanten Daten und deren anschließende Anzeige wird eine grundlegende GPS-Positionierungstestfunktion abgeschlossen.
Nach der Überprüfung habe ich herausgefunden, dass es nicht erforderlich ist, die NMEA-Datenanalyse zu lesen, um GPS-bezogene Positionierungsdienste auf Android durchzuführen. Android hat die relevanten Dienste bereits gepackt und Sie müssen lediglich die API aufrufen . Ich weiß nicht, ob ich darüber glücklich oder verwirrt sein soll. (Android bietet auch eine Schnittstelle zum Lesen von NMEA, die weiter unten besprochen wird)
1. Android-Ortungsdienst
Werfen wir zunächst einen Blick auf die Unterstützung, die Android für Ortungsdienste bietet:
Android-Standortdienste sind alle unter „Standort“ zu finden. Die entsprechenden Anweisungen finden Sie oben, daher werde ich sie hier nicht im Detail analysieren. Eine Sache, die erwähnt werden muss
ist: GpsStatus.NmeaListener. Die offizielle Aussage ist, dass es NMEA-Daten lesen kann, aber mein Test hier hat ergeben, dass keine NMEA-Daten gelesen wurden. Nach Rücksprache mit einigen Informationen heißt es, dass Google die Daten-Feedback-Funktion auf der untersten Ebene nicht implementiert. Wenn Sie Zeit haben, müssen Sie den Quellcode überprüfen.
2. LocationManager-Positionierung
//获取定位服务 LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); //判断是否已经打开GPS模块 if (locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) { //GPS模块打开,可以定位操作 }
// 通过GPS定位 String LocateType= locationManager.GPS_PROVIDER; Location location = locationManager.getLastKnownLocation(LocateType); // 设置监听器,设置自动更新间隔这里设置1000ms,移动距离:0米。 locationManager.requestLocationUpdates(provider, 1000, 0, locationListener); // 设置状态监听回调函数。statusListener是监听的回调函数。 locationManager.addGpsStatusListener(statusListener); //另外给出 通过network定位设置 String LocateType= locationManager.NETWORK_PROVIDER; Location location = locationManager.getLastKnownLocation(LocateType);
3. GpsStatus-Listener
Die ersten Einstellungsschritte des Positionierungsdienstes sind oben aufgeführt, aber wir alle wissen, dass GPS-Satelliten regelmäßig senden Es werden regelmäßig Daten, also GPS-Daten von Satelliten, empfangen. Wir können Daten von Satelliten nicht aktiv anfordern und nur passiv Daten empfangen. (Chinas Beidou 2 kann Satellitennachrichten an Satelliten senden.) Daher müssen wir einen Listener registrieren, um die vom Satelliten zurückgegebenen Daten zu verarbeiten.
private final GpsStatus.Listener statusListener = new GpsStatus.Listener() { public void onGpsStatusChanged(int event) { // GPS状态变化时的回调,获取当前状态 GpsStatus status = locationManager.getGpsStatus(null); //自己编写的方法,获取卫星状态相关数据 GetGPSStatus(event, status); } };
4. Abrufen der gesuchten Satelliten
private void GetGPSStatus(int event, GpsStatus status) { Log.d(TAG, "enter the updateGpsStatus()"); if (status == null) { } else if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) { //获取最大的卫星数(这个只是一个预设值) int maxSatellites = status.getMaxSatellites(); Iterator<GpsSatellite> it = status.getSatellites().iterator(); numSatelliteList.clear(); //记录实际的卫星数目 int count = 0; while (it.hasNext() && count <= maxSatellites) { //保存卫星的数据到一个队列,用于刷新界面 GpsSatellite s = it.next(); numSatelliteList.add(s); count++; Log.d(TAG, "updateGpsStatus----count="+count); } mSatelliteNum = numSatelliteList.size(); } else if(event==GpsStatus.GPS_EVENT_STARTED) { //定位启动 } else if(event==GpsStatus.GPS_EVENT_STOPPED) { //定位结束 } }
Das Obige dient dazu, die Anzahl der gesuchten Satelliten aus dem Statuswert abzurufen, hauptsächlich über status.getSatellites(). Das erhaltene GpsSatellite-Objekt wird zur späteren Aktualisierung der Schnittstelle in einer Warteschlange gespeichert. Das Obige dient dazu, den GPS-Status-Listener zu erhalten. Zusätzlich zum GPS-Status müssen wir auch einen Dienst überwachen: LocationListener, einen Positionierungs-Listener, der Standortänderungen überwacht. Dies ist sehr wichtig für Anwendungen, die Ortungsdienste bereitstellen.
5. LocationListener-Listener
private final LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { //当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发 updateToNewLocation(location); Log.d(TAG, "LocationListener onLocationChanged"); } public void onProviderDisabled(String provider) { //Provider被disable时触发此函数,比如GPS被关闭 Log.d(TAG, "LocationListener onProviderDisabled"); } public void onProviderEnabled(String provider) { // Provider被enable时触发此函数,比如GPS被打开 Log.d(TAG, "LocationListener onProviderEnabled"); } public void onStatusChanged(String provider, int status, Bundle extras) { Log.d(TAG, "LocationListener onStatusChanged"); // Provider的转态在可用、暂时不可用和无服务三个状态直接切换时触发此函数 if (status == LocationProvider.OUT_OF_SERVICE || status == LocationProvider.TEMPORARILY_UNAVAILABLE) { } } };
6. Erhalten Sie geografische Standortinformationen (Breitengrad und Länge, Anzahl der Satelliten, Höhe, Positionierungsstatus)
//location对象是从上面定位服务回调函数的参数获取。 mLatitude = location.getLatitude(); // 经度 mLongitude = location.getLongitude(); // 纬度 mAltitude = location.getAltitude(); //海拔 mSpeed = location.getSpeed(); //速度 mBearing = location.getBearing(); //方向
//temgGpsSatellite就是我们上面保存的搜索到的卫星 //方向角 float azimuth = temgGpsSatellite.getAzimuth(); //高度角 float elevation = temgGpsSatellite.getElevation(); //信噪比 float snr = temgGpsSatellite.getSnr();
8. Zeichnen Sie eine zweidimensionale Satellitenpositionskarte
Das Folgende ist eine Methode zur Berechnung der Position in der zweidimensionalen Satellitenkarte basierend auf dem Richtungswinkel und dem Höhenwinkel. Der grüne Punkt auf der linken Seite der obigen Darstellung stellt die Satellitenposition dar.
Das Signal-Rausch-Verhältnis-Histogramm auf der rechten Seite stellt die Signalempfangsfähigkeit des Satelliten dar.
Das Bild des Signal-Rausch-Verhältnisses ist nur eine Einheitenumrechnung, daher werde ich den Code hier nicht angeben.//根据方向角和高度角计算出,卫星显示的位置 Point point = new Point(); int x = mEarthHeartX; //左边地球圆形的圆心位置X坐标 int y = mEarthHeartY; //左边地球圆形的圆心位置Y坐标 int r = 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; //point就是你需要绘画卫星图的起始坐标
9. Zusammenfassung:
Android bietet uns sehr praktische Ortungsdienste, hauptsächlich über GpsStatus, LocationManager und GpsSatellite, um zugehörige Dienste und Überwachung zu implementieren.
Allerdings fände ich es persönlich sehr praktisch, wenn die NMEA-Daten direkt ausgelesen werden könnten. Zumindest für einige Anwendungen könnten dadurch mehr Informationen gewonnen werden.
Weitere Artikel zum Android-GPS-Positionierungstest (mit Darstellungen und Beispielen) finden Sie auf der chinesischen PHP-Website!