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)         可从此处下载可独立运行的代码

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 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​