android 从驱动到应用(二)
JAVA应用程序通过调用JNI来访问驱动程序
下面是一个Led测试程序例子,驱动程序参考(一)
具体步骤:
- 用eclipse创建一个android工程(TestLed),以下是默认生成的JAVA代码:
package com.android;import android.app.Activity;import android.os.Bundle;public class TestLedActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); }}
- 在程序中添加本地方法
// 添加本地实现方法public native int OpenLed();public native int ControlLed(int led_id, int cmd);// 添加 C/C++动态库导入方法static {System.loadLibrary("yyp_led_lib");}
- 在工程目录中建立一个jni文件夹
$ cd workspace/TestLed/
$ mkdir jni
- 用javah命令生成头文件
在工程主目录中输入命令:$ javah -classpath bin/classes/ -d jni com.android.TestLedActivity
说明:
-classpath bin/classes/:表示类的路径在 bin/classes 目录;
-d jni 表示.h 头文件的生成路径;
com.android.TestLedActivity:由 package.class 组成。命令执行成功后发现在jni文件夹生成头文件com_android_TestLedActivity.h
$ ls jni
com_android_TestLedActivity.h
- 创建C/C++文件 实现头文件接口
刷新eclipse工程,右键点击jni目录,创建yyp_led_lib.c文件并编辑(jni->New->File):
#include <string.h>#include <jni.h>#include <fcntl.h>//文件操作#include "android/log.h"static const char *TAG = "yyp_jni";#define LOG_INFO(fmt,args...)__android_log_print(ANDROID_LOG_INFO, TAG,fmt, ##args)#define LOG_DEBUG(fmt, args...)__android_log_print(ANDROID_LOG_DEBUG, TAG,fmt, ##args)#define LOG_ERROR(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt,##args)#define DEVICE_NAME"/dev/yyp_led"int fd;JNIEXPORT jint JNICALL Java_com_android_ledtest_LedTestActivity_OpenLed (JNIEnv *env, jobject this){fd = open(DEVICE_NAME,O_RDWR|O_SYNC);LOG_INFO("fd = %d\r\n",fd);if(-1 == fd){LOG_INFO("open led_devices is failed!\r\n");return -1;}return 0;}JNIEXPORT jint JNICALL Java_com_android_ledtest_LedTestActivity_ControlLed (JNIEnv *ent, jobject this, jint led_id, jint cmd){if (-1 == fd) {LOG_ERROR("Led Module is not open!\r\n");return -1;}if(cmd!=0 && cmd!=1){LOG_ERROR("This conmand is not surport!\r\n");return -2;}switch (led_id) {case 1:ioctl(fd, cmd, 0);break;case 2:ioctl(fd, cmd, 1);break;case 3:ioctl(fd, cmd, 2);break;case 4:ioctl(fd, cmd, 3);break;case 0:ioctl(fd, cmd, 0);ioctl(fd, cmd, 1);ioctl(fd, cmd, 2);ioctl(fd, cmd, 3);break;default:LOG_ERROR("This led is not exit!\r\n");break;}return 0;}
- 创建jni中C/C++文件中对应的makefile文件
在jin文件夹创建Android.mk文件($ vim jni/Android.mk)并编辑:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -llog
LOCAL_MODULE := yyp_led_lib
LOCAL_SRC_FILES := yyp_led_lib.c
include $(BUILD_SHARED_LIBRARY)
- 用ndk-build生成 .so文件
在工程目录中输入ndk-build命令:
$ ndk-build
Compile thumb : yyp_led_lib <= yyp_led_lib.c
SharedLibrary : libyyp_led_lib.so
Install : libyyp_led_lib.so => libs/armeabi/libyyp_led_lib.so
刷新eclipse工程,发现在libs目录中多了.so文件(libs/armeabi/libyyp_led_lib.so)
- 在eclipse工程中添加led控制按钮,达到在JAVA应用程序中控制led的效果
编辑TestLedActivity.java文件:
package com.android;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;public class TestLedActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 打开Led驱动 OpenLed();Button key_led1_on = (Button) findViewById(R.id.led1_on);key_led1_on.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubControlLed(1, 1);}});Button key_led2_on = (Button) findViewById(R.id.led2_on);key_led2_on.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubControlLed(2, 1);}});Button key_led3_on = (Button) findViewById(R.id.led3_on);key_led3_on.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubControlLed(3, 1);}});Button key_led4_on = (Button) findViewById(R.id.led4_on);key_led4_on.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubControlLed(4, 1);}});Button key_led0_on = (Button) findViewById(R.id.led0_on);key_led0_on.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubControlLed(0, 1);}});Button key_led0_off = (Button) findViewById(R.id.led0_off);key_led0_off.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubControlLed(0, 0);}}); }// 添加本地实现方法public native int OpenLed();public native int ControlLed(int led_id, int cmd);// 添加 C/C++动态库导入方法static {System.loadLibrary("yyp_led_lib");}}
分别在main.xml和strings.xml添加相应的控件和字符串:
main.xml:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/led1_on"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/LEDON1"></Button> <Button android:id="@+id/led2_on"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/LEDON2"></Button><Button android:id="@+id/led3_on"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/LEDON3"></Button> <Button android:id="@+id/led4_on"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/LEDON4"></Button><Button android:id="@+id/led0_on"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/LEDON0"></Button><Button android:id="@+id/led0_off"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/LEDOFF0"></Button></LinearLayout>
strings.xml:
<?xml version="1.0" encoding="utf-8"?><resources> <string name="hello">This is a led TestApp!</string> <string name="app_name">ledtest</string> <string name="LEDON1">开启1号灯</string> <string name="LEDON2">开启2号灯</string> <string name="LEDON3">开启3号灯</string> <string name="LEDON4">开启4号灯</string> <string name="LEDON0">开启所有灯</string> <string name="LEDOFF0">关闭所有灯</string></resources>
编译成apk,运行测试,ok!
更多相关文章
- Android媒体文件metadata是如何实现跟解码器结合获取的
- Android 读取U盘或SD卡中的所有.txt文件
- gif文件导出png
- 王道Java全栈工程师培养计划
- Android获取SD卡上图片和视频文件及其缩略图
- android 读取一个文件下所有的文件
- Android搜索手机文件
- Android之R文件