5.生成com_ndk_led_JniLed.h文件,具体为通过cmd命令进入windows的命令行控制界面,然后进入到工程所在的目录下,具体为进入D盘->test-Android/LEDAPP/bin/classes,然后输入:javah com.ndk.led.JniLed,再回车。这样会在classes文件下面生成:com_ndk_led_JniLed.h文件,这就是生成的c/c++文件的头文件。
6.在工程中的jni文件夹下,建立Android.mk文件,名字一定是这个,不能是其他的名字。并且输入如下的内容:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := LEDAPP
LOCAL_SRC_FILES := com_ndk_led_JniLed.c
include $(BUILD_SHARED_LIBRARY)
这就是Android下面的Makefile,注意第三行中的“LEDAPP”和第四行中的“com_ndk_led_JniLed.c”,一个是模块的名字,另外一个是要编译的c语言的源文件,要和上面的.h文件保存一致。
7.把在classes下面生成的com_ndk_led_JniLed.h文件拷贝到刚开始所建立的jni文件夹下,同时建立com_ndk_led_JniLed.c的文件,这个c文件就是通过调用Linux内核中的驱动函数,以一定的方式进行封装,使Android应用程序能调用驱动的关键。这个文件中的函数要看具体的驱动函数来完成,比如说,咱们现在就得看友善所提供的smart210的Linux-3.0.8内核中的led的驱动函数,具体位置为:友善的Linux-3.0.8/char/mini210_leds.c,我会把这个文件共享,方便大家查看,下面说说com_ndk_led_JniLed.c文件的内容,具体如下:
#include "com_ndk_led_JniLed.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <jni.h>
#include <fcntl.h> /*包括文件操作,如open() read() close() write()等*/
//----for output the debug log message
#include <android/log.h>
int fd; //文件标识符
#define DEVICE_NAME "/dev/leds" //这是linux下面的设备节点,Android应用程序就是通过这个来识别驱动程序的
#ifdef __cplusplus
extern "C"
{
#endif
JNIEXPORT jint JNICALL Java_com_ndk_led_JniLed_LedInit(JNIEnv *env, jclass arg)
{
fd = open(DEVICE_NAME,O_RDWR);//打开设备
ioctl(fd,1,2);
if(fd == -1)
return 0;
else
return 1;
}
JNIEXPORT jint JNICALL Java_com_ndk_led_JniLed_LedIOCTL(JNIEnv *env, jclass arg, jint cmd, jint led_num)
{
int CTLCODE = led_num;
switch(CTLCODE)
{
case 0:
if(cmd==0)
ioctl(fd,0,0); //调用led驱动函数中的ioctl,这里需要注意,要按驱动里的函数保持一致
else if(cmd==1)
ioctl(fd,1,0);
break;
case 1:
if(cmd==0)
ioctl(fd,0,1);
else if(cmd==1)
ioctl(fd,1,1);
break;
case 2:
if(cmd==0)
ioctl(fd,0,2);
else if(cmd==1)
ioctl(fd,1,2);
break;
case 3:
if(cmd==0)
ioctl(fd,0,3);
else if(cmd==1)
ioctl(fd,1,3);
break;
default: break;
}
return 1;
}
#ifdef __cplusplus
}
#endif
8.同时要更新com_ndk_led_JniLed.h文件中的内容,具体的更新代码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_ndk_led_JniLed */
#ifndef _Included_com_ndk_led_JniLed
#define _Included_com_ndk_led_JniLed
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_ndk_led_JniLed
* Method: LedInit
* Signature: ()I
*/
//这就是.c文件中实现函数的声明,注意要一致啊,负责会出现“unfortunately,xxx has stopped!”的错误
JNIEXPORT jint JNICALL Java_com_ndk_led_JniLed_LedInit
(JNIEnv *, jclass);
/*
* Class: com_ndk_led_JniLed
* Method: LedIOCTL
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_ndk_led_JniLed_LedIOCTL
(JNIEnv *, jclass, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
以上就是JNI的部分,下面我将进行Android应用程序的开发