IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android9.0系统中添加自定义系统服务给APP调用 -> 正文阅读

[移动开发]Android9.0系统中添加自定义系统服务给APP调用

软件平台:Android9.0

硬件平台:Mtk8175

? ? ? ? 近日开发了一个产品需求,APP端需要控制硬件LED灯,由于是多个APP需要调用,固计划将控制接口做成System Service级别的服务,APP可以通过跨进程调用相关的方法,话不多说,开干:

1、在frameworks/base/core/java/android/app/目录添加aidl接口文件,内容如下:

/**

* Lamp brightness controller

*/

package android.app;

interface IGeninLampManager {

? ? String getLampBrightness();

? ? void setLampSwitch(boolean switchOn);

? ? void setLampBrightness(int brightness);

? ? void setLampMode(int mode);

}

2、将该文件引入mk编译:

diff --git a/Android.bp b/Android.bp

index 282206126bc..1c2dadd6624 100644

--- a/Android.bp

+++ b/Android.bp

@@ -105,6 +105,7 @@ java_library {

?? ? ? ? "core/java/android/app/usage/ICacheQuotaService.aidl",

?? ? ? ? "core/java/android/app/usage/IStorageStatsManager.aidl",

?? ? ? ? "core/java/android/app/usage/IUsageStatsManager.aidl",

+? ? ? ? "core/java/android/app/IGeninLampManager.aidl",

?? ? ? ? ":libbluetooth-binder-aidl",

?? ? ? ? "core/java/android/content/IClipboard.aidl",

?? ? ? ? "core/java/android/content/IContentService.aidl",

3、创建注册系统级服务:

diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java

index 149af262441..4e016d92adb 100644

--- a/core/java/android/app/SystemServiceRegistry.java

+++ b/core/java/android/app/SystemServiceRegistry.java

@@ -31,6 +31,7 @@ import android.app.usage.IUsageStatsManager;

import android.app.usage.NetworkStatsManager;

import android.app.usage.StorageStatsManager;

import android.app.usage.UsageStatsManager;

+import android.app.GeninLampManager;

import android.appwidget.AppWidgetManager;

import android.bluetooth.BluetoothManager;

import android.companion.CompanionDeviceManager;

@@ -1002,6 +1003,16 @@ public final class SystemServiceRegistry {

?? ? ? ? ? ? ? ? ? ? }

?? ? ? ? ? ? ? ? });

+? ? ? ? registerService(Context.LAMP_MANAGER_SERVICE, GeninLampManager.class,

+? ? ? ? ? ? ? ? new CachedServiceFetcher<GeninLampManager>() {

+? ? ? ? ? ? ? ? @Override

+? ? ? ? ? ? ? ? public GeninLampManager createService(ContextImpl ctx) {

+? ? ? ? ? ? ? ? ? ? IBinder b = ServiceManager.getService(Context.LAMP_MANAGER_SERVICE);

+? ? ? ? ? ? ? ? ? ? IGeninLampManager service = IGeninLampManager.Stub.asInterface(b);

+? ? ? ? ? ? ? ? ? ? return new GeninLampManager(ctx, service);

+? ? ? ? ? ? ? ? }});

+

+

?? ? ? ? registerService(Context.SLICE_SERVICE, SliceManager.class,

?? ? ? ? ? ? ? ? new CachedServiceFetcher<SliceManager>() {

?? ? ? ? ? ? ? ? ? ? @Override

4、在frameworks/base/core/java/android/app/目录创建GeninLampManager.java

/**

* Lamp brightness controller

*/

package android.app;

import android.content.Context;

import android.os.RemoteException;

import android.util.Slog;

public class GeninLampManager {

? ? Context mContext;

? ? IGeninLampManager mService;

? ? static final String TAG = "GeninLampManager";

? ? public GeninLampManager(Context context, IGeninLampManager service) {

? ? ? ? mContext = context;

? ? ? ? mService = service;

? ? ? ? if (mService != null)

? ? ? ? ? ? Slog.d(TAG, " mService not null");

? ? }? ?

? ? public String getLampBrightness() {

? ? ? ? if (mService != null) {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? //Slog.d(TAG, " Will return getLampBrightness");

? ? ? ? ? ? ? ? return mService.getLampBrightness();

? ? ? ? ? ? } catch (RemoteException e) {

? ? ? ? ? ? ? ? Slog.d(TAG, "RemoteException " + e);

? ? ? ? ? ? ? ? return null;

? ? ? ? ? ? }? ?

? ? ? ? }? ?

? ? ? ? return null;

? ? }? ?

public void setLampSwitch(boolean switchOn) {

? ? ? ? if (mService != null) {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? //Slog.d(TAG, " Will setLampSwitch======");

? ? ? ? ? ? ? ? mService.setLampSwitch(switchOn);

? ? ? ? ? ? } catch (RemoteException e) {

? ? ? ? ? ? ? ? Slog.d(TAG, "RemoteException " + e);

? ? ? ? ? ? }? ?

? ? ? ? }

? ? }

? ? public void setLampMode(int mode) {

? ? ? ? if (mService != null) {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? //Slog.d(TAG, " Will setLampMode======");

? ? ? ? ? ? ? ? mService.setLampMode(mode);

? ? ? ? ? ? } catch (RemoteException e) {

? ? ? ? ? ? ? ? Slog.d(TAG, "RemoteException " + e);

? ? ? ? ? ? }

? ? ? ? }

? ? }

? ? public void setLampBrightness(int brightness) {

? ? ? ? if (mService != null) {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? //Slog.d(TAG, " Will setLampBrightness======");

? ? ? ? ? ? ? ? mService.setLampBrightness(brightness);

? ? ? ? ? ? } catch (RemoteException e) {

? ? ? ? ? ? ? ? Slog.d(TAG, "RemoteException " + e);

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

同aidl文件声明的方法相对应,并实现;

5、在Context.java文件添加Service的注册名称,APP通过这个名称获取远程调用代理:

diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java

index 90a94ee7608..1e2328419fe 100644

--- a/core/java/android/content/Context.java

+++ b/core/java/android/content/Context.java

@@ -4199,6 +4199,8 @@ public abstract class Context {

? ? ? */

?? ? public static final String CROSS_PROFILE_APPS_SERVICE = "crossprofileapps";

+? ? public static final String LAMP_MANAGER_SERVICE = "lampmanager";

+

?? ? /**

? ? ? * Use with {@link #getSystemService} to retrieve a

? ? ? * {@link android.se.omapi.ISecureElementService}

6、实现Service服务实体类:

frameworks/base/services/core/java/com/android/server/GeninLampManagerService.java:

package com.android.server;

import android.app.IGeninLampManager;

import android.content.Context;

import android.os.Build;

import android.util.Slog;

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.FileWriter;

import java.io.FileReader;

import java.io.IOException;

public class GeninLapManagerService extends IGeninLampManager.Stub {

? ? private Context mContext;

? ? static final String TAG = "GeninLampManagerService";

? ? private boolean Debug = false;

? ? private final int LEISURE_MODE = 1;

? ? private final int WRITE_MODE = 2;

? ? private final int NETWORK_MODE = 3;

? ? // 台灯控制节点

? ? static public final String LMAP_SWITCH_PATH = "/sys/bus/i2c/drivers/as9072/3-0011/as9072_debug/power"; //写1关灯,写2开灯

? ? static public final String LMAP_MODE_PATH = "/sys/bus/i2c/drivers/as9072/3-0011/as9072_debug/mode"; //写1 休闲模式;2 书写模式 ,3网课模式

? ? static public final String LMAP_BRIGHTNESS_PATH = "/sys/bus/i2c/drivers/as9072/3-0011/as9072_debug/brightness_level"; //写0x1-0xd 13个亮度级别;

? ? public GeninLampManagerService(Context context) {

? ? ? ? mContext = context;

? ? }? ?

? ? @Override

? ? public String getLampBrightness() {

? ? ? ? String brightness = null;

? ? ? ? BufferedReader reader = null;

? ? ? ? try {

? ? ? ? ? ? reader = new BufferedReader(new FileReader(LMAP_BRIGHTNESS_PATH));

? ? ? ? ? ? brightness = reader.readLine();

? ? ? ? ? ? if (Debug) {

? ? ? ? ? ? ? ? Slog.e("======", "read lamp brightness: " + brightness);

? ? ? ? ? ? }? ?

?? ? ? } catch (IOException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? } finally {

? ? ? ? ? ? if(reader != null){

? ? ? ? ? ? ? ? try {

? ? ? ? ? ? ? ? ? ? reader.close();

? ? ? ? ? ? ? ? } catch (IOException e) {

? ? ? ? ? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? return brightness;

? ? }

? ? @Override

? ? public void setLampBrightness(int brightness) {

? ? ? ? BufferedWriter bufWriter = null;

? ? ? ? try {

? ? ? ? ? ? bufWriter = new BufferedWriter(new FileWriter(LMAP_BRIGHTNESS_PATH));

? ? ? ? ? ? if (Debug)

? ? ? ? ? ? ? ? Slog.e(TAG,"write brightness:" + String.valueOf(brightness));

? ? ? ? ? ? bufWriter.write(String.valueOf(brightness));

? ? ? ? ? ? bufWriter.close();

? ? ? ? } catch (IOException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? }

? ? }

? ? @Override

? ? public void setLampMode(int mode) {

? ? ? ? BufferedWriter bufWriter = null;

? ? ? ? try {

? ? ? ? ? ? bufWriter = new BufferedWriter(new FileWriter(LMAP_MODE_PATH));

? ? ? ? ? ? if (mode == LEISURE_MODE) {

? ? ? ? ? ? ? ? if (Debug)

? ? ? ? ? ? ? ? ? ? Slog.e(TAG,"Go to 1 mode.");

? ? ? ? ? ? ? ? bufWriter.write("1");

? ? ? ? ? ? } else if (mode == WRITE_MODE){

? ? ? ? ? ? ? ? if (Debug)

?? ? ? ? ? ? ? ? ? Slog.e(TAG,"Go to 2 mode.");

? ? ? ? ? ? ? ? bufWriter.write("2");

? ? ? ? ? ? } else if (mode == NETWORK_MODE) {

? ? ? ? ? ? ? ? if (Debug)

? ? ? ? ? ? ? ? ? ? Slog.e(TAG,"Go to 3 mode.");

? ? ? ? ? ? ? ? bufWriter.write("3");

? ? ? ? ? ? }

? ? ? ? ? ? bufWriter.close();

? ? ? ? } catch (IOException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? Slog.e(TAG,"can't write the " + LMAP_MODE_PATH);

? ? ? ? }

? ? }

? ? @Override

? ? public void setLampSwitch(boolean switchOn) {

? ? ? ? BufferedWriter bufWriter = null;

? ? ? ? try {

? ? ? ? ? ? bufWriter = new BufferedWriter(new FileWriter(LMAP_SWITCH_PATH));

? ? ? ? ? ? if (switchOn) {

? ? ? ? ? ? ? ? bufWriter.write("2");? //ON

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? bufWriter.write("1");? //OFF

? ? ? ? ? ? }

? ? ? ? ? ? bufWriter.close();

? ? ? ? } catch (IOException e) {

? ? ? ? ? ? e.printStackTrace();

? ? ? ? ? ? Slog.e(TAG,"can't write the " + LMAP_SWITCH_PATH);

? ? ? ? }

? ? }

}

7、向SystemServer注册开机启动服务:

diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java

index b5274586d3b..640c141eac1 100644

--- a/services/java/com/android/server/SystemServer.java

+++ b/services/java/com/android/server/SystemServer.java

@@ -120,6 +120,7 @@ import com.android.server.usage.UsageStatsService;

import com.android.server.vr.VrManagerService;

import com.android.server.webkit.WebViewUpdateService;

import com.android.server.wm.WindowManagerService;

+import com.android.server.GeninLampManagerService;

import com.mediatek.server.MtkSystemServer;

@@ -1261,6 +1262,15 @@ public final class SystemServer {

?? ? ? ? ? ? }

?? ? ? ? ? ? traceEnd();

+? ? ? ? ? ? traceBeginAndSlog("StartGeninLampManagerService");

+? ? ? ? ? ? try {

+ ? ? ? ? ? ? ? Slog.i(TAG, "ClassMonitor Service is create");

+ ? ? ? ? ? ? ? ServiceManager.addService(Context.LAMP_MANAGER_SERVICE, new GeninLampManagerService(context));

+? ? ? ? ? ? } catch (Throwable e) {

+ ? ? ? ? ? ? ? reportWtf("starting ClassMonitorService", e);

+? ? ? ? ? ? }

+? ? ? ? ? ? traceEnd();

+

?? ? ? ? ? ? traceBeginAndSlog("StartNotificationManager");

?? ? ? ? ? ? mSystemServiceManager.startService(NotificationManagerService.class);

?? ? ? ? ? ? SystemNotificationChannels.createAll(context);

8、返回代码根目录,更新一下api,执行make update-api -j32命令,这个执行完毕,framework/base/api目录的current.txt会更新:

diff --git a/api/current.txt b/api/current.txt

index 65de90fdf8a..fc55efa1b56 100644

--- a/api/current.txt

+++ b/api/current.txt

@@ -4926,6 +4926,28 @@ package android.app {

?? ? field public static final int TRANSIT_UNSET = -1; // 0xffffffff

?? }

+? public class GeninLampManager {

+? ? ctor public GeninLampManager(android.content.Context, android.app.IGeninLampManager);

+? ? method public java.lang.String getLampBrightness();

+? ? method public void setLampBrightness(int);

+? ? method public void setLampMode(int);

+? ? method public void setLampSwitch(boolean);

+? }

+

+? public abstract interface IGeninLampManager implements android.os.IInterface {

+? ? method public abstract java.lang.String getLampBrightness() throws android.os.RemoteException;

+? ? method public abstract void setLampBrightness(int) throws android.os.RemoteException;

+? ? method public abstract void setLampMode(int) throws android.os.RemoteException;

+? ? method public abstract void setLampSwitch(boolean) throws android.os.RemoteException;

+? }

+

+? public static abstract class IGeninLampManager.Stub extends android.os.Binder implements android.app.IGeninLampManager {

+? ? ctor public IGeninLampManager.Stub();

+? ? method public android.os.IBinder asBinder();

+? ? method public static android.app.IGeninLampManager asInterface(android.os.IBinder);

+? ? method public boolean onTransact(int, android.os.Parcel, android.os.Parcel, int) throws android.os.RemoteException;

+? }

+

?? public class Instrumentation {

?? ? ctor public Instrumentation();

?? ? method public android.os.TestLooperManager acquireLooperManager(android.os.Looper);

@@ -10460,6 +10482,7 @@ package android.content {

?? ? field public static final java.lang.String IPSEC_SERVICE = "ipsec";

?? ? field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";

?? ? field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";

+? ? field public static final java.lang.String LAMP_MANAGER_SERVICE = "lampmanager";

?? ? field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";

?? ? field public static final java.lang.String LAYOUT_INFLATER_SERVICE = "layout_inflater";

?? ? field public static final java.lang.String LOCATION_SERVICE = "location";

到这一步,服务添加流程基本完成;

9、如何使用该服务接口:

在app的类文件导入服务类包名,然后通过servicemanager拿到代理,进行方法调用:

mManager = (GeninLampManager) mContext.getSystemService(Context.LAMP_MANAGER_SERVICE);

mManager.setLampBrightness(bright);

10、这一步至关重要,添加系统服务需要修改selinux规则,否则会无法操作内核的设备节点:

修改device/mediatek/sepolicy/bsp目录对应文件

diff --git a/non_plat/system_server.te b/non_plat/system_server.te

index 6565630..d9f627b 100644

--- a/non_plat/system_server.te

+++ b/non_plat/system_server.te

@@ -136,6 +136,10 @@ hal_client_domain(system_server,hal_dfps)

allow system_server mute_key_file:dir { search read };

allow system_server mute_key_file:file { read open getattr };

+# For system service lamp_mcu permission

+allow system_server mcu_file:dir { search read };

+allow system_server mcu_file:file { read write open getattr };

+

#============= system_server ==============

allow system_server audioserver:file write;

diff --git a/plat_private/service.te b/plat_private/service.te

index d1dcaab..58571c2 100644

--- a/plat_private/service.te

+++ b/plat_private/service.te

@@ -5,3 +5,4 @@

# Other Services

type aal_service, service_manager_type;

type mtk_connmetrics_service, service_manager_type;

+type genin_lamp_service, app_api_service, system_server_service, service_manager_type;

diff --git a/plat_private/service_contexts b/plat_private/service_contexts

index b2b0002..af224f9 100644

--- a/plat_private/service_contexts

+++ b/plat_private/service_contexts

@@ -28,6 +28,7 @@ search_engine_service ? ? ? ? ? ? ? ? ? u:object_r:mtk_search_engine_service:s0

duraspeed ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? u:object_r:mtk_duraspeed_service:s0

FullscreenSwitchService ? ? ? ? ? ? ? ? u:object_r:mtk_fullscreen_switch_service:s0

fm_radio_service? ? ? ? ? ? ? ? ? ? ? ? u:object_r:mtk_fm_radio_service:s0

+lampmanager ? ? ? ? ? ? ? ? ? ? ? ? ? ? u:object_r:genin_lamp_service:s0

# Other Services

GoogleOtaBinder ? ? ? ? ? ? ? ? ? ? ? ? u:object_r:ota_agent_service:s0

至此,添加完成~~~欢迎老细和张老师多提宝贵意见!

感谢!

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-23 10:54:40  更:2021-07-23 10:57:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 21:35:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码