首页
社区
课程
招聘
[原创]Android GPS定位概述
发表于: 2012-9-30 23:26 7077

[原创]Android GPS定位概述

2012-9-30 23:26
7077

  在Android系统中,定位有三种方式,一是WIFI热点定位;二是GPS定位;三是AGPS定位。
  WIFI热点定位,利用WIFI热点的相关信息来实现,如MAC地址、IP地址等等。获取的WIFI热点信息发送到Google服务器,在服务器上做处理查找后返回定位信息。这样不依赖平台,实现也很简单。
  AGPS(AssistedGPS)定位,结合GSM与GPRS与GPS定位,利用基站代送辅助卫星信息。这样可以充分利用基站,减少对GPS卫星的依赖,从而在被遮挡处也能利用基站提供信号,也可以更快更精确的获取到定位信息。
  主要看一下GPS定位,GPS系统架构图如下(发现不能提交图片,改为附件中,附件一:图片1):
  
  App就是使用GPS定位的应用。
  我下载的android源码是2.3.3的,所以以下的目录都是在这个基础上的,可能在4.0版本目录会有一定差别。
  先从“上层”看起,Framework层。Framework层主要在三个目录底下,分别是frameworks/base/location/java/android/location、frameworks/base/location/java/com/android/internal/location 和framework\base\services\java\com\android\server 。
  frameworks/base/location/java/com/android/internal/location是对Location服务的内部实现。framework\base\services\java\com\android\server下有LocationManagerService.java文件,是Location服务对内部实现的封装。
  frameworks/base/location/java/android/location提供API给App调用。平常开发GPS App使用的调用都是由Framework层提供。API包是android.location。下图(附件二:图片2)是App中对包的调用:
  
  Framework层的源文件在frameworks/base/location/java/android/location中,可以看到,里面的文件如下图所示(附件三:图片3):
  
  摘取一段Location.java中计算两点距离(computeDistanceAndBearing)的部分代码看一下。private static void computeDistanceAndBearing(double lat1, double lon1, double lat2, double lon2, float[] results),可以很明显看出是根据两个地点的经纬度进行相关计算,至于results数组是干什么的,看一下代码就知道了。
  float distance = (float) (b * A * (sigma - deltaSigma));
  results[0] = distance;
  if (results.length > 1) {
        float initialBearing = (float) Math.atan2(cosU2 * sinLambda,cosU1 * sinU2 - sinU1 * cosU2 * cosLambda);
        initialBearing *= 180.0 / Math.PI;
        results[1] = initialBearing;
        if (results.length > 2) {
            float finalBearing = (float) Math.atan2(cosU1 * sinLambda,-sinU1 * cosU2 + cosU1 * sinU2 * cosLambda);
            finalBearing *= 180.0 / Math.PI;
            results[2] = finalBearing;
         }
  }
  
  可以看出,变量distance是计算得到的两地的距离,而results[0]被初始为distance,通过对results数组所含值的个数做判断,当为大于等于2时,results[1]存放的是initial bearing,当为大于等于3时,results[2]存放的是final bearing。由此我们也可以知道,GPS定位获取的方位不是像指南针那样原地指明方向,而是得出的是你运动的方向。
  JNI层主要是连接Framework和HAL,调用HAL层具体硬件抽象的实现。
  HAL(Hardware Abstract Layer),硬件抽象层。我们知道Android底层是基于Linux的,HAL就相当于Linux应用程序接口,从而进行硬件设备操作。hardware\libhardware\include\hardware中有gps.h文件,从中可以看到使用的数据结构。具体的实现是由高通提供的,在hardware\qcom\gps中。
  主要看一下gps.h文件。下面是GpsInterface,是底层驱动实现的接口。当其中的接口被调用时,可以实现相应的操作,注释已经比较完整。感觉比较特殊的是int  (*inject_time)(GpsUtcTime time, int64_t timeReference,int uncertainty),可以在两种情况下被调用,分别是应用发送相应命令时调用和网络可获取时自动调用。
  /** Represents the standard GPS interface. */
  typedef struct {
      /** set to sizeof(GpsInterface) */
      size_t          size;
      /**
       * Opens the interface and provides the callback routines
       * to the implemenation of this interface.
       */
      int   (*init)( GpsCallbacks* callbacks );
  
      /** Starts navigating. */
      int   (*start)( void );
  
      /** Stops navigating. */
      int   (*stop)( void );
  
      /** Closes the interface. */
      void  (*cleanup)( void );
  
      /** Injects the current time. */
      int   (*inject_time)(GpsUtcTime time, int64_t timeReference,
                           int uncertainty);
  
      /** Injects current location from another location provider
       *  (typically cell ID).
       *  latitude and longitude are measured in degrees
       *  expected accuracy is measured in meters
       */
      int  (*inject_location)(double latitude, double longitude, float accuracy);
  
      /**
       * Specifies that the next call to start will not use the
       * information defined in the flags. GPS_DELETE_ALL is passed for
       * a cold start.
       */
      void  (*delete_aiding_data)(GpsAidingData flags);
  
      /**
       * min_interval represents the time between fixes in milliseconds.
       * preferred_accuracy represents the requested fix accuracy in meters.
       * preferred_time represents the requested time to first fix in milliseconds.
       */
      int   (*set_position_mode)(GpsPositionMode mode, GpsPositionRecurrence recurrence,
              uint32_t min_interval, uint32_t preferred_accuracy, uint32_t preferred_time);
  
      /** Get a pointer to extension information. */
      const void* (*get_extension)(const char* name);
  } GpsInterface;
  
  下面是GpsLocation,可以看出Location的包含内容。主要有经度、维度、方向、海拔、速度、使用的准确度、时间。底层驱动会获取Location的信息后通过相应解析得到所需要的信息。
  /** Represents a location. */
  typedef struct {
      /** set to sizeof(GpsLocation) */
      size_t          size;
      /** Contains GpsLocationFlags bits. */
      uint16_t        flags;
      /** Represents latitude in degrees. */
      double          latitude;
      /** Represents longitude in degrees. */
      double          longitude;
      /** Represents altitude in meters above the WGS 84 reference
       * ellipsoid. */
      double          altitude;
      /** Represents speed in meters per second. */
      float           speed;
      /** Represents heading in degrees. */
      float           bearing;
      /** Represents expected accuracy in meters. */
      float           accuracy;
      /** Timestamp for the location fix. */
      GpsUtcTime      timestamp;
  } GpsLocation;






  
暂时只看这么多了,写的比较粗略,只做大体了解,以后会继续跟进。也希望能和大家交流。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 6
支持
分享
最新回复 (4)
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
很不幸  你来错地方了...这些应该是精通J2EE 以后然后做的事情.....
2012-10-2 22:04
0
雪    币: 68
活跃值: (30)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
就是 你来对地方了 ,现在好多人都开始研究案作了
2012-10-3 17:45
0
雪    币: 42
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
不是吧,只要有兴趣什么时候都可以啊
2012-10-4 00:26
0
雪    币: 42
活跃值: (40)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
我要发帖得会员,然后才能在android版块发言交流……悲剧
2012-10-4 00:27
0
游客
登录 | 注册 方可回帖
返回
//