[实验3_app]_[2.5_开发Android应用程序来使用硬件访问服务]
回顾
我们首先看一下Android体系结构图:
在第2章,我们从 Linux Device Drivers,到 HAL,External Libraries & Android Runtime,Application Framework 再到 Applications,自底向上实现来一个应用程序控制Freg硬件驱动。
画图:https://www.processon.com/diagraming/674eb1c592740c307cc423ea

2.5,开发Android应用程序来使用硬件访问服务
目标:开发Android应用程序,通过硬件访问服务FregService来访问虚拟硬件设备freg的寄存器val的值。
Freg应用程序的目录结构:
aosp/packages/experimental/Freg
----AndroidManifest.xml
----Android.mk
----src
----shy/luo/freg
----Freg.java
----res
----layout
----main.xml
----values
----strings.xml
----drawable
----icon.png
Freg应用程序包含一个源代码目录src,一个资源目录res,一个配置文件AndroidManifest.xml和一个编译脚本文件Android.mk。
Freg.java
文件路径:packages/experimental/Freg/src/shy/luo/freg/Freg.java
文件定义了一个Activity组件Freg,它是应用程序Freg的主界面。在Activity组件Freg的界面上,有一个编辑框和三个按钮Read、Write和Clear,其中,编辑框用来显示或者输入虚拟硬件设备freg的寄存器val的值;按钮Read和Write分别用来读写虚拟硬件设备freg的寄存器val,而按钮Clear用来清空编辑框。
package shy.luo.freg;
import android.app.Activity;
import android.os.ServiceManager;
import android.os.Bundle;
import android.os.IFregService;
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 Freg extends Activity implements OnClickListener {
private final static String LOG_TAG = "shy.luo.freg.FregActivity";
private IFregService fregService = 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);
// 通过 Service Manager 获得一个名称为"freg"的服务的Binder代理对象接口。
// 这个服务对应于运行在系统进程System中的硬件访问服务FregService。
fregService = IFregService.Stub.asInterface(
ServiceManager.getService("freg"));
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, "Freg Activity Created");
}
@Override
public void onClick(View v) {
if (v.equals(readButton)) {
try {
int val = fregService.getVal();
String text = String.valueOf(val);
valueText.setText(text);
Log.i(LOG_TAG, "Freg App read val :" + text);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Remote Exception while reading value from freg service.");
}
} else if (v.equals(writeButton)) {
try {
String text = valueText.getText().toString();
int val = Integer.parseInt(text);
fregService.setVal(val);
Log.i(LOG_TAG, "Freg App write val :" + val);
} catch (RemoteException e) {
Log.e(LOG_TAG, "Remote Exception while writing value to freg service.");
}
} else if (v.equals(clearButton)) {
String text = "";
valueText.setText(text);
}
}
}
main.xml
文件路径:packages/experimental/Freg/res/layout/main.xml
这是应用程序Freg的主界面配置文件,在屏幕中显示一个 TextView 空间和三个 Button 控件。
<?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>
strings.xml
文件路径:packages/experimental/Freg/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Freg</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>
icon.png
文件路径: packages/experimental/Freg/res/drawable/icon.png
这是应用程序Freg的图标文件,可以根据需要来放置不同的图片文件。
AndroidManifest.xml
文件路径:packages/experimental/Freg/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="shy.luo.freg"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Freg"
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>
Android.mk
文件路径:packages/experimental/Freg/Android.mk
这是应用程序Freg的编译脚本文件,指定程序的名称为"Freg"。
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_PACKAGE_NAME := Freg
include $(BUILD_PACKAGE)
编译
dt@ubuntu:~/2.3.1_r1$ export PATH=$PATH:/home/dt/2.3.1_r1/out/host/linux-x86/bin
dt@ubuntu:~/2.3.1_r1$ source build/envsetup.sh
including device/htc/passion/vendorsetup.sh
including device/samsung/crespo/vendorsetup.sh
dt@ubuntu:~/2.3.1_r1$ mmm ./packages/experimental/Freg/
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.3.1
TARGET_PRODUCT=generic
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=GRH78
============================================
make: Entering directory `/home/dt/2.3.1_r1`
target R.java/Manifest.java: Freg (out/target/common/obj/APPS/Freg_intermediates/src/R.stamp)
Warning: AndroidManifest.xml already defines versionCode (in http://schemas.android.com/apk/res/android); using existing value in manifest.
Warning: AndroidManifest.xml already defines versionName (in http://schemas.android.com/apk/res/android); using existing value in manifest.
target Java: Freg (out/target/common/obj/APPS/Freg_intermediates/classes)
Copying: out/target/common/obj/APPS/Freg_intermediates/classes-jarjar.jar
Copying: out/target/common/obj/APPS/Freg_intermediates/emma_out/lib/classes-jarjar.jar
Copying: out/target/common/obj/APPS/Freg_intermediates/classes.jar
Copying: out/target/common/obj/APPS/Freg_intermediates/noproguard.classes.jar
target Dex: Freg
Copying: out/target/common/obj/APPS/Freg_intermediates/noproguard.classes.dex
target Package: Freg (out/target/product/generic/obj/APPS/Freg_intermediates/package.apk)
Warning: AndroidManifest.xml already defines versionCode (in http://schemas.android.com/apk/res/android); using existing value in manifest.
Warning: AndroidManifest.xml already defines versionName (in http://schemas.android.com/apk/res/android); using existing value in manifest.
'out/target/common/obj/APPS/Freg_intermediates//classes.dex' as 'classes.dex'...
Install: out/target/product/generic/system/app/Freg.apk
make: Leaving directory `/home/dt/2.3.1_r1`
dt@ubuntu:~/2.3.1_r1$ make snod
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=2.3.1
TARGET_PRODUCT=generic
TARGET_BUILD_VARIANT=eng
TARGET_SIMULATOR=
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
HOST_ARCH=x86
HOST_OS=linux
HOST_BUILD_TYPE=release
BUILD_ID=GRH78
============================================
find: `frameworks/base/frameworks/base/docs/html': No such file or directory
find: `out/target/common/docs/gen': No such file or directory
find: `frameworks/base/frameworks/base/docs/html': No such file or directory
find: `out/target/common/docs/gen': No such file or directory
find: `frameworks/base/frameworks/base/docs/html': No such file or directory
find: `out/target/common/docs/gen': No such file or directory
find: `frameworks/base/frameworks/base/docs/html': No such file or directory
find: `out/target/common/docs/gen': No such file or directory
find: `frameworks/base/frameworks/base/docs/html': No such file or directory
find: `out/target/common/docs/gen': No such file or directory
Install: out/host/linux-x86/bin/mkyaffs2image
make snod: ignoring dependencies
Target system fs image: out/target/product/generic/system.img
打包后,得到的 Android 系统镜像文件 system.img 就包含有应用程序 Freg 了,下面我们启动模拟器看看:
运行
dt@ubuntu:~/goldfish$ cp out/target/product/generic/system.img /mnt/hgfs/AndroidEmulator/images/system.img
dt@ubuntu:~/goldfish$ cp out/target/product/generic/ramdisk.img /mnt/hgfs/AndroidEmulator/images/ramdisk.img
[win]> pushd d:\AndroidEmulator
[win]> start /b emulator.exe -sysdir d:\AndroidEmulator -system images\system.img -data images\userdata.img -ramdisk images\ramdisk.img -kernel images\zImage -skindir d:\AndroidEmulator\skins -skin HVGA
[win]> adb logcat | grep freg
I/FregServiceJNI( 66): Initializing HAL stub freg......
I/FregServiceJNI( 66): Device freg found.
I/FregHALStub( 66): Open device file /dev/freg successfully.
I/FregServiceJNI( 66): Device freg is open.
I/ActivityManager( 66): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=shy.luo.freg/.Freg } from pid 131
I/ActivityManager( 66): Start proc shy.luo.freg for activity shy.luo.freg/.Freg: pid=351 uid=10029 gids={}
I/shy.luo.freg.FregActivity( 351): Freg Activity Created
I/ActivityManager( 66): Displayed shy.luo.freg/.Freg: +1s853ms
I/FregHALStub( 66): Get value 0 from device file /dev/freg.
I/FregServiceJNI( 66): Get value 0 from device freg.
I/shy.luo.freg.FregActivity( 351): Freg App read val :0
I/FregServiceJNI( 66): Set value 68 to device freg.
I/FregHALStub( 66): Set value 68 to device file /dev/freg.
I/shy.luo.freg.FregActivity( 351): Freg App write val :68
I/FregHALStub( 66): Get value 68 from device file /dev/freg.
I/FregServiceJNI( 66): Get value 68 from device freg.
I/shy.luo.freg.FregActivity( 351): Freg App read val :68
I/FregServiceJNI( 66): Set value 6 to device freg.
I/FregHALStub( 66): Set value 6 to device file /dev/freg.
I/shy.luo.freg.FregActivity( 351): Freg App write val :6
I/FregHALStub( 66): Get value 6 from device file /dev/freg.
I/FregServiceJNI( 66): Get value 6 from device freg.
I/shy.luo.freg.FregActivity( 351): Freg App read val :6
Android模拟器运行起来之后,我们就可以在应用程序启动器中启动应用程序 Freg 了,打开 Freg 输入68,点击【Write】按钮写入值,然后点击【Read】按钮,读取值。
