Android gradle打包并自动上传的方法

简介

这篇文章主要介绍Android用gradle打包,并且调用python脚本将打包好的apk上传到fir.im供相关人员下载,对于学习gradle 打包和python 几个常用网络库有一定帮助

关键字 :Android Gradle Python fir.im

1 开发前准备

开发前需要下载 AndroidStudio ,gradle(3.3版本),python3.6,Curl,pycurl

准备fir.im账号一个,有账号对应的apitoken,具体fir.im的细节可查看文档fir.im

开发环境为macOS,windows推荐把pycurl部分全部替换为requests,即上传apk部分代码换为上传图标的那种方式,详细见代码

2 Gradle 脚本编写

我们脚本需要做的事情就是在APK打包完成以后,把apk的路径传递给python脚本即可,如何保证打包好了,就用gradle的dependsOn方法,例如打debug包,我们就可以写一个task ,这个task dependsOn ‘assembleDebug',这样这个task调用时,会先执行assembleDebug,然后在执行里面的代码,即符合我们的需要
具体代码

//这个task 需要放在 app/build.gradle文件中的android 代码块里 task assemblewithlog { dependsOn 'assembleDebug' doLast { //这个需要配置一下,app的图标 def appicon = "app/src/main/res/drawable/icon.png" //这个需要配置一下,app的输出到fir.im的名称 def outId = "yitiji_Debug" //取 apk的版本名和apk的输出文件目录 def verName = project.android.defaultConfig.versionName; def apkpath = applicationVariants.first().outputs.first().outputFile //调用python脚本 这个脚本需要放在工程目录下 def process = "python3 uploadfirim.py ${outId} ${verName} ${appicon} ${apkpath}".execute() // Wait till the process completes before continuing println("上传apk中") //将python代码里面打印的内容在gradle窗口中打印出来 ByteArrayOutputStream result = new ByteArrayOutputStream(); def inputStream = process.getInputStream() byte[] buffer = new byte[1024]; int length; while ((length = inputStream.read(buffer)) != -1) { result.write(buffer, 0, length); } println(result.toString("UTF-8")); //阻塞gradle代码直到python代码执行结束 int exitValue = process.waitFor() println "上传结束 with value $exitValue" } }

3 python脚本的编写

这个python脚本有点学习的内容,所以使用了 urllib ,requests,pycurl三个网络请求库,实际上只用一种就好了。这里关键是需要了解fir.im上传的请求格式和响应,细节可以看文档fir.im,主要是先将apk的标识信息和用户的apitoken传给fir.im,它会响应文件上传的地址和图标上传的地址,然后将对应的文件和信息传入返回的地址即可,最后在通过apk的标识信息和用户的apitoken可以查询到此apk在fir.im对应的下载页面

那么就安装这三步来讲好了

3.1 查询上传地址

官方文档 如下

调用示例 curl -X "POST" "http://api.fir.im/apps" \ -H "Content-Type: application/json" \ -d "{\"type\":\"android\", \"bundle_id\":\"xx.x\", \"api_token\":\"aa\"}" 响应示例 # status: 201 { "id": "5592ceb6537069f2a8000000", "type": "ios", "short": "yk37", "cert": { "icon": { "key": "xxxxx", "token": "xxxxxx", "upload_url": "http://upload.qiniu.com" }, "binary": { "key": "xxxxx", "token": "xxxxxx", "upload_url": "http://upload.qiniu.com" } } }

所以按照文档写python3 代码如下

#encoding = utf-8 import traceback from urllib import request from urllib import parse import requests import pycurl import json from io import BytesIO import time import sys def uploadtofirim(): minlen = 5 #检查参数传递,定义好按照 name version 图标路径 apk路径 apitoken 的顺序传递参数 syslen = len(sys.argv) if syslen < minlen: print("传递参数有误") return if syslen > 5: apitoken = sys.argv[5] else: #这是一个无效的token,只是为了展示用,需要替换为你自己的fir.imtoken apitoken = "7a15a28c75005akkkklllle051c71" appname = sys.argv[1] appversion = sys.argv[2] iconpath = sys.argv[3] apkpath = sys.argv[4] #利用urllib 请求并获取响应,数据格式见fir.im文档 data = parse.urlencode({'type': 'android', 'bundle_id': appname, 'api_token': apitoken}) datas = data.encode('utf-8') req = request.Request(url='http://api.fir.im/apps', data=datas, method='POST') icondict = {} binarydict = {} try: with request.urlopen(req) as f: strdec = f.read().decode('utf-8') resjson = json.loads(strdec) #将请求的结果存起来后面用 icondict = (resjson["cert"]["icon"]) binarydict = (resjson["cert"]["binary"]) except: print("读取地址失败") pass

3.2 上传图标和apk

之前获取了路径,接下来将文件传上去,注意 python3对于https的请求有坑,如果代码报ssl错误,执行python3 按照目录下的Install Certificates.command文件 ,路径参考 /Applications/Python 3.6/Certificates.command官方文档如下,细节查阅官网

调用示例 curl -F "key=xxxxxx" \ -F "token=xxxxx" \ -F "file=@aa.apk" \ -F "x:name=aaaa" \ -F "x:version=a.b.c" \ -F "x:build=1" \ -F "x:release_type=Adhoc" \ #type=ios 使用 -F "x:changelog=first" \ https://up.qbox.me 响应示例 # status: 201 { "is_completed": true }

所以对应的py脚本如下

#接上面的py代码,复制时注意下格式和缩进 try: local_filename = iconpath c = pycurl.Curl() print("上传图片") files = {'file': open(local_filename, 'rb')} paramdata = {'key': icondict["key"],"token":icondict["token"]} #用 requests库上传图标文件并读取响应,verify=False是因为上传地址是https,不这样写会报错 res = requests.post(icondict["upload_url"], files=files, data=paramdata,verify=False) print(res.text) local_apkfilename = apkpath timenow = str('time :' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) #用 pycurl库上传apk文件并读取响应 c.setopt(c.URL, binarydict["upload_url"]) c.setopt(c.HTTPPOST, [ ("file", (c.FORM_FILE, local_apkfilename)), ("key", binarydict["key"]), ("token", binarydict["token"]), ("x:name", appname), ("x:version", appversion), ("x:build", '1'), ("x:changelog", timenow) ]) print("上传apk") c.perform() c.close() print("上传成功") except Exception as e: print(e) print("上传文件失败,请检查") return

3.3获得apk文件的下载页面

apk上传好了以后会生成下载分享页面,可以直接通过get请求拿到
官方文档

请求示例 curl http://api.fir.im/apps/latest/xxx?api_token=xxx #使用 `id` 请求 curl http://api.fir.im/apps/latest/im.fir.xxx?api_token=xxx&type=android #根据`bundle_id` 获取更新 响应数据 # status: 200 { "name": "fir.im", "version": "1.0", "changelog": "更新日志", "versionShort": "1.0.5", "build": "6", "installUrl": "http://download.fir.im/v2/app/install/xxxxxxxxxxxxxxxxxxxx?download_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxx", "install_url": "http://download.fir.im/v2/app/install/xxxxxxxxxxxxxxxx?download_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxx", # 新增字段 "update_url": "http://fir.im/fir", # 新增字段 "binary": { "fsize": 6446245 } }

我们用的就是bundle_id,这个bundleid就是我们gradle传进去的名字,返回的update_url 就是分享apk的页面

所以py代码如下

#接上面的py代码,复制时注意下格式和缩进 queryurl='http://api.fir.im/apps/latest/%s?api_token=%s&type=android'%(appname,apitoken) print(queryurl) req = request.Request(url=queryurl,method="GET") try: with request.urlopen(req) as f: strdec = f.read().decode('utf-8') resjson = json.loads(strdec) print("apk下载地址 " + resjson["update_url"]) except Exception as e: print(e) traceback.print_exc() print("读取地址失败") pass

完整的py代码如下

#encoding = utf-8 import traceback from urllib import request from urllib import parse import requests import pycurl import json from io import BytesIO import time import sys def uploadtofirim(): minlen = 5 syslen = len(sys.argv) if syslen < minlen: print("传递参数有误") return if syslen > 5: apitoken = sys.argv[5] else: apitoken = "7akkkkkkkkkkkk1c71" appname = sys.argv[1] appversion = sys.argv[2] iconpath = sys.argv[3] apkpath = sys.argv[4] data = parse.urlencode({'type': 'android', 'bundle_id': appname, 'api_token': apitoken}) datas = data.encode('utf-8') req = request.Request(url='http://api.fir.im/apps', data=datas, method='POST') icondict = {} binarydict = {} try: with request.urlopen(req) as f: strdec = f.read().decode('utf-8') resjson = json.loads(strdec) icondict = (resjson["cert"]["icon"]) binarydict = (resjson["cert"]["binary"]) except: print("读取地址失败") pass try: local_filename = iconpath c = pycurl.Curl() print("上传图片") files = {'file': open(local_filename, 'rb')} paramdata = {'key': icondict["key"],"token":icondict["token"]} res = requests.post(icondict["upload_url"], files=files, data=paramdata,verify=False) print(res.text) local_apkfilename = apkpath timenow = str('time :' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) c.setopt(c.URL, binarydict["upload_url"]) c.setopt(c.HTTPPOST, [ ("file", (c.FORM_FILE, local_apkfilename)), ("key", binarydict["key"]), ("token", binarydict["token"]), ("x:name", appname), ("x:version", appversion), ("x:build", '1'), ("x:changelog", timenow) ]) print("上传apk") c.perform() c.close() print("上传成功") except Exception as e: print(e) print("上传文件失败,请检查") return queryurl='http://api.fir.im/apps/latest/%s?api_token=%s&type=android'%(appname,apitoken) print(queryurl) req = request.Request(url=queryurl,method="GET") try: with request.urlopen(req) as f: strdec = f.read().decode('utf-8') resjson = json.loads(strdec) print("apk下载地址 " + resjson["update_url"]) except Exception as e: print(e) traceback.print_exc() print("读取地址失败") pass # appid vesion icon apk apitoken if __name__ == '__main__': uploadtofirim()

这样就好了

在Android studio对应的工程里面执行代码 gradle assemblewithlog

就开始打包debug并上传到fir.im了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

时间: 2024-10-27 23:55:38

Android gradle打包并自动上传的方法的相关文章

maven/gradle 打包后自动上传到nexus仓库

前提: nexus的相关repository必须设置允许redeploy,参考下图:   maven项目: pom.xml中增加以下节点: <distributionManagement> <repository> <id>nexus-3rd</id> <url>http://localhost:8081/nexus/content/repositories/thirdparty/</url> </repository>

Android App开发中Gradle构建过程的配置方法_Android

在build文件中使用了Android或者Java插件之后就会自动创建一系列可以运行的任务. Gradle中有如下一下默认约定的任务: 1. assemble 该任务包含了项目中的所有打包相关的任务,比如java项目中打的jar包,Android项目中打的apk 2. check 该任务包含了项目中所有验证相关的任务,比如运行测试的任务 3. build 该任务包含了assemble和check 4. clean 该任务会清空项目的所有的输出,删除所有在assemble任务中打的包 assemb

Android App开发中Gradle构建过程的配置方法

在build文件中使用了Android或者Java插件之后就会自动创建一系列可以运行的任务. Gradle中有如下一下默认约定的任务: 1. assemble 该任务包含了项目中的所有打包相关的任务,比如java项目中打的jar包,Android项目中打的apk 2. check 该任务包含了项目中所有验证相关的任务,比如运行测试的任务 3. build 该任务包含了assemble和check 4. clean 该任务会清空项目的所有的输出,删除所有在assemble任务中打的包 assemb

Android多渠道打包的方法步骤

本文介绍了Android多渠道打包的方法步骤,分享给大家,具体如下: 1.生成签名文件 点击 Build -> Generate Signed APK: 2.创建一个签名 红色填写部分需要认真填写,并牢记,其余部分随意填写 有了签名,单个app打包我就不详细说了,具体说下多渠道打包的步骤 2.多渠道打包 作用:就是根据不同的渠道值,去具体分析每个渠道的用户情况 步骤一: 在AndroidManifest.xml的application标签里添加一个meta-data标签定义 <meta-dat

gradle打包android程序时,如何修改java文件中的属性值

问题描述 gradle打包android程序时,如何修改java文件中的属性值 工程有个文件例如1.java文件:其中有个public final static String URL = "/www.baidu.com"; 现在的问题是如何在用gradle打包的时候可以更换1.java文件中的URL? ant打包就可以写不同的build.xml,在build.xml中更换URL的字符串,在利用ant构建的时候通过编译不同的build.xml来达到更换URL的目的. 现在不知道gradl

Android Gradle Build Error:Some file crunching failed, see logs for details的快速解决方法_Android

错误日志:Error:java.lang.RuntimeException: Some file crunching failed, see logs for details Log: FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:mergeDebugResources'. > Error: java.lang.RuntimeException: Crunch

有些方法不能被调用呢-Android打包后,有些方法不能被调用

问题描述 Android打包后,有些方法不能被调用 Android打包后,有些方法不能被调用??请大神们看看啊..我看了有些说 混淆的问题,我试了啊 解决方案 是被混淆了吧,对于用于反射的数据最好不要混淆 解决方案二: android webview addJavascriptInterface 的方法不能调用 解决方案三: 怎么解决呢?? // 数字字典 同步 private void getDigitalDictionary() { DictVersionDBManager versionD

Android编程实现webview将网页打包成apk的方法

本文实例讲述了Android编程实现webview将网页打包成apk的方法.分享给大家供大家参考,具体如下: 功能非常简单,而且乍一看没什么特别大的用处,因为实际上就是浏览器而已...但如果说网页一开始就是针对手机开发的呢?是不是可以将android的开发转变为网页的开发了?有待研究,不过据说也可以用这种方法将html5打包哦,先记录一下可能以后也可以赶下潮流. public class MainActivity extends Activity { private WebView webvie

android studio 3.0 gradle 打包脚本配置详解

本文介绍了android studio 3.0 gradle 打包脚本配置,分享给大家,具体如下: 修改输出的名字 保存输出的文件路径 def fileArray = [] //遍历输出文件 android.applicationVariants.all { variant -> variant.outputs.all { output -> def outputFile = output.outputFile if (outputFile != null && outputF