Android framework 中间件开发(一)

news2025/5/18 2:33:27

        在Android开发中,经常会调用到一些系统服务,这些系统服务简化了上层应用的开发,这便是中间件的作用,中间件是介于系统和应用之间的桥梁,将复杂的底层逻辑进行一层封装,供上层APP直接调用,或者将一些APP没有权限一些操作放到中间件里面来实施.

        假设一个需求,通过中间件调节系统亮度,这边我们使用DisplayManager来调节亮度,DisplayManager在上层应用中是获取不到setBrightness函数的,但是在中间件中可以,这便是中间件的作用.
        这里我将一步一步展示中间件开发的步骤:

总共分为三部分:

        Android framework 中间件开发(一)

        Android framework 中间件开发(二)

        Android framework 中间件开发(三)

目录

        1.定义接口文件

        2.实现接口 

        3.添加到系统服务

        4.定义代表服务的字符串

        5.定义外部控制类

        6.实例化

        7.添加权限

        8.编译源码

        9.调用中间件


        1.定义接口文件

        frameworks\base\core\java\android\路径下新建一个文件夹,名字为"darkcontrol",在文件夹中新建一个文件,名字为IDarkControlManager.aidl,里面定义一个函数,传入需要调节的亮度值(0~1),内容如下

package android.darkcontrol;

/** {@hide} */
interface IDarkControlManager{

    void setBright(float bright);

}

 注意:这边开头的/** {@hide} */不能少,要不然会编译不通过

        2.实现接口 

         frameworks\base\services\core\java\com\android\server\路径下新建文件,名字为DarkControlService.java,实现IDarkControlManager里面的接口

package com.android.server;

import static android.view.Display.DEFAULT_DISPLAY;
import android.content.Context;
import android.util.Log;
import android.hardware.display.DisplayManager;
import android.os.PowerManager;

import android.darkcontrol.IDarkControlManager;

public class DarkControlService extends IDarkControlManager.Stub {

    private final String TAG = "--==>>DarkControlService";

    private final Context mContext;
    private float maxBrightness = 1;
    private float minBrightness = 0;

    private DisplayManager mDisplayManager;
    private PowerManager mPowerManager;

    public DarkControlService(Context context) {
        mContext = context;
        Log.i(TAG, "DarkControlService init");

        mDisplayManager = context.getSystemService(DisplayManager.class);
        mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        
        maxBrightness = mPowerManager.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MAXIMUM);
        minBrightness = mPowerManager.getBrightnessConstraint(PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_MINIMUM);
    }

    /**
     * 设置亮度
     *
     * @param bright 0~1
     */
    @Override
    public void setBright(float bright) {
        Log.i(TAG, "setBright: " + bright);
        if (bright > 1) {
            bright = 1;
        }
        if (bright < 0) {
            bright = 0;
        }

        float brightness = (maxBrightness - minBrightness) * bright;

        setBrightnessToSystem(brightness );
    }

    //设置亮度到系统
    private void setBrightnessToSystem(float brightness) {
        Log.i(TAG, "setBrightnessToSystem: " + brightness);
        // 设置系统亮度
        mDisplayManager.setBrightness(DEFAULT_DISPLAY, brightness);
        
    }

}

        到这里我们需要的业务逻辑基本完成了, 接下来在系统中注册我们的服务.

        3.添加到系统服务

        frameworks\base\services\java\com\android\server\SystemServer.java
        在startOtherServices函数中添加

这些就按照系统原有的服务添加即可.

        4.定义代表服务的字符串

        frameworks\base\core\java\android\content\Context.java
文件中定义字符串,这边的字符串内容要和SystemServer中addService中的一致

        5.定义外部控制类

        frameworks\base\core\java\android\darkcontrol\路径下新建文件,名字为DarkControlManager.java,内容如下:

package android.darkcontrol;

import android.annotation.SystemService;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.darkcontrol.IDarkControlManager;

@SystemService(Context.DARK_CONTROL_SERVICE)
public class DarkControlManager {

    private final String TAG = "--==>>DarkControlManager";

    private final Context mContext;
    private final IDarkControlManager mService;

    /**
     * {@hide}
     */
    public DarkControlManager(Context context) {
        mContext = context;
        mService = IDarkControlManager.Stub.asInterface(ServiceManager.getService(Context.DARK_CONTROL_SERVICE));
    }

    /**
     * 设置亮度
     *
     * @param bright 0~1
     */
    public void setBright(float bright){
        try {
            mService.setBright(bright);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

注意:1.开头的@SystemService(Context.DARK_CONTROL_SERVICE)

        2.调用services中的函数需要包裹一层try{}catch(){};

        6.实例化

        frameworks\base\core\java\android\app\SystemServiceRegistry.java
在SystemServiceRegistry文件中,找到开头的static{}代码块,实例化DarkControlManager

至此,中间件开发已经完成一半了.接下来的都是体力活...

        7.添加权限

        system/sepolicy/路径下,添加权限,总共41个文件.挨个添加

这些文件中的权限添加方式都差不多,大致分为一下几种,照着系统的抄就行,注意版本号的改动

*\service_contexts:

*\system_server.te

*\service.te

*\*.cil(注意这边的28,每个文件中的不一样)

到这里就中间件全部完成了

        8.编译源码

        不出意外,编译过程会出现这个error的情况:

        意思是修改了API,需要更新下,执行一下这行:

m api-stubs-docs-non-updatable-update-current-api

 然后再重新编译一下就行了

        9.调用中间件

        调用方式为getSystemService

注意不能直接new中间件对象,因为系统启动时已经new了一个对象了,这边不要重复new,使中间件保持单例.

下一篇:打包中间件

Android framework 中间件开发(二)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2378158.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MATLAB中的概率分布生成:从理论到实践

MATLAB中的概率分布生成&#xff1a;从理论到实践 引言 MATLAB作为一款强大的科学计算软件&#xff0c;在统计分析、数据模拟和概率建模方面提供了丰富的功能。本文将介绍如何使用MATLAB生成各种常见的概率分布&#xff0c;包括均匀分布、正态分布、泊松分布等&#xff0c;并…

C# 面向对象 构造函数带参无参细节解析

继承类构造时会先调用基类构造函数&#xff0c;不显式调用基类构造函数时&#xff0c;默认调用基类无参构造函数&#xff0c;但如果基类没有写无参构造函数&#xff0c;会无法调用从而报错&#xff1b;此时&#xff0c;要么显式的调用基类构造函数&#xff0c;并按其格式带上参…

在 C# 中将 DataGridView 数据导出为 CSV

在此代码示例中&#xff0c;我们将学习如何使用 C# 代码将 DataGridView 数据导出到 CSV 文件并将其保存在文件夹中。 在这个程序中&#xff0c;首先&#xff0c;我们必须连接到数据库并从中获取数据。然后&#xff0c;我们将在数据网格视图中显示该数据&#xff0c;…

MySQL中表的增删改查(CRUD)

一.在表中增加数据&#xff08;Create&#xff09; INSERT [INTO] TB_NAME [(COLUMN1,COLUMN2,...)] VALUES (value_list1),(value_list2),...;into可以省略可仅选择部分列选择插入&#xff0c;column即选择的列&#xff0c; 如图例可以选择仅在valuelist中插入age和id如果不指…

项目思维vs产品思维

大家好&#xff0c;我是大明同学。 这期内容&#xff0c;我们来聊一下项目思维和产品思维的区别。 项目是实施关键&#xff0c;力求每一步都精准到位&#xff1b;产品则是战略导向&#xff0c;确保所选之路正确无误。若缺乏优异成果&#xff0c;即便按时完成&#xff0c;也只…

游戏引擎学习第285天:“Traversables 的事务性占用”

回顾并为当天的工作做准备 我们有一个关于玩家移动的概念&#xff0c;玩家可以在点之间移动&#xff0c;而且当这些点移动时&#xff0c;玩家会随之移动。现在这个部分基本上已经在工作了。我们本来想实现的一个功能是&#xff1a;当玩家移动到某个点时&#xff0c;这个点能“…

文件上传Ⅲ

#文件-解析方案-执行权限&解码还原 1、执行权限 文件上传后存储目录不给执行权限&#xff08;即它并不限制你上传文件的类型&#xff0c;但不会让相应存有后门代码的PHP文件执行&#xff0c;但是PNG图片是可以访问的&#xff09; 2、解码还原 数据做存储&#xff0c;解…

基于深度学习的工业OCR数字识别系统架构解析

一、项目场景 春晖数字识别视觉检测系统专注于工业自动化生产监控、设备运行数据记录等关键领域。系统通过高精度OCR算法&#xff0c;能够实时识别设备上显示的关键数据&#xff08;如温度、压力、计数等&#xff09;&#xff0c;并定时存储至Excel文件中。这些数据对于生产过…

go-中间件的使用

中间件介绍 Gin框架允许开发者在处理请求的过程中加入用户自己的钩子(Hook)函数这个钩子函数就是中间件&#xff0c;中间件适合处理一些公共的业务逻辑比如登录认证&#xff0c;权限校验&#xff0c;数据分页&#xff0c;记录日志&#xff0c;耗时统计 1.定义全局中间件 pac…

学习以任务为中心的潜动作,随地采取行动

25年5月来自香港大学、OpenDriveLab 和智元机器人的论文“Learning to Act Anywhere with Task-centric Latent Actions”。 通用机器人应该在各种环境中高效运行。然而&#xff0c;大多数现有方法严重依赖于扩展动作标注数据来增强其能力。因此&#xff0c;它们通常局限于单一…

15.springboot-控制器处理参数传递

22.springMVC Spring MVC 是非常著名的 Web 应用框架&#xff0c;现在的大多数 Web 项目都采用 Spring MVC。它与 Spring 有着紧 密的关系。是 Spring 框架中的模块&#xff0c;专注 Web 应用&#xff0c;能够使用 Spring 提供的强大功能&#xff0c;IoC , Aop 等等。 Spring…

半成品的开源双系统VLA模型,OpenHelix-发表于2025.5.6

半成品的开源双系统VLA模型&#xff0c;OpenHelix https://openhelix-robot.github.io/ 0. 摘要 随着OpenVLA的开源&#xff0c;VLA如何部署到真实的机器人上获得了越来越多的关注&#xff0c;各界人士也都开始尝试解决OpenVLA的效率问题&#xff0c;双系统方案是其中一个非…

网站推荐(第四期)

好久没有推荐过网站了&#xff0c;重拾推荐一波&#xff0c;最近发现这几个确实不错。 某火箭共享账号 官网&#xff1a;https://id.bocchi.vip/ 苹果用户专用&#xff0c;都是买了某火箭的账号&#xff0c;懂得都懂。 这玩意竟然还是个开源项目&#xff0c;项目地址&#x…

2024 睿抗机器人开发者大赛CAIP-编程技能赛-专科组(国赛)解题报告 | 珂学家

前言 题解 2024 睿抗机器人开发者大赛CAIP-编程技能赛-专科组&#xff08;国赛&#xff09;&#xff0c;陈越姐姐出题。 国赛比省赛&#xff0c;难度增强了不少&#xff0c;题目就剩下4个题了。 涉及堆栈&#xff0c;hash表&#xff0c;优先队列等高阶数据结构的使用&#x…

git工具使用详细教程-------命令行和TortoiseGit图形化

下载 git下载地址&#xff1a;https://git-scm.com/downloads TortoiseGit&#xff08;图形化工具&#xff09;下载地址&#xff1a;https://tortoisegit.org/download/ 认识git结构 工作区&#xff1a;存放代码的地方 暂存区&#xff1a;临时存储&#xff0c;将工作区的代码…

Mysql新增

插入一个记录需要的时间由下列因素组成&#xff0c;其中的数字表示大约比例&#xff1a; 连接&#xff1a;(3)发送查询给服务器&#xff1a;(2)分析查询&#xff1a;(2)插入记录&#xff1a;&#xff08;1x记录大小&#xff09;插入索引&#xff1a;&#xff08;1x索引&#x…

AI Agent开发第64课-DIFY和企业现有系统结合实现高可配置的智能零售AI Agent(上)

开篇 我们之前花了将近10个篇章讲Dify的一些基础应用,包括在讲Dify之前我们讲到了几十个AI Agent的开发例子,我不知道大家发觉了没有,在AI Agent开发过程中我们经常会伴随着这样的一些问题: 需要经常改猫娘;需要经常改调用LLM的参数,甚至在一个流程中有3个节点,每个节点…

【嵌入式】记一次解决VScode+PlatformIO安装卡死的经历

PlatformIO 是开源的物联网开发生态系统。提供跨平台的代码构建器、集成开发环境&#xff08;IDE&#xff09;&#xff0c;兼容 Arduino&#xff0c;ESP8266和mbed等。 开源库地址&#xff1a;https://github.com/platformio 在 VScode 中配置 PlatformIO 插件&#xff0c;记录…

MySQL 事务(一)

文章目录 CURD不加控制&#xff0c;会有什么问题CURD满足什么属性&#xff0c;能解决上述问题&#xff1f;什么是事务为什么要有事务事务的版本支持了解事务的提交方式 事务常见操作方式研究并发场景事务的正常操作事务的非正常情况的案例结论事务操作的注意事项 CURD不加控制&…

【全解析】EN 18031标准下的 AUM 身份认证机制[下篇]

在上篇文章中&#xff0c;我们详细介绍了EN 18031标准中AUM身份认证机制的AUM - 1、AUM - 2和AUM - 3条款。今天&#xff0c;我们将继续深入探讨AUM - 4到AUM - 6的相关内容&#xff0c;进一步了解该标准如何保障无线电设备的身份认证安全。 一、AUM - 4&#xff1a;更改认证器…