美文网首页
apk系统签名记录

apk系统签名记录

作者: smallestt | 来源:发表于2023-07-31 16:32 被阅读0次

    1、系统签名

    当项目开发需要使用系统级别权限或frame层某些api时,普通应用是无法使用的,需要在AndroidManifest中配置sharedUserId:


    20180628193621701.png
    android:sharedUserId="android.uid.system"
    

    配置完 android:sharedUserId="android.uid.system" 之后,此时的 app 是无法成功安装到设备的,控制台会提示 INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,这是因为此时 app 已经被识别为系统应用,但是其签名信息却不是系统签名,于是无法通过系统检验。进行系统签名需要准备好如下几个文件:

    • platform.pk8:签名证书
    • platform.x509.pem:签名证书
    • signapk.jar:签名工具
      注:我们是与Android系统厂商合作开发,以上文件为硬件厂商提供。

    1.1 单独签名

    将签名文件和签名工具、签名apk放置同一目录,定位到该目录,使用如下命令:

    java -jar signapk.jar platform.x509.pem platform.pk8 unsign.apk signed.apk

    signed.apk就是生成已经拥有系统签名的apk

    1.2 生成平台platform.keystore文件

    除了直接使用signapk.jar签名外,还可以将签名文件生成keystore文件,然后给apk进行签名。

    1.2.1将pkcs8格式的私钥转化成pkcs12格式

    openssl pkcs8 -in platform.pk8 -inform DER -outform PEM -out shared.priv.pem -nocrypt

    1.2.2 将x509.pem公钥转换成pkcs12格式

    openssl pkcs12 -export -in platform.x509.pem -inkey shared.priv.pem -out shared.pk12 -name test

    这里会输入密码和确认密码,密码是android

    1.2.3 生成platform.keystore

    keytool -importkeystore -deststorepass android -destkeypass android -destkeystore test.jks -srckeystore shared.pk12 -srcstoretype PKCS12 -srcstorepass android -alias test

    1.2.4 引入AndroidStudio

    配置项目builde.gradle,在android区域下(与defaultConfig同级)添加配置:

    signingConfigs {
        release {
            storeFile file("../test")
            storePassword 'android'
            keyAlias 'test'
            keyPassword 'android'
        }
        debug {
            storeFile file("../test")
            storePassword 'android'
            keyAlias 'test'
            keyPassword 'android'
        }
    }
    

    2 代码安装

    使用场景:版本更新

    2.1 安装方法

    /*系统签名apk 使用pm安装*/
    fun systemInstall(apkFile: File, finish: (() -> Unit)? = null) {
        try {
            if (apkFile.exists()) {
                val cmd = "pm install -r " + apkFile.absolutePath
                val runtime = Runtime.getRuntime()
                val process = runtime.exec(cmd)
                val errorInput = process.errorStream
                val inputStream = process.inputStream
                var bufferedReader = BufferedReader(InputStreamReader(inputStream))
                var error = ""
                var result = ""
                var line = ""
                while (bufferedReader.readLine().also { line = it } != null) {
                    result += line
                }
                bufferedReader = BufferedReader(InputStreamReader(errorInput))
                while (bufferedReader.readLine().also { line = it } != null) {
                    error += line
                }
                Log.e("===>", result)
                if (result == "Success") {
                    Log.e("===>", "install: Success")
                } else {
                    Log.e("===>", "install: error$error")
                }
                finish?.invoke()
            } else {
                finish?.invoke()
            }
     
        } catch (e: IOException) {
            e.printStackTrace()
            finish?.invoke()
     
        } catch (e: Exception) {
            finish?.invoke()
        }
    }
    

    2.2 注册广播,安装成功后自启

    manifest文件下

     <!-- 注册广播 安装包更新调起自启 -->
    <receiver
        android:name=".receiver.UpdateRestartReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.PACKAGE_REPLACED" />
     
            <data android:scheme="package" />
        </intent-filter>
    </receiver>
    

    2.3 重启app

    
    public class UpdateRestartReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())) {
                Uri data = intent.getData();
                if (data != null && context.getPackageName().equals(data.getEncodedSchemeSpecificPart())) {
                    // 重新启动APP
                    Intent intentToStart = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
                    context.startActivity(intentToStart);
                }
            }
     
     
        }
    }
    

    相关文章

      网友评论

          本文标题:apk系统签名记录

          本文链接:https://www.haomeiwen.com/subject/zxiepdtx.html