
正文
<Android> Location Service 分析
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
由于各种原因,老师希望我学习Android系统源码以应对可能参与的项目。我只好深入曹营,刺探军情了。
定位服务是手机上最常用的功能之一,据说也是相对比较简单的服务,所以从这里入手。其他系统服务的架构都是类似的。明白其中一个之后,再去理解其他的会容易得多。下面以 Android 源码为基础,大致分析了 Android 系统中定位服务的架构和实现。版本是6.0.1。
一. 应用层:
1.在App中调用位置服务
在Android App中使用定位服务,要先向系统请求一个
LocationManager
实例,
LocationManager mLocationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
然后用Criteria对其进行设置,获取一个provider,provider有3种基本定位类型 network/gps/passive
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
...
String provider = mLocationManager.getBestProvider(criteria, true);
(1)LocationManager利用provider直接获取一个最新的位置信息
Location location = mLocationManager.getLastKnownLocation(provider);
(2)使用事件绑定的方式,获取更新的位置信息
LocationListener{
...
public void onLocationChanged(Location location)
}
二.框架层
2.LocationManager类的实现(
/frameworks/base/location/java/android/location/LocationManager.java)
其代码的主要作用是访问系统位置服务
LocationManagerService
关键成员
private final ILocationManager mService;
构造器
public LocationManager(Context context, ILocationManager service);
ILocationManager与系统服务通信的接口
mService=Service;
如getProviders方法,实际是通过mService成员请求系统服务响应这个方法
public List<String> getProviders(boolean enabledOnly) {
...
return mService.getProviders(null, enabledOnly);
}
3.接口定义
(/frameworks/base/location/java/android/location/ILocationManager.aidl)
通过aidl定义通信接口,与系统位置服务进行进程间通信icp(涉及binder)
4.LocationManagerService的实现
(/frameworks/base/services/core/java/com/android/server/LocationManagerService.java)
系统位置服务的实现,包括实现LocationManager调用的接口
如
public List<String> getProviders(Criteria criteria, boolean enabledOnly)
public Location getLastLocation(LocationRequest request, String packageName)
...
在LocationManagerService中主要是有两种定位方式,一种通过网络,一种通过GPS模块。通过GPS模块定位的是GpsLocationProvider。
5.GpsLocationProvider( frameworks/base/services/core/java/com/android/server/location/GpsLocationProvider.java)
核心的涉及定位的方法是native的,通过JNI与HAL层C++语言函数交互
如这个注入一条位置信息的函数,接下来主要以他为线索。
private native void
native_inject_location
(double latitude, double longitude, float accuracy);
三、硬件抽象层(HAL)
6.GpsLocationProvider 本地方法在HAL层的实现(
/frameworks/base/services/core/jni/com_android_server_location_GpsLocationProvider.cpp)
#include "hardware/hardware.h"
#include "hardware/gps.h" //这里的hardware目录为/hardware/libhardware/include/hardware/
...
上面第5点中native_inject_location方法对应的实现
static void android_location_GpsLocationProvider_
inject_location
(JNIEnv* /* env */,
jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy)
{
if (sGpsInterface)
sGpsInterface->inject_location(latitude, longitude, accuracy);
}
可以看出这里是通过sGpsInterface调用下一层函数去实现,他是一个GpsInterface结构体指针,
static const GpsInterface* sGpsInterface = NULL;
GpsInterface结构体定义在 gps.h 中
结构体包含函数指针,则sGpsInterface引用的实例包含函数的具体实现
err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
if (err == 0) {
hw_device_t* device;
err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
if (err == 0) {
gps_device_t* gps_device = (gps_device_t *)device;
//在这里获得了device提供的具体的
sGpsInterface
sGpsInterface = gps_device->get_gps_interface(gps_device);
}
}
7.上面提到的gps.h( /hardware/libhardware/include/hardware/gps.h)
GpsInterface的定义
typedef struct {
...
/** 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);
...
} GpsInterface;
四、高通的一个实现
硬件厂商主要的工作室引用gps.h, 实现一个gps.c,把GpsInterface等内容实现了。这里分析一下高通的一个实现。
8.gps.c
(/hardware/qcom/gps/loc_api/libloc_api_50001/gps.c)
#include <hardware/gps.h>
...
extern const GpsInterface* get_gps_interface(); //外部函数
const GpsInterface* gps__get_gps_interface(struct gps_device_t* dev)
{
return get_gps_interface();
//在高通的实现中,第6点中的gps_device->get_gps_interface()调用的函数来自于此,此处
//返回的函数指针是一个外部函数,该外部函数实际在9.2中实现
}
...
//dev结构体
struct gps_device_t *dev = (struct gps_device_t *) malloc(sizeof(struct gps_device_t));
...
//给dev结构体get_gps_interface的函数指针指向前面高通实现的函数。
dev->get_gps_interface = gps__get_gps_interface;
9.loc.cpp
(/hardware/qcom/gps/loc_api/libloc_api_50001/loc.cpp)
9.1
//这里定义的静态函数,供同一个文件里的sLocEngInterface使用
static int loc_init(GpsCallbacks* callbacks);
static int loc_start();
static int loc_inject_time(GpsUtcTime time, int64_t timeReference, int uncertainty);
static int loc_
inject_location
(double latitude, double longitude, float accuracy);
...
//在gps.h中的GpsInterface,在这里被实现成了sLocEngInterface
static const GpsInterface sLocEngInterface =
{
sizeof(GpsInterface),
loc_init,
loc_start,
loc_inject_time,
loc_
inject_location
,
...
};
9.2
// for gps.c
extern "C" const GpsInterface* get_gps_interface(){
...
}
9.3
这个文件里的静态函数的具体实现
static int loc_
inject_location
(double latitude, double longitude, float accuracy)
{
ENTRY_LOG();
int ret_val = 0;
ret_val = loc_eng_
inject_location
(loc_afw_data, latitude, longitude, accuracy);
//这里又是依靠调用其它函数,还要继续深挖到 loc_eng,在第10点
EXIT_LOG(%d, ret_val);
return ret_val;
}
10.loc_eng.cpp
(/hardware/qcom/gps/loc_api/libloc_api_50001/loc_eng.cpp)
int loc_eng_
inject_location
(loc_eng_data_s_type &loc_eng_data, double latitude,
double longitude, float accuracy)
{
ENTRY_LOG_CALLFLOW();
INIT_CHECK(loc_eng_data.adapter, return -1);
LocEngAdapter* adapter = loc_eng_data.adapter;
if(adapter->mSupportsPositionInjection)
{
adapter->sendMsg(new LocEngInjectLocation(adapter, latitude, longitude,
accuracy));
//这里发出了消息
}
EXIT_LOG(%d, 0);
return 0;
}
再往下就得是Linux kernel里面GPS模块的写的驱动程序了,应该通过UART,传送基本的数据和控制命令,我就没去看了。。。
第一次看Android源码,简单分析,水平有限,如有错漏,还请包涵。
<Android> Location Service 分析的更多相关文章
-
Android系统Gps分析(一)【转】
本文转载自:http://blog.csdn.net/xnwyd/article/details/7198728 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 1 G ...
-
【Android 】Service 全面总结
1.Service的种类 按运行地点分类: 类别 区别 优点 缺点 应用 本地服务(Local) 该服务依附在主进程上, 服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外L ...
-
Android源码分析-全面理解Context
前言 Context在android中的作用不言而喻,当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context,而这个Context到底是什么呢,这个问题好像很好回答又好像 ...
-
cocos2d-x for android:SimpleGame分析
cocos2d-x for android:SimpleGame分析 作为cocos2d-x的标配DEMO,SimpleGame可算是给入门学cocos2d-x的俺们这些新手门学习的对象了,那么来分析 ...
-
Android平台APK分析工具包androguard的部署使用和原理分析
原创文章,转载请注明出处,谢谢. Android应用程序分析主要有静态分析和动态分析两种,常见的静态分析工具是Apktool.dex2jar以及jdgui.今天突然主要到Google code上有个叫 ...
-
android usb挂载分析---MountService启动
android usb挂载分析---MountService启动 分类: android框架 u盘挂载2012-03-27 23:00 11799人阅读 评论(4) 收藏 举报 androidsock ...
-
Android Foreground Service (前台服务)
一.如何保活后台服务 在Android Services (后台服务) 里面,我们了解了Android四大组件之一的Service,知道如何使用后台服务进行来完成一些特定的任务.但是后台服务在系统内存 ...
-
Android开发--Service和Activity通过广播传递消息
Android的Service也运行在主线程,但是在服务里面是没法直接调用更改UI,如果需要服务传递消息给Activity,通过广播是其中的一种方法: 一.在服务里面发送广播 通过intent传送数据 ...
-
Android HandlerThread 源代码分析
HandlerThread 简单介绍: 我们知道Thread线程是一次性消费品,当Thread线程运行完一个耗时的任务之后.线程就会被自己主动销毁了.假设此时我又有一 个耗时任务须要运行,我们不得不又 ...
随机推荐
-
【PHP+MySQL学习笔记】php操作MySQL数据库中语句
1.连接 MYSQL 服务器的函数 mysql_connect();<?php $con = mysql_connect("localhost","root&quo ...
-
PAT-1134 Vertex Cover (图的建立 + set容器)
A vertex cover of a graph is a set of vertices such that each edge of the graph is incident to at le ...
-
LightOJ1030 Discovering Gold
题目链接:https://vjudge.net/problem/LightOJ-1030 知识点: 概率与期望 解题思路: 设某一个点 \(i\) 能到达的点的个数为 \(x\),其上有金 \(g\) ...
-
Ajax长轮询(LongPoll)
1)HTML HTTP是无状态.单向的协议,用户只能够通过客服端向服务器发送请求并由服务器处理发回一个响应.若要实现聊天室.WEBQQ.在线客服.邮箱等这些即时通讯的应用,就要用到“ 服务器推送技术( ...
-
WordPress批量更换域名
UPDATE wp_options SET option_value = replace( option_value, 'http://www.old.com', 'http://www.new.co ...
-
StreamSets使用指南
StreamSets使用指南 最近在调研Streamsets,照猫画虎做了几个最简单的Demo鉴于网络上相关资料非常少,做个记录. 1.简介 Streamsets是一款大数据实时采集和ETL工具,可以 ...
-
[工具-005] C#如何绑定HotKey
由于某种需要,需要做一个控制鼠标在屏幕乱点的程序,运用C#的 [DllImport("user32.dll")] private static extern int mo ...
-
dubbo报com.alibaba.dubbo.remoting.TimeoutException: Waiting server-side response timeout. start time: 2020-03-28 23:08:50.342, end time: 2020-03-28 23:08:51.344,
当进行debug 启动项目报 dubbo remotiong timeout ,默认1一秒,要在spring配置文件中,dubbo配置中dubbo:service配置timeout属性,如下图配置10 ...
-
vue-cli4 + TS构建新项目
1. 如果你之前没有安装vue-cli,可以通过如下命令进行安装: npm install -g @vue/cli yarn global add @vue/cli 2. 创建vue项目 vue cr ...
-
Rocket - devices - CLINT
https://mp.weixin.qq.com/s/4LfZZDKCTQhiKIUjvbDKEg 简单介绍CLINT的实现. 1. 概述 CLINT即是Core Local Interrupter的 ...
本文转载自:http://blog.csdn.net/xnwyd/article/details/7198728 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 1 G ...
1.Service的种类 按运行地点分类: 类别 区别 优点 缺点 应用 本地服务(Local) 该服务依附在主进程上, 服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外L ...
前言 Context在android中的作用不言而喻,当我们访问当前应用的资源,启动一个新的activity的时候都需要提供Context,而这个Context到底是什么呢,这个问题好像很好回答又好像 ...
cocos2d-x for android:SimpleGame分析 作为cocos2d-x的标配DEMO,SimpleGame可算是给入门学cocos2d-x的俺们这些新手门学习的对象了,那么来分析 ...
原创文章,转载请注明出处,谢谢. Android应用程序分析主要有静态分析和动态分析两种,常见的静态分析工具是Apktool.dex2jar以及jdgui.今天突然主要到Google code上有个叫 ...
android usb挂载分析---MountService启动 分类: android框架 u盘挂载2012-03-27 23:00 11799人阅读 评论(4) 收藏 举报 androidsock ...
一.如何保活后台服务 在Android Services (后台服务) 里面,我们了解了Android四大组件之一的Service,知道如何使用后台服务进行来完成一些特定的任务.但是后台服务在系统内存 ...
Android的Service也运行在主线程,但是在服务里面是没法直接调用更改UI,如果需要服务传递消息给Activity,通过广播是其中的一种方法: 一.在服务里面发送广播 通过intent传送数据 ...
HandlerThread 简单介绍: 我们知道Thread线程是一次性消费品,当Thread线程运行完一个耗时的任务之后.线程就会被自己主动销毁了.假设此时我又有一 个耗时任务须要运行,我们不得不又 ...
-
【PHP+MySQL学习笔记】php操作MySQL数据库中语句
1.连接 MYSQL 服务器的函数 mysql_connect();<?php $con = mysql_connect("localhost","root&quo ...
-
PAT-1134 Vertex Cover (图的建立 + set容器)
A vertex cover of a graph is a set of vertices such that each edge of the graph is incident to at le ...
-
LightOJ1030 Discovering Gold
题目链接:https://vjudge.net/problem/LightOJ-1030 知识点: 概率与期望 解题思路: 设某一个点 \(i\) 能到达的点的个数为 \(x\),其上有金 \(g\) ...
-
Ajax长轮询(LongPoll)
1)HTML HTTP是无状态.单向的协议,用户只能够通过客服端向服务器发送请求并由服务器处理发回一个响应.若要实现聊天室.WEBQQ.在线客服.邮箱等这些即时通讯的应用,就要用到“ 服务器推送技术( ...
-
WordPress批量更换域名
UPDATE wp_options SET option_value = replace( option_value, 'http://www.old.com', 'http://www.new.co ...
-
StreamSets使用指南
StreamSets使用指南 最近在调研Streamsets,照猫画虎做了几个最简单的Demo鉴于网络上相关资料非常少,做个记录. 1.简介 Streamsets是一款大数据实时采集和ETL工具,可以 ...
-
[工具-005] C#如何绑定HotKey
由于某种需要,需要做一个控制鼠标在屏幕乱点的程序,运用C#的 [DllImport("user32.dll")] private static extern int mo ...
-
dubbo报com.alibaba.dubbo.remoting.TimeoutException: Waiting server-side response timeout. start time: 2020-03-28 23:08:50.342, end time: 2020-03-28 23:08:51.344,
当进行debug 启动项目报 dubbo remotiong timeout ,默认1一秒,要在spring配置文件中,dubbo配置中dubbo:service配置timeout属性,如下图配置10 ...
-
vue-cli4 + TS构建新项目
1. 如果你之前没有安装vue-cli,可以通过如下命令进行安装: npm install -g @vue/cli yarn global add @vue/cli 2. 创建vue项目 vue cr ...
-
Rocket - devices - CLINT
https://mp.weixin.qq.com/s/4LfZZDKCTQhiKIUjvbDKEg 简单介绍CLINT的实现. 1. 概述 CLINT即是Core Local Interrupter的 ...







