Android11 给系统添加进程服务,并打包成jar包给apk调用
如果你很急,直接往下面看内容!!!!如果有耐心,慢慢看完收获会更大。
完成这个的时候我踩了好多个坑,经过各种尝试和验证才成功的,网上的资料大同小异,还没有一个人讲的很全面最坏的是,有人还特意挖坑,不知道别人跟着他验证一遍浪费多少时间 ,本人从aidl进程的编写,管理,配置,编译,服务集成的效果,最后自己写Demo验证,我会详细的把每个细节点都说清楚,让你的困哪此解决。
1、下面是给系统添加服务的整个逻辑和流程,我这么写也第一是让你们写完后思维上就明白了自己为啥这么做,第二是让你们集成后来排查有没有遗漏。①创建一个aidl用来定义方法接口 。
②创建Manager管理aidl的类,用来暴露这个接口给外部调用的。
③创建一个Service服务,继承aidl并实现里面的方法,到时候处理逻辑事务。
④在Context.java中添加变量,这里变量很重要,后面会讲到细节。
⑤在SystemServer.java中添加系统服务,把自己的服务添加到系统里面。
⑥在SystemServiceRegistry.java里面注册,注册后自己的管理类才有效。
⑦Android 11 添加Service服务SELinux的路径,这一步非常重要。
2、下面我开始按照步骤一步一步告诉你怎么做。①在frameworksasecorejavaandroidhardware目录下创建一个ITestManager.aidl ,这里有个细节就是这个接口上面必须写上hide这个方法,不然那编译会报错,这是因为AIDL自动生成的Java文件不满足Android 11 12 framework API的规范,(网友说了扒遍国内全网都没在找到,在Google中才找到的根本解决办法,添加@hide)就是报下面这个该死的错误
package android.hardware;/** {@hide} */interface ITestManager { String getName(); }②在frameworksasecorejavaandroidhardware目录下创建一个TestManager.java,这里类其实是做aidl和service的桥梁作用的,从外部调用的。
package android.hardware;import android.util.Slog;import android.os.RemoteException;import android.annotation.SystemService;import android.content.Context;import android.util.Log;import android.annotation.NonNull;public class TestManager { private final ITestManager mService;/** * @hide */ public TestManager(@NonNull Context context,ITestManager mService) { this.mService = mService; }/** * @hide */ public String getName() { try { Log.i("bll", "TestManager-getName");return mService.getName(); } catch (RemoteException ex) { ex.printStackTrace(); } }}③在frameworksaseservicescorejavacomandroidserver目录下创建一个TestService.java,这里就是写了一个系统服务,做逻辑的地方。
package com.android.server;import android.content.Context;import android.util.Slog;import android.hardware.ITestManager;import android.util.Log;public class TestService extends ITestManager.Stub { private final Context mContext; public TestService(Context context) { super(); mContext = context; } public String getName() { Log.i("bll", "TestService getName");return "请叫我齐天大圣熏悟空"; }}④在frameworksasecorejavaandroidcontentContext.java,这个文件里添加两个东西,第一个创建一个变量,第二个就是把变量名添加到 StringDef这个方法里面。
/** * Use with {@link #getSystemService} to retrieve a {@link * android.hardware.TestManager} for access to Cashier. * * @see #getSystemService * @see android.hardware.TestManager * * @hide */public static final String TEST_SERVICE = "test"; /** @hide */ @StringDef(suffix = { "_SERVICE" }, value = { TEST_SERVICE, })⑤在frameworksaseservicesjavacomandroidserverSystemServer.java,把自己写的TestService服务添加到系统里面。
//添加到这个方法里面 private void startOtherServices(@NonNull TimingsTraceAndSlog t) { t.traceBegin("startOtherServices"); final Context context = mSystemContext; //这三行是我添加的 t.traceBegin("TestService");ServiceManager.addService(Context.TEST_SERVICE, new TestService(context));t.traceEnd();}⑥在frameworksasecorejavaandroidappSystemServiceRegistry.java,把TestManager管理类在这里面注册。
//第一要记得导包import android.hardware.TestManager; import android.hardware.ITestManager;//第二 在这个static位置下面写注册private SystemServiceRegistry() { }static { //这个是我写的注册文件 registerService(Context.TEST_SERVICE,TestManager.class, new CachedServiceFetcher(){ @Override public TestManager createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(Context.TEST_SERVICE); Log.i("bll","SystemServiceRegistry registerService method"); return new TestManager(ctx,ITestManager.Stub.asInterface(b)); }});⑦Android 11 添加服务SELinux权限,这个地方把我给坑惨了,很多文章写的要么版本对不上路劲错了,还有的写的就跟狗屎一样不全,更坑逼的的人就是写错,或者直接忽略这一步,我都不知道他们是怎么编译过去的,还是故意坑人,这个地方配置不全,编译会有各种错误,不写编译出来的固件完全就没有这个系统服务,这个地方熬了我很久,终于摸索出来了,希望你们的坑再此填满。
在下面几个文件里面都得配置上这句话type test_service, system_api_service, system_server_service, service_manager_type;-------------------------------------------------------------------------------------systemsepolicyprebuiltsapi30.0publicservice.tesystemsepolicyprebuiltsapi29.0publicservice.tesystemsepolicyprebuiltsapi28.0publicservice.tesystemsepolicyprebuiltsapi27.0publicservice.tesystemsepolicyprebuiltsapi26.0publicservice.tesystemsepolicypublicservice.te *************************************************************************************在下面几个文件里面都得配置上这句话test u:object_r:test_service:s0-------------------------------------------------------------------------------------systemsepolicyprebuiltsapi30.0privateservice_contextssystemsepolicyprebuiltsapi29.0privateservice_contextssystemsepolicyprebuiltsapi28.0privateservice_contextssystemsepolicyprebuiltsapi27.0privateservice_contextssystemsepolicyprebuiltsapi26.0privateservice_contextssystemsepolicyprivateservice_contexts *************************************************************************************仔细看我的这句话,上面的service_contexts里面添加的 test这个名称必须跟Context.java 新增的TEST_SERVICE = "test";这个变量对应,不然的话这个服务就没有用,切记!!!
以上的操作几乎就是把服务配置写写好了,我也不知道踩了多少坑,错了多少步才完成的。
配置完以后在根目录执行 make update-api
等上面的命令执行完后再整编一次,把固件刷进机器用adb 命令看一下系统下面是否有这个服务。
先执行 adb shell 再执行 service list, 然后找到自己的服务,就算是集成OK了。
编译执行完后会产生一个jar包,每个版本的路径都会不同,Android11目录是在
out argetcommonobjJAVA_LIBRARIESframework-minus-apex_intermediates
里面有一个classes.jar。到这里整个系统服务的集成就算是完成了,后续把jar包集成到AndroidStudio工程里面去的时候,又有一些坑,如果你也有,可以看我的后续。