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了

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

(0)

相关推荐

  • Gradle编译打包Android apk详细介绍

    Gradle编译打包Android apk详细介绍 理解Gradle构建过程,解读Android Gradle插件的配置 阅读本文一定是要使用过Gradle生成apk,文中不会讲如何安装运行Gradle,如有需要可先看文末的参考文章. APK包是一个ZIP压缩包,从Java源代码.资源文件到生成这个APK,经过了编译打包一系列特定的过程,SDK文档(/docs/tools/building/index.html)中找到.而这一系列特定的过程,重复繁琐,构建工具(build tool)就是来流程化

  • AndroidStudio Gradle基于友盟的多渠道打包方法

    AndroidStudio由于使用了gradle的进行项目构建,使我们开发app方便很多,今天我就给大家列出几点是用gradle的方便之处. 一.AndroidStudio Gradle第三依赖统一管理 二.AndroidStudio Gradle基于友盟的多渠道打包 三.AndroidStudio安全管理签名文件keystroe和签名密码 好久没写博客了,今天写一篇关于多渠道打包的文章. 首先我们要下载友盟的jar包,然后照着文档配置即可.(这里就不过多讲解了,直接看我的代码) 文档地址:ht

  • ionic2打包android时gradle无法下载的解决方法

    问题 之前在使用ionic2时使用建立android平台命令或者编译时,总是会在获取gradle时卡住,等很久进度也不变化,导致命令超时失败.于是经过查阅资料和自己实践测试,总结出以下办法. 方法 其实主要原因是用命令下载时用的是指定的下载途径(可能不该这样形容,欢迎大家评论批评指正),国内通过这样下载十分慢,甚至时断时续,从而导致出现上面的问题. 所以我们自己去下载gradle,存放在本地,然后更改配置文件,使其不去网上下载而是从我们指定的本地位置获取. 首先我们打开下面这个js: 你的项目名

  • Android客户端程序Gradle如何打包

    一.前言 android客户端开发进入尾声,负责SEO同事突然发给我一个涉及45个发布渠道的噩耗,之前只发布自有渠道的工作方式(手动修改参数打包)已经不满足需求,所以引入最近比较流行的gradle打包技术. gradle基于groovy语言,引入的原因也方便了以后从现在使用的eclipse开发环境迁移到Android Studio,所以blablabla--,不多说了,先上干货. 二.准备工作 1.首先,如果使用eclipse作为开发环境,需右键点击项目,在菜单中选择"Export-"

  • Android Studio使用教程(六):Gradle多渠道打包

    由于国内Android市场众多渠道,为了统计每个渠道的下载及其它数据统计,就需要我们针对每个渠道单独打包,如果让你打几十个市场的包岂不烦死了,不过有了Gradle,这再也不是事了. 友盟多渠道打包 废话不多说,以友盟统计为例,在AndroidManifest.xml里面会有这么一段: 复制代码 代码如下: <meta-data     android:name="UMENG_CHANNEL"     android:value="Channel_ID" /&g

  • 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

  • Android程序打包为APK的方法详解

    Andriod安装包文件(Android Package),简称APK,后缀名为.apk. 1.生成未签名的安装包 Build -> Build Bundle(s)/APK(s) -> Build APK(s)    会生成一个未签名的apk文件,默认为debug版,可以正常安装使用. 可以 Build -> Select Build Variant -> 选择生成的apk版本(debug.release),再 Build -> Build Bundle(s)/APK(s)

  • Android Studio 打包生成APK文件方法

    Android Studio是谷歌推出一个Android集成开发工具,基于IntelliJ IDEA.它类似于Eclipse ADT,Android Studio 提供了集成的Android开发工具用于开发和调试.那么今天我们就来讲讲如何通过Android Studio打包APK文件,相信有很多用户还不是非常了解,下面通过这篇文章给大家介绍一下. 前面一直使用的是out文件夹里面的那个apk文件(debug版本),最近在使用在线升级的时候发现有些问题,所以想用(release版)试试看. 一.没

  • Android gradle插件打印时间戳的方法详解

    Android中时间戳的详细解释: (1).定义: 时间戳就是根据当前系统时间生成的一组随机数字. (2).作用: 作为对数据唯一性的一种判断依据.避免了重复修改数据所带来的错误! (3).应用: (1).在银行account表中建立时间戳字段timestamp,设定为文本类型varchar. (2).当银行A读取account表中的存款字段时,同时也读取时间戳字段,比如123456. (3).当银行A修改完存款数值后,进行存盘操作时,将先前读取的时间戳123456与当时表中的时间戳进行一次对比

  • Mac中配置gradle环境及使用android studio打包jar包与arr包的方法

    前言 在Mac中用android studio 导出jar包最重要的是需要配置gradle ,它包的导出也是通过gradle命令进行的. 所以,如果想成功打包,要先配置好gradle环境,这样你才可以在android studio中的terminal中直接使用gradle命令了.下面话不多说了,来一起看看详细的介绍吧. gradle 环境变量的配置 1.这个配置和jdk的环境变量配置类似 启动终端,进入当前用户目录. 2.创建 .bash_profile 文件,如果已经有了就直接打开 3.用命令

  • Android Gradle多渠道打包的实现方法

    一.前言 什么是多渠道打包以及多渠道打包可以做什么,这里就不做介绍了,相信看到这篇文章的你已经了解了,多渠道打包的方式比较多,这里我们用Gradle多渠道打包方式. 和其他文章有什么不同 网上看到的大多数文章都只讲解了 1.如何修改包名 2.如何修改变量的值 3.如何替换string中的资源 4.如何替换AndroidManifest中的资源 本篇文章会在上述知识点上增加 5.不同渠道如何使用不同的java文件 6.Base模块化中如何使用多渠道 新建项目,在app下build.gradle中a

  • 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

  • Android Studio 超级简单的打包生成apk的方法

    本文介绍了Android Studio 超级简单的打包生成apk,分享给大家,也给自己留个笔记. 为什么要打包: apk文件就是一个包,打包就是要生成apk文件,有了apk别人才能安装使用.打包分debug版和release包,通常所说的打包指生成release版的apk,release版的apk会比debug版的小,release版的还会进行混淆和用自己的keystore签名,以防止别人反编译后重新打包替换你的应用. 简单点说就是给你的apk发身份证,上户口,防止和你长的一样的人,假冒你.这里

随机推荐