簡介
這篇文章主要介紹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 = http://www.jb51.net/article/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 = http://www.jb51.net/article/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=http://www.jb51.net/article/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 "[email protected]" \ -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 = http://www.jb51.net/article/{'key': icondict["key"],"token":icondict["token"]} #用 requests庫上傳圖標文件並讀取響應,verify=False是因為上傳地址是https,不這樣寫會報錯 res = requests.post(icondict["upload_url"], files=files, data=http://www.jb51.net/article/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"name": "fir.im", "version": "1.0", "changelog": "更新日誌", "versionShort": "1.0.5", "build": "6", "installUrl": "http://download.fir.im/v2/app/install/xxxxxxxxxxxxxxxxxxxx", "install_url": "http://download.fir.im/v2/app/install/xxxxxxxxxxxxxxxx", # 新增字段 "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"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 = http://www.jb51.net/article/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=http://www.jb51.net/article/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 = http://www.jb51.net/article/{'key': icondict["key"],"token":icondict["token"]} res = requests.post(icondict["upload_url"], files=files, data=http://www.jb51.net/article/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"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了
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持電腦玩物。
Tags: 打包 腳本 需要 這個 gradle 代碼
文章來源: