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(二)相关推荐

  1. NDK JNI方式读写Android系统的GPIO

    https://blog.csdn.net/zjc3909/article/details/78732374

  2. 深入Android系统(十二)Android图形显示系统-2-SurfaceFlinger与图像输出

    最近有些忙,切实体验了一把拖更的羞耻感 ( *︾▽︾) 本文和上一篇深入Android系统(十二)Android图形显示系统-1-显示原理与Surface关系比较密切,撸完前篇更易理解本文啦 (๑‾ ...

  3. 定制Android系统开发之二——系统服务

    转自:http://blog.csdn.net/wtianok/article/details/49175581 何为系统服务 做Android APP开发的过程中,会经常需要调用类似于下面这样的函数 ...

  4. cm-14.1 Android系统定制(二):内置系统应用

    声明 Android系统定制时免不了预置一些APP进系统中: 预置的结果一般有三种:       1.预置的APK用户可以卸载,恢复出厂设置后APK不恢复:       2.预置的APP用户可以卸载, ...

  5. android 图片读写,Android系统中图片的读写

    读取手机图片: Bitmap bmp=BitmapFactroy.decodeFile("/sdcard/xxx.png"); imageview.setImageBitmap(b ...

  6. Android 系统开发系列二

    这一章主要是讲如何测试驱动. 1.驱动的简单测试 在上一篇文章中,我们已经把添加驱动模块做完了,并把驱动下载到了板子上.下面将介绍一下如何测试驱动是否正常. 这个ttt驱动,我们实现了一个读.一个写的 ...

  7. Android系统的Ashmem匿名共享内存子系统分析(4)- Ashmem子系统的 Java访问接口

    声明 其实对于Android系统的Ashmem匿名共享内存系统早就有分析的想法,记得2019年6.7月份Mr.Deng离职期间约定一起对其进行研究的,但因为我个人问题没能实施这个计划,留下些许遗憾- ...

  8. 用于Android系统的pango + cairo交叉编译

    做Android系统下的开发也有几年了,这几年间也遇到过很多问题,大多是从网上搜索解决办法,虽然不是都能找到完美的解决办法,但是基本对于结局问题是有帮助的,所以一直也没有整理遇到的问题(主要是太懒了! ...

  9. Android系统上部署usb打印机

    Android系统上部署usb打印机 一.综述 android系统现多用于手持设备,为手机等设备应用提供了很好的系统级支持.但对于PC机常用的打印功能,android到目前并不支持,也没有打印机厂家专 ...

最新文章

  1. spark编程基础--5.4综合实例
  2. Chrome 中的 JavaScript 断点设置和调试技巧
  3. 以架构师的眼睛看世界-Architect Inside
  4. CXF整合Spring开发WebService
  5. 60-120-040-使用-Data Transformation简介
  6. SAP License:PM实务
  7. 吴恩达|机器学习作业1.1多变量线性回归
  8. Linux SD卡建立两个分区
  9. 流水灯c语言代码switch,单片机C语言入门之六switch case语句流水灯
  10. Office安装时闪退,用Windows Installer Cleanup彻底卸载 或 注册表清理解决
  11. 小米10获取root权限_oppo A59s (全网通)一键ROOT获取ROOT权限
  12. 【Learning RAW-to-sRGB Mappings with Inaccurately Aligned Supervision通过不准确对齐的监督学习 RAW 到 sRGB 的映射】
  13. 世事洞明皆学问-拉链拉头的拆分安装
  14. C# .Net 邮箱发送含附件方法
  15. Flink中的CEP(二)
  16. 欺骗的艺术——第二部分(7)
  17. 基尔霍夫(kirchhoff)矩阵树定理
  18. choice数据库导出股票数据
  19. 什么叫做实体经济危机?
  20. nginx正向代理的配置及实现

热门文章

  1. consul服务下线通知_Consul微服务的配置中心体验篇-阿里云开发者社区
  2. php文件内含有隐藏的^m字符,【整理】如何取消Linux下,vi中显示的^M符号
  3. mysql h 127.0.0.1_MySQL 连接时尽量使用 127.0.0.1 而不是 localhost
  4. MySQL面试题 | 附答案解析(十六)
  5. OpenCV中的特征匹配+单应性以查找对象
  6. 数字图像处理:腐蚀与膨胀操作
  7. PCL:k-d tree 1 讲解
  8. Python Qt GUI设计:QPainter、QPen、QBrush和QPixmap窗口绘图类(基础篇—17)
  9. 直方图(opencv)
  10. 常用jQuery ajax代码片段