在正常开发一个Android软件项目时,我们需要生成一个签名文件。具体实现方式可以参考:项目签名。但当我们开发一个系统级的app时,如果apk已经集成到系统中,再想重新安装新包测试时,可能会遇到安装不上的问题,提示签名不一致。这是因为系统在整体编译时需要整体进行系统签名。而当我们把新的apk往系统安装时,就会提示签名不一致,因为当前编译好的apk是应用签名,终端上的app是系统签名,二者不匹配,所以不能覆盖安装。

为了解决这个问题,我们需要将编译好的apk进行系统签名才可以安装。以下是总结的系统签名方法:

1. 前提准备

- build/target/product/security文件夹

- testkey:普通签名APK,默认情况下使用。

- platform:该APK完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,这种方式编译出来的APK所在进程的UID为system。

- shared:该APK需要和home/contacts进程共享数据。

- media:该APK是media/download系统中的一环。

- .pk8代表私钥,.x509.pem公钥,它们都是成对出现;

- testkey是作为android编译的时候默认的签名key,如果系统中的apk的Android.mk中没有设置LOCAL_CERTIFICATE的值,就默认使用testkey。

- android:sharedUserId=“android.uid.system”

2. 生成系统的keystore文件

根据上述前提准备,我们可以按照以下步骤生成系统的keystore文件:

1. 首先确保你已经有了签名工具(如jarsigner)和相应的证书(如testkey.pk8)。

2. 将证书导入到Android Studio中。在Android Studio的菜单栏中,选择“File” > “Project Structure”。在弹出的窗口中,选择“Modules” > “Signing Certs”。点击右侧的“+”按钮,选择证书文件(如testkey.pk8),并为其设置密码。点击“OK”保存设置。

3. 在项目的build.gradle文件中,添加签名配置。在android闭包内添加以下代码:

```groovy

android {

...

signingConfigs {

release {

storeFile file("path/to/your/keystore") // 这里填写你的keystore文件路径

storePassword "your_keystore_password" // 这里填写你的keystore密码

keyAlias "your_key_alias" // 这里填写你的key别名

keyPassword "your_key_password" // 这里填写你的key密码

}

}

...

}

```

4. 在项目的build.gradle文件中的application闭包内添加以下代码:

```groovy

android {

...

lintOptions {

checkReleaseBuilds false

}

...

}

```

5. 最后,同步Gradle并重新构建项目。新生成的apk将具有系统签名。

如果之前没有生成platform.pem文件,可以执行以下命令来生成:

```shell

openssl pkcs8 -inform DER -nocrypt -in platform.pk8 -out platform.pem

```

接下来,生成platform.p12文件,设置对应的密码和alias名(app签名使用到),可以使用以下命令:

```shell

openssl pkcs12 -export -in platform.x509.pem -out platform.p12 -inkey platform.pem -password pass:密码 -name 名称

```

要生成platform.jks(app使用的签名文件),可以使用keytool工具。首先启动keytool:

```shell

keytool -importkeystore -deststorepass 密码 -destkeystore ./platform.keystore -srckeystore ./platform.p12 -srcstoretype PKCS12 -srcstorepass 密码

```

然后,在build.gradle文件中配置signingConfigs,如下所示:

```groovy

signingConfigs {

release {

storeFile file('../platfrom.keystore')

storePassword '密码'

keyAlias '别名'

keyPassword '密码'

}

}

```