Android系统APK操作GPIO读写及添加权限
需求描述
上层APK操作GPIO的diretction、value节点,实现点亮和熄灭灯,使用JNI方式,使用以下方式无效
extern "C"
JNIEXPORT jint JNICALL
Java_com_example_administrator_jni_Gpio_setOpenLed(JNIEnv *env, jclass instance) {int sd;system("echo 9 > /sys/class/gpio/export");system("echo out > /sys/class/gpio/gpio9/direction");system("echo 1 > /sys/class/gpio/gpio9/value");system("echo 9 > /sys/class/gpio/unexport");return 0;
}
实现方案
- GPIOControl.c:JNI调用接口
#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>#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_example_jnigpio_GPIOControl* Method: exportGpio* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_example_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_example_jnigpio_GPIOControl* Method: setGpioDirection* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_example_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_example_jnigpio_GPIOControl* Method: readGpioStatus* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_example_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_example_jnigpio_GPIOControl* Method: writeGpioStatus* Signature: (II)I*/
JNIEXPORT jint JNICALL Java_com_example_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_example_jnigpio_GPIOControl* Method: unexportGpio* Signature: (I)I*/
JNIEXPORT jint JNICALL Java_com_example_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.mk:编译出
libGPIOControl.so
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)
LOCAL_MODULE := GPIOControl
LOCAL_SRC_FILES := GPIOControl.c
LOCAL_LDLIBS := -lloginclude $(BUILD_SHARED_LIBRARY)
- 添加节点读写权限
device/qcom/common/rootdir/etc/init.qcom.rc on boot
+ chmod 0777 /sys/class/gpio/export
+ chmod 0777 /sys/class/gpio/unexport
- 添加实际节点的读写权限:
ls -al sys/class/gpio/
查看实际节点
device/qcom/common/rootdir/etc/ueventd.qcom.rc+/sys/devices/soc/1000000.pinctrl/gpio/gpio* direction 0777 system system
+/sys/devices/soc/1000000.pinctrl/gpio/gpio* value 0777 system system
- 添加节点的SELinux权限
device/qcom/sepolicy/common/system_app.te+allow system_app sysfs:file rw_file_perms;
- APK调用
- Android应用修改AndroidManifest.xml文件,在manifest节点中添加
android:sharedUserId="android.uid.system
,修改Android.mk文件,添加LOCAL_CERTIFICATE := platform
设置系统签名。 - Android APK调用JNI加载so动态库:
https://blog.csdn.net/weixin_44008788/article/details/114393087
相关拓展
- 节点读写
//读节点
private static String readSys(String path) {String prop = "waiting";// 默认值try {BufferedReader reader = new BufferedReader(new FileReader(path));prop = reader.readLine();} catch (IOException e) {e.printStackTrace();}return prop;
}
//调用方法readSys("/sys/class/demo/version")
//写节点
private static String writeSys(String path) {try {BufferedWriter bufWriter = null;bufWriter = new BufferedWriter(new FileWriter(path));bufWriter.write("1"); // 写操作bufWriter.close();} catch (IOException e) {e.printStackTrace();}
}
//调用方法
writeSys("/sys/class/demo/version")
//以FileOutputStream写节点
void IOCtrl(int pin, int level) {String path;path = "/sys/class/gpio/gpio" + pin + "/value";try {FileOutputStream out = new FileOutputStream(path);out.write(level);out.flush();out.close();} catch (IOException e) {e.printStackTrace();return;}
}
- 添加设备文件节点权限
/sys/class/leds/green/brightness //快捷方式
/sys/devices/soc.0/gpio-leds.66/leds/green/brightness //实际节点
操作LED灯的设备文件节点为APP层system app进程开放该节点访问权限(读或写),权限配置主要修改/device/qcom/sepolicy/common目录下的file.te、file_contexts和system_app.te三个文件
file.te修改如下
# GPIO accessed by system app
type sysfs_gpio, fs_type, sysfs_type;
file_contexts修改如下
/sys/devices/soc/1010000.pinctrl/gpio/gpio62/value u:object_r:sysfs_gpio:s0
/sys/devices/soc/1010000.pinctrl/gpio/gpio63/value u:object_r:sysfs_gpio:s0
system_app.te修改如下
allow system_app sysfs_gpio:file rw_file_perms;
如果通过以上添加SELinux之后,仍没有权限读写sys或proc节点,需要到init.rc里面配置如下
chown system system 文件结点
chmod 777 文件结点
相关参考
https://blog.csdn.net/wds1181977/article/details/54967110
https://blog.csdn.net/liangtianmeng/article/details/84698568
https://blog.csdn.net/d38825/article/details/81240851
https://blog.csdn.net/K_Hello/article/details/90038078
android 查看gpio状态_Android应用层操作GPIO
Android app如何正确读写系统sys设备节点
Android系统APK操作GPIO读写及添加权限相关推荐
- android系统APK签名生成大全
最近要做一个重复开关机的专项测试,发现需要系统权限才能实现 1.需要SYSTEM USER 1> android:sharedUserId="android.uid.sys ...
- android代码图片编辑,怎样修改android系统apk软件里面的代码和图片?
你好,你的问题我算是看明白了,从你的问题可以设计三个方面,apk反编译.apk回编译以及apk签名,看来,我得从头说起了. 首先,我在这里提供下反编译Android所需的软件,当然是全套,刚刚收集整理 ...
- android 系统(155)---如何自己添加号码归属地数据库?
如何自己添加号码归属地数据库? 如何自己添加号码归属地数据库? 并完成 InCallScreen 和 CallLog 界面显示自己添加的号码归属地信息. 以添加一个英文版的国内手机号码归属地举例说明. ...
- cm-14.1 Android系统定制(一):添加以太网上网功能
声明 本文使用的是代码是Nexus5的cm-14.1(要下载cm-14.1代码可参考此文:[日更-2019.3.31]如何下载Nexus5的LineageOS14.1(cm-14.1)系统源码并编译. ...
- android 图片读写,Android系统中图片的读写
读取手机图片: Bitmap bmp=BitmapFactroy.decodeFile("/sdcard/xxx.png"); imageview.setImageBitmap(b ...
- golang 文件操作 创建 读写 复制移动 权限 删除
目录 介绍 基本操作 创建空文件 Truncate文件 得到文件信息 重命名和移动 删除文件 打开和关闭文件 检查文件是否存在 检查读写权限 改变权限.拥有者.时间戳 硬链接和软链接 读写 复制文件 ...
- linux+gpio+嵌入式,嵌入式Linux系统中对GPIO操作的方法总结
在Linux系统里操作GPIO的方法有以下几个: 1. 写驱动的方式 需要自己编写linux驱动,在驱动里操控GPIO,应用通过驱动提供的节点来控制GPIO.优点是结构清晰,可扩展性强,比较灵活.缺点 ...
- 在Android系统中添加组合键快捷启动功能
启动系统特定功能的组合键的判断应该在系统分发按键消息前处理, 这样从系统运行 的角度来说成本最低. 添加组合键处理需要先搞清楚按键消息在framework中采集 和分发子系统的工作流程, 虽然有and ...
- android系统下替换so库等操作
在工作过程中由于android 系统过大编译起来太过费时,所以需要小编来进行验证修改. 下面的是小编TV android 系统的操作. 小编替换android模块步骤 1,编译出.so文件 andro ...
最新文章
- 最新Ceph L版与openstack Pike对接
- 错误 SQL TOP子句中的行数必须是整数
- 【python】xsspider零碎知识点
- 2048小游戏主要算法实现
- 猎鹰spacex_我如何重新创建SpaceX仪表板UI
- 可能是最好的单例模式
- 32位与64位、单精度(single-precision)与双精度(double-precision)
- TCPClient、TCPListener的用法
- Autojs实现图片转字符串(简易ocr预备步骤)
- Atitit q2016 qa doc list on home ntpc.docx
- 香槟分校计算机研究生专业,伊利诺伊大学香槟分校计算机科学专业各大方向介绍...
- WPF使用Blend
- 蓝桥杯之《人民币金额大写》
- html购物页面产品展示,html5 3D交互式房间购物商品展示特效
- css 实现随风摆动
- 【BZOJ1211】【HNOI2004】树的计数(prufer序,组合数)
- 一个简单的C语言代码段,逻辑题
- Python 绘画excel分组柱状图(懒人学习)
- 全选与反选 (转)
- javaweb技术及应用QST
热门文章
- 18B20,search rom命令,遍历搜索
- 分享几款常用远程连接工具
- 客户体验的重要性和企业发展的紧密联系
- 90套Axure原型模板源文件Rp高保真ui产品经理app web 网站案例模板(Axure9制作)
- js(es7-es10)特性
- 自动驾驶「时过境迁」,这家头部出行服务平台再出发
- UML类图几种关系的总结
- org.apache.jasper.JasperException: 未能加载或实例化TagLibraryValidator类
- mysql 单表2000多万条数据,模糊查询如何秒回
- 关于python实现CRC32Mpeg2的应用和总结