Android: Gradle empaqueta y carga automáticamente Dandelion y recuerda al grupo DingTalk

El empaquetado frecuente durante la fase de desarrollo y prueba es demasiado aburrido, y el empaquetado y lanzamiento automáticos pueden liberarle las manos. En la sección anterior, analizamos el proceso de empaquetado y publicación Fastlane. Bueno, es un poco engorroso en general, y Android usa Fast Lane para empaquetar automáticamente materiales en línea. Hay relativamente pocos materiales en línea y es bastante difícil de resolver. problemas después de errores. Así que hoy usaremos una forma más sencilla de empaquetar y publicar automáticamente.

1. Gradle empaqueta y lanza automáticamente Dandelion

Documentación oficial de Dandelion Upload Apk

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)
    }
}

Nota: Recuerde importar este archivo en el archivo build.gradle de la aplicación.

2. Notificación de grupo DingTalk

Documentación personalizada del robot DingTalk

1. Cree un robot DingTalk personalizado

Haga clic en el botón de configuración en la esquina superior derecha del grupo 打开群设置->智能群助手->添加机器人->自定义机器人->填写机器人名称和关键词(al enviar un mensaje de grupo DingTalk después de la palabra clave aquí, el contenido del mensaje debe contener la palabra clave; de ​​lo contrario, el envío no se realizará correctamente)
inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

2. Acceder a la notificación del grupo DingTalk

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()
        }
    }
}

Busque el robot recién creado y abra
inserte la descripción de la imagen aquí
Copiar Webhook地址para ver accessTokenlos campos. A continuación, configuremos los parámetros que deben usarse.
群组消息类型Puede consultar la documentación oficial y ajustarla según sus necesidades. Valores predeterminados para escribir el código link.

3. Configuración relacionada

Abra build.gradle en el directorio raíz y complete el código:

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

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

    dingding = [
            accessToken: "xxx",
    ]
}

4. Imagen de efecto:

inserte la descripción de la imagen aquí

5. Modificación de errores de SSL

Recientemente, lo subí a la computadora (Windows) OpenSSLy ocurrió un error en el curcomando de llamada de carga automática.

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

causas del problema:

La versión de Windows curlse basa en WinSSL / WinTLS (es decir, el canal seguro de Microsoft, consulte https://msdn.microsoft.com/en-us/library/aa380123.aspx) para brindar compatibilidad con https, mientras que la versión de Linux de curl se basa en la opensslversión de los dos funcionan de manera inconsistente.

Dado que la ventana estaba originalmente integrada ssh, esta vez instalé OpenSSL nuevamente y supuse que había un conflicto entre los dos.

Solución:

Agregue --ssl-no-revokeparámetros y 关闭证书吊销检查funciones a curl, y el código de carga de curl modificado es el siguiente:

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. Buenas noticias @alguien

Documento oficial: https://open.dingtalk.com/document/group/robot-message-type-staff-information-in-an-enterprise
admite el mensaje Dingding @someone Hay tres formatos de mensaje: text, markdown, actioncard. Solo textse resaltará uno de ellos, los otros dos no.

//发送到群,@所有人
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)
}

Nota:
1. Hay dos formas de @alguien en el documento oficial, una es configurar a esta persona 钉钉useridy la otra es configurar a esta persona 手机号. La premisa es garantizar que el ID de usuario configurado o el número de teléfono móvil debe estar en este grupo. , de lo contrario no será válido.
2. El método de configuración de la identificación de usuario en el documento oficial es el siguiente atUserIds. Después de la prueba, se encuentra que este elemento de configuración no es válido y debe cambiarse. atDingtalkIds Tal vez se olvidó actualizar el documento.
3. atDespués de configurar la información que requiere @personas en , es obligatorio 在发送的消息中加上@xx, de lo contrario @ no es válido.

  • text消息: contentEmpalme @xx en
  • markdown消息| actionCard消息: textempalme @xx en

4. atDingtalkIdsy atMobilesse puede configurar al mismo tiempo.
5. Preste atención al método de configuración de matriz en gradle ([]). No entiendo muy bien la gramática de groovy. Los estudiantes que quieran saber más al respecto pueden Baidu ellos mismos.

Supongo que te gusta

Origin blog.csdn.net/u012230055/article/details/124753120
Recomendado
Clasificación