android 5.1 添加自定义的SystemServer服务

    某些情况下,在系统研发时,需要加入自定义的SystemServer服务,以便为应用提供自定义的功能。

    下面介绍如果添加自定义的SystemServer系统服务。

    本示例基于Android 5.1版本,如果是其他的android版本,可参考。

    以自定义DDTS服务为例,步骤如下:

1、创建自定义服务的aidl文件

    创建aidl文件目录:frameworks/base/core/java/android/app

    在上面的目录下,创建IDDTSManager.aidl文件,aidl文件中定义需要服务实现的接口

package android.app;

interface IDDTSManager {
    boolean setValue(boolean val);
    boolean getValue();
}

2、把aidl文件添加到Android.mk中参与编译

   打开文件:frameworks/base/Android.mk

   在“LOCAL_SRC_FILES”变量中添加aidl的文件。建议找到“app”目录对应的分类,并在后面添加,这样代码工整点。

LOCAL_SRC_FILES += \
    ......
    core/java/android/app/backup/IRestoreSession.aidl \
    core/java/android/app/usage/IUsageStatsManager.aidl \
    core/java/android/app/IDDTSManager.aidl \
    core/java/android/wipower/IWipower.aidl \

3、创建DDTSManagerService.java文件实现IDDTSManager.aidl中定义的接口

    创建目录:frameworks/base/services/core/java/com/android/server

     PS:如果服务端文件比较多,或者想把服务器文件放在同一个文件夹下,可以创建个文件夹存放

    如:frameworks/base/services/core/java/com/android/server/DDTS,如果定义了自定义目录,注意DDTSManagerService.java的包名

    

package com.android.server.DDTS
import android.content.Context;

pulic class DDTSManagerService extends IDDTSManager.stub {
    private final Context mContext;
    private boolean mVal;
    
    public DDTSManagerService(Context context) {
        mContext = context;
    }
    
    @Override
    public boolean setValue(boolean val) {
        mVal = val;
        return true;
    }
    
    @Override
    public boolean getValue() {
        return mVal;
    }
}

4、在SystemServer中注册自定义的Service

    打开文件:frameworks/base/services/java/com/android/server/SystemServer.java

    在private void startOtherServices()函数中添加自定义的Service

try {
    Slog.i(TAG,"DDTS Service");
    ServiceManager.addService(Context.DDTS_SERVICE, new DDTSManagerService(context));
} catch (Throwable e) {
    reportWtf("starting DDTS Service fail:",e);
}

在addService中的Context.DDTS_SERVICE为服务端的名称。

DDTS_SERVICE要在Context.java中添加

打开文件:frameworks/base/core/java/android/content/Context.java

添加

public static final String DDTS_SERVICE = "ddts";

5、创建DDTSManager.java文件

      DDTSManager.java主要是给应用调用的类,DDTSManager通过binder调用到DDTSManagerService实现的aidl接口。完成最终的服务。

     创建目录:frameworks/base/core/java/android/app

package android.app;
import android.content.Context;

public class DDTSManager
{
    private static IDDTSManager mService;
    private final Context mContext;
    
    DDTSManager(Context context) {
        mContext = context;
        mService = IDDTSManager.Stub.asInterface(ServiceManager.getService(Context.DDTS_SERVICE));
    }
    
    public boolean setValue(boolean val) {
        try {
            return mService.setValue(val);
        } catch (RemoteException e){
            return false;
        }
    }
    
    public boolean getValue() {
        try {
            return mService.getValue();
        } catch (RemoteException e){
            return false;
        }
    }
}

6、把DDTSManager注册到ContextImpl中

     在ContextImpl.java中的static{}代码中,添加注册代码,DDTSManager通过registerService函数注册服务,这样应用可以调用getSystemService获取到DDTSManager,从而调用DDTSManager中的接口,最终调用到DDTSManagerService

registerService(DDTS_SERVICE,new ServiceFetcher() {
        public Object createService(ContextImpl ctx) {
            return new DDTSManager(ctx.getOuterContext());
        }});

7、添加SELinux Policy权限

    打开文件:external/sepolicy/service_contexts

    在文件中添加:

ddts   u:object_r:system_server_service:s0

   其中:ddts为SystemServer注册服务时ServiceManager.addService函数中的Context.DDTS_SERVICE,也就是服务的名称。

8、编译framework.jar和Service.jar,并替换手机中的相应jar包。



写一个apk测试服务是否能用。

1、在Android studio中新建一个android library的项目。

     包名命名为:android.app(这个包名必须和DDTSManager.java的包名一致)

    并在android/app目录下创建一个java文件,文件名称和内容与DDTSManager.java一致。

    创建这个工程主要是因为要得到一个DDTSManager文件对应的jar,把这个jar包放在apk工程中,这样编译apk时不会报错。

2、新建一个apk工程,并把DDTSManager文件对应的jar包放入到apk工程的libs目录下。

     把apk工程中的build.gradle文件的dependecies中增加provided依赖

dependencies {
    provided fileTree(include: ['*.jar'], dir: 'libs')
    //compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile files('libs/DDTSManager.jar')
}
编译好apk后,就可以在手机上验证了。

你可能感兴趣的:(android)