背景

由于Google play的政策,提审aab的时候需要适配android12,适配android12最大的工作就是在AndroidManifesst.xml文件中声明的四大组件,都要显式声明exported字段。如果手动添加,在遇到第三方sdk时就会比较麻烦,所以只能使用gradle脚本自动添加,而网上给的gradle脚本例子都是只对apk生效,所以自己手动改造一下,以支持aab。

步骤

定义修改manifest文件的方法

遍历AndroidManifest.xml文件的每一个节点,识别到activity,receiver,service节点时,如果未声明exported字段则添加上去,入口类为true,其他默认为false

def fixManifest(File mainManifestFile) {try {def xml = new XmlParser(false, true).parse(mainManifestFile)def exportedTag = "android:exported"def androidSpace = new groovy.xml.Namespace('http://schemas.android.com/apk/res/android', 'android')def nodes = xml.application[0].'*'.findAll {(it.name() == 'activity' || it.name() == 'receiver' || it.name() == 'service') && it.attribute(androidSpace.exported) == null}nodes.each {def exportedValue = falseit.each {if (it.name() == "intent-filter") {it.each {if (it.name() == "action") {if (it.attributes().get(androidSpace.name) == "android.intent.action.MAIN") {exportedValue = true}}}}}it.attributes().put(exportedTag, "${exportedValue}")}PrintWriter pw = new PrintWriter(mainManifestFile)pw.write(groovy.xml.XmlUtil.serialize(xml))pw.close()} catch (Exception e) {}
}

打包流程中在特定task中插入代码段

  1. 打包debug/release apk时,会执行processDebugResources/processReleaseResources task将合并后的manifest打包进最终产物中,可以在gradle执行该task之前拦截,调用上面定义的方法修改manifest
  2. 打包debug/release aab时,会执行processDebugManifest/processReleaseManifest task将所有依赖的aar或library module中AndroidManifest.xml中的节点,合并到项目的AndroidManifest.xml中,可以在gradle执行该task之后拦截,调用上面定义的方法修改manifest

配置variant

获取打包的variant名称,以及打apk/bundle包时,manifest输出目录

project.afterEvaluate {android.applicationVariants.all { variant ->variant.outputs.all { output ->def s1 = output.processManifest.manifestOutputDirectory.get().asFile.absolutePathdef s2 = output.processManifest.bundleManifestOutputDirectory.get().asFile.absolutePathdef variantName = variant.name.capitalize()checkPackageType(project, variantName, s1, s2)}}
}

效果

查看打包后的aab manifest文件,第三方activity被自动添加上exported字段

完整代码

project.afterEvaluate {android.applicationVariants.all { variant ->variant.outputs.all { output ->def s1 = output.processManifest.manifestOutputDirectory.get().asFile.absolutePathdef s2 = output.processManifest.bundleManifestOutputDirectory.get().asFile.absolutePathdef variantName = variant.name.capitalize()addManifestTask(project, variantName, s1, s2)}}
}def addManifestTask(Project project, String variantName, manifestPath, bundleManifestPath) {try {def mergeResourcesTask = project.getTasks().getByName(String.format("process%sManifest", variantName))mergeResourcesTask.doLast {File mainManifestFile = new File(bundleManifestPath + "/AndroidManifest.xml")fixManifest(mainManifestFile)}def processResourcesTask = project.getTasks().getByName(String.format("process%sResources", variantName))processResourcesTask.doFirst {File mainManifestFile = new File(manifestPath + "/AndroidManifest.xml")fixManifest(mainManifestFile)}} catch (Exception e) {}
}def fixManifest(File mainManifestFile) {try {def xml = new XmlParser(false, true).parse(mainManifestFile)def exportedTag = "android:exported"def androidSpace = new groovy.xml.Namespace('http://schemas.android.com/apk/res/android', 'android')def nodes = xml.application[0].'*'.findAll {(it.name() == 'activity' || it.name() == 'receiver' || it.name() == 'service') && it.attribute(androidSpace.exported) == null}nodes.each {def exportedValue = falseit.each {if (it.name() == "intent-filter") {it.each {if (it.name() == "action") {if (it.attributes().get(androidSpace.name) == "android.intent.action.MAIN") {exportedValue = true}}}}}it.attributes().put(exportedTag, "${exportedValue}")}PrintWriter pw = new PrintWriter(mainManifestFile)pw.write(groovy.xml.XmlUtil.serialize(xml))pw.close()} catch (Exception e) {}
}

Android笔记(二十四):gradle写一个android12自动适配exported脚本,支持aab相关推荐

  1. Android热更新十:自己写一个Android热修复

    很早之前就想深入的研究和学习一下热修复,由于时间的原因一直拖着,现在才执笔弄起来. Android而更新系列: Android热更新一:JAVA的类加载机制 Android热更新二:理解Java反射 ...

  2. 教你用Python写一个京东自动下单抢购脚本(Python实现京东自动抢购)

    很多朋友都有网购抢购限量商品的经历,有时候蹲点抢怎么也抢不到,今天小编带你们学习怎么用Python写一个京东自动下单抢购脚本,以后再也不用拼手速拼网速啦,快来一起看看吧 1 问题背景 经过无数次抢购失 ...

  3. 嵌入式Linux驱动笔记(二十四)------framebuffer之使用spi-tft屏幕(上)

    你好!这里是风筝的博客, 欢迎和我一起交流. 最近入手了一块spi接口的tft彩屏,想着在我的h3板子上使用framebuffer驱动起来. 我们知道: Linux抽象出FrameBuffer这个设备 ...

  4. Java笔记二十四——Spring开发

    Spring是一个支持快速开发Java EE应用程序的框架.它提供了一系列底层容器和基础设施,并可以和大量常用的开源框架无缝集成,可以说是开发Java EE应用程序的必备. 在Spring Frame ...

  5. bat脚本如何自动输入y_在Mac如何写一个相对自动的翻译脚本

    近来使用的google翻译的插件有些不稳定, 时灵时不灵的,无奈的使用百度翻译了, 感觉体验也不好, 就想自己写一个翻译的脚本. 整体思路简单, 就是调用百度翻译api再将结果呈现出来, 最后使用al ...

  6. Android笔记(二十):写一个图片文字识别SDK给自己用

    背景 市面上文字识别大多需要开通会员才能使用,所以决定自己封装一个sdk出来,供后面开发扫描类app提供便捷工具 效果 SDK API 初始化 需进行初始化才能使用sdk EasyOcrSDK.get ...

  7. 【Visual C++】游戏开发笔记二十四 由DirectX的几个版本说开去

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...

  8. Java8的其它 新特性(笔记二十四)

    标题 Java 8新特性简介 一.Lambda表达式 1.为什么使用Lambda表达式 2.使用举例 二.函数式(Functional)接口 1.什么是函数式(Functional)接口 2.如何理解 ...

  9. Android笔记(十九)制作一个简易的指南针

    一.获取方向的方法 Android 获取手机旋转的方向和角度是通过加速度传感器和地磁传感器共同计算得出的,这是 Android 目前推荐使用的方式.正常情况下,手机的头部如果是正北方向,那么它围绕Z轴 ...

最新文章

  1. 中大李文均团队在氮循环功能基因的生物地理学分布格局研究中取得进展
  2. 依图超车争夺AI创业第一股!冲刺科创板,募资75亿为造芯,去年营收91%投向研发...
  3. 博弈论笔记:谈判与讨价还价
  4. html中超链接使用_干货 | HTML中表格的使用方法
  5. CSDN Blog 之七宗罪
  6. Android智能电视应用程序开发浅谈(二)
  7. js function定义函数的4种方法
  8. 开课吧课堂:什么是多线程编程?
  9. TensorFlow Seq2Seq模型样例:实现语言翻译
  10. VoLTE 信令分析手册
  11. 故障树手册(Fault Tree handbook)(3)
  12. 详说ArcGIS之重采样技术图文解析
  13. 江西2万余个村庄整治建设 古村落旧貌换新颜
  14. MySQL-day02作业
  15. Vulkan_Shader—高级光照_阴影_原理
  16. python中doc转docx
  17. 使用python批量下载需要的分子的SDF文件
  18. Elasticsearch 基于地理位置的搜索查询
  19. websocket系列:基于tio-websocket-spring-boot-starter实现二进制数据发送
  20. struts2 文件上传为空

热门文章

  1. “年薪 25 万只是白菜价”已成过去式,AI 岗位年薪下降 8.9%,最新薪酬报告发布
  2. 金融行业工作报告自动生成系统
  3. noteexpress 笔记导出_笔记软件Cloud Outliner值得被推荐的理由
  4. Ubuntu连接宽带的设置
  5. VB MSHFlexGrid控件:MergeCells和MergeCol、MergeRow 属性。msflexgrid 内容随流滚动条滚动
  6. openresty 操作 redis
  7. 百度文字识别API调用
  8. 爬取豆瓣Top 250电影信息、下载图片、存储到Excel,快来试试吧!
  9. HTML中 :before 和 :after 的用法
  10. 计算机教师职业幸福感,教师的职业幸福感