今日は仕事の都合で、以前書いたGPSテストプログラムを取り出して修正しました。このプログラムには少し歴史があり、私が Android 開発を学んで間もない 2011 年に作成したもので、実験的な作品と考えられていました。今度は作業で必要になったので、もう一度取り出して修理する必要があります。同時に、Android の GPS サービスについてあまり知らないことに気づきました。そこで、今日 GPS サービスに関する情報を読んで、関連する知識ポイントを記録しました。
私は数年間 GPS 関連の組み込みソフトウェアを作成してきました。そのため、GPS 測位モジュールをテストするプログラムを作成することになると、私の最初の反応は、シリアル ポートを介して GPS モジュールのデータを読み取り、解析することです。 GPSのNMEA形式のデータです。 NMEA は、GPS だけでなく、他の産業用通信でも使用される標準化されたデータ形式です。関連するデータを解析して表示することで、基本的な GPS 測位テスト機能が完成します。
確認したところ、Android で GPS 関連の測位サービスを実行するために NMEA データ分析を読み取る必要はなく、API を呼び出すだけで済みます。これについて喜んでいいのか戸惑っていいのかわかりません。 (Android は、後述する NMEA を読み取るためのインターフェースも提供します)
1. Android 測位サービス
まず、Android が提供する測位サービスのサポートを見てみましょう:
Android 測位サービスはすべて位置しています。 location の下に、上記の関連説明があるため、ここでは詳細に分析しません。 1 つ言っておきたいのは、GpsStatus.NmeaListener です。公式には NMEA データを読み取ることができると記載されていますが、ここでのテストでは NMEA データが読み込まれないことがわかりました。いくつかの情報を調べたところ、Google は最下位レベルでのデータ フィードバック機能を実装していないと言われています。時間があれば、ソースコードを確認してください。
2. LocationManager 測位
//获取定位服务 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 リスナー
測位サービスの初期設定手順は上記に示されていますが、GPS 衛星が定期的にデータをブロードキャストすることは、衛星からの GPS データが定期的に受信されることを誰もが知っています。私たちは衛星に積極的にデータを要求することはできず、受動的にデータを受信することしかできません。 (中国の北斗 2 号は衛星に衛星メッセージを送信できます) したがって、衛星から返されたデータを処理するためにリスナーを登録する必要があります。
private final GpsStatus.Listener statusListener = new GpsStatus.Listener() { public void onGpsStatusChanged(int event) { // GPS状态变化时的回调,获取当前状态 GpsStatus status = locationManager.getGpsStatus(null); //自己编写的方法,获取卫星状态相关数据 GetGPSStatus(event, status); } };4. 検索した衛星を取得する
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) { //定位结束 } }上記は主にstatus.getSatellites()を使ってステータス値から検索した衛星の数を取得するものです。取得された GpsSatellite オブジェクトは、後でインターフェイスを更新できるようにキューに保存されます。上記は、GPS ステータス リスナーを取得することです。GPS ステータスに加えて、位置の変化を監視する測位リスナーである LocationListener も監視する必要があります。これは、位置情報サービスを提供するアプリケーションにとって非常に重要です。
5. LocationListener リスナー
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) { } } };
//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();方位角と高度角を考慮すると、信号対雑音比がより大きな役割を果たす地球上の衛星の位置を示す 2 次元グラフを描くことができます。一般的な衛星測位テスト ソフトウェアは、GPS モジュールの星探索機能を表す信号対雑音比の状態図を提供します。
8. 二次元衛星位置地図を描画します
以下は私が行った GPS テストのレンダリングです:
以下は、衛星二次元地図に基づいて位置を計算する方法です。方位角と高度角では、上のレンダリングの左側にある緑色の点が衛星の位置を表します。
右側の信号対雑音比のヒストグラムは、衛星の信号受信能力を表しています。rreee
信号対雑音比の描画は単なる単位変換なので、ここではコードを示しません。 9. 概要:Android は、主に GpsStatus、LocationManager、および GpsSatellite クラスを通じて、関連サービスと監視を実装する非常に便利な位置情報サービスを提供します。
ただし、少なくとも一部のアプリケーションでは、NMEA データを直接読み取ることができれば非常に便利だと個人的には感じています。
Android GPS 測位テスト (レンダリングと例付き) 関連記事については、PHP 中国語 Web サイトに注目してください。