安卓ROM定制笔记(一) 使用安卓隐藏API配合安卓studio开发系统级APP

虽然在开发中使用隐藏API是不推荐的,但是为了一些需求,还是得做的。

获取安卓架包

在sdk中这个包叫做android.jar,有两种方式,

第一种方式 从github上获取,android-hidden-api,下载对应安卓版本的android.jar文件

第二种方式 从编译完成的安卓源码中获取,

在安卓源码目录/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates获取一个叫做classes.jar文件,如图所示:


添加架包至安卓studio

在安卓studio project中新建文件夹名为lib,名字无关紧要,将第一步获取的android.jar(这个名字也可以随便取)文件复制到lib文件夹下。如图所示:


编写子项目的build.gradle

什么是子项目?如图红框所示:


把guestuser称为子项目,根项目为AndroidRomLearn。

在子项目的build.gradle文件中添加framework.jar的依赖,如图所示:


编写根项目中的build.gradle

实现思路分为两步,第一步加载jar文件,在根项目的build.gradle文件中添加以下代码:

project('guestuser') {
    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs.add('-Xbootclasspath/p:'lib/framework.jar)
        }
    }
}

其中add函数的参数 Xbootclasspath/p:是Java编译的寻址优先设置,不确定路径可以用绝对路径,目录结构和我之前展示的一样无需使用绝对路径,绝对路径需对路径符号“/”进行转义,"\\"

第二步,降低安卓sdk 的优先级。先看一个文件名为guestuser.iml,以子项目名称命名的文件,如图所示:


其部分内容如下所示:


这些orderEntry标签的从上到下顺序决定了在碰到同包名同类名的情况下的架包的顺序,默认情况下sdk是排在第二位的,现在要做的是将sdk标签位置置后。

在根项目中的build.gradle文件中添加一个方法,如下所示:

def pushDownSDK(iml) {
    def imlFile = file(iml)
    try {
        def parsedXml = (new XmlParser()).parse(imlFile)
        def jdkIndexOf = parsedXml.component[1].orderEntry.findIndexOf { it.'@type' == 'jdk' }
        if (jdkIndexOf <= 1) {
            def jdkNode =parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
            parsedXml.component[1].remove(jdkNode)
            new Node(parsedXml.component[1], 'orderEntry',['type': 'jdk', 'jdkName': 'Android API 26 Platform', 'jdkType': 'Android SDK'])
            def writer = new StringWriter()
            new XmlNodePrinter(new PrintWriter(writer)).print(parsedXml)
            imlFile.text = writer.toString()
            println "Push File: $iml jdk priority ok"
            groovy.xml.XmlUtil.serialize(parsedXml,new FileOutputStream(imlFile))//简书上有个blog因为少写这个,搞了我好久
        }
    } catch (Exception e) {
        // do nothing
    }
}

在项目编译完成后应用此方法:

project('guestuser') {
    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs.add('-Xbootclasspath/p:lib/framework.jar')
        }
    }
    gradle.buildFinished {
        pushDownSDK("guestuser/guestuser.iml");
    }
}

完整的build.gradle文件如下所示:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }

}

def pushDownSDK(iml) {
    def imlFile = file(iml)
    try {
        def parsedXml = (new XmlParser()).parse(imlFile)
        def jdkIndexOf = parsedXml.component[1].orderEntry.findIndexOf { it.'@type' == 'jdk' }
        if (jdkIndexOf <= 1) {
            def jdkNode =parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
            parsedXml.component[1].remove(jdkNode)
            new Node(parsedXml.component[1], 'orderEntry',['type': 'jdk', 'jdkName': 'Android API 26 Platform', 'jdkType': 'Android SDK'])
            def writer = new StringWriter()
            new XmlNodePrinter(new PrintWriter(writer)).print(parsedXml)
            imlFile.text = writer.toString()
            println "Push File: $iml jdk priority ok"
            groovy.xml.XmlUtil.serialize(parsedXml,new FileOutputStream(imlFile))
        }
    } catch (Exception e) {
        // do nothing
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

project('guestuser') {
    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs.add('-Xbootclasspath/p:lib/framework.jar')
        }
    }
    gradle.buildFinished {
        pushDownSDK("guestuser/guestuser.iml");
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

重新编译项目就可以使用隐藏的api了

编写lint.xml抑制错误

在使用AndroidMainfest.xml配置了系统权限时,android studio会报错,导致无法编译,如下图所示:


在开发系统应用时这是不行的,所以需要一个方法抑制这个报错,lint.xml就是这个方法,在子项目中添加一个lint.xml文件,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<lint>
    <issue id="ProtectedPermissions" severity="warning"/>
</lint>
其中ProtectedPermissions定义了系统级别的权限,降为警告就行了
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值