1. gps說明
a) 原理
每一衛星播發一個僞隨機測距碼信號,該信號大約每1毫秒播發一次。接收儀同時複製出一個同樣結構的信號並與接收到的衛星信號進行比較,由信號的延遲時間(dT)推算出衛星至 接收儀的距離
b) 述語
TTFF:首次定位時間
PRN:僞隨機碼,用於辨別是哪顆衛星
SNR:信噪比
2. android對gps的內部支持
a) 位置服務
android對衛星定位的支持名字叫位置服務,可以通過設置來打開或關閉它
b) android實現
frameworks/base/location/java/android/location/LocationManager.java 接口
frameworks/base/services/java/com/android/server/LocationManagerService.java 服務
frameworks/base/core/jni/android_location_GpsLocationProvider.cpp 等待gps事件,發給service
libhardware_legacy/include/hardware_legacy/gps.h 定義了底級gps的實現,不同硬件以不同方式實現它,它可能是對設備的訪問,也可能與modem通過rpc通訊得到gps數據
c) 應用程序調用接口
frameworks/base/location/java/android/location/*.java
LocationManager.java是最重要的接口,通過它訪問gps定位資源
LocationListener.java是定位的回調函數,通過實現它來接收定位數據
Gps*.java提供了獲取當前gps信息的接口,包括捕獲的衛星數,信噪比等
d) 調試
想要調試gps,可以把/system/etc/gps.conf中的debug等級調爲5,此時你可以在logcat中看到全部的gps信息
在室內基本沒有信號,窗邊效果也不好,建議在室外,至少是站在陽臺上測試
3. 例程
a) 功能
顯示當前經緯度及搜到的衛星個數
b) 可從此處下載可獨立運行的代碼
http://download.csdn.net/source/2598910
c) 核心代碼及說明
package com.android.mygps;
import android.app.Activity;
import android.util.Log;
import android.os.Bundle;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.GpsSatellite;
import android.widget.TextView;
import android.content.Context;
import java.util.Iterator;
public class MyGpsActivity extends Activity {
LocationManager mLocationManager;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
String provider = mLocationManager.GPS_PROVIDER;
Location location = mLocationManager.getLastKnownLocation(provider);
mLocationManager.requestLocationUpdates(provider, 4000, 10,
locationListener); // 4秒一次,開始接聽gps數據
mLocationManager.addGpsStatusListener(statusListener); // 註冊狀態信息回調
updateWithNewLocation(location);
updateGpsStatus(0, null);
}
public void onDestroy() {
super.onDestroy();
}
private final GpsStatus.Listener statusListener = new GpsStatus.Listener() {
public void onGpsStatusChanged(int event) {
Log.w("xieyan", "now gps status changed" + event);
GpsStatus status = mLocationManager.getGpsStatus(null); // 取當前狀態
updateGpsStatus(event, status);
} // GPS狀態變化時的回調,如衛星數,信號強度等
};
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
Log.w("xieyan", "now location changed");
updateWithNewLocation(location);
} // 經緯度變化時的回調
public void onProviderDisabled(String provider) {
Log.w("xieyan", "now provider disable");
updateWithNewLocation(null);
}
public void onProviderEnabled(String provider) {
Log.w("xieyan", "now provider enable");
}
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.w("xieyan", "now provider status changed" + status);
}
};
private void updateGpsStatus(int event, GpsStatus status) {
TextView slView = (TextView) findViewById(R.id.TextViewSatellites);
if (status == null) {
slView.setText(getString(R.string.satellites) + "0");
} else if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) {
int maxSatellites = status.getMaxSatellites();
Iterator<GpsSatellite> it = status.getSatellites().iterator();
int count = 0;
while (it.hasNext() && count <= maxSatellites) {
GpsSatellite s = it.next();
count++;
} // 計算衛星個數,可在此打印出衛星的其它信息
slView.setText(getString(R.string.satellites) + count);
}
}
private void updateWithNewLocation(Location location) {
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude(); // 取經緯度
TextView latView = (TextView) findViewById(R.id.TextViewLng);
TextView lngView = (TextView) findViewById(R.id.TextViewLat);
latView.setText(getString(R.string.latitude)
+ String.format("%.5f", lat));
lngView.setText(getString(R.string.longitude)
+ String.format("%.5f", lng));
} else {
TextView latView = (TextView) findViewById(R.id.TextViewLng);
TextView lngView = (TextView) findViewById(R.id.TextViewLat);
latView.setText(getString(R.string.getinfo_fail));
lngView.setText("");
}
}
}
4. 輔助工具
定位程序要麼帶地圖很大,要麼太簡單不能得到足夠數據。推薦gpslogger,使用它可以看到當前的經緯度,速度,信號強度,當前搜到了幾顆星(搜到小於三顆星時,定位不到經緯度),幫助進一步定位問題。
http://gpslogger.codeplex.com/可以下載到它的源碼
5. 參考
a) gps術語
http://www.mobile01.com/newsdetail.php?id=257