AS--›Gradle乐固加固和下载

推荐阅读, 优先了解Gradle的使用:
AS–›Gradle上传文件至七牛云
AS–›Gradle上传文件至蒲公英

目录

  • 说明
    • 1. 只能加固url对应的apk
    • 2. 需要自己手动重新签名
  • 乐固加固
  • 待完善
  • 联系作者

说明

1. 只能加固url对应的apk

由于乐固加固只能使用在线APK的url, 所以需要先将本地的APK, 上传至七牛云或者其他文件存储服务器. 拿到url之后, 才能使用乐固加固

2. 需要自己手动重新签名

乐固加固后的APK, 并没有签名. 所以, 加固下载后的APK, 需要手动签名. 才能正常安装.

乐固加固

import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.MediaType

import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.concurrent.TimeUnit
import com.google.gson.Gson

import com.tencentcloudapi.common.*
import com.tencentcloudapi.common.profile.*
import com.tencentcloudapi.common.exception.*

import com.tencentcloudapi.ms.v20180408.*
import com.tencentcloudapi.ms.v20180408.models.*


buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "com.squareup.okhttp3:okhttp:3.12.0"
        classpath "com.google.code.gson:gson:2.8.5"
        classpath "com.tencentcloudapi:tencentcloud-sdk-java:3.0.8"
    }
}

ext.leguConfig = [
        "SecretId"       : "",
        "SecretKey"      : "",

        //需要加固的APK url地址
        "apkUrl"         : "",

        //本地APK的路径, 用来计算MD5值
        "apkPath"        : "./ademo.apk",
        //加固后, 下载保存到本地路径
        "downloadApkPath": "./ademo_legu.apk",

        //每隔多少秒, 查询一次加固结果
        "pollTime"       : "10",

        //加固后, 返回的ItemId, 用来轮询结果
        "ItemId"         : "",

        //加固成功的下载地址
        "downloadUrl"    : ""
]

task _leguJiaGu() {
    doFirst {
        Credential cred = new Credential(leguConfig.SecretId, leguConfig.SecretKey)
        HttpProfile httpProfile = new HttpProfile()
        httpProfile.setEndpoint("ms.tencentcloudapi.com")

        ClientProfile clientProfile = new ClientProfile()
        clientProfile.setHttpProfile(httpProfile)

        MsClient client = new MsClient(cred, "", clientProfile)

        def req = new CreateShieldInstanceRequest()
        def appInfo = new com.tencentcloudapi.ms.v20180408.models.AppInfo()
        appInfo.AppUrl = leguConfig.apkUrl
        appInfo.AppMd5 = getFileMd5(leguConfig.apkPath)

        def serviceInfo = new com.tencentcloudapi.ms.v20180408.models.ServiceInfo()
        serviceInfo.ServiceEdition = "basic"
        serviceInfo.SubmitSource = "RDM-rdm"
        serviceInfo.CallbackUrl = ""

        req.AppInfo = appInfo
        req.ServiceInfo = serviceInfo

        CreateShieldInstanceResponse resp = client.CreateShieldInstance(req)

        leguConfig.ItemId = resp.ItemId
        //Progress任务状态: 1-已完成,2-处理中,3-处理出错,4-处理超时
        println "加固处理中:" + DescribeShieldInstancesRequest.toJsonString(resp)

        _legtGetResult.doLast {
            println "加固结束"
        }
        _legtGetResult.execute()
    }
}

/**
 * 用户查询提交过的app列表
 * */
task _leguGetAppList() {
    doFirst {
        Credential cred = new Credential(leguConfig.SecretId, leguConfig.SecretKey)
        HttpProfile httpProfile = new HttpProfile()
        httpProfile.setEndpoint("ms.tencentcloudapi.com")

        ClientProfile clientProfile = new ClientProfile()
        clientProfile.setHttpProfile(httpProfile)

        MsClient client = new MsClient(cred, "", clientProfile)

        String params = "{}"
        DescribeShieldInstancesRequest req = DescribeShieldInstancesRequest.fromJsonString(params, DescribeShieldInstancesRequest.class)

        DescribeShieldInstancesResponse resp = client.DescribeShieldInstances(req)

        System.out.println(DescribeShieldInstancesRequest.toJsonString(resp))
    }
}

/**
 * 查询加固结果
 * */
task _legtGetResult() {
    doFirst {
        def TaskStatus = 2
        while (TaskStatus == 2) {
            println ""

            def cred = new Credential(leguConfig.SecretId, leguConfig.SecretKey)
            def httpProfile = new HttpProfile()
            httpProfile.setEndpoint("ms.tencentcloudapi.com")

            def clientProfile = new ClientProfile()
            clientProfile.setHttpProfile(httpProfile)

            def client = new MsClient(cred, "", clientProfile)

            def params = "{\"ItemId\":\"" + leguConfig.ItemId + "\"}"
            def req = DescribeShieldResultRequest.fromJsonString(params, DescribeShieldResultRequest.class)

            println leguConfig.pollTime + "s后, 查询加固状态:" + params
            Thread.sleep(Integer.parseInt(leguConfig.pollTime) * 1000L)
            def resp = client.DescribeShieldResult(req)

            TaskStatus = resp.TaskStatus

            leguConfig.downloadUrl = resp.ShieldInfo.AppUrl

            //TaskStatus任务状态: 1-已完成,2-处理中,3-处理出错,4-处理超时
            println DescribeShieldResultRequest.toJsonString(resp)
        }

        println ""

        if (TaskStatus == 1) {
            println "加固成功下载地址:" + leguConfig.downloadUrl

            println "开始下载->" + file(leguConfig.downloadApkPath).getAbsolutePath()
            downloadFile(leguConfig.downloadUrl, leguConfig.downloadApkPath)
        } else {
            println "加固失败"
        }
    }
}

static def getFileMd5(filePath) {
    def FILE_READ_BUFFER_SIZE = 16 * 1024
    MessageDigest digester = MessageDigest.getInstance("MD5")
    def stream = new FileInputStream(filePath)
    int bytesRead
    byte[] buf = new byte[FILE_READ_BUFFER_SIZE]
    while ((bytesRead = stream.read(buf)) >= 0) {
        digester.update(buf, 0, bytesRead)
    }
    def md5code = new BigInteger(1, digester.digest()).toString(16)// 16进制数字
    // 如果生成数字未满32位,需要前面补0
    for (int i = 0; i < 32 - md5code.length(); i++) {
        md5code = "0" + md5code
    }
    return md5code

}

//下载加固后的文件
static def downloadFile(url, filePath) {
    def clientBuilder = new OkHttpClient.Builder()
    clientBuilder.connectTimeout(10, TimeUnit.SECONDS)
    clientBuilder.readTimeout(60, TimeUnit.SECONDS)

    OkHttpClient client = clientBuilder.build()

    def request = new Request.Builder()
            .url(url)
            .get()
            .build()

    def response = client.newCall(request).execute()

    def write = new BufferedOutputStream(new FileOutputStream(filePath, false))
    def read = new BufferedInputStream(response.body().byteStream())

    def bytes = new byte[1024]
    def bytesRead = 0
    while ((bytesRead = read.read(bytes)) != -1) {
        write.write(bytes, 0, bytesRead)
    }
    read.close()
    write.flush()
    write.close()
}

执行: gradlew _leguJiaGu

待完善

  • 1:添加自动签名脚本
  • 2:添加Walle分包脚本

如果有小伙伴写好了, 欢迎分享给我.


群内有各(pian)种(ni)各(jin)样(qun)的大佬,等你来撩.

联系作者

点此快速加群

请使用QQ扫码加群, 小伙伴们都在等着你哦!

关注我的公众号, 每天都能一起玩耍哦!

你可能感兴趣的:(Android,Studio(AS),Gradle实用实战操作)