Android gradle打包并自動上傳

簡介

這篇文章主要介紹Android用gradle打包盗扇,并且調用python腳本將打包好的apk上傳到fir.im供相關人員下載,對于學習gradle 打包和python 幾個常用網絡庫有一定幫助
關鍵字 :Android Gradle Python fir.im

1 開發(fā)前準備

開發(fā)前需要下載 AndroidStudio 甩栈,gradle(3.3版本)承璃,python3.6栽渴,Curl互妓,pycurl
準備fir.im賬號一個芥备,有賬號對應的apitoken冬耿,具體fir.im的細節(jié)可查看文檔fir.im
開發(fā)環(huán)境為macOS,windows推薦把pycurl部分全部替換為requests萌壳,即上傳apk部分代碼換為上傳圖標的那種方式亦镶,詳細見代碼

2 Gradle 腳本編寫

我們腳本需要做的事情就是在APK打包完成以后,把apk的路徑傳遞給python腳本即可袱瓮,如何保證打包好了缤骨,就用gradle的dependsOn方法,例如打debug包懂讯,我們就可以寫一個task 荷憋,這個task dependsOn ‘assembleDebug’,這樣這個task調用時褐望,會先執(zhí)行assembleDebug勒庄,然后在執(zhí)行里面的代碼,即符合我們的需要
具體代碼

//這個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代碼執(zhí)行結束
            int exitValue = process.waitFor()
            println "上傳結束 with value $exitValue"
        }
    }

3 python腳本的編寫

這個python腳本有點學習的內容,所以使用了 urllib 谨读,requests局装,pycurl三個網絡請求庫,實際上只用一種就好了
這里關鍵是需要了解fir.im上傳的請求格式和響應劳殖,細節(jié)可以看文檔
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錯誤解阅,執(zhí)行python3 按照目錄下的Install Certificates.command文件 ,路徑參考 /Applications/Python 3.6/Certificates.command
官方文檔如下泌霍,細節(jié)查閱官網

調用示例

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對應的工程里面執(zhí)行代碼 gradle assemblewithlog
就開始打包debug并上傳到fir.im了

圖片.png
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末琼梆,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子窿吩,更是在濱河造成了極大的恐慌茎杂,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纫雁,死亡現場離奇詭異煌往,居然都是意外死亡,警方通過查閱死者的電腦和手機轧邪,發(fā)現死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門刽脖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人忌愚,你說我怎么就攤上這事曲管。” “怎么了硕糊?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵院水,是天一觀的道長。 經常有香客問我简十,道長檬某,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任螟蝙,我火速辦了婚禮恢恼,結果婚禮上,老公的妹妹穿的比我還像新娘胶逢。我一直安慰自己厅瞎,他們只是感情好,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布初坠。 她就那樣靜靜地躺著和簸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碟刺。 梳的紋絲不亂的頭發(fā)上锁保,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天,我揣著相機與錄音半沽,去河邊找鬼爽柒。 笑死,一個胖子當著我的面吹牛者填,可吹牛的內容都是我干的浩村。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼占哟,長吁一口氣:“原來是場噩夢啊……” “哼心墅!你這毒婦竟也來了?” 一聲冷哼從身側響起榨乎,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤怎燥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蜜暑,有當地人在樹林里發(fā)現了一具尸體铐姚,經...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年肛捍,在試婚紗的時候發(fā)現自己被綠了隐绵。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡篇梭,死狀恐怖氢橙,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情恬偷,我是刑警寧澤悍手,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站袍患,受9級特大地震影響坦康,放射性物質發(fā)生泄漏。R本人自食惡果不足惜诡延,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一滞欠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肆良,春花似錦筛璧、人聲如沸逸绎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽棺牧。三九已至,卻和暖如春朗儒,著一層夾襖步出監(jiān)牢的瞬間颊乘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工醉锄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留乏悄,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓恳不,卻偏偏與公主長得像檩小,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子烟勋,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內容