android gps时间格式,android gps 数据传输流程
Android
GPS数据流程分析
概述:
该文档将介绍android
GPS数据流程分析,在debug的时候可以做为数据流的捕捉的参考。
=============================================================
在介绍数据流之前首先介绍的数据在hal层究竟从哪里来的,也就是原生的没经过解码的数据时从哪儿来的,首先进入到hardware下创建RPC通讯的地方开始,也就是创建一个RPC
client,也就是loc_api_glue_init函数做这件事情:
进入到loc_api_glue_init=>
clnt_create:
CLIENT
*clnt_create(
char
* host,
uint32
prog,
uint32
vers,
char
* proto)
{
…………………………………………………………….
client->xdr
=xdr_init_common(name,
1 /* client XDR */);
…………………………………………………………………
if
(!num_clients++) {
D("launching
RX thread.\n");
pthread_create(&rx_thread,
NULL,rx_context,NULL);
}
else {
/*
client added, wake up rx_thread */
if
(write(wakeup_pipe[1], "a", 1) < 0)
E("error
writing to pipe\n");
}
……………………………………………………………………
}
NOTE:XDR是一个数据描述和数据编码的标准,它对于不同架构计算机之间的数据传输是非常有用的。
RPC是计算机之间的远过程调用协议。
RPC使用XDR描述它的数据格式的。
=============================================================
这个函数有两个功能:
初始化相关的XDR读取RPC数据的方法。
创建一个线程rx_context去接收RPC的数据。
对于前者主要的:
xdr_s_type
*xdr_init_common(const char *router, int is_client)
{
xdr_s_type
*xdr = (xdr_s_type *)calloc(1, sizeof(xdr_s_type));
xdr->xops
= &xdr_std_xops;
……………………………
return
xdr;
}
实际上xdr_std_xops是xdr操作的各种方法
const
xdr_ops_s_type xdr_std_xops = {
xdr_std_destroy,
xdr_std_control,
xdr_std_read,//读数据
xdr_std_msg_done,
xdr_std_msg_start,
xdr_std_msg_abort,
xdr_std_msg_send,
/*数据编码*/
xdr_std_send_int8,
xdr_std_send_uint8,
xdr_std_send_int16,
xdr_std_send_uint16,
xdr_std_send_int32,
xdr_std_send_uint32,
xdr_std_send_bytes,
/*数据解码*/
xdr_std_recv_int8,
xdr_std_recv_uint8,
xdr_std_recv_int16,
xdr_std_recv_uint16,
xdr_std_recv_int32,
xdr_std_recv_uint32,
xdr_std_recv_bytes,
};
对于后者创建一个线程去读取RPC数据:
static
void *rx_context(void *__u __attribute__((unused)))
{
……………………………………………..
ret
= client->xdr->xops->read(client->xdr);
if
(ret == FALSE) {
E("%08x:%08x
xops->read() error %s (%d)\n",
client->xdr->x_prog,
client->xdr->x_vers,
strerror(errno),
errno);
……………………………………………….
}
通过ret
= client->xdr->xops->read(client->xdr);读取rpc数据,这个read函数的
注册实际上就在xdr_init_common里面,那么到这个我已经知道数据从哪儿来的了,后面介绍jni与hal层交互的数据过程:
回到hardware/qcom/gps/loc_api/libloc_api/loc_eng.cpp的loc_eng_init
中的loc_eng_data.client_handle
= loc_open (event, loc_event_cb);
这个函数主要的目的是打开前面创建的rpc
client并把相关的数据提交上报的
过程:
首先看loc_event_cb这个函数,
static
int32 loc_event_cb( )
{
if
(client_handle == loc_eng_data.client_handle)
{
………………………………………………..
memcpy(&loc_eng_data.loc_event_payload,
loc_event_payload, sizeof(*loc_event_payload));
………………………………………………..
pthread_cond_signal
(&loc_eng_data.deferred_action_cond);
pthread_mutex_unlock
(&loc_eng_data.deferred_action_mutex);
}
}
这个函数主要完成的功能是
1、将接收到的数据搬移
2、发送一个信号给处理这个数据的线程
进到处理这个数据的线程:
进入到这个函数中loc_eng_process_deferred_action,这也是一个线程专门用于处理数据,在init的时候被创建:
调用函数loc_eng_process_deferred_action=>
loc_eng_report_position真正的实现数据的上报到jni层,进入到函数loc_eng_report_position看看:
static
void loc_eng_report_position (const rpc_loc_parsed_position_s_type
*location_report_ptr)
{
GpsLocation
location;
……………………………………………………
if
(location_report_ptr->valid_mask &
RPC_LOC_POS_VALID_HOR_UNC_CIRCULAR)
{
location.flags
|= GPS_LOCATION_HAS_ACCURACY;
location.accuracy
= location_report_ptr->hor_unc_circular;
}
if
(loc_eng_data.location_cb != NULL)
{
LOGV
("loc_eng_report_position: fire callback\n");
loc_eng_data.location_cb
(&location);
}
}
}
最关键的是loc_eng_data.location_cb
(&location);调用这个函数的时候相当于真正调的是jni注册到hal的函数,通过这种方式就实现了jni与hal的数据传递了。
再回到loc_open这个函数:
在loc_open中将通过这句话loc_glue_callback_table[i].cb_func
= event_callback;
将loc_event_cb注册给了loc_glue_callback_table[i],那么什么时候真正的调用呢?
在qcom/proprietary/gps/loc_api/libloc-rpc/src/loc_api_rpc_glue.c的
rpc_loc_event_cb_f_type_svc中实现了真正的调用,
后续的调用关系如下:
rpc_loc_event_cb_f_type_svc=>RPC_CALLBACK_FUNC_VERSION(rpc_loc_event_cb_f_type_,
RPC_LOC_EVENT_CB_F_TYPE_VERSION, _svc) =>
rpc_loc_event_cb_f_type_0x00050001_svc
在qcom/proprietary/modem-apis/msm7627_ktouch/api/libs/remote_apis/loc_api/rpcgen/src/loc_api_rpcgen_cb_svc.c
+45
有函数loc_apicbprog_0x00050001将rpc_loc_event_cb_f_type_0x00050001_svc
赋值给了local,后面通过retval
= (bool_t) (*local)((char *)&argument, (void *)&result,
rqstp)实现对rpc_loc_event_cb_f_type_0x00050001_svc真正的调用,
Argument中的内容就是转换之后的数据指针,从哪儿来的呢?
通过svc_getargs这个函数实现的,svc_getargs中的参数_xdr_argument得到了调用,也就是xdr_rpc_loc_event_cb_f_type_args得到了调用,进入这个函数看看:
bool_t
xdr_rpc_loc_event_cb_f_type_args
(XDR *xdrs, rpc_loc_event_cb_f_type_args *objp)
{
if
(!xdr_rpc_uint32(xdrs, &objp->cb_id))
return
FALSE;
if
(!xdr_rpc_loc_client_handle_type (xdrs, &objp->loc_handle))
return
FALSE;
if
(!xdr_rpc_loc_event_mask_type (xdrs, &objp->loc_event))
return
FALSE;
if
(!xdr_pointer (xdrs, (char **)&objp->loc_event_payload, sizeof
(rpc_loc_event_payload_u_type), (xdrproc_t)
xdr_rpc_loc_event_payload_u_type))
return
FALSE;
return
TRUE;
}
也就是xdr_rpc_uint32实现了数据的解码过程
=============================================================
到这里将hal层与jni层的通讯数据的传递分析完了,后面分析jni层的数据时怎么到java层的:
进入jni的函数里面:
进入android_location_GpsLocationProvider_wait_for_event这个函数:
比如位置的信息的上报时通过什么方式的,截取了一段程序如下:
if
(pendingCallbacks & kLocation) {
env->CallVoidMethod(obj,method_reportLocation,sGpsLocationCopy.flags,
(jdouble)sGpsLocationCopy.latitude,
(jdouble)sGpsLocationCopy.longitude,
(jdouble)sGpsLocationCopy.altitude,
(jfloat)sGpsLocationCopy.speed,
(jfloat)sGpsLocationCopy.bearing,
(jfloat)sGpsLocationCopy.accuracy,
(jlong)sGpsLocationCopy.timestamp);
首先当这个线程得到信号sEventCond后就会进入到运行状态,被谁唤醒呢?就是hal掉init的jni的相关回调结束的时候会发送一个信号给该线程,实现线程的同步,
注意到当判断到时位置信息的时候进入到这个分支,调用method_reportLocation这个方法将数据上报,为什么呢?看jni里面这句话
method_reportLocation
= env->GetMethodID(clazz, "reportLocation",
"(IDDDFFFJ)V");
也就是说method_reportLocation映射为java层的reportLocation这种方法,所以
reportLocation这个方法实现在GpsLocationProvider.java中
private
void reportLocation(int flags, double latitude, double longitude,
double altitude,
float
speed, float bearing, float accuracy, long timestamp) {
if
(VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + "
long: " + longitude +
"
timestamp: " + timestamp);
mLastFixTime
= System.currentTimeMillis();
…………………………………………………..
}
到这里数据就已经到java层了。reportLocation这个函数可以认为是java层注册到jni的一个回调,便于两层之间传递数据。
android gps时间格式,android gps 数据传输流程相关推荐
- android gps时间格式,android – GPS:NTP时间注入的工作原理
我最近知道一个gps.conf文件在/ system / etc /目录. 似乎将NTP_SERVER值调整到更接近通常位置的NTP服务器改善了TTFF. 读取LocationProvider类中的源 ...
- android 日期键盘,android 日期时间格式转换;软键盘显示消失;获取系统title
获取activty title bar: TextView actionTitle = (TextView) findViewById(com.android.internal.R.id.action ...
- Android各种时间格式转换
今天就给大家提供一个时间操作的转换类,比较全,大家可以收藏一下,一个满满的DateUtils就这样诞生了. /** * 获取现在时间 * * @return 返回时间类型 yyyy-MM-dd HH: ...
- android 常用时间格式转换代码
/** * 获取现在时间 * * @return 返回时间类型 yyyy-MM-dd HH:mm:ss */ public static Date getNowDate() { ...
- android 日期时间类,Android 时间与日期操作类
获取本地日期与时间 public String getCalendar() { @SuppressLint("SimpleDateFormat") SimpleDateFormat ...
- android格式化时间中文版,Android 仿微信聊天时间格式化显示功能
本文给大家分享android仿微信聊天时间格式化显示功能. 在同一年的显示规则: 如果是当天显示格式为 HH:mm 例:14:45 如果是昨天,显示格式为 昨天 HH:mm 例:昨天 13:12 如果 ...
- android车载支持格式,Android车载版来了:车机实现全部功能
汽车厂商沃尔沃和奥迪宣布,将与谷歌合作,开发基于Android的车载信息娱乐系统,并直接集成至车辆. 这一合作的详情将在本周晚些时候的谷歌I/O开发者大会上公布.目前已知,这一合作将独立于谷歌当前专注 ...
- android列表时间轴,Android实现列表时间轴
本文实例为大家分享了Android列表时间轴展示的具体代码,供大家参考,具体内容如下 实现的效果图如下: 实现的方式是利用recycleview的ItemDecoration这个抽象类,就是我们经常用 ...
- android 自定义时间对话框,android自定义日期和时间选择对话框得实现
1,先写布局文件,把时间选择器和日期选择器都放到一起去 android:layout_width="match_parent" android:layout_height=&quo ...
最新文章
- db2分页查询语句优化_面试官:数据量很大,分页查询很慢,怎么优化?
- 贝叶斯优化神经网络参数_贝叶斯超参数优化:神经网络,TensorFlow,相预测示例
- Spring集成–第1节– Hello World
- 回溯算法解决八皇后_4皇后问题和使用回溯算法的解决方案
- 【Flink】Flink keyed State多年的误解 以及 Keyed state redistribute
- struts2权威指南学习笔记:struts2引入自定义库
- 各种SQL数据库的数据类型
- web文件上传(二)--使用form还是ajax
- 字符串转数组和数组转字符串
- word2vec字向量_Anything2Vec:将Reddit映射到向量空间
- 钉钉签到自动签到python_原来实现钉钉自动签到如此简单,每天准时上下班不是梦...
- 5款 Linux 常用远程连接工具,总有一款适合你
- [乐意黎]某音上超酷炫的 Word Clock 文字云时钟屏保配置
- Verilog实现数字时钟
- 网络词典[U~Z](转)
- 计算机伦理学案例分析,医药伦理学案例分析
- 【数据分析项目实战】篇1:游戏数据分析——新增、付费和用户行为评估
- 移动端Touch (触摸)事件
- 浪潮服务器加速计算系统,超强AI计算系统囊括浪潮人工智能服务器
- 链队的创建、入队、出队