标签:android com class http code div java style size string width
一、编写JNI模块
当安装好NDK编译环境后,会在它的目录下找到sample目录,它里面有一些例子,可以参考这些例子来写我们自已的模块。
1、在/home/android/文件夹下,新建“ledjni”文件夹。
2、/ledjni/jni/目录下,新建“led-jni.c”
led-jni.c文件
#include <stdio.h> #include <string.h> #include <jni.h> #include <fcntl.h> /*包括文件操作,如open() read() close()write()等*/ #include <android/log.h> #define LOG_TAG "led-jni" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) #define DEVICE_NAME "/dev/led_by_wenhui" //device point //#define DEVICE_NAME "/dev/leds" //device point //#define DEVICE_NAME "/dev/led_" //device point #define LED_ON 1 #define LED_OFF 0 int fd; jstring Java_com_auly_control_ledClass_stringFromJNI( JNIEnv* env, jobject thiz ) { return (*env)->NewStringUTF(env, "This is wenhui project ,Hello from JNI !"); } jint Java_com_auly_control_ledClass_Init( JNIEnv* env) { LOGE("LEDclass_Init()\n"); fd = open(DEVICE_NAME, 0); LOGE("LEDclass_Init()-> fd = %d \n", fd); if (fd < 0){ LOGE("open device %s error \n", DEVICE_NAME); return 0; } return 1; } jint Java_com_auly_control_ledClass_IOCTL( JNIEnv* env, jobject thiz , jint ledID, jint ledState) { LOGE("IOCTL()-> %d ledState \n",ledState); LOGE("IOCTL()-> %d ledState \n",0); ioctl(fd,ledState, NULL); return 1; } jint Java_com_auly_control_ledClass_CLOSE( JNIEnv* env, jobject thiz ) { close(fd); return 1; }
3、相同目录下的新建Android.mk如下
Android.mk文件
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := led-jni LOCAL_SRC_FILES := led-jni.c LOCAL_CFLAGS := -Werror LOCAL_LDLIBS := -llog -lGLESv2 include $(BUILD_SHARED_LIBRARY)
可以看到,主要是修改LOCAL_SRC_FILES指向源文件的名称!
还有一点很重要,如果要使用调试LOG打印,也就是__android_log_print函数。要在LOCAL_LDLIBS中添加-llog,如上面的Android.mk所示。
4、编译JNI模块
#cd /home/android/ledjni
进到刚才写的JNI目录
#ndk-build
编译JNI,编译成功后,会在ledjni文件夹下生成libs和obj两个文件夹,并在
ledjni/libs/armeabi下得到目标文件libled-jni.so
(目前ledjni文件夹只有3个目录jni,libs,obj)
二、JAVA程序
1、Eclipse新建工程 LEDAPP
注意 Location: 选刚才的 ledjni
然后 Runas > Android application,就会出现android的模拟器了,里面跑个helloworld出来。
2、加入button和文本输出
程序到上面为止代码是ADT自动生成的,似乎与我们一点关系也没有。那我们来改一下代码,因为我们调用JNI接口是为了访问驱动程序操作硬件的,例如写,读,打开LED,关闭LED等等,由按钮触发的动作。
第一步是,增加两个Button,,在main.xml里描述一下:打开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" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <Button android:id="@+id/led_on" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/LEDon" /> <Button android:id="@+id/led_off" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/LEDoff" /> </LinearLayout>
实际代码中,把注释去掉,否则编译不过的。
3、加入输出字符串资源
工程 >values > strings.xml文件
修改如下
<?xmlversion="1.0"encoding="utf-8"?>
<resources>
<stringname="hello">Led控制程序</string>
<stringname="app_name">LEDAPP</string>
<stringname="LEDon">打开LED</string>
<stringname="LEDoff">关闭LED</string>
</resources>
上面的”打开LED”等资源,就是用在按钮上显示出来的字符串
经过上面的修改,现在程序界面上,已经有如下效果了
鼠标右键工程名>Runas > Android application运行程序。
4、加入按钮对应的动作
“关闭LED”按钮:
“打开LED”按扭:调用JNI的IOCTL(int ledID, int ledState);
操作:
在LEDAPP> src > com.auly.control >LEDAPPActivity.java文件
package com.auly.control; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class LEDAPPActivity extends Activity { /** Called when the activity is first created. */ //定义变量 public static final int LED_ON = 0X01; public static final int LED_OFF = 0x00; private Button btn1 = null; private Button btn2 = null; //定义类 ledClass myledclass; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); //初始化 setContentView(R.layout.main); myledclass = new ledClass(); //声明类 myledclass.Init(); //调用JNI库里的初始化函数 //按钮 打开 led btn1 = (Button)findViewById(R.id.led_on); btn1.setOnClickListener(new MyBtn1Listener()); //捆绑监听器 //按钮 关闭 led btn2 = (Button)findViewById(R.id.led_off); btn2.setOnClickListener(new MyBtn2Listener()); //捆绑监听器 } class MyBtn1Listener implements OnClickListener { @Override public void onClick(View v) { myledclass.Init(); System.out.println("debug LED_ON"); myledclass.IOCTL(0,LED_ON); } } class MyBtn2Listener implements OnClickListener { @Override public void onClick(View v) { System.out.println("debug LED_OFF"); myledclass.IOCTL(0,LED_OFF); myledclass.CLOSE(); } } }
5、添加类ledClass
鼠标右键com.auly.control> new > Class
填参数:
Finish后,在/src/com/auly/control/得到如下的类文件
ledClass.java
修改如下
package com.auly.control;
public class ledClass
{
/*声明函数*/
//初始化函数 对应 JNI 里面的 jint
Java_com_auly_control_ledClass_Init( JNIEnv* env) 函数 以下的同理
public native int Init();
public native int
IOCTL(int ledID, int ledState);
public native String
stringFromJNI();
public native int
CLOSE();
static{
System.loadLibrary("led-jni");/*加载JNI库*/
}
}
三、 编译运行
鼠标右键工程名,弹出菜单,选择 Runas > Android Application就可以看到编译过程,编译完成后,会自动调用android模拟器,看到界面效果
安装到开发板:(方式有多种 adb )
或直接用u盘拷贝(这样调试比较麻烦)
在LEDSJNI目录下,会看到bin文件夹,里面的LEDAPP.apk就是这个程序的安装文件,可以把它安装的开发板上,运行本程序,看控制开发板上的LED灯的效果。
注意!运行前 要修改的驱动节点的权限
#chmod777 /dev/vib
这是为了使得led_by_wenhui这个节点可以被我们写的JNI操作,不然会open失败的,因为APK安装的JNI模块,权限不够,这个节点是我们的LED驱动生成的控制节点。
也可以在android文件系统yaffs编译时,通过init.rc文件来实现这个操作,就是在该文件里随便一行,写上面的命令行,启动时会自动执行!这样就不用手动的改变该节点的属性了。
拷贝LEDAPP.apk到开发板上,通过安装工具把它安装到开发板上
运行程序,就能按程序上的近钮来控制开发板上的LED亮灭了!
mini6410-JNI-led,码迷,mamicode.com
标签:android com class http code div java style size string width
原文地址:http://www.cnblogs.com/luxiaolai/p/3695205.html