JNI打开 /dev/input/event 返回 -1 /dev/input/event无权限 Permission denied

(如果哪里不对请指出)**

先记录一下我碰到的问题。

	做一个比较特殊的功能  安卓触摸事件注入,(模拟安卓触摸操作)
	我碰到的问题如下面这个链接(权限问题):
	遗憾的是这个帖子的提问并没有得到解决
	
	https://bbs.csdn.net/topics/390945886?list=lz

下面的操作都需要设备有root权限。

本来模拟点击 使用adb命令可以很轻松的实现该功能。
例如:
可以这样实现一个点击屏幕的功能
在这里插入图片描述

但是我实际测试了这样操作,有一个很大的弊端,。发送的命令要好久才能响应的到(卡卡的感觉)

接下来就是一顿百度猛如虎

得到结论是 JNI直接打开设备 /dev/input/eventx 往里面写事件

于是有了下面的代码:

	int Init(const char* path)
	{
		LOGI("开始初始化");
		TOUCH_FD = open(path, O_RDWR);//O_RDWR

		if (TOUCH_FD < 0) {
			LOGI("erro: %s\n", strerror(errno));
			LOGI("Open touch screen file discriptor error!%d", TOUCH_FD);
			LOGI("erro code %d.\r\n", errno);
			return TOUCH_FD;
		}
		return 0;
	}

运行这段代码之前我已经申请了root权限
并且给了路径" chmod 777 " + "/dev/input/event5"这样的权限
但是无论怎么测试都是返回-1 Permission denied
接下来就开始煎熬了。。。
爬了好几天谷歌

下面贴一下我的解决方案
测试手机小米4 android 7

adb控制台 先执行setenforce 0
设置SELinux 成为permissive模式 临时关闭selinux的
代码中加入 如下这样:

                List<string> commands = new List<string>();
                commands.Add("chmod 777 " + "/dev/input/event" + 1.ToString());
                commands.Add("chmod 777 " + "/dev/input/event" + 2.ToString());
                commands.Add("chmod 777 " + "/dev/input/event" + 3.ToString());
                commands.Add("chmod 777 " + "/dev/input/event" + 4.ToString());
                commands.Add("chmod 777 " + "/dev/input/event" + 5.ToString());
                commands.Add("chmod 777 " + "/dev/input/event" + 6.ToString());
                commands.Add("chmod 777 " + "/dev/input/event" + 7.ToString());
                commands.Add("chmod 777 " + "/dev/input/event" + 8.ToString());
                commands.Add("setenforce 0");
                ret = ShellUtils.execCommand(commands, true, true);

然后就可以愉快的打开设备了。

据了解SELinux 从4.3版本就已经集成了,默认permissive模式。
但安卓5.0又强化了一下,强制enforcing模式,导致这样的问题。
可能是保护机制吧。。

贴一下我找到原因的原文链接(可能访问要架梯子)
https://www.pocketmagic.net/programmatically-injecting-events-on-android-part-2/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现 Android 8bit 灰度图像的压缩,你可以使用 Android NDK中的libpng库来进行实现。以下是 JNI C/C++ 实现的步骤: 1. 在 JNI C/C++ 代码中,引入 libpng 库: ```c++ #include <png.h> ``` 2. 定义 compress 函数: ```c++ JNIEXPORT void JNICALL Java_com_example_example_MainActivity_compress(JNIEnv *env, jobject obj, jobject bitmap, jstring filePath) { // TODO: 实现压缩功能 } ``` 3. 获取 Android Bitmap 对象的信息,例如宽度、高度、像素格式等信息: ```c++ AndroidBitmapInfo info; AndroidBitmap_getInfo(env, bitmap, &info); int width = info.width; int height = info.height; int format = info.format; ``` 4. 将 Android Bitmap 转换为 libpng 中的 png_bytep 数组: ```c++ png_bytep* row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); for (int y = 0; y < height; y++) { row_pointers[y] = (png_byte*) malloc(info.stride); AndroidBitmap_getRow(env, bitmap, y, row_pointers[y], 0); } ``` 5. 打开 PNG 文件: ```c++ FILE *fp = fopen(filePath, "wb"); ``` 6. 初始化 PNG 压缩结构体: ```c++ png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_infop info_ptr = png_create_info_struct(png_ptr); setjmp(png_jmpbuf(png_ptr)); // 处理错误 png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); ``` 7. 写入 PNG 数据: ```c++ png_write_image(png_ptr, row_pointers); ``` 8. 完成 PNG 写入: ```c++ png_write_end(png_ptr, NULL); ``` 9. 释放内存: ```c++ for (int y = 0; y < height; y++) { free(row_pointers[y]); } free(row_pointers); fclose(fp); ``` 完整的 JNI C/C++ 代码如下: ```c++ #include <jni.h> #include <android/bitmap.h> #include <png.h> JNIEXPORT void JNICALL Java_com_example_example_MainActivity_compress(JNIEnv *env, jobject obj, jobject bitmap, jstring filePath) { AndroidBitmapInfo info; AndroidBitmap_getInfo(env, bitmap, &info); int width = info.width; int height = info.height; int format = info.format; png_bytep* row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); for (int y = 0; y < height; y++) { row_pointers[y] = (png_byte*) malloc(info.stride); AndroidBitmap_getRow(env, bitmap, y, row_pointers[y], 0); } const char *path = env->GetStringUTFChars(filePath, NULL); FILE *fp = fopen(path, "wb"); png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); png_infop info_ptr = png_create_info_struct(png_ptr); setjmp(png_jmpbuf(png_ptr)); png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, NULL); for (int y = 0; y < height; y++) { free(row_pointers[y]); } free(row_pointers); fclose(fp); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值