目标:写一个能够通过jni操控硬件,用于测试安卓硬件驱动是否Ok的安卓app。
一、界面布局layout的关键修改点
二、对控件添加监听方法
在mainactivity的onCreat()方法中调用findViewById(),获得控件(如:Button)的对象,调用其中的setOnClickListener()方法,设置控件被点击时对应的操作。
public class MainActivity extends AppCompatActivity {
private Button button = null;
boolean ledsAllOn = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button =(Button) findViewById(R.id.BUTTON);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click
if (ledsAllOn) {
ledsAllOn = false;
//turn off all leds
button.setText("click to turn on all leds");
} else {
ledsAllOn = true;
//turn on all leds
button.setText("click to turn off all leds");
}
}
});
}
也可以在acticity_main.xml文件中在控件的配置项里添加android:onClick=“method name”,来指定控件被点击时调用的方法,在MainActivity.java里实现这个方法。
三、使用oast.makeText().show()在界面上打印信息
```java
public void checkbox_click(View view) {
CheckBox c = (CheckBox) findViewById(view.getId());
int which_led = view.getId() - R.id.LED1 + 1;
if (c.isChecked())
Toast.makeText(getApplicationContext(), "LED" + which_led + " on!", Toast.LENGTH_SHORT).show();
else
Toast.makeText(getApplicationContext(), "LED" + which_led + " off!", Toast.LENGTH_SHORT).show();
}
``
四、添加硬件控制
1.实现java层的硬件控制接口文件LedControl.java
在静态块里调用System.loadlibrary(“ledcontrol”)加载对于的c库文件libledcontrol.so
并将接口方法申明为static native方法;
2.在Main_activity.java中添加对硬件控制接口的调用
3.实现c库的文件
3.1将LedControl.java中的native方法与c库中的函数建立联系,可以使用隐式建立。
先用javac和javah -jni命令生成对应的.h文件,这个.h文件里就有c接口函数的类型声明,要使用隐式建立java于c这间的连接,就不能改这个函数的名字和参数类型。
3.2在ledcontrol.c中实现这些接口函数
//android系统中用于打印log的接口__android_log_print(ANDROID_LOG_INFO,...),可用logcat捕获
//需要包含android/log.h,依赖于liblog.so
#include <android/log.h>
#include <jni.h>
#define TAG "ledcontrol"
/*
* Class: com_example_mypc_app01_leddemo_LedControl
* Method: led_ctl
* Signature: (IZ)I
*/
JNIEXPORT jint JNICALL Java_com_example_mypc_app01_1leddemo_LedControl_led_1ctl
(JNIEnv *env, jclass cls, jint id, jboolean on) {
__android_log_print(ANDROID_LOG_INFO, TAG, "led_1ctl:%d,%s\n", id, (on?"on":"off"));
}
/*
* Class: com_example_mypc_app01_leddemo_LedControl
* Method: led_open
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_example_mypc_app01_1leddemo_LedControl_led_1open
(JNIEnv *env, jclass cls) {
__android_log_print(ANDROID_LOG_INFO, TAG, "led_1open succeed\n");
return 0;
}
/*
* Class: com_example_mypc_app01_leddemo_LedControl
* Method: led_close
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_mypc_app01_1leddemo_LedControl_led_1close
(JNIEnv *env , jclass cls) {
__android_log_print(ANDROID_LOG_INFO, TAG, "led_1close succeed\n");
}
3.3编译成libledcontrol.so
``Makefile
C_SRC :=
(
s
h
e
l
l
f
i
n
d
.
−
n
a
m
e
∗
.
c
)
O
B
J
:
=
(shell find . -name *.c) OBJ :=
(shellfind.−name∗.c)OBJ:=(patsubst %.c,%.o,$(C_SRC))
MAKE = arm-linux-gcc
TARGET = libledcontrol.so
INC =-I /work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/include/
INC +=-I /usr/lib/jvm/java-1.7.0-openjdk-amd64/include/
LIBS =/work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/lib/libc.so
LIBS +=/work/android-5.0.2/prebuilts/ndk/9/platforms/android-19/arch-arm/usr/lib/liblog.so
all:$(OBJ) $(LIBS)
$(MAKE) -shared -nostdlib -o $(TARGET) $^
%.o:%.c
$(MAKE) $(INC) -fPIC -c -o $@ $<
clean:
rm libledcontrol.so *.o
五、把liledcontrol.so 用adb push到/vendor/lib目录下,然后就可以测试,app调用到对应的c函数