系统内置APK并签名并配置AndroidStudio
前言
最近在集成内置APK的时候遇到了些问题,遂整理一份文档以记录。
一,APP内置进系统固件
-
将APK源码或编译出的apk文件放在package或vendor等目录下,并且编写相应的android,mk文件,想要内置成系统应用,必须得包含
LOCAL_CERTIFICATE := platform
这一行(关于LOCAL_CERTIFICATE 怎么配置后面会说),文件内容如下(这是APK集成):LOCAL_PATH := $(my-dir) include $(CLEAR_VARS) LOCAL_MODULE := image LOCAL_MODULE_CLASS := APPS LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/bundled_persist-app LOCAL_SRC_FILES := $(LOCAL_MODULE)$(COMMON_ANDROID_PACKAGE_SUFFIX) LOCAL_CERTIFICATE := PRESIGNED #LOCAL_DEX_PREOPT := false LOCAL_MODULE_TAGS := optional LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX) LOCAL_JNI_SHARED_LIBRARIES_ABI := arm MY_LOCAL_PREBUILT_JNI_LIBS := \ lib/arm/libimagemagick.so\ lib/arm/libwebpbackport.so\ MY_APP_LIB_PATH := $(TARGET_OUT_VENDOR)/bundled_persist-app/$(LOCAL_MODULE)/lib/$(LOCAL_JNI_SHARED_LIBRARIES_ABI) ifneq ($(LOCAL_JNI_SHARED_LIBRARIES_ABI), None) $(warning MY_APP_LIB_PATH=$(MY_APP_LIB_PATH)) LOCAL_POST_INSTALL_CMD := mkdir -p $(MY_APP_LIB_PATH) $(foreach lib, $(MY_LOCAL_PREBUILT_JNI_LIBS), ; cp -f $(LOCAL_PATH)/$(lib) $(MY_APP_LIB_PATH)/$(notdir $(lib))) endif include $(BUILD_PREBUILT)
-
然后在系统SDK目录
mmm your_apk_file
编译,或者加入进PRODUCT_PACKAGES+= your_apk_file
后在统一编译,之后会在out响应的目录生成对应的带签名的APK。
关于配置
LOCAL_CERTIFICATE
: PRESIGNED:使用之前的签名,不再重复签名。
testkey:普通APK,默认情况下使用。
platform:该APK完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的APK所在进程的UID为system。
shared:该APK需要和home/contacts进程共享数据。
media:该APK是media/download系统中的一环。
应用程序的Android.mk中有一个LOCAL_CERTIFICATE字段,由它指定用哪个key签名,未指定的默认用testkey.
二,配置AndroidStudio编译并调试系统级APP
- 生成签名
有两种方式:
- 通过系统SDK的
build/target/product/security
里的platform.pk8
和platform.x509.pem
生成 系统签名platform.jks
cd 到目录
build/target/product/security
生成临时文件platform.pem
使用命令:
openssl pkcs12 -export -in platform.x509.pem -out platform.p12 -inkey platform.pem -password pass:android -name fireflyKeystore
请注意 pass后面跟的是密码 name后面跟的是别名。后续会使用到 生成签名文件 platform.jks
使用命令:
keytool -importkeystore -deststorepass android -destkeystore ./platform.jks -srckeystore ./platform.p12 -srcstoretype PKCS12 -srcstorepass android
请注意 srcstorepass后面跟的是签名文件的 密码
-
通过
android studio
生成签名然后再在其中添加系统签名a. studio新建key,build->Generate Signed APK… ,填写相关信息生成证书文件。
b. 使用keytool-importkeypair工具给生成的证书添加系统签名,需要将
build/target/product/security/ platform.x509.pem、platform.pk8
两个文件拷贝到相应目录,命令如下:keytool-importkeypair -k [jks文件名] -p [jks的密码] -pk8 platform.pk8 -cert platform.x509.pem -alias [jks的别名]
- 配置
gradle
文件使用签名文件
配置build.gradle
文件(Module:app),在Android{}代码块中添加如下代码:
signingConfigs {
release {
storeFile file("你弄出来的证书相对路径或绝对路径.jks")
storePassword 'android'
keyAlias 'platform'
keyPassword 'android'
}
debug {
storeFile file("同上.jks")
storePassword 'android'
keyAlias 'platform'
keyPassword 'android'
}
}
-
为APK添加共享UID,具体为什么要添加这一行,后面再介绍
在AndroidManifest.xml中添加一行
android:sharedUserId="android.uid.system"
例:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:sharedUserId="android.uid.system" package="com.xiaox.mymediaplayer">
-
编译运行
点击run或者debug运行app,这样装在手机后就能够正确运行了。
关于共享UID sharedUserId
安装在设备中的每一个apk文件,Android给每个APK进程分配一个单独的用户空间,其manifest中的userid就是对应一个Linux用户都会被分配到一个属于自己的统一的Linux用户ID,并且为它创建一个沙箱,以防止影响其他应用程序(或者其他应用程序影响它)。用户ID 在应用程序安装到设备中时被分配,并且在这个设备中保持它的永久性。
通过Shared User id,拥有同一个User id的多个APK可以配置成运行在同一个进程中.所以默认就是可以互相访问任意数据. 也可以配置成运行成不同的进程, 同时可以访问其他APK的数据目录下的数据库和文件.就像访问本程序的数据一样.
总结
对于一个APK来说,如果要使用某个共享UID的话,必须做三步:
1、在Manifest节点中增加android:sharedUserId属性。
2、在Android.mk中增加LOCAL_CERTIFICATE的定义。
如果增加了上面的属性但没有定义与之对应的LOCAL_CERTIFICATE
的话,APK是安装不上去的。提示错误是:Package com.test.MyTest has no signatures that match those in shared user android.uid.system; ignoring!也就是说,仅有相同签名和相同sharedUserID标签的两个应用程序签名都会被分配相同的用户ID。例如所有和media/download相关的APK都使用android.media作为sharedUserId的话,那么它们必须有相同的签名media。
3、把APK的源码放到packages/apps/目录下,用mm进行编译。
相关命令
#查看APK签名
jarsigner -verbose -certs -verify .\xxxx.apk
keytool -printcert -jarfile .\xxxx.apk
#查看签名详细信息
keytool -list -v -keystore xxxx.jks或xxxx.keystore
#给APK签名
jarsigner -verbose -keystore .\xxx.keystore -storepass 密码 -signedjar .\dest.apk -digestalg SHA1 -sigalg MD5withRSA .\src.apk Alias别名
#修改证书别名
keytool -changealias -keystore .\xxxx.keystore -alias 原别名 -destalias 要改成啥别名
#APK包对齐,这里是4字节对齐
zipalign -f -v 4 .\src.apk .\dest.apk
参考博客:
1,http://t.zoukankan.com/rootshaw-p-13521129.html
2,https://www.nhooo.com/note/qa3jsu.html
3,https://blog.csdn.net/hmg25/article/details/6447067
感谢
顺便提一句:
这次所遇到的问题竟然是裁剪系统包的时候弄出来的
--- a/target/product/core_base.mk
+++ b/target/product/core_base.mk
@@ -22,10 +22,10 @@ PRODUCT_PROPERTY_OVERRIDES := \
# delete follow apk by xtw-lwm --2022-11-03
# Home \
-# DefaultContainerService \
-# UserDictionaryProvider \
PRODUCT_PACKAGES += \
+ DefaultContainerService \
+ UserDictionaryProvider \
atrace \
libandroidfw \
libaudiopreprocessing \
问了下度娘,DefaultContainerService它是负责这个的
总体说来就两件事情:拷贝APK 和 解析APK,解析APK主要是解析 AndroidManifest.xml,以便获得它的安装信息。在安装的过程中还会这个应用分配 Linux用户ID 和 Linux用户组ID(以便它可以在系统中获取合适的运行权限)。
涉及的三个进程
- PackageInstaller进程:PackageInstaller事实上是一个应用,它负责APK安装以及卸载过程中与用户的交互流程。
- SystemServer进程:该进程主要运行的是系统服务,APK的安装、卸载和查询都由PackageManagerService负责,它也是Android核心系统服务的一种,在SystemServer里初始化系统服务的时候被启动。
- DefaultContainerService进程:DefaultContainerService也是一个单独的进程,它主要负责检查和复制设备上的文件,APK的复制就是由DefaultContainerService来完成的。
擦,原来是这个问题,又浪费我一两天的时间~
码字不易,转载请注明原作者 ~ (from:https://erdong.work)
see you~
本文来自博客园,作者:耳东Sir,转载请注明原文链接:https://www.cnblogs.com/erdongsir/p/16896038.html