使用 hideApi SystemApi 在 Android Studio 中开发系统级 APP

使用 hideApi SystemApi 在 Android Studio 中开发系统级 APP

欢迎入群交流

效果图
获取 jar 包

GitHub:

https://github.com/anggrayudi/android-hidden-api

从安卓源码获取:

out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/

添加 jar 包到 Android Studio

在这里插入图片描述

app 的 build.gradle 配置
dependencies {
//    implementation fileTree(dir: "libs", include: ["*.jar"])
    compileOnly files('libs/mini_framework.jar')
}
  • api 或 compile 关键字引用的包对于其他 module 来说是可见的
  • implementation 关键字引用的包对于其他 module 来说是不可见的
  • compileOnly 只需要参与编译,而不需要将 mini_framework.jar 的内容编译进 apk 中
preBuild {
    doLast {
        def imlFile = file("../.idea/modules/app/app.iml")
        println('preBuild file exists:' + imlFile.exists())
        if (imlFile.exists()) {
            try {
                println('preBuild start')
                def parsedXml = (new XmlParser()).parse(imlFile)
                def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
                parsedXml.component[1].remove(jdkNode)
                def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform"
                new groovy.util.Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])

//                def settingslibName ='Gradle: ./app/libs/settingslib.jar'
//                def jdkNode1 = parsedXml.component[1].orderEntry.find { it.'@name' == settingslibName }
//                parsedXml.component[1].remove(jdkNode1)
//                new groovy.util.Node(parsedXml.component[1], 'orderEntry', ['type': 'library', 'name': settingslibName, 'level': 'project'])

                groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
                println('preBuild end')
            } catch (Exception e) {
                println('preBuild Exception:' + e.getMessage())
            }
        }
    }
}

此方法是优先加载 libs 下的 jar 包,实际过程中此方法不需要

使用此方法会将系统的 API 加载放到最后

在这里插入图片描述

根目录下的 build.gradle 配置
allprojects {
    repositories {
        google()
        jcenter()
        mavenCentral()
    }

    def path = getRootDir().getAbsolutePath() + '\\app\\libs\\mini_framework.jar'
    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs.add('-Xbootclasspath/p:' + path)
//            options.compilerArgs.add('-Xbootclasspath/p:app\\libs\\settingslib.jar')
            println('bootpath:' + path)
        }
    }
}
签名成系统包
方法一:

用到的文件

platform.pk8、platform.x509.pem、signapk.jar、libconscrypt_openjdk_jni.so

  • 在 AndroidManifest 中添加

    android:sharedUserId="android.uid.system"
    
  • 在 android 系统目录 build/target/product/security/拷贝系统签名文件

    platform.x509.pem、platform.pk8

  • 在 out/host/linux-x86/framework 目录下找到 signapk.jar 文件;

  • 在 out/host/linux-x86/lib64 下拷贝 libconscrypt_openjdk_jni.so 文件;

  • 将以上文件放到同一文件夹下,并将需要系统签名的 apk 也放在同一文件夹

  • 进入该文件目录下执行以下命令即可完成签名

    java -Djava.library.path=. -jar signapk.jar platform.x509.pem platform.pk8 app.apk 
    app_sign.apk
    
    方法二:

从 android 源码中生成系统签名文件

  • 编译 android 源码。

  • cd build/target/product/security/

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

生成 platform.pem 文件

  • 执行 openssl pkcs12 -export -in platform.x509.pem -out platform.p12 -inkey platform.pem -password pass:123456 -name system_debug

生成 platform.p12 文件,其中 system_debug 为 alias 名(app添加签名要用到),123456 为密码。

  • 执行 keytool -importkeystore -deststorepass 123456 -destkeystore platform.jks -srckeystore platform.p12 -srcstoretype PKCS12 -srcstorepass 123456

生成 platform.jks -deststorepass 123456 设置的是这个签名的密码,上面指令中的 -src* 的其他参数都是从前面两个指令中生成的。

  • 将生成的 platform.jks 拷贝到 app 工程目录下。
signingConfigs {
    main {
        storeFile file("platform.jks")  
        storePassword "123456"
        keyAlias "system_debug"
        keyPassword "123456"
    }
}

更新时间 2023年6月
在新版本的Android Studio下使用 preBuild { } 方法已经不适用,在根目录下的 build.gradle 添加如下

allprojects {
	repositories {
        google()
        jcenter()
        mavenCentral()
    }
	def path = getRootDir().getAbsolutePath() + '\\app\\libs\\mini_framework.jar'
	gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            Set<File> fileSet = options.bootstrapClasspath.getFiles()
            List<File> newFileList = new ArrayList<>();
            //相对位置,根据存放的位置修改路径
            newFileList.add(new File(path))
            newFileList.addAll(fileSet)
            options.bootstrapClasspath = files(newFileList.toArray())
        }
    }
}

微信公众号【他晓】,关注并转发,谢谢

效果图
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值