Android APK 通过lib库直接与内核交互

这篇博客介绍了如何在Android应用中通过JNI封装的SO库直接与内核交互,跳过HAL层,简化了Android APK与底层系统的通信过程。内容包括lib库的创建、Android.mk文件的编写以及在APK中如何调用JNI接口实现通信。

1、lib库代码,这里直接将JNI封装成SO库,看情况是否需要实现HAL层,比较简单的可以省去HAL层,JNI直接与底层交互,JNI库命名需要以lib开头,这个库需要在system/etc/public.libraries.txt中公布一下,不然apk找不到。

#define LOG_TAG "GSensor"
#include <utils/Log.h>

#include <log/log.h>
#include <fcntl.h>
#include <errno.h>
#include <math.h>
#include <poll.h>
#include <unistd.h>
#include <dirent.h>
#include <stdlib.h>
#include <linux/input.h>
#include <sys/select.h>
#include <android/log.h> 
#include <cutils/log.h>
#include "jni.h"

#define GSENSOR_INPUT_NAME  "accelerometer" 
#define SYSFS_PATH_CLASS_INPUT "/sys/class/input/input"
#define SYSFS_NODE_STEP_VALUE "step_value"
#define SYSFS_NODE_STEP_CLEAN "step_clean"
 
static char input_sysfs_path[PATH_MAX] = {
   
   0};

int getInputNum(const char *InputName) {
   
   
  int num = -1;
  char filename[64];
  int err;
  char ev_name[64];
  int fd;

  for (int i = 0; i < 100; i++) {
   
   
    sprintf(filename, "/dev/input/event%d", i);
    fd = open(filename, O_RDONLY);

    if (fd >= 0) {
   
   
      err = ioctl(fd, EVIOCGNAME(sizeof(ev_name) - 1), &ev_name);
      ALOGD("get input device ev_name: %s", ev_name);

      if (err < 1)
        ev_name[0] = '\0';

      if (0 == strcmp(ev_name, InputName)) {
   
   
        num = i;
        close(fd);
        break;
      }

      close(fd);
    } else
      ALOGE("GSensor: open %s failed fd=%d\n", filename, fd);
  }

  return num;
}


static int  open_file_dev(JNIEnv *env, jobject thiz)
{
   
   
	int InputNum = -1;