当前位置: 首页 > 编程日记 > 正文

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 

相关文章:

【数据结构】顺序串的插入算法,删除算法,连接运算,顺序串求子串算法

主函数自行添加 头文件 宏定义 #include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 串的顺序存储 typedef struct {char str[MAXSIZE];int length; }seqstring; 顺序串的创建 void creat(seqstring *S) {char c;int i0;while((cgetchar())!\n){S-…

log4j日志记录级别是如何工作?

级别p的级别使用q&#xff0c;在记录日志请求时&#xff0c;如果p>q启用。这条规则是log4j的核心。它假设级别是有序的。对于标准级别它们关系如下&#xff1a;ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF。 举个栗子 下面的栗子明确指出如何可以过…

Kafka背后公司获1.25亿融资,估值超25亿美元

北京时间1月24日&#xff0c;开源Apache Kafka项目背后的公司Confluent在官方博客宣布进行了D轮融资&#xff0c;价值约为1.25亿美元&#xff0c;公司总估值高达25亿美元。 Confluent公司CEO Jay Kreps在博客中表示&#xff1a;我很高兴地宣布&#xff0c;Confluent已经募集了1…

深入学习jQuery描述文本内容的3个方法

前面的话 在javascript中&#xff0c;描述元素内容有5个属性&#xff0c;分别是innerHTML、outerHTML、innerText、outerText和textContent。这5个属性各自有各自的功能&#xff0c;且兼容性不同。jQuery针对这样的处理提供了3个便捷的方法&#xff0c;分别是&#xff1a;html(…

NDK JNI Android Studio开发与调试DEMO(三)(生成 .so 文件)

Android Studio NDK 开发与调试&#xff08;生成 .so 文件&#xff09; 温馨提示&#xff1a;如果你的 Android Studio 版本在 3.0以上 &#xff0c; 建议你用 cMake /ndk-build 的新姿势进行 NDK 开发 : https://developer.android.google.cn/index.html AS与&#xff47;&am…

字符串的模式匹配 (朴素模式匹配算法 ,KMP算法)

字符串的模式匹配 寻找字符串p在字符串t中首次出现的起始位置 字符串的顺序存储 typedef struct {char str[MAXSIZE];int length; }seqstring; 朴素的模式匹配算法 基本思想&#xff1a;用p中的每一个字符去与t中的字符一一比较。 模式p 正文 t 如果匹配成功&#xff0c…

框架页面jquery装载

转载于:https://www.cnblogs.com/moonsoft/p/10313309.html

NDKJNI Android 相关资料整理(四)

JNI/NDK开发指南 JNI/NDK开发指南&#xff08;一&#xff09;—— JNI开发流程及HelloWorld http://blog.csdn.net/xyang81/article/details/41777471 JNI/NDK开发指南&#xff08;二&#xff09;——JVM查找java native方法的规则 http://blog.csdn.net/xyang81/article/det…

【ACM】与全排列相关的STL函数 prev_permutation next_permutation

排列 与 全排列 从n个不同元素中任取m&#xff08;m≤n&#xff09;个元素&#xff0c;按照一定的顺序排列起来&#xff0c;叫做从n个不同元素中取出m个元素的一个排列。 当mn时所有的排列情况叫全排列。如果这组数有n个&#xff0c;那么全排列数为n!个。 对于全排列的求解…

虚拟机无法使用网卡桥接模式

重装了好几遍操作系统&#xff0c;换了两个虚拟机&#xff0c;差点怀疑人生…… 最终的原因竟然是win10&#xff01;&#xff01;&#xff01; 1.执行WINR 输入services.msc&#xff0c;打开服务管理器&#xff08;回车&#xff09;。 2.找到Device Install Service服务 启动此…

Azure自动化部署运维浅谈

本次来谈一谈如何在Azure中实现一些简单的自动化运维的需求&#xff0c;一般来讲自动化运维我们通过很多第三方的工具平台实现&#xff0c;比较流行的目前有很多&#xff0c;比如老牌的chef, puppet,新兴的PowerShell DSC, ansible。这些应该都是耳熟能详的了。那么在Azure平台…

NDK/JNI demo ( 五 ) ORB_SLAM2在Android上的移植过程

Android平台搭建和NDK环境配置 Android移植基础 NDK是集成的Android中调用C代码的工具包&#xff0c;核心是JNI&#xff08;Java Native Interface&#xff09;技术&#xff0c;具体这里略过不表。只说说NDK开发的基本步骤&#xff1a; 1. 编写Java代码&#xff1a;在Java中定义…

[Nancy On .Net Core Docker] 轻量级的web框架

.net core现在已经有了大的发展&#xff0c;虽然笔者现在已经从事python开发&#xff0c;但是一直在关注.net的发展&#xff0c;在逛博客园的时候&#xff0c;发现有大家都会提到Nancy这个框架&#xff0c;在简单的使用之后&#xff0c;发现竟然是如此的简单而优雅 public clas…

【算法】【ACM】深入理解Dijkstra算法(单源最短路径算法)

Dijkstra算法是用来求解从某个源点到其他各顶点的最短路径&#xff08;单源最短路径&#xff09;。 下面的Dijkstra算法的讲解都是基于这个有向图&#xff0c;在遇到其他问题可以类比。 算法的基本思想&#xff1a; 把图中的定点分成两组&#xff0c;第一组包括已确定最短路径…

智能POS常见问题整理

智能POS预警值为小于所设的数量&#xff0c;H5就会变为锁定状态 智能POS查看数据库方法&#xff1a; 商米D1&#xff1a;设置-存储设备和USB-内部存储设备-浏览-winboxcash tablet.db为智能POS数据库 Winbox文件夹内&#xff0c;为相应logcat文件&#xff0c;应用出现问题时&am…

解决安卓系统写入SD卡权限问题

1.需要用户手动赋予的权限&#xff08; Dangerous Permissions&#xff09; 所属权限组权限日历READ_CALENDAR日历WRITE_CALENDAR相机CAMERA联系人READ_CONTACTS联系人WRITE_CONTACTS联系人GET_ACCOUNTS位置ACCESS_FINE_LOCATION位置ACCESS_COARSE_LOCATION麦克风RECORD_AUDIO…

【ACM】【STL】stack应用

C Stacks&#xff08;堆栈&#xff09; C Stack&#xff08;堆栈&#xff09; 是一个容器类的改编&#xff0c;为程序员提供了堆栈的全部功能&#xff0c;——也就是说实现了一个先进后出&#xff08;FILO&#xff09;的数据结构。 操作比较和分配堆栈empty()堆栈为空则返回真…

CHUCK手把手带你搞定OPENSTACK

以下是原文链接&#xff1a;http://blog.oldboyedu.com/openstack/转载于:https://blog.51cto.com/bovin/1858198

JVM基础面试题及原理讲解

2019独角兽企业重金招聘Python工程师标准>>> 本文从 JVM 结构入手&#xff0c;介绍了 Java 内存管理、对象创建、常量池等基础知识&#xff0c;对面试中 JVM 相关的基础题目进行了讲解。 写在前面&#xff08;常见面试题&#xff09; 基本问题 介绍下 Java 内存区域…

SLAM前端 ---------特征提取之ORB(ORB与SIFT与SURF)

ORB 论文翻译&#xff1a; 一种特征匹配替代方法&#xff1a;对比SIFT或SURF 1.ORB特征简介 ORB是Oriented FAST and Rotated BRIEF&#xff08;oFAST and rBRIEF&#xff09;的简称&#xff0c;ORB的名字已经说明了其来源&#xff0c;其实ORB特征是采用FAST方法来检测提取特…

oracle 内存分配和调优 总结

一直都想总结一下oracle内存调整方面的知识&#xff0c;最近正好优化一个数据库内存参数&#xff0c;查找一些资料并且google很多下。现在记录下来&#xff0c;做下备份。 一、概述&#xff1a; oracle 的内存可以按照共享和私有的角度分为系统全局区…

【ACM】Doubly Linked List(STL list)

题目链接&#xff1a;https://vjudge.net/problem/Aizu-ALDS1_3_C 这一题一开始的时候想的是用vector&#xff0c;超时 #include <iostream> #include <stack> #include <cstdio> #include <cstring> #include <queue> #include <vector>…

IOS获取焦点页面上移问题

var u navigator.userAgent; var flag; var myFunction; var isIOS !!u.match(/(i1;( U;)? CPU.Mac OS X/); if (isIOS) { document.body.addEventListener(focusin, () > { //软键盘弹起事件flag true;clearTimeout(myFunction); }) document.body.addEventListener(f…

SLAM之特征匹配(二)————RANSAC--------翻译以及经典RANSAC以及其相关的改进的算法小结

本文翻译自维基百科&#xff0c;英文原文地址是&#xff1a;http://en.wikipedia.org/wiki/ransac RANSAC是“RANdom SAmple Consensus&#xff08;随机抽样一致&#xff09;”的缩写。它可以从一组包含“局外点”的观测数据集中&#xff0c;通过迭代方式估计数学模型的参数…

【ACM】树 小结

树是一种表达层级结构的数据结构&#xff0c;也是实现高效算法与数据结构的基础。 学习之前的基础&#xff1a;数组&#xff0c;循环处理&#xff0c;结构体&#xff0c;递归函数。 树&#xff1a;由结点&#xff08;node&#xff09;和连接结点的边&#xff08;edge&#xf…

【cocos2d-js官方文档】九、cc.loader

概述 原来的cc.Loader被改造为一个单例cc.loader&#xff0c;采用了插件机制设计&#xff0c;让loader做更纯粹的事。 各种资源类型的loader可以在外部注册进来&#xff0c;而不是直接将所有的代码杂揉在cc.Loader中&#xff0c;更好的方便管理以及用户自定义loader的创建。 cc…

更换VC后DDC提示证书不可用

问题描述&#xff1a;客户环境由Windows VC更换成Linux VC后&#xff0c;DDC提示证书不可用问题原因&#xff1a;因为VC更换后&#xff0c;存储在DDC数据库HostingUnitServiceSchema.HypervisorConnectionSSLThumbprint表中证书指纹信息和新得VC证书指纹信息不匹配。解决方法&a…

尺度空间理论与图像金字塔

我们之所以决定使用卷积后的特征是因为图像具有一种“静态性”的属性。也就是说使用卷积就是为了提取显著特征&#xff0c;减少特征维数&#xff0c;减少计算量。 在对图像进行卷积操作后的只管现象&#xff1a;图像变得模糊了&#xff0c;可是我们依然能够分辨出是什么&#x…

【ACM】 multiset 的 一些应用

一、The kth great number 题目链接&#xff1a;https://vjudge.net/problem/HDU-4006 用set写超时 &#xff08;在VJ里&#xff0c;用C显示Compilation Error&#xff0c;选择G&#xff0c;则是TLE&#xff09; #include <iostream> #include <set> #include &…

apache2.2 做后端,增加真实ip到日志中

apache2.2使用mod_remoteip模块 一.安装 wget https://github.com/ttkzw/mod_remoteip-httpd22/raw/master/mod_remoteip.c/usr/local/apache/bin/apxs -i -c -n mod_remoteip.so mod_remoteip.c 二.添加Apache配置vi /usr/local/apache/conf/httpd.confInclude conf/extra/htt…