android 典型应用之 gps

#移动开发 #Android

1. gps 说明

  1. 原理
    每一卫星播发一个伪随机测距码信号,该信号大约每 1 毫秒播发一次。接收仪同时复制出一个同样结构的信号并与接收到的卫星信号进行比较,由信号的延迟时间

(dT) 推算出卫星至 接收仪的距离

  1. 述语
    TTFF:首次定位时间
    PRN:伪随机码,用于辨别是哪颗卫星
    SNR:信噪比

2. android 对 gps 的内部支持

  1. 位置服务
    android 对卫星定位的支持名字叫位置服务,可以通过设置来打开或关闭它

  2. 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 数据

  1. 应用程序调用接口
    frameworks/base/location/java/android/location/.java
    LocationManager.java 是最重要的接口,通过它访问 gps 定位资源
    LocationListener.java 是定位的回调函数,通过实现它来接收定位数据
    Gps
    .java 提供了获取当前 gps 信息的接口,包括捕获的卫星数,信噪比等

  2. 调试
    想要调试 gps,可以把 /system/etc/gps.conf 中的 debug 等级调为 5,此时你可以在 logcat

中 看到全部的 gps 信息
在室内基本没有信号,窗边效果也不好,建议在室外,至少是站在阳台上测试

3. 例程

  1. 功能
    显示当前经纬度及搜到的卫星个数

  2. 可从此处下载可独立运行的代码
    [http://download.csdn.net/source/2598910

](http://download.csdn.net/source/2598910)

  1. 核心代码及说明

_ 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. 参考

  1. gps 术语
    [http://www.mobile01.com/newsdetail.php?id=257

](http://www.mobile01.com/newsdetail.php?id=257)

_ _

_ (转载请注明出处 http://xy0811.spaces.live.com)

_