写在前面
某一天查看 App 的权限列表发现多了很多没声明过的权限,现在开发 App 都不可避免引入各种 SDK,很显然就是他们的锅,在背后干着不可告人的事情.. 怎么删除这些权限呢?
方法1:利用 xml 的 “remove” 节点删除
<uses-permission
android:name="android.permission.CHANGE_NETWORK_STATE"
tools:node="remove"
/>
这样 Android 处理 AndroidManifest.xml 文件时会自动删除这个权限。
有时我们在 debug 需要这个权限,但是在 release 正式版不想有这个权限。比如我在测试包的时候写了点测试功能,需要引入一个 android:name=”android.permission.SYSTEM_ALERT_WINDOW” 权限,但是正式环境并不需要。
一个做法是,将这个测试功能单独做成一个 lib 引入,正式版引用一个 lib-noop 版本,常见的第三方库如滴滴的多啦爱梦就是这么做的。
如果我们自己处理可以利用 gradle 直接对 xml 文件进行操作:
方法2:利用 gradle 编辑 xml 文件
gradle 处理 Manifest 任务之后会有一个回调,我们在系统处理完之后再进行二次处理,通过 XmlParser 解析 xml 来修改文件。
以下是一个 删除 android.permission.SYSTEM_ALERT_WINDOW 的例子:
// 发布正式版时 将 manifest 中不必要的权限删除
android.applicationVariants.all { variant ->
if (variant.buildType.name == "release") {
def output = variant.outputs[0]
output.getProcessManifestProvider().get().doLast {
println("start process manifest")
def manifestFilePath = "${manifestOutputDirectory.asFile.get()}/AndroidManifest.xml"
def xmlParser = new XmlParser()
Node manifest = xmlParser.parse(file(manifestFilePath))
def android = new Namespace('http://schemas.android.com/apk/res/android', 'android')
def tools = new Namespace('http://schemas.android.com/tools', 'tools')
Node systemAlertWindow = manifest.get("uses-permission").find {
def name = it.attributes().get(android.name)
def remove = it.attributes().get(tools.remove)
name == "android.permission.SYSTEM_ALERT_WINDOW"
}
def remove = manifest.remove(systemAlertWindow)
// write xml to file
file(manifestFilePath).withPrintWriter { out ->
def printer = new XmlNodePrinter(out)
printer.preserveWhitespace = true
printer.print(manifest)
}
println("end process manifest, delete systemAlertWindow permission success? $remove")
}
}
}