新增一个自定义的系统服务,并尝试在SystemUI中调用自定义service

一、新建相关文件以及定义服务的注册与启动

        1.新建aidl文件

         到android8.1/frameworks/base/core/java/android 目录下,可以看到app文件夹,目录下是aidl服务接口文件和对应的服务管理类。 可以将自定义的aidl文件放在这个目录里。

         本文在android8.1/frameworks/base/core/java/android目录下新建了chenzqTest文件夹,方便管理自定义内容。

        android8.1/frameworks/base/core/java/android/chenzqTest 目录下 新增ITestService.aidl文件。

package android.chenzqTest;

interface ITestService {
    void log();  //因为只是个测试,所以就写一个无参的log方法
}

     

         2. 同目录下新建管理类 TestManager.java

package android.chenzqTest;

import android.os.RemoteException;
import android.content.Context;
import android.os.ServiceManager;
import android.util.Log;

public class TestManager {
    private ITestService mService;

    public TestManager(Context ctx ){
    mService =ITestService.Stub.asInterface(ServiceManager.getService("test-service"));//获取ITestService实例
    }

    public void log ()throws RemoteException{
        mService.log();
    }
}

记得抛异常

注意这个包名“android.chenzqTest

        3.新建aidl实现类

        一般把实现类放在android8.1/frameworks/base/core/java/com/android/server 目录下

        在android8.1/frameworks/base/core/java/com/目录下 新建chenzqTest/server目录

         android8.1/frameworks/base/core/java/com/chenzqTest/server目录下,新建TestServiceImpl.java继承ITestService.Stub

package com.chenzqTest.server;
import android.os.RemoteException;
import android.util.Log;
import android.chenzqTest.ITestService;

public class TestServiceImpl extends ITestService.Stub {

    public void log() {
        for (int i=0;i<10;i++) {
            Log.d("chenzq","服务循环"+i );//这个服务就是打log
        }
    }

}

注意包名“com.chenzqTest.server

        4.在Context中定义服务标识

        android8.1/frameworks/base/core/java/android/content/Context.java中新增

public static final String CHENZQ_TEST_SERVICE = "test-service";

        5.在SystemServer中启动服务

        android8.1/framework/base/services/java/com/android/server/SystemServer.java的startOtherServices方法中新增try-catch

import com.chenzqTest.server.TestServiceImpl;
        try {
            TestServiceImpl testService = new TestServiceImpl();
            Slog.e(TAG, "Create  successfully .");
            // Add this service to service manager
            ServiceManager.addService(Context.CHENZQ_TEST_SERVICE,testService);
        } catch (Throwable e) {
            Slog.e(TAG, "Starting  exception ", e);
        }

        6.在SystemServiceRegisty中注册服务管理类

import android.chenzqTest.TestManager;
    static {
        .......
        .......
        registerService(Context.CHENZQ_TEST_SERVICE, TestManager.class,
                new CachedServiceFetcher<TestManager>() {
                    @Override
                    public TestManager createService(ContextImpl ctx) {
                        Log.d("chenzq","注册服务" );
                        return new TestManager(ctx);
            }});


二、修改Android.mk文件

修改android8.1/frameworks/base/目录下Android.mk

LOCAL_SRC_FILES += \
	core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl \
	core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl \
	core/java/android/accounts/IAccountManager.aidl \        
    core/java/android/chenzqTest/ITestService.aidl\ //自己写的aidl文件(本文的LOCAL_SRC_FILES在67行)

三、修改配置文件

注:本文采用的是RK3399的源码

        1.设置上下文服务类型

android8.1/system/sepolicy/prebuilts/api/26.0/private/service_contexts 以及android8.1/system/sepolicy/private/service_contexts两个配置文件分别添加

test-service    u:object_r:test_service:s0

这里的“test-service”与Context中定义的相同

        2.service.te 新增服务类型

android8.1/system/sepolicy/prebuilts/api/26.0/public/service.te 以及 android8.1/system/sepolicy/public/service.te两个配置文件分别添加

type test_service, system_api_service, system_server_service, service_manager_type;

        3.白名单修改

android8.1/build/core/tasks/check_boot_jars/package_whitelist.txt

文件末尾新增

#add
com\.chenzqTest
com\.chenzqTest\..*

       注:编译前要先执行 make update-api

四、修改SystemUI调用自定义服务

在我前一篇文章里有介绍怎么自定义SystemUI的快捷方式

android 8.1 SystemUI修改 QuickSetting 新增快捷设置图标_陈十方的博客-CSDN博客

这次在点击事件里加入如下代码,在单击控件时调用自定义服务

import android.chenzqTest.TestManager;

@Override
protected void handleClick() {
        TestManager con =(TestManager)mContext.getSystemService(Context.CHENZQ_TEST_SERVICE);
        try{
            Log.d("chenzq2", "TestManager");
            con.log();
        }
        catch (Throwable e){
            Log.d("chenzq2", "TestManager excpetion");
        }
     
    }

结果

五、自定义服务导包到其它SDK中

本文是在源码环境下,所以可以直接导包,如果想要在在别的SDK使用可以到

目录:android8.1/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes

找到目录:android/chenzqTest/下:

找到目录:com/chenzqTest/server/下:

        

 找到自己所用的SDK目录:

解压 /platforms/android-**/ 目录下的android.jar文件,在解压文件里对应位置创建上面自定义的文件目录,并复制文件。重新压缩成android.jar。

六、自定义服务生成jar包

        1.相关文件的操作

 android8.1/framework/base/目录下新建chenzqtest文件夹,该文件夹下新建Android.mk文件

                

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
ANDROID_COMPILE_WITH_JACK := false
LOCAL_SRC_FILES := $(call all-java-files-under, java/android/chenzqTest)
LOCAL_SRC_FILES += $(call all-java-files-under, java/com/chenzqTest)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
LOCAL_MODULE := chenzqtest
include $(BUILD_STATIC_JAVA_LIBRARY)
                                            

移动 framework/base/core/java/android/chenzqTest 目录下文件到 framework/base/chenzqtest/java/android/chenzqTest 目录下。

移动 framework/base/core/java/com/chenzqTest/server 目录下文件到 framework/base/chenzqtest/java/com/chenzqTest/server 目录下。

        2.修改其它文件

第二步在 framework/base/下Android.mk中的修改改为

chenzqtest/java/android/chenzqTest/ITestService.aidl\

在 framework/base/下Android.mk中的packages_to_document新增自己的包

# TODO: deal with com/google/android/googleapps
packages_to_document := \
        android \
        javax/microedition/khronos \
        org/apache/http/conn \
        org/apache/http/params\
        android/chenzqTest//自己类的包名

在build/core/pathmap.mk文件的FRAMEWORKS_BASE_SUBDIRS变量后添加chenzqtest

FRAMEWORKS_BASE_SUBDIRS := \
        $(addsuffix /java, \
            core \
            graphics \
            .....
            keystore \
            rs \
            chenzqtest\ //自己的文件夹名
        )

修改android8.1/build/target/product/base.mk文件

PRODUCT_PACKAGES += \
    20-dns.conf \
    95-configured \
    org.apache.http.legacy.boot \
    ....
    vdc \
    vold \
    wm \
    chenzqTest //自己在Android.mk文件中定义的模块名

修改同目录下的generic_no_telephony.mk文件

PRODUCT_PACKAGES := \
    Bluetooth \
    BluetoothMidiService \
    Camera2 \
    ....
    EasterEgg \
    WallpaperCropper \
    chenzqTest //模块名

这样编译生成后就能在android8.1/out/target/common/obj/JAVA_LIBRARIES/chenzqtest_intermediates

目录下找到生成的jar包了

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐