android P添加自定义系统服务,编译成jar包供上层使用

之前写过一篇8.1添加自定义系统服务的文章,这篇文章有点区别,就是把manager部分单独新建了一个模块,方便编译成jar包,提供给上层调用。

1.编写aidl文件

在framework/base下新建infrarescan/java/com/infrare/scan文件夹

  • frameworks/base/infrarescan/java/com/infrare/scan/IInfrareScanManager.aidl
package com.infrare.scan;

import com.infrare.scan.ScanDataCallback;

interface IInfrareScanManager {
	void startDecode();
	void registerCallback(ScanDataCallback sdc);
	void unRegisterCallback(ScanDataCallback sdc);
}

这个aidl是用于服务端到客户端的回调,RemoteCallbackList详情

  • frameworks/base/infrarescan/java/com/infrare/scan/ScanDataCallback.aidl
package com.infrare.scan;

interface ScanDataCallback {
	void decodeComplete(String str);
}
2.编写manager类
  • frameworks/base/infrarescan/java/com/infrare/scan/InfrareScanManager.java
package com.infrare.scan;

import android.content.Context;
import android.util.Log;

public class InfrareScanManager {
	private static final String TAG = "InfrareScanManager";
	private Context mContext;
	private IInfrareScanManager mService;
	
	public InfrareScanManager (Context context, IInfrareScanManager service){										
		mContext = context;
		mService = service;
	}

	public void startDecode(){
		try {
			mService.startDecode();
		}catch (Exception e){
			Log.d(TAG,"startDecode failur :"+e);
		}
	}
	
	public void registerCallback(ScanDataCallback sdc){
		try {
			mService.registerCallback(sdc);
		}catch (Exception e){
			Log.d(TAG,"registerCallback failur :"+e);
		}
	}

	public void unRegisterCallback(ScanDataCallback sdc){
		try {
			mService.unRegisterCallback(sdc);
		}catch (Exception e){
			Log.d(TAG,"unRegisterCallback failur :"+e);
		}
	}
}
3.创建服务
  • frameworks/base/services/java/com/android/server/InfrareScanService.java
package com.android.server;

import android.content.Context;
import com.infrare.scan.ScanDataCallback;
import com.infrare.scan.IInfrareScanManager;
import android.os.RemoteCallbackList;

public class InfrareScanService extends IInfrareScanManager.Stub {
	private static final String TAG = "InfrareScanService";
	
	private Context mContext;
	private RemoteCallbackList<ScanDataCallback> mDataCallbacks
             = new RemoteCallbackList<ScanDataCallback>();

	public InfrareScanService (Context context){
		mContext = context;
	}
	
	@Override
	public void startDecode(){
		Log.d(TAG," startDecode ");
		onDecodeComplete("测试"); // 测试服务端到客户端的回调
	}
	
	@Override
	public void registerCallback(ScanDataCallback scb){
		mDataCallbacks.register(scb);	
	}

	@Override
	public void unRegisterCallback(ScanDataCallback scb){
		mDataCallbacks.unregister(scb);
	}

	// 获取到数据之后回传给客户端时调用
	private void onDecodeComplete(String str){
		final int N = mDataCallbacks.beginBroadcast();
        for (int i=0; i<N; i++) {
             try {
                  mDataCallbacks.getBroadcastItem(i).decodeComplete(str);
             } catch (Exception e) {
               // The RemoteCallbackList will take care of removing
               // the dead object for us.
				  Log.d(TAG," Callbacks broacast excp"+e);
             }
        }						  
        mDataCallbacks.finishBroadcast();	
	}
}
4.将服务添加到系统中

①将manager部分编译成jar包,新建/frameworks/base/infrarescan/Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := infrarescan
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, java)
LOCAL_SRC_FILES += \
	java/com/infrare/scan/ScanDataCallback.aidl  // 将用于服务端到客户端的回调的aidl也加入到jar包中
	
LOCAL_MODULE_CLASS := JAVA_LIBRARIES
include $(BUILD_JAVA_LIBRARY)

②添加新加入的模块:device/mediatek/xxx/device.mk

// add for infrare scan
PRODUCT_PACKAGES += infrarescan

③将新添加的模块加入到framework:build/core/pathmap.mk

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 \
  +	    infrarescan \
	 )

aidl和java文件引入: framework/base/android.bp

java_library {
    name: "framework",
    
    srcs: [
        // From build/make/core/pathmap.mk FRAMEWORK_BASE_SUBDIRS
        "core/java/**/*.java",
        "graphics/java/**/*.java",
        "location/java/**/*.java",
        "lowpan/java/**/*.java",
        "media/java/**/*.java",
        "media/mca/effect/java/**/*.java",
        "media/mca/filterfw/java/**/*.java",
        "media/mca/filterpacks/java/**/*.java",
        "drm/java/**/*.java",
        "opengl/java/**/*.java",
        "sax/java/**/*.java",
        "telecomm/java/**/*.java",
        "telephony/java/**/*.java",
        "wifi/java/**/*.java",
        "keystore/java/**/*.java",
        "rs/java/**/*.java",
   +    "infrarescan/java/**/*.java",

        ":framework-javastream-protos",

   +    "infrarescan/java/com/infrare/scan/IInfrareScanManager.aidl",
   +    "infrarescan/java/com/infrare/scan/ScanDataCallback.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",
   +        "infrarescan/java",
        ],

不加编译不过,找不到aidl和java文件

④ 添加自定义服务名:frameworks/base/core/java/android/content/Context.java

// add for infrare scan
public static final String INFRARE_SCAN_SERVICE = "infrare_scan";

④添加服务到ServiceManager:frameworks/base/services/java/com/android/server/SystemServer.java

private void startOtherServices(){
			...
	// add for infrae scan
    traceBeginAndSlog("StartIfrareScanService");
    InfrareScanService infrareScanService = new InfrareScanService(context);
    ServiceManager.addService(Context.INFRARE_SCAN_SERVICE,infrareScanService);
    traceEnd();
    // add end
}

⑤注册自定义服务:frameworks/base/core/java/android/app/SystemServiceRegistry.java

import com.infrare.scan.IInfrareScanManager;
import com.infrare.scan.InfrareScanManager;

 // add for infrare scan
 registerService(Context.INFRARE_SCAN_SERVICE, InfrareScanManager.class,
       new CachedServiceFetcher<InfrareScanManager>() {
            @Override
            public InfrareScanManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                IBinder b = ServiceManager.getService(Context.INFRARE_SCAN_SERVICE);
                IInfrareScanManager service = IInfrareScanManager.Stub.asInterface(b);
                Log.d("InfrareScanManager"," "+b+"   "+service);
                return new InfrareScanManager(ctx.getOuterContext(), service);
            }});
  // add end
5.添加selinux权限
  • device/mediatek/sepolicy/bsp/plat_private/service_contexts
# add for infrare scan
# infrare_scan就是在Context中定义的服务名称
infrare_scan                            u:object_r:infrare_scan_service:s0
# add end
  • device/mediatek/sepolicy/bsp/plat_private/service.te
# add for infrare scan
type infrare_scan_service,system_api_service,system_server_service,service_manager_type;
# add end

使用 make update-api && make -j20 2>&1 | tee build.log 进行编译

6.检查服务是否添加成功

adb shell 进入后使用 service list | grep infrare_scan ,如果能显示
infrare_scan: [com.infrare.scan.IInfrareScanManager]
证明添加成功

7.客户端中使用

①将out/target/common/obj/JAVA_LIBRARIES/infrarescan_intermediates/classes.jar包导入到项目中
②使用

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    InfrareScanManager infrareScanManager = (InfrareScanManager) mContext.getSystemService("infrare_scan");
    if (infrareScanManager != null){
    	infrareScanManager.registerCallback(scanDataCallback);
        infrareScanManager.startDecode();
    }
}

ScanDataCallback scanDataCallback = new ScanDataCallback.Stub() {
    @Override
    public void decodeComplete(String s) throws RemoteException {
		Log.d(TAG," decodeComplete "+s);   
    }
};

log显示 D/InfrareScanTest:decodeComplete :测试

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要将自定义jar包添加Android系统的/system/framework目录下并允许APK调用,需要进行以下步骤: 1. 将自定义jar包复制到Android代码的/frameworks/base/libs/目录下。 2. 修改Android代码的/frameworks/base/core/java/Android.mk文件,在LOCAL_JAVA_LIBRARIES变量中添加自定义库的名称。 例如,如果自定义库的名称是mylibrary.jar,修改后的LOCAL_JAVA_LIBRARIES变量应该是: ``` LOCAL_JAVA_LIBRARIES := core-libart bouncycastle apache-xml conscrypt mylibrary ``` 3. 修改Android代码的/build/target/product/core.mk文件,在PRODUCT_BOOT_JARS变量中添加自定义库的名称。 例如,如果自定义库的名称是mylibrary.jar,修改后的PRODUCT_BOOT_JARS变量应该是: ``` PRODUCT_BOOT_JARS := $(call add-to-boot-jars,core-libart bouncycastle apache-xml conscrypt mylibrary) ``` 4. 编译Android代码,并将编译后的系统镜像烧录到设备上。 5. 在APK中使用自定义库,需要在AndroidManifest.xml文件中添加以下权限: ``` <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> ``` 6. 在APK中使用自定义库,需要在build.gradle文件中添加以下依赖: ``` dependencies { implementation files('/system/framework/mylibrary.jar') } ``` 注意:由于/system/framework目录是系统级别的目录,因此需要具有root权限才能将自定义jar包复制到该目录中。同时,修改Android代码需要一定的编译和构建知识和经验,建议在熟悉Android代码的情况下进行操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值