android系统级别硬件访问服务程序

2024-09-05 22:18

本文主要是介绍android系统级别硬件访问服务程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

硬件访问服务程序

实现一个硬件访问服务程序,需要
- 接口文件aidl
- service实现这个aidl
- SystemServer中注册这个服务
- service需要的jni文件
- OnLoad.cpp中添加jni文件
- hal 文件
- 相应的Android.mk

接口文件aidl

  • aidl的路径
  • aidl的写法
  • aidl的结果

aidl的路径

android系统的aidl文件在

/frameworks/base/core/java/android/os/IVibratorService.aidl
/frameworks/base/core/java/android/hardware/

这两个目录下都存在一些aidl文件。其他的目录下也存在一些aidl文件。
android.os下的aidl文件,通过其实现类,在SystemService中被调用,并添加到了ServiceManager中。同时通常能被应用程序通过getSystemService来访问使用。
在android.hardware下模块。通常允许应用程序调用andrid.hardware.xxx来实现相应的功能。例如开源的二维码扫描软件zxing,就利用android.hardware.camera来调用camera的相关接口。

aidl的写法

aidl内定义的是一些接口

package android.os;/** {@hide} */
interface IVibratorService
{boolean hasVibrator();void vibrate(int uid, String opPkg, long milliseconds, int usageHint, IBinder token);void vibratePattern(int uid, String opPkg, in long[] pattern, int repeat, int usageHint, IBinder token);void cancelVibrate(IBinder token);
}

首先需要指定包名。Vibrator位于android.os这个包下。
需要注意的是这些接口文件,需要使用/* {@hide} / 进行修饰一下
这些接口是隐藏的。

aidl的结果

将aidl文件放入
frameworks/base/core/java/android/os/目录下后,
修改framework/base/Android.mk 添加定义的aidl文件
使用 . build/envsetu.sh
lunch xxx
mmm framework/base

 将会在 /out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/

下生成 IVibratorService.java文件
生成的文件依然是一个interface类型的文件
内部还有一个静态的类。继承android.os.binder 并实现了 IVibratorService 这个接口

public interface IVibratorService extends android.os.IInterface{
public static abstract class Stub extends android.os.Binder implements android.os.IVibratorService
{}
}

android的编译系统自动帮助我们实现了binder机制,实现了这个interface。
必然存在一个文件实现这个interface

service来实现这个aidl

  • 代码的路径
/frameworks/base/services/core/java/com/android/server/VibratorService.java
  • 代码实现
public class VibratorService extends IVibratorService.Stubimplements InputManager.InputDeviceListener {//本地实现的方法 native static boolean vibratorExists();native static void vibratorOn(long milliseconds);native static void vibratorOff();//构造方法VibratorService(Context context) {// Reset the hardware to a default state, in case this is a runtime// restart instead of a fresh boot.vibratorOff();mContext = context;PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*vibrator*");mWakeLock.setReferenceCounted(true);mAppOpsService = IAppOpsService.Stub.asInterface(ServiceManager.getService(Context.APP_OPS_SERVICE));mBatteryStatsService = IBatteryStats.Stub.asInterface(ServiceManager.getService(BatteryStats.SERVICE_NAME));mVibrations = new LinkedList<Vibration>();IntentFilter filter = new IntentFilter();filter.addAction(Intent.ACTION_SCREEN_OFF);context.registerReceiver(mIntentReceiver, filter);}

SystemServer中注册这个服务

调用构造函数,同时将virbator添加到ServiceManager中

 VibratorService vibrator = null;
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);try {vibrator.systemReady();} catch (Throwable e) {reportWtf("making Vibrator Service ready", e);}

service需要的jni文件

在构造函数中调用了
vibratorOff(); 这个本地方法

这个本地的方法是在
/frameworks/base/services/core/jni/com_android_server_VibratorService.cpp
中实现的

     static jboolean vibratorExists(JNIEnv *env, jobject clazz){return vibrator_exists() > 0 ? JNI_TRUE : JNI_FALSE;}static void vibratorOn(JNIEnv *env, jobject clazz, jlong timeout_ms){// ALOGI("vibratorOn/n");vibrator_on(timeout_ms);}static void vibratorOff(JNIEnv *env, jobject clazz){// ALOGI("vibratorOff/n");vibrator_off();}static JNINativeMethod method_table[] = {{ "vibratorExists", "()Z", (void*)vibratorExists },{ "vibratorOn", "(J)V", (void*)vibratorOn },{ "vibratorOff", "()V", (void*)vibratorOff }};int register_android_server_VibratorService(JNIEnv *env){return jniRegisterNativeMethods(env, "com/android/server/VibratorService",method_table, NELEM(method_table));}

在jni中,可以知道最终调用的是 vibrator_off
这个vibrator_off 是在jni中实现的

OnLoad.cpp中添加jni文件

register_android_server_VibratorService(env);

hal

/hardware/libhardware/include/hardware/vibrator.h
/hardware/libhardware_legacy/vibrator/vibrator.c

在libhardware下的hal文件,形成的是libhardware.so这个动态库。

Context进行注册

    registerService(VIBRATOR_SERVICE, new ServiceFetcher() {public Object createService(ContextImpl ctx) {return new SystemVibrator(ctx);}});

应用程序的使用

vibrator=(Vibrator)getSystemService(Context.VIBRATOR_SERVICE);

其他

vibrator的java binder层面。在service部分,还有 binder的 死亡通知。
(还需要深入的理解)

总结

以上是从系统的角度来进行的硬件访问服务程序。

参考文献

Android震动vibrator系统开发全过程

这篇关于android系统级别硬件访问服务程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1140219

相关文章

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

JWT + 拦截器实现无状态登录系统

《JWT+拦截器实现无状态登录系统》JWT(JSONWebToken)提供了一种无状态的解决方案:用户登录后,服务器返回一个Token,后续请求携带该Token即可完成身份验证,无需服务器存储会话... 目录✅ 引言 一、JWT 是什么? 二、技术选型 三、项目结构 四、核心代码实现4.1 添加依赖(pom

基于Python实现自动化邮件发送系统的完整指南

《基于Python实现自动化邮件发送系统的完整指南》在现代软件开发和自动化流程中,邮件通知是一个常见且实用的功能,无论是用于发送报告、告警信息还是用户提醒,通过Python实现自动化的邮件发送功能都能... 目录一、前言:二、项目概述三、配置文件 `.env` 解析四、代码结构解析1. 导入模块2. 加载环

Android协程高级用法大全

《Android协程高级用法大全》这篇文章给大家介绍Android协程高级用法大全,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友跟随小编一起学习吧... 目录1️⃣ 协程作用域(CoroutineScope)与生命周期绑定Activity/Fragment 中手

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境

Linux查询服务器系统版本号的多种方法

《Linux查询服务器系统版本号的多种方法》在Linux系统管理和维护工作中,了解当前操作系统的版本信息是最基础也是最重要的操作之一,系统版本不仅关系到软件兼容性、安全更新策略,还直接影响到故障排查和... 目录一、引言:系统版本查询的重要性二、基础命令解析:cat /etc/Centos-release详

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

通过配置nginx访问服务器静态资源的过程

《通过配置nginx访问服务器静态资源的过程》文章介绍了图片存储路径设置、Nginx服务器配置及通过http://192.168.206.170:8007/a.png访问图片的方法,涵盖图片管理与服务... 目录1.图片存储路径2.nginx配置3.访问图片方式总结1.图片存储路径2.nginx配置

更改linux系统的默认Python版本方式

《更改linux系统的默认Python版本方式》通过删除原Python软链接并创建指向python3.6的新链接,可切换系统默认Python版本,需注意版本冲突、环境混乱及维护问题,建议使用pyenv... 目录更改系统的默认python版本软链接软链接的特点创建软链接的命令使用场景注意事项总结更改系统的默

SpringBoot集成EasyExcel实现百万级别的数据导入导出实践指南

《SpringBoot集成EasyExcel实现百万级别的数据导入导出实践指南》本文将基于开源项目springboot-easyexcel-batch进行解析与扩展,手把手教大家如何在SpringBo... 目录项目结构概览核心依赖百万级导出实战场景核心代码效果百万级导入实战场景监听器和Service(核心