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

来源:互联网 发布:淘宝2元包邮 编辑:程序博客网 时间:2024/05/17 09:08

内容来源于网络以及自己的一些总结。

GPS JAVA API 示例

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

 

使用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));

源码结构

主要分为四部分,clientservicejnihardware

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

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

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 层发起的比如enabledisable 的控制命令,这个在”设置/ 位置和安全设置/ 使用GPS 卫星”里面设置。

LocationManager.java 主要负责通信。具体的实现在LocationManagerService.java 中,通过AIDL 实现通信,接口文件是ILocationManager.aidl 。在LocationManagerService 在初始化的时候,会判断是否有GPS 设备,如果存在则创建了一个GpsLocationProvider.java ,并通过JNIandroid_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() 来触发eventcopy Location 数据,等待到event 后再调用GpsLocationProvider.java 中的reportLocation() 上报Location.

 

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

 

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

 

 

hardware 那部分有个线程gps_state_thread 一直在读串口的内容并进行解析,最后解析到location 的信息

cpp 文件的GpsCallbacks sGpsCallbacks = { location_callback....} 同步上层的线程。

 

 

FrameworkHAL 调用过程大致如下:

 

Android 2.2 Settings 程序GPS 设置:

Settings -> Location & security ->My Location 里面有”Use wireless networks” 和”Use GPS satelites” 两个选项。一个是通过网络定位(Internet/Mobile networks ),另一个是通过GPS 芯片定位。

 

这部分相应的代码:

packages/apps/Settings/src/com/android/settings/SecuritySettings.java

 

SecuritySettings.java 中的大概调用流程如下:

首先加载XML 绑定视图:

onCreate()

createPreferenceHierarchy()

addPreferencesFromResource(R.xml.security_settings);

mGps = (CheckBoxPreference) getPreferenceScreen().findPreference(LOCATION_GPS);

mAssistedGps = (CheckBoxPreference) getPreferenceScreen().findPreference(ASSISTED_GPS);

 

然后onPreferenceTreeClick 方法会监听checkuncheck 事件。

如果Use GPS satelites 被选择,就会调用:

/frameworks/base/core/java/android/provider/Settings.java

Settings.Secure.setLocationProviderEnabled(getContentResolver(),

LocationManager.GPS_PROVIDER , enabled);

putString(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, provider);

putString(ContentResolver resolver, Uri uri, String name, String value)

values.put(NAME, name); // name = location_providers_allowed

values.put(VALUE, value);

resolver.insert(uri, values);

最后会调用resolver.insert(uri, values); 把写到数据库(uri=”content://settings/secure” )中。

 

如果Use wireless networks 被选中:

Settings.Secure.setLocationProviderEnabled(getContentResolver(),

LocationManager.NETWORK_PROVIDER , mNetwork.isChecked());

后续的调用都是一样的,只是参数不同。

Google Android 2.2 AGPS 说明:

谷歌在security_settings.xml 文件中注释掉了AGPS 的部分,解释如下:

原创粉丝点击