android在framework层增加自己的service---仿照GPS

本文介绍了如何在Android系统中仿照GPS服务,从kernel层到framework层逐步实现自己的service。主要涉及HAL层的动态链接库生成、JNI层的接口函数以及framework层的服务封装和注册。
摘要由CSDN通过智能技术生成

     不少公司在开发android产品的时候,都需要在android中增加自己的service,尤其是定制的工业用途的设备,我们公司的项目中就涉及到要增加一个service,是一个北斗通信service,具体的内容不便透露,涉及到保密。但是增加service的过程大概能描述一下,具体代码就按着不重要的来帖,大家见谅!!

    其实增加自己的service不论是谁来,我想都会仿照现有service来做,在android现有service中,最简单明了的是vibrator service,其次的是location service也就是GPS,这两个service 虽然简单,但是service的架构都是相同,我们仿照的目标就是要这样,明了的架构,往里面填东西就是体力活了。下面我们从下往上一一来看每个步骤。

1.kernel层

   我们的硬件连接到设备上一个串口,因此kernel层我们就不用什么改动。当然如果你们添加的硬件设备需要驱动的话,自己加进去就是了,这里不多说了。

2.HAL层

  我们先找到了GPS的HAL层代码 \android\hardware\imx\libgps中一共两个文件,仔细分析来看,这两个文件主要功能是生成一个动态链接库,向下与硬件通信,向上为系统提供访问的接口函数,知道了这个,我们就明白了HAL层大概的功能,我们的工作就是选一个适合自己硬件的方法实现这个功能。

我们的硬件是一个串口通信的设备,无非就是可以由上层控制来发送命令和接受命令,因此我选的是串口通信很常见的方式: 每条发送命令都单独写一个函数,有上层来控制发送哪条。接收命令就启动一个接收线程,每当收到数据后,进行一系列的判定,把有效的数据传送到上层。

下面我们来看具体代码在android\hardware\imx\librd目录中:

首先是我们与硬件通信的几个函数:

static const RDInterface  goldtelrdInterface = {
	sizeof(RDInterface),
	goldtel_rd_init,
	goldtel_rd_close,
	goldtel_rd_send_XTZJ,
	goldtel_rd_send_ICJC,
	goldtel_rd_send_SJSC,
	goldtel_rd_send_DWSQ,
	goldtel_rd_send_BBDQ,
	goldtel_rd_send_YHZL_SJTX,
	goldtel_rd_send_TXSQ,
};

具体的函数功能就不多说了,反正就是发送命令初始化和关闭。当上层打开这个service的时候会调用goldtel_rd_init()这个函数,因此在这个函数里面我们要实现一系列的初始化功能,包括打开设备电源,打开串口,创建接收进程等等。具体代码:

static int goldtel_rd_init(RDCallbacks* callbacks)
{
	RdState*  s = _rd_state;
	//lijianzhang
	write_sysfs("/sys/devices/platform/bd_power/enable_rdss","1",1); //给设备上电
	usleep(1500000);
	if (!s->init)
		rd_state_init(s, callbacks);//进行一系列的初始化 注意这里的一个参数callbacks,
									//这是一些回调函数,是在jni层实现的,传到底层来运行
									//android很多都是这么来实现,如果以后看别的代码看到
									//类似方式就不要慌乱,去jni层里肯定能找到

	if (s->fd < 0)
		return -1;
    
	rd_state_start(s); //开始工作

	return 0;
}

然后是rd_state_init()

static void
rd_state_init( RdState*  state, RDCallbacks* callbacks )
{
	.................
	一系列初始化
	。。。。。。。。。。。。。。。。。。。
	state->thread = callbacks->create_thread_cb( "rd_state_thread", rd_state_thread, state );//这个函数里最主要的功能就是创建接收线程

	。。。。。。。。。。。。。。。。。。。
	。。。。。。。。。。。。。。。。。。。
}
下面来看接收线程里的东西:
这里面用到了很多的epoll通信机制,其实逻辑很简单一看就明白,下面把代码贴出来,大家给个参考指正

static void
rd_state_thread( void*  arg )
{
	RdState*   state = (RdState*) arg;
	NmeaReader  reader[1];
	int         epoll_fd   = epoll_create(2);
	int         started    = 0;
	int         rd_fd     = state->fd;
	int         control_fd = state->control[1];

	nmea_reader_init( reader );

	// 注册epoll 文件
	epoll_register( epoll_fd, control_fd );
	epoll_register( epoll_fd, rd_fd );

	LOGE("RD thread running");

	// now loop
	for (;;) {
		struct epoll_event   events[2];
		int                  ne, nevents;

		nevents = epoll_wait( epoll_fd, events, 2, -1 ); //等待epoll消息
		if (nevents < 0) {
			if (errno != EINTR)
				E("epoll_wait() unexpected error: %s", strerror(errno));
			continue;
		}
		D("rd thread received %d events", nevents);
		for (ne = 0; ne < nevents; ne++) {	//处理每条消息
			if ((events[ne].events & (EPOLLERR
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值