android|android通过JNI控制GPIO

少废话直接贴代码:
软件环境:android studio 2.2 ; NDK最好单独下载12r版本就可以; allwinner开发板
1、编写jni头文件及源文件
在main/java同级目录下创建jni文件夹用于存放.h,.c文件
.h文件如下:

/* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class com_example_beep_GpioCtr */#ifndef _Included_com_example_beep_GpioCtr #define _Included_com_example_beep_GpioCtr #ifdef __cplusplus extern "C" { #endif /* * Class:com_example_beep_GpioCtr * Method:exportGpio * Signature: (I)I */ JNIEXPORT jint JNICALL Java_com_example_beep_GpioCtr_exportGpio (JNIEnv *, jclass, jint); /* * Class:com_example_beep_GpioCtr * Method:setGpioDirection * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_example_beep_GpioCtr_setGpioDirection (JNIEnv *, jclass, jint, jint); /* * Class:com_example_beep_GpioCtr * Method:readGpioStatus * Signature: (I)I */ JNIEXPORT jint JNICALL Java_com_example_beep_GpioCtr_readGpioStatus (JNIEnv *, jclass, jint); /* * Class:com_example_beep_GpioCtr * Method:writeGpioStatus * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_example_beep_GpioCtr_writeGpioStatus (JNIEnv *, jclass, jint, jint); /* * Class:com_example_beep_GpioCtr * Method:unexportGpio * Signature: (I)I */ JNIEXPORT jint JNICALL Java_com_example_beep_GpioCtr_unexportGpio (JNIEnv *, jclass, jint); #ifdef __cplusplus } #endif #endif

.c文件如下:
// // Created by Administrator on 2018/12/1. //#include #include #include #include #include #include #include #include #include #include #include #include "com_example_beep_GpioCtr.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 IN0 #define OUT1 #define LOW0 #define HIGH1#define BUFFER_MAX3 #define DIRECTION_MAX 48/* * Class:com_zhuang_jnigpio_GPIOControl * Method:exportGpio * Signature: (I)I */ JNIEXPORT jint JNICALL Java_com_example_beep_GpioCtr_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); } LOGE("sizeof(buffer) : %d", sizeof(buffer)); len = snprintf(buffer, BUFFER_MAX, "%d", gpio); LOGE("gpio : %d , len : %d, buffer : %s , sizeof(buffer) : %d", gpio, len, buffer, sizeof(buffer)); 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_example_beep_GpioCtr_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); LOGE("path : %s", path); 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_example_beep_GpioCtr_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_example_beep_GpioCtr_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 =https://www.it610.com/article/= 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_example_beep_GpioCtr_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; }

2、java初始化本地方法
package com.example.beep; /** * Created by Administrator on 2018/12/1. */ public class GpioCtr {static { System.loadLibrary("GpioCtr"); }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); }

3、app调用部分代码
package com.example.beep; import android.os.Build; import android.os.Bundle; import android.support.annotation.RequiresApi; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { Buzzer bz = new Buzzer(); static int BEEP = 228 ; static int LED5 = 362; static int LED6 = 361; static int flag1 = 0; static int flag2 = 0; static int flag3 = 0; //String out="out"; //String in ="in"; static int out = 1; static int in = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //bz.export(BEEP); //bz.export(LED5); //bz.export(LED6); GpioCtr.exportGpio(BEEP); GpioCtr.exportGpio(LED5); GpioCtr.exportGpio(LED6); setContentView(R.layout.activity_main); final Button mybutton1 = (Button) findViewById(R.id.beep); final Button mybutton2 = (Button) findViewById(R.id.led5); final Button mybutton3 = (Button) findViewById(R.id.led6); mybutton1.setOnClickListener(new View.OnClickListener() { @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) public void onClick(View v) { if(flag1==0){ flag1 = 1; v.setBackground(getResources().getDrawable(R.drawable.beep_on)); //bz.gpio(BEEP,out,flag1); GpioCtr.setGpioDirection(BEEP, out); GpioCtr.writeGpioStatus(BEEP, flag1); }else { flag1 = 0; v.setBackground(getResources().getDrawable(R.drawable.beep_off)); //bz.gpio(BEEP,in,flag1); GpioCtr.setGpioDirection(BEEP, in); GpioCtr.writeGpioStatus(BEEP, flag1); } } }); mybutton2.setOnClickListener(new View.OnClickListener() { @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) public void onClick(View v) { if(flag2==0){ flag2=1; v.setBackground(getResources().getDrawable(R.drawable.light_on)); GpioCtr.setGpioDirection(LED5, out); GpioCtr.writeGpioStatus(LED5, flag2); //bz.gpio(LED5,out,flag2); }else { flag2=0; v.setBackground(getResources().getDrawable(R.drawable.light_off)); GpioCtr.setGpioDirection(LED5, in); GpioCtr.writeGpioStatus(LED5, flag2); //bz.gpio(LED5,in,flag2); } } }); mybutton3.setOnClickListener(new View.OnClickListener() { @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN) public void onClick(View v) { if(flag3==0){ flag3=1; v.setBackground(getResources().getDrawable(R.drawable.light_on)); //bz.gpio(LED6,out,flag3); GpioCtr.setGpioDirection(LED6, out); GpioCtr.writeGpioStatus(LED6, flag3); }else { flag3=0; v.setBackground(getResources().getDrawable(R.drawable.light_off)); //bz.gpio(LED6,in,flag3); GpioCtr.setGpioDirection(LED6, in); GpioCtr.writeGpioStatus(LED6, flag3); } } }); } protected void onStop() { super.onStop(); //bz.unexport(BEEP); //bz.unexport(LED5); //bz.unexport(LED6); GpioCtr.unexportGpio(BEEP); GpioCtr.unexportGpio(LED5); GpioCtr.unexportGpio(LED6); }}

4、app/gradle里面添加ndk配置
ndk{ moduleName "GpioCtr" //so文件: lib+moduleName+.so ldLibs "log", "z", "m" // 添加android日志引用 //abiFilters "all"//cpu的类型 abiFilters "armeabi-v7a", "x86" }

5、local.properties中添加sdk和ndk目录
ndk.dir=D\:\\Users\\Administrator\\AppData\\Local\\Android\\android-ndk-r12b-windows-x86_64\\android-ndk-r12b sdk.dir=D\:\\Users\\Administrator\\AppData\\Local\\Android\\sdk

6、gradle.properties中添加配置
android.useDeprecatedNdk=true(我自己试了这句不加也可以,你们也试试看)

【android|android通过JNI控制GPIO】最后运行安装完成

    推荐阅读