Android——Gradle automatically packages and uploads Dandelion and reminds DingTalk group

Frequent packaging during the development and testing phase is too boring, and automatic packaging and release can free your hands. In the previous section, we analyzed the process of fastlane packaging and publishing. Well, it is a bit cumbersome in general, and Android uses fast lane to automatically package online materials. There are relatively few online materials, and it is quite difficult to solve problems after errors. So today we will use a simpler way to automatically package and publish.

1. Gradle automatically packages and releases Dandelion

Dandelion Upload Apk Official Documentation

apply from: './dingding.gradle'//引用钉钉通知方法

def apkFileName = "${
      
      buildTime()}_test_v${rootProject.ext.android["versionName"]}_release.apk"
def apkFilePath = "${
      
      projectDir.absolutePath}/build/outputs/apk/test/release/${
      
      apkFileName}"

private def uploadPGY(String filePath) {
    
    
    def stdout = new ByteArrayOutputStream()
    exec {
    
    
        executable = 'curl'
        args = ['-F', "file=@${
      
      filePath}", '-F', "_api_key=${rootProject.ext.pgy["apiKey"]}", rootProject.ext.pgy["uploadUrl"]]
        standardOutput = stdout
    }
    String output = stdout.toString()
    def parsedJson = new groovy.json.JsonSlurper().parseText(output)
    println parsedJson.data.buildQRCodeURL
    println "蒲公英上传完成 版本号:" + parsedJson.data.buildVersion

    println "开始发送钉钉群通知"
    def downloadUrl = "https://www.pgyer.com/" + parsedJson.data.buildShortcutUrl
    postDingMsg(parsedJson.data.buildQRCodeURL, downloadUrl)
}

task uploadApk(dependsOn: '打包Task名称') {
    
    //可以从Gradle的Task列表中选取,也可以点击查看Generate Signed Bundle/Apk执行的task是什么,复制出来就好了
    group = "publish"//GradleTask列表中会生成一个publish的分组,里面包含uploadApk,后续只要点击这个uploadTask任务就可以自动打包发布了
    doLast {
    
    
        println "打包完成: ${
      
      apkFilePath}"
        println "开始上传蒲公英"
        uploadPGY(apkFilePath)
    }
}

Note: Remember to import this file in the app's build.gradle.

2. DingTalk group notification

Custom DingTalk Robot Documentation

1. Create a custom DingTalk robot

Click the setting button in the upper right corner of the group 打开群设置->智能群助手->添加机器人->自定义机器人->填写机器人名称和关键词(when sending a DingTalk group message after the keyword here, the message content must contain the keyword, otherwise the sending will not be successful)
insert image description hereinsert image description here
insert image description here

2. Access DingTalk group notification

import groovy.json.JsonBuilder
import groovy.json.JsonOutput

def dingDingUrl = "https://oapi.dingtalk.com/robot/send?access_token=${rootProject.ext.dingding["accessToken"]}"

ext.postDingMsg = {
    
     String qrcodeUrl, String downloadUrl ->
    String allTips =
            "版本号:V${rootProject.ext.android["versionName"]}\n" +
            "下载地址:${
      
      downloadUrl}\n" 

    postAll(dingDingUrl, allTips, qrcodeUrl, downloadUrl)
}

//发送到群,@所有人
def postAll(url, tips, qrcodeUrl, downloadUrl) {
    
    
    JsonBuilder builder = new JsonBuilder()
    builder {
    
    
        msgtype 'link'
        link {
    
    
            title '新版本发布提醒'
            text tips
            messageUrl downloadUrl
            picUrl qrcodeUrl
        }
        at {
    
    
            isAtAll false   //@所有人(只有text,markdown,actioncard这三种消息类型支持@功能)
        }
    }
    String data = JsonOutput.prettyPrint(builder.toString())
    postDingDing(url, data)
}

//调用接口,发送消息
def postDingDing(urlString, msg) {
    
    
    if (msg == null) {
    
    
        return
    }
    HttpURLConnection conn = null
    OutputStream outputStream = null
    try {
    
    
        if (conn == null) {
    
    
            URL url = new URL(urlString)
            conn = (HttpURLConnection) url.openConnection()
        }
        if (conn != null) {
    
    
            conn.setReadTimeout(15000)
            conn.setConnectTimeout(15000)
            conn.setDoOutput(true)
            conn.setUseCaches(false)
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8")
        }

        if (conn == null) {
    
    
            return null
        }
        if (msg != null && msg.length() > 0) {
    
    
            DataOutputStream dataOutputStream = new DataOutputStream(conn.getOutputStream())
            byte[] t = msg.getBytes("utf-8")
            dataOutputStream.write(t)
            dataOutputStream.flush()
            dataOutputStream.close()

            int res = conn.getResponseCode()
            if (res == 200) {
    
      //成功
                InputStream input = conn.getInputStream()
                StringBuffer sb = new StringBuffer()
                int ss
                while ((ss = input.read()) != -1) {
    
    
                    sb.append((char) ss)
                }
                println "发送消息成功: ${
      
      sb.toString()}"
            } else {
    
    
                println("发送消息失败: " + conn.getResponseCode())
            }
        }
    } catch (EOFException e) {
    
    
        e.printStackTrace()
    } catch (IOException e) {
    
    
        e.printStackTrace()
    } finally {
    
    
        if (outputStream != null) {
    
    
            try {
    
    
                outputStream.close()
            } catch (IOException e) {
    
    
                e.printStackTrace()
            }
        }
        if (conn != null) {
    
    
            conn.disconnect()
        }
    }
}

Find the newly created robot and open
insert image description here
Copy Webhook地址to see accessTokenthe fields. Next, let's configure the parameters that need to be used.
群组消息类型You can refer to the official documentation and adjust it according to your needs. Defaults to type in code link.

3. Related configuration

Open build.gradle in the root directory and fill in the code:

ext {
    
    
    android = [
            versionCode: 1,
            versionName: "1.0.0.0"
    ]

    pgy = [
            apiKey     : "xxx",
            uploadUrl  : "https://www.pgyer.com/apiv2/app/upload"
    ]

    dingding = [
            accessToken: "xxx",
    ]
}

4. Effect picture:

insert image description here

5. SSL bug modification

Recently, I uploaded it to the computer (windows) OpenSSL, and an error occurred in the automatic upload curcall command.

curl: (35) schannel: next InitializeSecurityContext failed: Unknown error (0x80092013)

problem causes:

The windows version curlrelies on WinSSL / WinTLS (that is, Microsoft's Secure Channel, see https://msdn.microsoft.com/en-us/library/aa380123.aspx ) to provide https support, while the Linux version of curl relies on the opensslversion of the two. perform inconsistently.

Since the window was originally built-in ssh, this time I installed OpenSSL again and guessed that there was a conflict between the two.

Solution:

Add --ssl-no-revokeparameters and 关闭证书吊销检查functions to curl, and the modified curl upload code is as follows:

private def uploadPGY(String filePath) {
    
    
    def stdout = new ByteArrayOutputStream()
    exec {
    
    
        executable = 'curl'
        args = ['--ssl-no-revoke','-F', "file=@${
      
      filePath}", '-F', "_api_key=${rootProject.ext.pgy["apiKey"]}", rootProject.ext.pgy["uploadUrl"]]
        standardOutput = stdout
    }
    String output = stdout.toString()
    def parsedJson = new groovy.json.JsonSlurper().parseText(output)
    println parsedJson.data.buildQRCodeURL
    println "蒲公英上传完成 版本号:" + parsedJson.data.buildVersion
}

6. Dingding news @someone

Official document: https://open.dingtalk.com/document/group/robot-message-type-staff-information-in-an-enterprise
supports Dingding message @someone There are three message formats: text, markdown, actioncard. Only one of them textwill be highlighted, the other two will not.

//发送到群,@所有人
def postAtSomeone(url, tips, qrcodeUrl, downloadUrl) {
    
    
    //发送@某人消息
    JsonBuilder atPersonBuilder = new JsonBuilder()
    atPersonBuilder {
    
    
        msgtype 'text'
        text {
    
    
            content "更新内容:\n${rootProject.ext.android["versionUpdateRemark"]}\n" +
                    "@zfndm1v81"
        }
        at {
    
    
            isAtAll false   //@所有人
            atDingtalkIds (["zfndm1v81"])//打开钉钉群,找到要@的人,复制他的钉钉号即可
            //atMobiles (["135********"])
        }
    }
    String personData = JsonOutput.prettyPrint(atPersonBuilder.toString())
    postDingDing(url, personData)
}

Note:
1. There are two ways to @someone in the official document, one is to configure this person 钉钉userid, and the other is to configure this person 手机号. The premise is to ensure that the configured userid or mobile phone number must be in this group, otherwise it will be invalid.
2. The configuration method of the user id in the official document is as atUserIdsfollows. After testing, it is found that this configuration item is invalid, and it needs to be changed. atDingtalkIds Maybe the document has been forgotten to be updated.
3. atAfter configuring the information that requires @people in , it is required 在发送的消息中加上@xx, otherwise @ is invalid.

  • text消息: contentSplice @xx in
  • markdown消息| actionCard消息: textsplice @xx in

4. atDingtalkIdsand atMobilescan be configured at the same time.
5. Pay attention to the array configuration method in gradle ([]). I don't understand the grammar of groovy very well. Students who want to know more about it can Baidu it themselves.

Guess you like

Origin blog.csdn.net/u012230055/article/details/124753120