Android 自定义Gradle插件(八):检查Manifest中的权限

·  阅读 597

最近公司上到Google Play的App收到了通知,需要对QUERY_ALL_PACKAGES权限进行处理,如果确实需要使用该权限,需要提交声明表单,无需使用则要在Manifest中移除该权限。

1652505389(1).png

第一时间检查了App主项目中的清单文件,没有发现该权限,所以这个权限是来自三方SDK,接入的三方SDK比较多,一个个去看有点麻烦。想到了可以使用自定义Gradle插件来解决,下面介绍一下如何实现。

1. 向插件传入需检查的权限

自定义extensions用于从主项目向插件传入需要检测的权限,代码如下:

//Extension类
class PermissionExtension {
    ArrayList<String> checkPermissions
}

class MiniGamePermissionPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        //注册Extension类
        def permissionExtension = project.extensions.create("CheckPermissionExtension", PermissionExtension)

        project.afterEvaluate {
            //获取传入的需检查的权限
            permissionExtension.checkPermissions
        }
    }
}
复制代码

2. 自定义检查Manifest权限的Task

自定义的Task代码如下:

class CheckPermissionEntity {

    def permissionName = ""

    def hasPermission = false
}

class CheckPermissionTask extends DefaultTask {

    private static def manifestCollection
    private static def checkPermissions = new ArrayList<CheckPermissionEntity>()
    private static def android = new Namespace("http://schemas.android.com/apk/res/android", "android")

    @TaskAction
    void doTaskAction() {
        manifestCollection.each {
            handlerVariantManifestFile(it)
        }
    }

    static void setData(FileCollection collection, ArrayList<String> checkPermissions) {
        manifestCollection = collection
        this.checkPermissions.clear()
        checkPermissions.each {
            def entity = new CheckPermissionEntity()
            entity.permissionName = it
            entity.hasPermission = false
            this.checkPermissions.add(entity)
        }
    }

    static void handlerVariantManifestFile(File manifestFile) {
        if (!manifestFile.exists()) {
            LogUtils.println("manifestFile do not exists")
            return
        }

        //每个Manifest读取前先把是否有权限置为false
        checkPermissions.each {
            it.hasPermission = false
        }

        try {
            XmlParser xmlParser = new XmlParser()
            def node = xmlParser.parse(manifestFile)
            //获取user-permission标签
            NodeList nodeList = node.get("uses-permission")
            if (!nodeList.isEmpty()) {
                checkPermissions.each {
                    nodeList.find { permissionNode ->
                        def permissionName = permissionNode.attributes()[android.get("name")]
                        if (permissionName == it.permissionName) {
                            it.hasPermission = true
                        }
                        return it.hasPermission
                    }
                }
            }
            def hasOnePermissionAtLeast = false
            def result = node.attributes()["package"] + " contains permission "
            checkPermissions.each {
                if (it.hasPermission) {
                    if (!hasOnePermissionAtLeast) {
                        hasOnePermissionAtLeast = true
                    }
                    result = result + it.permissionName + (checkPermissions.indexOf(it) == checkPermissions.size() - 1 ? "." : ",")
                }
            }
            //至少包含一个权限,则输出日志
            if (hasOnePermissionAtLeast) {
                LogUtils.println(result)
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace()
        } catch (SAXException e) {
            e.printStackTrace()
        } catch (IOException e) {
            e.printStackTrace()
        }
    }
}
复制代码

3. 添加自定义Task

代码如下:

class MiniGamePermissionPlugin implements Plugin<Project> {

    static def variantNames = new ArrayList()

    @Override
    void apply(Project project) {
        def permissionExtension = project.extensions.create("CheckPermissionExtension", PermissionExtension)
        def appExtension = project.extensions.findByType(AppExtension.class)

        project.afterEvaluate {
            appExtension.getApplicationVariants().findAll {
                if (!variantNames.contains(it.name)) {
                    variantNames.add(it.name)
                }
            }

            variantNames.each {
                //创建Task,并设置分组
                CheckPermissionTask checkPermissionTask = project.getTasks().create(String.format("MiniGameCheck%sPermissionTask", it.capitalize()), CheckPermissionTask)
                checkPermissionTask.group = "MiniGameCheckPermission"
                setCheckPermissionTaskData(project, checkPermissionTask, it.capitalize(), permissionExtension.checkPermissions)
            }
        }
    }

    private static void setCheckPermissionTaskData(Project project, CheckPermissionTask checkPermissionTask, String name, ArrayList<String> checkPermissions) {
        try {
            //找到处理Manifest的Task
            ProcessApplicationManifest processManifestTask = project.getTasks().getByName(String.format("process%sMainManifest", name))
            //设置Manifest文件和需要检查的权限集合
            checkPermissionTask.setData(processManifestTask.getManifests(), checkPermissions)
        } catch (Exception e) {
            e.printStackTrace()
        }
    }
}
复制代码

接入插件

在项⽬下的build.gradle中添加如下代码:

buildscript {

    repositories {
        maven {
            allowInsecureProtocol(true)
            url 'http://101.43.13.248:8081/repository/sdk-aggregation/' 
        }
    

    dependencies {
        classpath("com.minigame.minicloud:checkpermission-g65-debug:1.0.1.14-SNAPSHOT")
    }
}
复制代码

在app module下的build.gradle中添加如下代码:

plugins {
    id("minigame-permission-plugin")
}

//要检测的权限
CheckPermissionExtension {
    checkPermissions = [
            "android.permission.ACCESS_NETWORK_STATE",
            "android.permission.ACCESS_WIFI_STATE",
            "com.google.android.gms.permission.AD_ID"
    ]
}
复制代码

接入插件构建后,可以在Gradle中看到自定义的Task。

1652509603.png

执行Task之后,可以在AndroidStudio底部的Build或者Run中看到日志。

1652510900(1).png

分类:
Android
标签:
分类:
Android
标签:
收藏成功!
已添加到「」, 点击更改