| |
|
开发:
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 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年4日历 | -2025/4/11 22:16:42- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |