`
lmx227
  • 浏览: 51354 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Android2.2[GPS模块]源码分析

阅读更多

下面这个程序在会监听GPS 开启,关闭,位置改变,

 

  1. public class MainActivity extends Activity implements LocationListener {  
  2.     /** Called when the activity is first created. */  
  3.     private final static String TAG = "LocationTest";  
  4.     TextView tv;  
  5.     Button btn;  
  6.     private LocationManager lm;  
  7.     public void onCreate(Bundle savedInstanceState) {  
  8.         super.onCreate(savedInstanceState);  
  9.         setContentView(R.layout.main);  
  10.         // 与Location_service建立连接  
  11.         lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);  
  12.         // 注册activity到监听队列中  
  13.         lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1l, 1l, this);  
  14.     }  
  15.     // Location发生变化时会调用这个  
  16.     public void onLocationChanged(Location location) {  
  17.         Log.d(TAG, "location: " + location);  
  18.     }  
  19.     // 关闭GPS卫星会调用这个  
  20.     public void onProviderDisabled(String provider) {  
  21.         Log.d(TAG, "provider disable" + provider);  
  22.     }  
  23.     // 启用GPS卫星会调用这个  
  24.     public void onProviderEnabled(String provider) {  
  25.         Log.d(TAG, "provider enable");  
  26.     }  
  27.     public void onStatusChanged(String provider, int status, Bundle extras) {  
  28.         Log.d(TAG, "status changed status = " + status);  
  29.     }  
  30. }  

 

 

使用GPS 需要这个权限:

< uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" >

</ uses-permission >

使用GPS 相关的资源,需要先用getSystemService 获得一个LOCATION_SERVICE 的实例,获得这个实例之后就可以进行相关操作了。

@frameworks/base/services/java/com/android/server/SystemServer.java

LOCATION_SERVICE 是在SystemServer.java 中启动的,也就是系统启动之后,这个服务就已经启动了:

ServiceManager.addService(Context.LOCATION_SERVICE, new LocationManagerService(context));

源码结构

主要分为四部分,client ,service ,jni ,hardware

frameworks/base/location/* (client 部分)

frameworks/base/services/java/com/android/serverLocationManagerService.java (server 部分)

frameworks/base/core/jni/android_location_GpsLocationProvider.cpp JNI 部分)

hardware/libhardware_legacy/gps/* hardware 接口部分)

 

1. frameworks/base/location/java (Client 部分)

.

├── android

│   └── location

│   ├── Address.aidl

│   ├── Address.java 描述地理位置信息

│   ├── Criteria.aidl

│   ├── Criteria.java 定位提供商的应用标准

│   ├── Geocoder.java 地理编码,好像是定位信息转换用的

│   ├── GpsSatellite.java 描述当前GPS satellite 信息

│   ├── GpsStatus.java 描述当前GPS engine 信息

│   ├── IGeocodeProvider.aidl

│   ├── IGpsStatusListener.aidl

│   ├── IGpsStatusProvider.aidl

│   ├── ILocationListener.aidl

│   ├── ILocationManager.aidl

│   ├── ILocationProvider.aidl

│   ├── INetInitiatedListener.aidl

│   ├── Location.aidl

│   ├── Location.java 描述定位的详细信息经度,纬度等等

│   ├── LocationListener.java 监听定位服务

│   ├── LocationManager.java 用来访问定位服务AIDL

│   ├── LocationProvider.java 定位提供者信息

│   └── package.html

└── com

└── android

└── internal

└── location

├── DummyLocationProvider.java

├── GpsLocationProvider.java

├── GpsNetInitiatedHandler.java

├── GpsXtraDownloader.java

├── LocationProviderProxy.java

├── MockProvider.java

└── NmeaParser.java

 

2. frameworks/base/services/java/com/android/server/ LocationManagerService.java (server 部分)

 

3. frameworks/base/core/jni/android_location_GpsLocationProvider.cpp (JNI 部分)

 

4. hardware 接口部分)

hardware/libhardware_legacy/gps.h

hardware/libhardware_legacy/gps_ni.h

hardware/libhardware_legacy/gps/*

.

├── Android.mk

├── gps.cpp

└── gps_qemu.c


代码分析

1. 控制通道,也就是由app 层发起的比如enable 或disable 的控制命令,这个在”设置/ 位置和安全设置/ 使用GPS 卫星”里面设置。

LocationManager.java 主要负责通信。具体的实现在LocationManagerService.java 中,通过AIDL 实现通信,接口文件是ILocationManager.aidl 。在LocationManagerService 在初始化的时候,会判断是否有GPS 设备,如果存在则创建了一个GpsLocationProvider.java ,并通过JNI 调 android_location_GpsLocationProvider.cpp ,该文件再通过GPSInterface 来调用硬件的具体实现代码。

 

2. enable 后的Location 数据和状态上报。对于数据的上报过程,主要就是关注几个callback 函数。主要代码分析如下:

在 GpsLocationProvider.java 文件中enable() 一个GpsLocationProvider 时,会启动一个 GpsEventThread, 该线程主要就是调用了native_wait_for_event(); 通过JNI 调用到了android_location_GpsLocationProvider_wait_for_event()@ anroid_location_GpsLocationProvider.cpp ,而该event的触发是由来自硬件驱动 Location 数据包的上报,底层的硬件驱动程序会把raw gps data 通过串口或其他的方式送出来,这个要看gps 驱动的实现了,我们通过自己实现的GpsInterface 来解析raw gps data 并调用loaction_callback() 来触发event 并copy Location 数据,等待到event 后再调用GpsLocationProvider.java 中的reportLocation() 上报Location.

 

另外一部分就是hardware/libhardware_legacy/gps 部分的实现,这个主要就是实现gps.h 里面的几个数据结构:

 

  1.   const void* (*get_extension)(const char* name);  
  2. } GpsInterface;  
  3. typedef struct {  
  4.     uint16_t        flags;  
  5.     double          latitude;  
  6.     double          longitude;  
  7.     double          altitude;  
  8.     float           speed;  
  9.     float           bearing;  
  10.     float           accuracy;  
  11.     GpsUtcTime      timestamp;  
  12. } GpsLocation;   

GpsInterface->init() 的时候要把上层的GpsCallbacks 传进来,然后start 后,从驱动那里poll 获得gps raw data ,并对raw data 进行解析并填充GpsLocation 数据结构,然后调用location_cb 上报location 数据。

  1. //初始化的时候,得到GpsInterface,调用init,并且设置callback函数:  
  2. static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)  
  3. {  
  4.     if (!sGpsInterface)  
  5. padding-top: 0px !important; padding-right: 3px !important; padding-bottom: 0px !important; padding-left: 10px !important; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: solid; border-color: initial; border-left-width: 3px; border-left-color: #6ce26c; background-color: #ffffff; color: inherit; line-height: 14px; mar
    分享到:
    评论

相关推荐

Global site tag (gtag.js) - Google Analytics