前言

最近在集成内置APK的时候遇到了些问题,遂整理一份文档以记录。


一,APP内置进系统固件

  1. 将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)
  2. 然后在系统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

  1. 生成签名

    有两种方式:
  • 通过系统SDK的build/target/product/security里的 platform.pk8platform.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的别名]
  1. 配置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'
}
}
  1. 为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">
  2. 编译运行

点击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~

系统内置APK并签名并配置AndroidStudio的更多相关文章

  1. 酷派8150S(移动定制版)可用的第三方Recovery备份数据、刷机并精简系统内置APK经验

    希望使用的第三方Recovery下载地址: ClockworkMod ROM Manager - Recoveries http://clockworkmod.com/rommanager 适配的型号 ...

  2. Gradle配置APK自动签名完整流程

    转载请注明出处:http://www.cnblogs.com/LT5505/p/6256683.html 一.生成签名 1.命令行生成签名,输入命令keytool -genkey -v -keysto ...

  3. 开发Android系统内置应用小记

    Android系统内置应用可以使用更多的API.更高的权限,与开发普通应用最大的差别在于编译,内置应用编译需要用到Android.mk文件.下面是我在开发过程中的一些小记. 1.在AndroidMai ...

  4. Android 4.4中AudioRecord用例 - 录制系统内置声音

    通过API 19新加的MediaRecorder.AudioSource.REMOTE_SUBMIX參数能够让系统App录制系统内置的声音,也就是扬声器的声音.以下是一个巨简单的样例来演示样例怎样通过 ...

  5. Apk去掉签名以及重新签名的方法

    Android开发中很重要的一部就是用自己的密钥给Apk文件签名,不经过签名的Apk文件一般是无法安装的,就算装了最后也是失败. 网上流传的"勾选允许安装未知来源的应用"其实跟签不 ...

  6. WCF系统内置绑定列表与系统绑定所支持的功能

      WCF系统内置绑定列表 绑定 配置元素 说明 传输协议 编码格式 BasicHttpBinding <basicHttpBnding> 一个绑定,适用于与符合 WS-Basic Pro ...

  7. C# 3.0 / C# 3.5 系统内置委托

    内置委托的定义声明: System.Func,代表有返回类型的委托: public delegate TResult Func<out TResult>(); public delegat ...

  8. apk文件签名绕过

    声明: 1.本文转载自:http://www.2cto.com/Article/201311/256406.html,为了留作日后参考上传博客 2.如有转载请复试上面连接,尊重原创 apk文件签名绕过 ...

  9. android apk的签名和权限问题

    一. android apk的签名问题(http://blog.csdn.net/lyq8479/article/details/6401093) 1.为什么要给Android应用程序签名?      ...

  10. Android APK 重签名

    对APK 进行在线 加固后,Apk体积一般会变大,而且Apk会无法直接安装,因为缺少了你的签名.是的,你需要对这个Apk进行重签名. 如何重签名 重签名的方法,一般来说,有两种,第一种是用JDK自带的 ...

随机推荐

  1. go 中解析JSON的三种姿势

    背景 这是一篇写给0-1年新人的文章,短平快的教会你如何解析json字符串. 示例Json 假设有如下json字符串: { "userName":"admin" ...

  2. 《网页设计基础——CSS的四种引入方式详解》

    网页设计基础--CSS的四种引入方式详解     一.行内式:   规则: 1. 行内式是所有样式方法中最为直接的一种,它直接对HTML的标记使用style属性,然后将CSS代码直接写在其中.   格 ...

  3. Rust-语句和表达式

    语句和表达式 Rust 的函数体是由一系列语句组成,最后由一个表达式来返回值,例如: fn add_with_extra(x: i32, y: i32) -> i32 { let x = x + ...

  4. getSessionFactory().openSession()导致druid连接池中的连接都占用满但无法回收

    该问题产生的现象 页面刷新几次后,就卡住,线上就得需要重新部署(还好是测试环境,不是真正生产环境) 过程及原因 查看日志线程池满了 Caused by: org.springframework.jdb ...

  5. 学习完nio的一个小笔记吧

    这是一个nio网络通信服务端的demo,主要就学习了selector的一些用法,以及它里面的事件类型 selector是对nio的一个优化,它能保证既能高效处理线程中的事件,又能保证线程不会一直占用c ...

  6. kvm安装windows使用virtio驱动下载地址

    https://dl.fedoraproject.org/pub/alt/virtio-win/latest/images/bin/deprecated-README 老版本下载地址:https:// ...

  7. 使用scrapy爬取长安有妖气小说

    目标网站:https://www.snwx3.com/txt/434282.html 第一章地址:https://www.snwx3.com/book/434/434282/92792998.html ...

  8. 一天五道Java面试题----第十一天(分布式架构下,Session共享有什么方案--------->分布式事务解决方案)

    这里是参考B站上的大佬做的面试题笔记.大家也可以去看视频讲解!!! 文章目录 1.分布式架构下,Session共享有什么方案 2.简述你对RPC.RMI的理解 3.分布式id生成方案 4.分布式锁解决 ...

  9. 齐博X1-栏目的调用2

    fun('sort@fathers',$fid,'cms')  获取上层多级栏目这样的,比如我们现在所属第三级栏目,现在可以利用这个函数获取第二级和第一级的栏目,当然自身也会被调用出来,所以此函数用的 ...

  10. 九、docker swarm主机编排

    一. 什么是Docker Swarm Swarm 是 Docker 公司推出的用来管理 docker 集群的平台,几乎全部用GO语言来完成的开发的,代码开源在https://github.com/do ...