好记性不如烂笔头------按键灯jni使用,打包成so文件并使用
MTK平台如果在硬件上增加了按键灯,第三方APP和framework层想要调用的话,均需要通过jni接口,具体用法不太一样,这里简单介绍一下我的使用过程。
首先,需要增加KeyLed.c和头文件KeyLed.h两个接口函数:
(\hardware\libhardware_legacy\key_leds\key_leds.c)
( \hardware\libhardware_legacy\include\hardware_legacy\KeyLed.h)
1,这里简单介绍一下打包成so文件的方法(工具eclipse,NDK):
将key_leds.c和key_leds.h文件放入应用程序中jni目录下,增加C++接口jni_key_leds.cpp,jni_key_leds.h,Android.mk文件,目录结构如下:
文件说明:
Android.mk:(定义so名称,引入头文件等)内如如下
1 LOCAL_PATH:= $(call my-dir) 2 include $(CLEAR_VARS) 3 4 LOCAL_MODULE := jni_key_leds 5 LOCAL_MODULE_TAGS := optional 6 7 LOCAL_C_INCLUDES += \ 8 $(JNI_H_INCLUDE) \ 9 $(LOCAL_PATH)/key_leds.h \ 10 $(LOCAL_PATH)/key_leds.h \ 11 $(LOCAL_PATH)/pressure.h 12 13 LOCAL_SRC_FILES := \ 14 jni_key_leds.cpp \ 15 key_leds.c \ 16 pressure.c 17 18 LOCAL_SHARED_LIBRARIES := libutils 19 20 LOCAL_LDLIBS := -llog 21 22 LOCAL_STATIC_LIBRARIES := 23 24 LOCAL_CFLAGS += 25 26 LOCAL_PRELINK_MODULE := false 27 28 include $(BUILD_SHARED_LIBRARY)
Application.mk:
1 APP_STL := gnustl_static 2 APP_GPPFLAGS := -frtti -fexceptions 3 APP_ABI := all
APP_ABI : 默认情况下,NDK的编译系统根据 "armeabi" ABI生成机器代码。可以使用APP_ABI 来选择一个不同的ABI,
比如:为了在ARMv7的设备上支持硬件FPU指令。可以使用 APP_ABI := armeabi-v7a
或者为了支持IA-32指令集,可以使用 APP_ABI := x86
或者为了同时支持这三种,可以使用 APP_ABI := armeabi armeabi-v7a x86
APP_ABI := all全部编译出来
jni_key_leds.cpp:引入接口文件和头文件,写方法接口
1 #include <jni.h> 2 #include <unistd.h> 3 #include <fcntl.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <math.h> 10 #include <string.h> 11 12 #include "jni_key_leds.h" 13 #include "key_leds.h" 14 #include "pressure.h" 15 16 #include <android/log.h> 17 18 #define LOG_TAG "MainActivity" 19 #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) 20 21 extern "C" { 22 23 JNIEXPORT jint JNICALL Java_com_elderposition_util_DeviceManager_red1LedsExists( 24 JNIEnv * env, jobject obj) { 25 LOGD("red1_leds_exists !!!"); 26 return red1_leds_exists(); 27 } 28 JNIEXPORT jint JNICALL Java_com_elderposition_util_DeviceManager_red2LedsExists( 29 JNIEnv * env, jobject obj) { 30 LOGD("red2_leds_exists !!!"); 31 return red2_leds_exists(); 32 } 33 ....... 34 }
jni_key_leds.h:
1 #ifndef __JNI_KEY_LEDS 2 #define __JNI_KEY_LEDS 1 3 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 JNIEXPORT jint JNICALL Java_com_elderposition_util_DeviceManager_red1LedsExists( 9 JNIEnv * env, jobject obj); 10 JNIEXPORT jint JNICALL Java_com_elderposition_util_DeviceManager_red2LedsExists( 11 JNIEnv * env, jobject obj); 12 }
key_leds.c:接口文件,方法(注意方法名,程序的完整路径中用"_"连接)
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <fcntl.h> 4 #include <errno.h> 5 6 #define RED1_DEVICE "/sys/devices/platform/key_leds/red1_leds_onoff" 7 #define RED2_DEVICE "/sys/devices/platform/key_leds/red2_leds_onoff" 8 #define RED3_DEVICE "/sys/devices/platform/key_leds/red3_leds_onoff" 9 #define BLUE_DEVICE "/sys/devices/platform/key_leds/blue_leds_onoff" 10 #define GREEN_DEVICE "/sys/devices/platform/key_leds/green_leds_onoff" 11 12 int red1_leds_exists() 13 { 14 int fd; 15 16 #ifdef QEMU_HARDWARE 17 if (qemu_check()) { 18 return 1; 19 } 20 #endif 21 22 fd = open(RED1_DEVICE, O_RDWR); 23 if(fd < 0) 24 return 0; 25 close(fd); 26 return 1; 27 }
key_leds.h:接口头文件
1 #ifndef _HARDWARE_IR_LEDS_H 2 #define _HARDWARE_IR_LEDS_H 3 4 #if __cplusplus 5 extern "C" { 6 #endif 7 8 int red1_leds_exists(); 9 10 int red2_leds_exists(); 11 }
以上步骤完成后,在eclipse中编译出so文件后,即可在第三方APP中使用了。
第三方APP想要使用jni时,可以将打包成so的文件放在lib文件夹下使用,用法同其他API一样:
public class DeviceManager {
static {
System.loadLibrary("jni_key_leds");//关键点1,引入so文件
}
public native int red1LedsExists(); //关键点2,对应每个方法写接口
public native int red2LedsExists();
public native int red3LedsExists();
public native int blueLedsExists();
public native int greenLedsExists();
}
2,上层使用jni(从java层到framework到JNI到HAL到kernel的用法过程)