android 10 自定义系统服务接口给app调用
android 10 自定义系统服务接口给app调用android 10 自定义系统服务,生成成jar包安卓自定义系统服务
Android 安卓自定义系统服务
最近有个需求,要增加系统服务,生成第三方 jar 包提供给第三方应用调用,而且 jar 包必须用特定的包名 ,最后生成的 jar 包不能包含 frameworks 相关代码。
网上搜索了很多资料,搜索结果都没有自定义包名的案例,导出的 jar 也包含了 frameworks
相关代码。最终搜到这篇 博客 ,结合其他博客,最终完成功能
Android 10 自定义系统服务 安卓自定义系统服务 输出jar包
- 该案例基于 rockchip 芯片开发,在 PX30 Android10 上进行的测试,在其他设备上大同小异,请自行查找或替换为对应的路径。
- 实操过程中,可以在 AndroidStudio 中先编写好代码,检查代码中是否有语法错误,然后将代码拷贝到 frameworks 中,最后进行编译。
- 该示例包名为
com.test.customservice
1. 编写代码
1.1 编写 AIDL ITestService.aidl
文件
frameworks/base/test/java/com/test/customservice/ITestService.aidl
package com.test.customservice;
import android.os.Bundle;
interface ITestService {
void setValue(int value);
int getValue();
void setBundle( in Bundle bundle);
Bundle getBundle();
}
1.2 编写服务管理 TestServiceManager.java
文件
frameworks/base/test/java/com/test/customservice/TestServiceManager.java
package com.test.customservice;
import android.content.Context;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import com.test.customservice.ITestService;
public class TestServiceManager {
private static final String TAG = "TestServiceManager";
private ITestService iTestService;
public TestServiceManager(Context context, ITestService iTestService) {
this.iTestService = iTestService;
}
public void setValue(int value) {
try {
iTestService.setValue(value);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
public int getValue() {
try {
return iTestService.getValue();
} catch (RemoteException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
return 0;
}
public void setBundle(Bundle bundle) {
try {
iTestService.setBundle(bundle);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
public Bundle getBundle() {
try {
return iTestService.getBundle();
} catch (RemoteException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
return null;
}
}
1.3 编写服务的实现 TestService.java
文件
frameworks/base/services/core/java/com/test/customservice/TestService.java
package com.test.customservice;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
import android.content.Context;
import com.test.customservice.ITestService;
public class TestService extends ITestService.Stub {
public static final String TAG = "TestService";
private Context mContext;
public TestService(Context context){
this.mContext = context;
}
@Override
public void setValue(int value) throws RemoteException {
Log.i(TAG, "set value is " + value);
}
@Override
public int getValue() throws RemoteException {
Log.i(TAG, "get value is default value 0");
return 0;
}
@Override
public void setBundle(Bundle bundle) throws RemoteException {
Log.i(TAG, "set bundle is " + bundle.toString());
}
@Override
public Bundle getBundle() throws RemoteException {
Bundle bundle = new Bundle();
Log.i(TAG, "get bundle is " + bundle);
return bundle;
}
}
1.4 编写 Android.mk
文件
此文件用于将自定义的 service 生成jar包
frameworks/base/test/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, java)
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
include $(BUILD_JAVA_LIBRARY)
1.5 拷贝文件到 frameworks
指定目录
该步骤仅针对先在 AndroidStudio 中创建好 AIDL 和 java 文件的情况;如果你是直接在 frameworks 源码中创建的,请忽略本步骤。
- 拷贝
ITestService.aidl
和TestServiceManager.java
+ 在frameworks/base
目录下创建子目录test/java/com/test/customservice
,
+ 将ITestService.aidl
和TestServiceManager.java
拷贝到frameworks/base/test/java/com/test/customservice
路径下
- 拷贝
Android.mk
+ 将Android.mk
拷贝到frameworks/base/test
路径下,用来生成 jar 包,供第三方应用使用
- 拷贝
TestService.java
+ 在frameworks/base/services/core/java/
目录下创建子目录com/test/customservice
,
由于frameworks/base/services/core/java/com
目录已经创建,因此相当于在frameworks/base/core/java/com
创建test/customservice
目录即可。
+ 将TestService.java
拷贝到frameworks/base/core/java/com/test/customservice
路径下
2. 配置
2.1 frameworks 引入创建的 AIDL 和 java 代码
编辑 frameworks/base/Android.bp
或者 frameworks/base/Android.mk
文件,配置自定义的 aidl 和 java 文件
java_library {
name: "framework",
srcs: [
"packages/services/PacProcessor/com/android/net/IProxyService.aidl",
"packages/services/Proxy/com/android/net/IProxyCallback.aidl",
"packages/services/Proxy/com/android/net/IProxyPortListener.aidl",
"core/java/android/service/quicksettings/IQSService.aidl",
"core/java/android/service/quicksettings/IQSTileService.aidl",
+ "test/java/**/*.java",
+ "test/java/com/test/customservice/ITestService.aidl",
],
aidl: {
export_include_dirs: [
// From build/make/core/pathmap.mk FRAMEWORK_BASE_SUBDIRS
"core/java",
"graphics/java",
"location/java",
"lowpan/java",
"media/java",
"media/mca/effect/java",
"media/mca/filterfw/java",
"media/mca/filterpacks/java",
"drm/java",
"opengl/java",
"sax/java",
"telecomm/java",
"telephony/java",
"wifi/java",
"keystore/java",
"rs/java",
+ "test/java",
],
}
2.2 编辑 device.mk
将 test 模块编译进 system 中
编辑 device/rockchip/rk3326/PX30_indpx30a/device-common.mk
,增加以下内容
# add test service
PRODUCT_PACKAGES += \
test
# add test service
2.3 将 test 模块加入到 framework
编辑 build/core/pathmap.mk
在 FRAMEWORKS_BASE_SUBDIRS
中增加 test \
FRAMEWORKS_BASE_SUBDIRS := \
$(addsuffix /java, \
core \
graphics \
location \
media \
media/mca/effect \
media/mca/filterfw \
media/mca/filterpacks \
drm \
opengl \
sax \
telecomm \
telephony \
wifi \
lowpan \
keystore \
rs \
+ test \
)
2.4 编辑 Context.java
修改 frameworks/base/core/java/android/content/Context.java
增加 TEST_SERVICE
常量
/**
* Use with {@link #getSystemService(String)} to retrieve a {@link com.test.customservice.TestServiceManager} for test by the system.
*
* @see #getSystemService(String)
* @see com.test.customservice.TestServiceManager
*/
public static final String TEST_SERVICE = "test";
2.5 编辑 SystemServer.java
在 frameworks/base/services/java/com/android/server/SystemServer.java
的 startOtherServices()
方法中中增加服务,注意别漏掉 import 语句
import com.test.customservice.TestService;
***
private void startOtherServices() {
***
traceBeginAndSlog("Start Test Service");
try {
ServiceManager.addService(Context.TEST_SERVICE, new TestService(context));
} catch (Throwable e) {
reportWtf("starting TestService", e);
}
traceEnd();
***
}
2.6 编辑 SystemServiceRegistry.java
注册服务
在 frameworks/base/core/java/android/app/SystemServiceRegistry.java
中注册服务,注意别漏掉 import 语句
import com.test.customservice.ITestService;
import com.test.customservice.TestServiceManager;
***
static {
***
registerService(Context.TEST_SERVICE, TestServiceManager.class,
new CachedServiceFetcher<TestServiceManager>() {
@Override
public TestServiceManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
IBinder b = ServiceManager.getService(Context.TEST_SERVICE);
return new TestServiceManager(ctx,
ITestService.Stub.asInterface(b));
}});
***
}
2.7 编辑 package_whitelist.txt
添加白名单
在 build/make/core/tasks/check_boot_jars/package_whitelist.txt
中最后一行增加
com\.test\.customservice\..*
hiddenapi-greylist-packages.txt
添加白名单
2.8 编辑 在 frameworks/base/config/hiddenapi-greylist-packages.txt
中最后一行增加
***
org.apache.xpath
org.apache.xpath.axes
org.apache.xpath.compiler
org.apache.xpath.domapi
org.apache.xpath.functions
org.apache.xpath.jaxp
org.apache.xpath.objects
org.apache.xpath.operations
org.apache.xpath.patterns
org.apache.xpath.res
org.ccil.cowan.tagsoup
org.ccil.cowan.tagsoup.jaxp
+ com.test.customservice
2.9 配置SELinux
- 在
device/rockchip/common/sepolicy/private/service_contexts
中加一行,其中 test 为frameworks/base/core/java/android/content/Context.java
中增加的TEST_SERVICE
的值
test u:object_r:test_service:s0
- 在
device/rockchip/common/sepolicy/vendor/service.te
中加一行
type test_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
3. 编译验证
先执行 make update-api
,然后编译新固件,刷机后开机验证 ,
windows : adb shell service list | findstr "test"
linux : adb shell service list | grep test
如果显示有 test: [com.test.customservice.ITestService]
证明 service 启动成功
4. 集成到应用并调用
自定义服务生成的 jar 包路径为 out/target/common/obj/JAVA_LIBRARIES/test_intermediates/classes.jar
,将其拷贝到 AndroidStudio 工程的 libs
目录,然后右击Add As Library
集成到工程中。
调用示例如下
package com.test.tempserviceclient;
import android.annotation.SuppressLint;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.test.customservice.TestServiceManager;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@SuppressLint("WrongConstant") TestServiceManager testServiceManager = (TestServiceManager) getSystemService("test");
int value = testServiceManager.getValue();
System.out.println(value);
}
}
更多推荐
所有评论(0)