在漫长的Android开发生涯中难免需要实现某个系统应用的系统功能,比如,appstore的静默安装,静默卸载
这两个功能对app的权限是有要求的,app必须是系统级别的应用才行,每个厂商的定制不同,对权限的定义也不同,有的厂商对app的权限级别只要根据安装包的路径就可以决定,
比如:厂商可以定制只要app的apk安装在系统目录/system/app/下或者在/system/priv-app/下,就将该app视为系统级别的app,;
而有的厂商却不这么认为,他们沿用的就是Android原生认可的,系统级别的应用必须在AndroidManifest.xml中注册了
android:sharedUserId="android.uid.system"才是系统级别的应用;
当然也有些厂商并不这么认为,他们对应用的权限设定的更为详细,他们制定在/system/app/路径下的应用是一种权限级别,在/system/priv-app/下又是一种级别,在清单文件中配置了android:sharedUserId="android.uid.system"的又是一种级别,且是权限最高的级别。
那么问题就来了,无论值哪种系统权限的申请都绕不开厂商的开放,比如要想将应用安装在/system/app/ 或者 /system/priv-app/路径下,首先就要对机器进行root, 然后remount, 之后才可以手动将apk push到/system/app/ 或者 /system/priv-app/ 路径下,重启机器后,利用Android 的PMS自己管理机制,扫描system路径下的所有apk进行自动安装,然而这种方式条件及其的苛刻,现在的机器经过厂商的严格定制与管控,市面上基本已经看不到可以获取root权限的产品了,也因此这条路并不适用于Android的三方开发;
那么就只有配置sharedUserId这一条路了,然而这条路也是有条件的,就是当app配置了sharedUserId后,会发现编出来的apk是无法直接install 到机器中的,这是为什么呢?通过install的错误指令我们就可以得到答案,如图:
图中的install 错误提示已经明确的指出了apk安装失败的原因,是因为sharedUserId缘故,解决的办法就是需要对配置了sharedUserId的apk进行系统签名文件的签名,也将是本文的重点,签名文件的生成,
什么是签名文件?
从应用层出发理解,在Android 中的签名文件可以被开发人员直接使用以及可以直接对外释放的只有两种,一种是jks,一种是keystore
在代码中的使用:
jsk:
signingConfigs { debug { keyAlias 'key0' // 别名 keyPassword '123456' // 密码 storeFile file('../signApk/giftedcat.jks') // 签名文件在本地的相对路径 storePassword '123456' // 密码 } release { keyAlias 'key0' keyPassword '123456' storeFile file('../signApk/giftedcat.jks') storePassword '123456' } }
keystore:
signingConfigs { debug { keyAlias 'key0' // 别名 keyPassword 'desaysv' // 密码 storeFile file('../signApk/giftedcat.keystore') // 签名文件在本地的相对路径 storePassword 'desaysv' // 密码 } release { keyAlias 'key0' keyPassword 'desaysv' storeFile file('../signApk/giftedcat.keystore') storePassword 'desaysv' } }
至于在哪里配置?为什么这么配置?每个属性的含义是什么?就不在本文过多解释了,有兴趣的可以学习一下这篇博客:Android签名机制之签名过程详解(一)_fengjinghuanian的博客-CSDN博客_android签名机制
那么jks哪里来的呢?
其实在Android中原始的签名文件只有两个,platform.pk8 和 platform.x509.pem,所谓的jks就是由这两个文件进行的转换而来的,转换中需要用到一个工具keytool-importkeypair,工具的下载地址:
使用方式:
找到系统的 platform.pk8 和 platform.x509.pem 放在 keytool-importkeypair目录下执行
./keytool-importkeypair -k giftedcat.jks -p 123456 -pk8 platform.pk8 -cert platform.x509.pem -alias key0
命令中属性解释:
giftedcat.jks: 输出的文件名称
123456 :密码
platform.pk8:.pk8 的本地文件路径
platform.x509.pem:.pem的本地文件路径
key0:签名的别名
platform.pk8 和platform.x509.pem 的文件下载可以在AndroidXref中找到:
http://androidxref.com/9.0.0_r3/
keystore的根:
keystore的其实就是通过platform.pk8 和platform.x509.pem的转换而来的,转换方式还是需要借助工具keytool-importkeypair,转换命令:
./keytool-importkeypair -k ./platform.keystore -p 123456 -pk8 platform.pk8 -cert platform.x509.pem -alias key0
当然jks和keystore之间也是可以进行互相转换的:
jks 转 keystore:
keytool -importkeystore -srckeystore D:\***.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore ***.p12
keytool -v -importkeystore -srckeystore D:\***.p12 -srcstoretype PKCS12 -destkeystore D:\***.keystore -deststoretype JKS
现在test.keystore的签名应该与test.jks的签名信息是一样的了。
可以通过以下命令来验证
keytool -v -list -keystore D:\test.keystore
keystore转jks
同理,keystore
也可以转jks
keytool -importkeystore -srckeystore ***.keystore -srcstoretype JKS -deststoretype PKCS12 -destkeystore ***.p12
keytool -v -importkeystore -srckeystore ***.p12 -srcstoretype PKCS12 -destkeystore ***.jks -deststoretype JKS
keystore命令签名:
jarsigner -verbose -keystore zdd.keystore -signedjar 123x.apk 456.apk androidkey(androidkey: 是别名)
可能会出现此类异常,原因是因为:
签名后生成的apk文件所要存放的路径最好不要用当前bin目录的路径 否则会生成失败 最好用D盘或者E盘
修改为:
jarsigner -verbose -keystore zdd.keystore -signedjar 123x.apk 123.apk androidkey