局域网Apk包管理

532 阅读2分钟
需求

由于开发的应用体积较大,在公司内部分发同事下载不方便,写了个简单的包管理工具。

架构逻辑
  1. 使用go搭建一个支持下载的服务。
  2. 将构建好的包上传到和部署服务的同一个路径下。
  3. 将上传apk的逻辑包在脚本文件中。
  4. 在网页端访问指定的页面,该页面展示目录中所有的包文件。
服务端开发
  1. 扫描当前目录中文件以.apk的文件。
  2. 使用交叉编译为linux的执行文件。
注意

列表现实中我对文件名根据我构建的包名做了处理。

// 使用交叉编译到对应的平台应用
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ApkManager.go

package main

import (
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"strings"
	"time"
)

const TIME_FORMAT = "2006-01-02 15:04:05"

func FormatTime() string {
	t := time.Now().Format(TIME_FORMAT)
	return t
}

func main() {

	http.HandleFunc("/download", Download)
	http.HandleFunc("/", fileList)
	http.ListenAndServe(":8090", nil)
}

func Download(w http.ResponseWriter, r *http.Request) {
	if "GET" == r.Method {
		apkName := r.URL.Query().Get("apkName")
		fmt.Println("apkName=", apkName)
		isApk := strings.Contains(apkName, ".apk")
		if isApk {
			file, err := os.Open("./" + apkName)
			if err != nil {
				fmt.Println(err)
				return
			}
			defer file.Close()
			buf, err := ioutil.ReadAll(file)
			if err != nil {
				w.Write([]byte("文件不存在:" + err.Error()))
				return
			}
			w.Header().Add("Content-Type", "application/octet-stream")
			w.Header().Add("Content-Disposition", "attachment; filename=\""+apkName+"\"")
			w.Write(buf)
		} else {
			file, err := os.Open("./" + apkName)
			if err != nil {
				fmt.Println(err)
				return
			}
			defer file.Close()
			buf, err := ioutil.ReadAll(file)
			if err != nil {
				w.Write([]byte("文件不存在:" + err.Error()))
				return
			}
			w.Header().Add("Content-Type", "application/octet-stream")
			w.Header().Add("Content-Disposition", "attachment; filename=\""+apkName+"\"")
			w.Write(buf)
		}
	}
}

func fileList(w http.ResponseWriter, r *http.Request) {

	imgUrl := "https://picsum.photos/720/1080/?" + string(rune(rand.Int()))
	files, _ := ioutil.ReadDir("./")
	html := "<html style='background:url(" + imgUrl + ") no-repeat;background-size:cover'><head>" +
		"<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />" +
		"<title>android 端apk全部版本</title></head><body style=\"text-align:center;\">"
	baseUrl := "http://192.168.1.192:8090/download?apkName="
	for i := len(files) - 1; i >= 0; i-- {
		fmt.Println(files[i].Name())
		isApk := strings.Contains(files[i].Name(), ".apk")
		if isApk {
			isRelease := strings.Contains(files[i].Name(), "final")

			if isRelease {
				arr := strings.Split(files[i].Name(), ".")
				if len(arr) > 4 {
					html += "<a href=" + baseUrl + files[i].Name() + "><font color=\"red\">" + "正式发布版本  版本号:" + arr[4] + "</font></a></br>"
				} else {
					html += "<a href=" + baseUrl + files[i].Name() + ">" + "测试版本 " + "</a></br>"
				}
			} else {
				arr := strings.Split(files[i].Name(), ".")
				if len(arr) > 4 {
					html += "<a href=" + baseUrl + files[i].Name() + ">" + "测试版本  版本号:" + arr[4] + "</a></br>"
				} else {
					html += "<a href=" + baseUrl + files[i].Name() + ">" + "测试版本 " + "</a></br>"
				}

			}
			html += "</br>"
		}
	}
	html += "</body></html>"
	_, err := w.Write([]byte(html))
	if err != nil {
		return
	}

}

APK上传脚本
// 文件名 uploadAPK.sh
#!/bin/bash
scp cp ./app/release/*.apk root@192.168.1.192:/home/apk/apkManager
展示效果

image.png