前面文章讲述了Android APP怎么调用hal层的方法,和Android系统自带的灯光子系统类似;本文将讲述hal层如何回调APP应用接口,和android系统振动传感器数据上报类似,同时本文也会将App如何调用hal层接口进行再一次回顾,硬件环境基于amlogic的A311D,android系统9.0
一、首先定义frameworks/base/core/java/android/os/IXxxxListener.aidl回调函数接口,修改了该文件增加或者减少函数接口,需要先执行make update-api,再编译系统
package android.os;
/** {@hide} */
interface IXxxxListener
{
boolean xxxxReport(int param);
}
二、定义frameworks/base/core/java/android/os/IXxxxManager.aidl文件,定义APP控制hal层函数接口,同理增加或者减少函数接口,需要先执行make update-api,再编译系统,注视里面@hide关键字不能少(Android 框架的开发人员需要可见性为 public 或 protected 的类或成员,但又不希望这些方法成为开发者可用的 API,这就是 @hide 的用处了)

package android.os;
import android.os.IXxxxListener;
/** {@hide} */
interface IXxxxManager
{
void setOnListener(IPovodoListener iPovodoListener);
boolean xxxxOpen(); //打开操作
boolean setDevStatus(int status); //设置设备状态
}
在framework/base/Android.mk中添加aidl文件

 core/java/android/os/IVibratorService.aidl \core/java/android/os/IPovodoManager.aidl \core/java/android/os/IPovodoListener.aidl \

三、定义frameworks/base/services/core/java/com/android/server/XxxxService.java文件,实现Java层服务定义以及函数回调定义实现

import android.os.IXxxxManager;
import android.os.IXxxxListener;
import android.os.XxxxListener;
package com.android.server;import android.util.Slog;
import android.os.IXxxxManager;
import android.os.IXxxxListener;
import android.os.XxxxListener;
import android.os.Process;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.content.Context;
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import android.os.RemoteException;
public class XxxxService extends IXxxxManager.Stub {private static final String TAG = "XXXX_Service";static IXxxxListener mIXxxxListener;public XxxxService () {Slog.d(TAG, "--XxxxService--");}// --回调函数设置public static boolean xxxxReport(int param) {try {mIXxxxListener.xxxxReport(param);} catch (RemoteException e) {e.printStackTrace();}if (DEBUG_MODE) {Slog.d(TAG, "--xxxxReport-- end");}return true;}//控制函数设置// 打开设备public boolean xxxxOpen() throws android.os.RemoteException {return nativeXxxxOpen();}@Override  //该函数在APP中调用设置回调对象public void setOnListener(IXxxxListener iXxxxListener) {/** 将注册的回调通过集合来管理,可以实现多客户端 同时监听的功能。*/mIXxxxListener = iXxxxListener;}public boolean setDevStatus(int status);   //设置设备状态{return nativeSetDevStatus(status);}public static native boolean nativeXxxxOpen();public static native boolean nativeSetDevStatus(int status);
}

四、定义frameworks/base/core/java/android/os/XxxxListener.java文件,定义回调函数接口

package android.os;
import android.util.Slog;
import android.os.IXxxxListener;
import android.os.Process;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.content.Context;
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public interface XxxxListener {public  xxxxReport(int param);}

五、定义frameworks/base/core/java/android/os/XxxxListenerCallBack.java文件,实现Java层回调调用

package android.os;import android.os.XxxxListener;
import android.os.XxxxListener;import android.util.Slog;
import android.os.Process;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.content.Context;
import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class XxxxListenerCallBack extends IXxxxListener.Stub {private XxxxListener mXxxxListener;public XxxxListenerCallBack(XxxxListener xxxxListener) {mXxxxListener = xxxxListener;}@Overridepublic  boolean xxxxReport(int armId) throws RemoteException {return mXxxxListener.xxxxReport(int param) ;}}

六、在frameworks/base/services/java/com/android/server/SystemServer.java文件中,定义XxxxService

 private void startOtherServices() {...final Context context = mSystemContext;VibratorService vibrator = null;XxxxService xxxxService = null;....traceBeginAndSlog("StartXxxxService");xxxxService = new XxxxService();ServiceManager.addService("xxxx_service", xxxxService);traceEnd();.......}

在frameworks/base/core/java/android/content/Context.java文件中定义服务名

 public static final String VIBRATOR_SERVICE = "vibrator";public static final String XXXX_SERVICE = "xxxx_service";

在frameworks/base/core/java/android/app/SystemServiceRegistry.java文件中添加添加注册服务

 .....import android.os.IXxxxManager;import android.os.XxxxManager;.....registerService(Context.XXXX_SERVICE, XxxxManager.class,new CachedServiceFetcher<XxxxManager>() {@Overridepublic XxxxManager createService(ContextImpl ctx)throws ServiceNotFoundException {IXxxxManager service = IXxxxManager.Stub.asInterface(ServiceManager.getServiceOrThrow(Context.XXXX_SERVICE));return new XxxxxManager(service);}});

七,至此Java层的工作完成,剩下的就是jni和hal层的工作,在frameworks/base/services/core/jni/onload.cpp文件中定义jvm并初始化

 ...JavaVM* g_jvm;....
namespace android {int register_android_server_XxxxService(JNIEnv* env);
};
extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
{JNIEnv* env = NULL;jint result = -1;g_jvm = vm;if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {ALOGE("GetEnv failed!");return result;}ALOG_ASSERT(env, "Could not retrieve the env!");....register_android_server_XxxxService(env);....}

修改frameworks/base/services/core/jni/Android.mk

$(LOCAL_REL_DIR)/com_android_server_VibratorService.cpp \
$(LOCAL_REL_DIR)/com_android_server_PovodoService.cpp \

创建frameworks/base/services/core/jni/com_android_server_XxxxService.cpp

#include <jni.h>
#include <nativehelper/JNIHelp.h>
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/xxxx_hal.h>
#include <hardware/xxxx_callback.h>
#include <pthread.h>
#include <stdio.h>
#include <hardware/xxxx_common.h>struct xxxx_device_t *xxxx_dev;
struct xxxx_callback_t xxxx_callBack;
_JNIEnv *g_jenv; //native线程env对象
jobject g_jobj;  //全局对象
extern JavaVM *g_jvm;
using namespace FrameWork;
namespace android
{
jmethodID  xxxxReport_jmd; //java方法id,可以根据实际情况创建多个
bool xxxxReportCallBack(int armId); //回调函数定义//定义结构体
class WlListener
{
public:WlListener(JavaVM *vm, _JNIEnv *jenv, jobject obj);~WlListener();
};
WlListener *wlListener;
//定义构造函数
WlListener::WlListener(JavaVM *vm, _JNIEnv *env, jobject obj)
{//初始化回调函数xxxx_callBack.xxxxReport = xxxxReportCallBack;//获取类classjclass clz = env->FindClass("com/android/server/XxxxService");if (clz == NULL){ALOG(LOG_DEBUG, LOG_TAG, "get jclass wrong");}//获取方法IDxxxxReport_jmd= env->GetStaticMethodID(clz, "xxxxReport ", "(I)Z");if (!xxxxReport_jmd){ALOG(LOG_DEBUG, LOG_TAG, "get xxxxReport_jmdwrong");}
}bool xxxxReport (int param) //回调函数定义
{//实现函数return true;
}
pthread_t callBackThreadPid;
//线程执行函数
void *threadFunc(void *data)
{//在子线程中调用回调方法JNIEnv *env;ALOG(LOG_DEBUG, LOG_TAG, "threadFunc start....");g_jvm->AttachCurrentThread(&env, 0);jclass clz = env->GetObjectClass(g_jobj);if (clz == 0){ALOG(LOG_DEBUG, LOG_TAG, "get jclass wrong2");return NULL;}ALOG(LOG_DEBUG, LOG_TAG, "threadFunc start listen....");while (1){env->CallStaticBooleanMethod(clz, xxxxReport_jmd, 11);  //11表示回调函数参数,这里任意写的}}//jni和hal层接口初始化,该函数一般只调用一次
static jboolean xxxxOpen(JNIEnv *env, jobject thiz)
{hw_module_t *module;hw_device_t *device;jint err;static int sFirstInitFlag = 0;if (sFirstInitFlag == 0){//JavaVM是虚拟机在JNI中的表示,其他线程回调java层需要用到env->GetJavaVM(&g_jvm);// 生成一个全局引用保留下来,以便回调g_jobj = env->NewGlobalRef(thiz);err = hw_get_module(XXXX_HARDWARE_MODULE_ID, (hw_module_t const **)&module); //获取到对应的hal中的modules对象,第一个参数为hal层中的idif (err == 0){ALOG(LOG_DEBUG, LOG_TAG, "--xxxxOpen successful--");module->methods->open(module, NULL, &device); //获取到hal中的device信息xxxx_dev = (struct xxxx_device_t *)device;xxxx_dev->setCallBackFunc(&xxxx_callBack); //设置回调参数wlListener = new WlListener(g_jvm, env, env->NewGlobalRef(thiz));}pthread_create(&callBackThreadPid, NULL, threadFunc, NULL);ALOG(LOG_DEBUG, LOG_TAG, "--xxxxOpen succeed--");sFirstInitFlag = 1;return true;}else{ALOG(LOG_DEBUG, LOG_TAG, "--xxxxOpen error--");return false;}ALOG(LOG_DEBUG, LOG_TAG, "--xxxxOpen alread open--");return true;
}
//APP调用hal层函数定义
static jboolean setDevStatus(JNIEnv *env, jobject thiz, int status)
{if (DEBUG_MODE)ALOG(LOG_DEBUG, LOG_TAG, "--setDevStatus--");return xxxx_dev->setDevStatus(status);
}
static JNINativeMethod method_table[] = {
{"nativeXxxxOpen", "()Z", (void *)xxxxOpen}, //第二个参数()参数个数,I-返回值类型
{"nativeSetDevStatus", "(I)Z", (void *)setDevStatus},
}
int register_android_server_XxxxService(JNIEnv *env)
{return jniRegisterNativeMethods(env, "com/android/server/XxxxService",method_table, NELEM(method_table));
}
}  ;

八、创建hardware/libhardware/include/hardware/xxxx_callback.h
//自定义一个对外的结构体

struct xxxx_callback_t
{bool (*xxxxReport)(int param);
};

创建hardware/libhardware/include/hardware/xxxx_hal.h

#include "xxxx_callback.h"
#define XXXX_HARDWARE_MODULE_ID "xxxx"//自定义一个对外的结构体
struct xxxx_device_t
{struct hw_device_t xxxx_device;bool (*setCallBackFunc)(struct xxxx_callback_t *pCallBack);bool (*setDevStatus)(int status);
};
boolean setDevStatus(int status);   //设置设备状态

创建hardware/libhardware/modules/xxxx/xxxx_hal.c

#include <hardware/xxxx_hal.h>
#include <hardware/xxxx_callback.h>
struct xxxx_callback_t *g_xxxxCallBack = NULL;
static struct xxxx_device_t xxxx_dev ={.xxxx_device ={.tag = HARDWARE_DEVICE_TAG,},.setCallBackFunc = setCallBackFunc,.setDevStatus = setDevStatus,};//设置回调函数
bool setCallBackFunc(struct xxxx_callback_t *pCallBack)
{g_xxxxCallBack = pCallBack;return true;
}
static int xxxxHalOpen(const struct hw_module_t *module, char const *id, struct hw_device_t **device)
{(void)module;(void)id;static sFirstInitflagif (sFirstInitflag== 0){*device = (struct hw_device_t *)(&xxxx_dev);//执行一系列hal层的初始化工作,比如初始化串口,保存日志初始化等等}else{sFirstInitflag  == 1;}}//APP调用hal层接口bool setDevStatus(int status){return true;}
//hal层回调APP接口
bool xxxxReport(int param)
{g_xxxxCallBack->xxxxReport(11);   //是参数,根据需要设置
}
//定义HAL_MODULE_INFO_SYM,并对其进行初始化
static hw_module_methods_t xxxx_methods ={.open = xxxxHalOpen,
};struct hw_module_t HAL_MODULE_INFO_SYM ={.tag = HARDWARE_MODULE_TAG,.id = XXXX_HARDWARE_MODULE_ID, //该id起到了承上启下的作用,硬件服务层会匹配该id,一般这里使用宏定义(VIBRATOR_HARDWARE_MODULE_ID),不然可能会出错.author = "yujd",.methods = &xxxx_methods,
};

添加hal模块编译信息
hardware/libhardware/modules/Android.mk

build/target/product/generic_no_telephony.mk(不添加的话,默认不会编译生成so库)

做到这步,系统层的工作完成,接下来写测试APP进行测试,测试之前需要先编译系统,生成class.jar包导入到APP工程,编译过程和导入方法在上篇文章有详细介绍,文件路径(out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar
out/target/common/obj/JAVA_LIBRARIES/services_intermediates/classes.jar)
九、编写测试APP

package com.xxxx.yujd;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Context;
import android.os.XxxxListener;   //导入自定义服务类
import android.os.XxxxManager;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.util.Log;
import java.text.DecimalFormat;
import java.util.List;
import java.util.ArrayList;
import android.app.Dialog;
import android.app.Person;
import android.app.AlertDialog;
public class MainActivity extends AppCompatActivity implements View.OnClickListener, XxxxListener{private XxxxManager mXxxxManager = null;//初始化服务对象mXxxxManager = (XxxxManager)getSystemService(Context.XXXX_SERVICE);//IXxxxManager.Stub.asInterface(ServiceManager.getService("xxxx_service"));if (mXxxxManager == null) {Log.i("Xxxx_APP--", "get servcie error");}else{Log.i("Xxxx_APP--", "get servcie success");}mXxxxManager.setOnListener(this);  //设置回调监听对象//打开初始化设备if(mXxxxManager.xxxxOpen() == true){Log.i("Xxxx_APP", "open successful");}else{Log.i("Xxxx_APP", "open error");}//调用hal层方法if(mXxxxManager.setDevStatus(1) == true){Log.i("Xxxx_APP", "setDevStatus  successful");}else{Log.i("Xxxx_APP", "setDevStatus error");}//回调函数-当hal层调用xxxxReport函数调用时,APP层函数xxxxReport就会被调用public boolean xxxxReport(int param ){Log.i("Xxxx_APP","xxxxReport:"  + param);return true;}}

到此整个回调流程完成了,如果不准确的地方,欢迎指点,交流QQ:1308418494

Android Hal层回调APP应用接口相关推荐

  1. Android Hal层简要分析

    Android Hal层简要分析 Android Hal层(即 Hardware Abstraction Layer)是Google开发的Android系统里上层应用对底层硬件操作屏蔽的一个软件层次, ...

  2. Android HAL 层,三个重要的结构体的源码~

    最近在学习android HAL 层 ~ 离不开这三个数据结构~~先贴出来 typedef struct hw_module_t {     /** tag must be initialized t ...

  3. Android 系统(4)---Android HAL层与Linux Kernel层驱动开发简介

    Android HAL层与Linux Kernel层驱动开发简介 近日稍微对Android中的驱动开发做了一些简要的了解,稍稍理清了一下Android驱动开发的套路,总结一下笔记. HAL:Hardw ...

  4. Android HAL层与Linux Kernel层驱动开发简介

    Android HAL层与Linux Kernel层驱动开发简介 阅读数:5070 近日稍微对Android中的驱动开发做了一些简要的了解,稍稍理清了一下Android驱动开发的套路,总结一下笔记. ...

  5. Android hal 层 C 堆栈打印方法

    Android hal 层 C 堆栈打印方法 一.添加CallStack文件 在hardware/qcom/audio/hal/ 下添加 callstack.cpp 和 callstack.h文件 # ...

  6. 【转】android hal 层GPS 研究总结——关于GPS GGA/GSV/RMC 数据的解析

    [转]android hal 层GPS 研究总结 2011-09-22 快跑的未必能赢,力战的未必获胜,聪明的未必得粮食,明哲的未必得资财,灵活的未必得喜悦.所临到世人的,是在乎当时的机会. 人生一世 ...

  7. aidl android 怎么mk编译,使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序

    先实现HIDL,打通从HAL到framework层 可以把自己的HIDL模块建立在hardware/interfaces/.frameworks/hardware/interfaces/. syste ...

  8. Android HAL层分析 (gralloc显示模块 举例)

     Android的HAL是为了保护一些硬件提供商的知识产权而提出的,是为了避开linux的GPL束缚.思路是把控制硬件的动作都放到了Android HAL中,而linux driver仅仅完成一些 ...

  9. Android HAL层浅析

    文章目录 1.HAL层在Android系统中的位置 2.HAL层概述 3.旧的HAL架构module 4.新的HAL架构module stub 5.HAL Stub框架分析 1.HAL层在Androi ...

最新文章

  1. Java.util.Date.getTime()出现负数的问题
  2. 动画 java_Java动画程序介绍
  3. e盾服务端源码_gRPC服务注册发现及负载均衡的实现方案与源码解析
  4. UVA4671 K-neighbor substrings FFT+字符串hash
  5. 收藏 | Kaggle神器LightGBM最全解读!
  6. [00011]-[2015-08-26]-[00]-[Windows 程序设计 ---MFC 截屏---BMP格式 ---JPG格式]
  7. 华为多臂路由_华为单臂路由配置
  8. java求两个时间相差月_java计算两个时间相差几个月
  9. 我们玩游戏,还是游戏玩我们……
  10. 在多个浏览器中添加IDM插件
  11. 本特利振动探头177230-01-01-CN
  12. java实现PDF转tif格式并且设置颜色和dpi
  13. 一招解决网页文字无法复制
  14. 川西云南行散记之五《稻城-亚丁-洛绒牛场》
  15. PCA主成分分析去噪与降维
  16. pycharm读取CSV文件
  17. java获取小数位数_Java获取小数位数 | 学步园
  18. 完成全球90万人工智能集装箱箱况残损检验,集装箱人工智能垂直领域领军者,中集集团人工智能企业中集飞瞳领跑全球港口航运人工智能AI
  19. 关于urllib2.urlopen()的理解
  20. 【java】SSM框架浅薄理解

热门文章

  1. 博客园添加导航目录(转)
  2. css 实现图片间用间隔线(竖线)
  3. 关于简历,网申,笔试,面试过程的分享
  4. 商业广告CPT-物料召回
  5. mybatis-plus,sgg,杨bochao
  6. 我们都是被上帝咬过的苹果
  7. 树莓派插入耳机孔之后不能播放声音
  8. python做excel数据条件_懂点EXCEL就行!教你利用Python做数据筛选(上)
  9. Pikachu靶场暴力破解关卡3
  10. 10首现代诗歌欣赏:什么是孤独