Ubuntu中为Android系统实现内置Java应用程序测试Application Frameworks层的硬件服务
我们在android系统增加硬件服务的目的是为了让应用层的app能够通过java接口来访问硬件服务。那么, app如何通过java接口来访问application frameworks层提供的硬件服务呢?在这一篇文章中,我们将在android系统的应用层增加一个内置的应用程序,这个内置的应用程序通过servicemanager接口获取指定的服务,然后通过这个服务来获得硬件服务。
一. 参照在ubuntu android实现application frameworks层增加硬件访问服务一文,在application frameworks层定义好自己的硬件服务helloservice,并提供ihelloservice接口提供访问服务。
二. 为了方便开发,我们可以在ide环境下使用android sdk来开发android应用程序。
开发完成后,再把程序源代码移植到android源代码工程目录中。使用eclipse的android插件adt创建android工程很方便,这里不述,可以参考网上其它资料。工程名称为hello,下面主例出主要文件:
主程序是src/shy/luo/hello/hello.java:
package shy.luo.hello; import shy.luo.hello.r; import android.app.activity; import android.os.servicemanager; import android.os.bundle; import android.os.ihelloservice; import android.os.remoteexception; import android.util.log; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.edittext; public class hello extends activity implements onclicklistener { private final static string log_tag = "shy.luo.renju.hello"; private ihelloservice helloservice = null; private edittext valuetext = null; private button readbutton = null; private button writebutton = null; private button clearbutton = null; /** called when the activity is first created. */ @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); helloservice = ihelloservice.stub.asinterface( servicemanager.getservice("hello")); valuetext = (edittext)findviewbyid(r.id.edit_value); readbutton = (button)findviewbyid(r.id.button_read); writebutton = (button)findviewbyid(r.id.button_write); clearbutton = (button)findviewbyid(r.id.button_clear); readbutton.setonclicklistener(this); writebutton.setonclicklistener(this); clearbutton.setonclicklistener(this); log.i(log_tag, "hello activity created"); } @override public void onclick(view v) { if(v.equals(readbutton)) { try { int val = helloservice.getval(); string text = string.valueof(val); valuetext.settext(text); } catch (remoteexception e) { log.e(log_tag, "remote exception while reading value from device."); } } else if(v.equals(writebutton)) { try { string text = valuetext.gettext().tostring(); int val = integer.parseint(text); helloservice.setval(val); } catch (remoteexception e) { log.e(log_tag, "remote exception while writing value to device."); } } else if(v.equals(clearbutton)) { string text = ""; valuetext.settext(text); } } }
程序通过servicemanager.getservice("hello")来获得helloservice,接着通过ihelloservice.stub.asinterface函数转换为ihelloservice接口。其中,服务名字“hello”是系统启动时加载helloservice时指定的,而ihelloservice接口定义在android.os.ihelloservice中,具体可以参考在ubuntu上为android系统的application frameworks层增加硬件访问服务一文。这个程序提供了简单的读定自定义硬件有寄存器val的值的功能,通过ihelloservice.getval和ihelloservice.setval两个接口实现。
界面布局文件res/layout/main.xml:
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <linearlayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center"> <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/value"> </textview> <edittext android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/edit_value" android:hint="@string/hint"> </edittext> </linearlayout> <linearlayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:gravity="center"> <button android:id="@+id/button_read" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/read"> </button> <button android:id="@+id/button_write" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/write"> </button> <button android:id="@+id/button_clear" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/clear"> </button> </linearlayout> </linearlayout>
字符串文件res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">hello</string> <string name="value">value</string> <string name="hint">please input a value...</string> <string name="read">read</string> <string name="write">write</string> <string name="clear">clear</string> </resources>
程序描述文件androidmanifest.xml:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="shy.luo.hello" android:versioncode="1" android:versionname="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".hello" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> </application> </manifest>
三. 将hello目录拷贝至packages/experimental目录,新增android.mk文件:
user-name@machine-name:~/android/packages/experimental$ vi android.mk
android.mk的文件内容如下:
local_path:= $(call my-dir)
include $(clear_vars)
local_module_tags := optional
local_src_files := $(call all-subdir-java-files)
local_package_name := hello
include $(build_package)
四. 编译:
user-name@machine-name:~/android$ mmm packages/experimental/hello
编译成功后,便可以在out/target/product/generic/system/app目录下看到hello.apk文件了。
五. 重新打包系统镜像文件system.img:
user-name@machine-name:~/android$ make snod
重新打包后的system.img文件就内置了hello.apk文件了。
六. 运行android模拟器:
user-name@machine-name:~/android$ emulator -kernel kernel/common/arch/arm/boot/zimage &
在home screen中可以看到hello应用程序:
打开hello应用程序:
点击read按钮,可以从helloservice中读取硬件寄存器val的值;点击clear按钮,可以清空文本框的值;在文本框中输入一个数值,再点击write按钮,便可以将这个值写入到硬件寄存器val中去,可以再次点击read按钮来验证是否正确写入了值。
至此,我们就完整地学习了在android的linux内核空间添加硬件驱动程序、在android的硬件抽象层添加硬件接口、在android的application frameworks层提供硬件服务以及在android的应用层调用硬件服务的整个过程了,希望能为读者进入android系统提供入门帮助。重新学习整个过程。
系列文章:
ubuntu android系统上编写linux内核驱动程序实现方法
ubuntu android hal编写jni方法提供java访问硬件服务接口
ubuntu android实现application frameworks层增加硬件访问服务
以上就是ubuntu android 实现简单的应用,从内核到驱动,hal,frameworks层,在到app的实现, 希望能帮到深入研究android源码的朋友。