NDK JNI方式读写Android系统的demo(二)
NDK & JNI(方式讀寫Android系統的Demo)
大家都知道Android系統是一種基于Linux的自由及開放源碼的操作系統,所以讀寫GPIO也可以直接用Linux那一套export/unexport方法,本文將介紹如何使用NDK jni方式來讀寫Android系統的GPIO。
1.環境的具體配置參考博客:http://blog.csdn.net/darlingqiang/article/details/79049638
2. Android Studio安裝NDK
打開Android Studio 中的SDK Manager,菜單Tools -> Android -> SDK Manager
查看安裝情況如下,如果沒有安裝完整的話,請選中NDK,點擊OK就可以安裝NDK
3. 創建Android工程
(1) 創建Android工程jnigpio,然后添加一個新的java類GPIOControl.java
代碼如下:
public class GPIOControl {static {System.loadLibrary("GPIOControl");}public final static native int exportGpio(int gpio);public final static native int setGpioDirection(int gpio, int direction);public final static native int readGpioStatus(int gpio);public final static native int writeGpioStatus(int gpio, int value);public final static native int unexportGpio(int gpio);}
(2) Build -> Rebuild Project即可,會生成 .class文件
(3) 生成jni的頭文件
Android Studio Terminal中輸入如下命令:cd app/src/main/java/
Ternial執行:?????? javah -d jni com.sun.jnigpio.GPIOControl(前面博客有介紹具體的意思)
生成jni頭文件如下圖: 生成
(4) jni目錄下創建GPIOControl.c程序
代碼如下:
//
// Created by Gavin Zhuang on 05/12/2017.
//#include <jni.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <android/log.h>#include "com_zhuang_jnigpio_GPIOControl.h"#define TAG "jni_gpio"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG ,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,TAG ,__VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,TAG ,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG ,__VA_ARGS__)
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,TAG ,__VA_ARGS__)#define IN 0
#define OUT 1
#define LOW 0
#define HIGH 1#define BUFFER_MAX 3
#define DIRECTION_MAX 48/** Class: com_zhuang_jnigpio_GPIOControl* Method: exportGpio* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_zhuang_jnigpio_GPIOControl_exportGpio(JNIEnv *env, jobject instance, jint gpio)
{char buffer[BUFFER_MAX];int len;int fd;fd = open("/sys/class/gpio/export", O_WRONLY);if (fd < 0) {LOGE("Failed to open export for writing!\n");return(0);}len = snprintf(buffer, BUFFER_MAX, "%d", gpio);if (write(fd, buffer, len) < 0) {LOGE("Fail to export gpio!\n");return 0;}close(fd);return 1;
}/** Class: com_zhuang_jnigpio_GPIOControl* Method: setGpioDirection* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_zhuang_jnigpio_GPIOControl_setGpioDirection(JNIEnv *env, jobject instance, jint gpio, jint direction)
{static const char dir_str[] = "in\0out";char path[DIRECTION_MAX];int fd;snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", gpio);fd = open(path, O_WRONLY);if (fd < 0) {LOGE("failed to open gpio direction for writing!\n");return 0;}if (write(fd, &dir_str[direction == IN ? 0 : 3], direction == IN ? 2 : 3) < 0) {LOGE("failed to set direction!\n");return 0;}close(fd);return 1;
}/** Class: com_zhuang_jnigpio_GPIOControl* Method: readGpioStatus* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_zhuang_jnigpio_GPIOControl_readGpioStatus(JNIEnv *env, jobject instance, jint gpio)
{char path[DIRECTION_MAX];char value_str[3];int fd;snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/value", gpio);fd = open(path, O_RDONLY);if (fd < 0) {LOGE("failed to open gpio value for reading!\n");return -1;}if (read(fd, value_str, 3) < 0) {LOGE("failed to read value!\n");return -1;}close(fd);return (atoi(value_str));
}/** Class: com_zhuang_jnigpio_GPIOControl* Method: writeGpioStatus* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_zhuang_jnigpio_GPIOControl_writeGpioStatus(JNIEnv *env, jobject instance, jint gpio, jint value)
{static const char values_str[] = "01";char path[DIRECTION_MAX];int fd;snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/value", gpio);fd = open(path, O_WRONLY);if (fd < 0) {LOGE("failed to open gpio value for writing!\n");return 0;}if (write(fd, &values_str[value == LOW ? 0 : 1], 1) < 0) {LOGE("failed to write value!\n");return 0;}close(fd);return 1;
}/** Class: com_zhuang_jnigpio_GPIOControl* Method: unexportGpio* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_zhuang_jnigpio_GPIOControl_unexportGpio(JNIEnv *env, jobject instance, jint gpio)
{char buffer[BUFFER_MAX];int len;int fd;fd = open("/sys/class/gpio/unexport", O_WRONLY);if (fd < 0) {LOGE("Failed to open unexport for writing!\n");return 0;}len = snprintf(buffer, BUFFER_MAX, "%d", gpio);if (write(fd, buffer, len) < 0) {LOGE("Fail to unexport gpio!");return 0;}close(fd);return 1;
}android.useDeprecatedNdk=true
在defaultConfig中添加ndk內容:
ndk{moduleName "GPIOControl" //so文件: lib+moduleName+.soldLibs "log", "z", "m" // 添加android日志引用abiFilters "armeabi", "armeabi-v7a", "x86" //cpu的類型}3
(6) Rebuild Project 生成so文件
so文件在app>build>intermediates>make>debug>lib>目錄下,如圖:
(7) 方法調用
// 定義GPIO輸入輸出方式和高低電平public final static int GPIO_DIRECTION_IN = 0;public final static int GPIO_DIRECTION_OUT = 1;public final static int GPIO_VALUE_LOW = 0;public final static int GPIO_VALUE_HIGH = 1;
Thread.sleep(1000);}GPIOControl.unexportGpio(gpioPin);} catch (Exception ex){}}});thread.start();}});
注意事項:該控制GPIO需要su權限,可以試著用adb shell去修改 /sys/class/gpio/export 和 /sys/class/gpio/unexport 的讀寫權限。如:chmod 666 /sys/class/export
參考自博客:http://blog.csdn.net/zjc3909/article/details/78732374?
總結
以上是生活随笔為你收集整理的NDK JNI方式读写Android系统的demo(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黄沙黄沙满天飞是什么歌呢?
- 下一篇: NDK JNI Android Stu