1,需要准备系统签名所需的证书文件,即:platform.pk8,platform.x509.pem。可在此处下载
2,keytool-importkeypair用来生成.jks的系统签名,可以在github下载
3,生成.jks文件时,需要在linux环境
以下两步都应该在linux环境下运行,windows会报错没有深究。
将keytool-importkeypair、platform.pk8和platform.x509.pem文件放在同一个目录下,执行如下命令,会生成platform.keystore文件:
sh keytool-importkeypair -k ./platform.keystore -p 123456 -pk8 platform.pk8 -cert platform.x509.pem -alias platform
-p 表示新生成的keystore的密码是什么,这里为123456
-pk8 ,-cert 分别指向签名的两个证书文件
-alias 表示给生成的platform.keystore取一个别名,这个名字只有我们在签名的时候才用的到,这里我们生成的文件名是platform。这个名字可以随便取
代码如下(示例):
./keytool-importkeypair -k test.jks -p 123456 -pk8 platform.pk8 -cert platform.x509.pem -alias test
test.jks : 签名文件
123456 : 签名文件密码
platform.pk8、platform.x509.pem : 系统签名文件
test: 签名文件别名
将生成的jks文件复制到windows电脑上,并配置项目builde.gradle,在android区域下(与defaultConfig同级)添加配置:
signingConfigs {
release {
storeFile file("../test.jks")
storePassword '123456'
keyAlias 'test'
keyPassword '123456'
}
debug {
storeFile file("../test.jks")
storePassword '123456'
keyAlias 'test'
keyPassword '123456'
}
}
storeFile file 指定签名文件所在位置
keyAlias 为创建时取得别名
其余两个为密码
这样debug或release apk就带有系统签名了。
public static void install(File apkFile) {
String cmd = "pm install -r " + apkFile.getAbsolutePath();
Log.e("qqq","cmd="+cmd);
Runtime runtime = Runtime.getRuntime();
try {
Process process = runtime.exec(cmd);
InputStream errorInput = process.getErrorStream();
InputStream inputStream = process.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String error = "";
String result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader = new BufferedReader(new InputStreamReader(errorInput));
while ((line = bufferedReader.readLine()) != null) {
error += line;
}
if(result.equals("Success")){
Log.i("qqq", "install: Success");
}else{
Log.i("qqq", "install: error"+error);
}
} catch (IOException e) {
e.printStackTrace();
}
}
直接使用SignUtils.install(new File(filePath));调用即可。
manifest文件下
<!-- 注册广播 -->
<receiver android:name=".ReplaceAddRemoveBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
重启app
if (Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())) {
Uri data = intent.getData();
if (data != null && context.getPackageName().equals(data.getEncodedSchemeSpecificPart())) {
Log.d("TAG", "更新安装成功.....");
Toast.makeText(context, "更新安装成功", Toast.LENGTH_LONG).show();
// 重新启动APP
Intent intentToStart = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
context.startActivity(intentToStart);
}
}
//添加权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name= "android.permission.RESTART_PACKAGES" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" tools:ignore="ProtectedPermissions" />
//
android:sharedUserId="android.uid.system"
以上方法只在低版本android测试成功,高版本可能受限于签名
参考地址:
https://www.codenong.com/cs106023369/
https://blog.csdn.net/zhixuan322145/article/details/51277921