-
Notifications
You must be signed in to change notification settings - Fork 0
/
build-android.go
121 lines (112 loc) · 2.68 KB
/
build-android.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package main
import (
"encoding/xml"
"fmt"
"go/build"
"os"
"path/filepath"
)
var (
iconAttr = xml.Attr{
Name: xml.Name{
Space: "http://schemas.android.com/apk/res/android",
Local: "icon",
},
Value: "@drawable/ic_launcher",
}
)
func buildAndroid(pkg *build.Package, ctx CmdContext) error {
name := filepath.Base(pkg.ImportPath)
output := name + ".apk"
if len(buildO) > 0 {
output = buildO
}
subargs := append(ctx.Args, []string{
"-target", buildTarget, "-o", output, pkg.ImportPath,
}...)
if err := Cmd(ctx, goMobileExe, subargs...); err != nil {
return err
}
if len(customIcon) == 0 {
return nil
}
_ = Cmd(ctx, "keytool", "-genkey",
"-keystore", filepath.Join("build", "android", "app.keystore"),
"-storepass", "secret",
"-dname", fmt.Sprintf("CN=%s,O=apps.gomobile.org,C=JP", name),
"-keypass", "secret",
"-keyalg", "RSA", "-validity", "18250",
"-alias", name,
)
_ = os.RemoveAll(filepath.Join("build", "android", "apk"))
if err := Cmd(ctx, "apktool", "decode", "-o",
filepath.Join("build", "android", "apk"), output); err != nil {
return err
}
manifest := filepath.Join("build", "android", "apk", "AndroidManifest.xml")
fp, err := os.Open(manifest)
if err != nil {
return err
}
defer fp.Close()
var v *Tag
if err := xml.NewDecoder(fp).Decode(&v); err != nil {
return err
}
attrs := v.Attr
v.Attr = []xml.Attr{}
for _, a := range attrs {
switch a.Name.Local {
case "versionCode":
case "versionName":
default:
v.Attr = append(v.Attr, a)
}
}
var app *Tag
for _, c := range v.Children {
if cf, ok := c.(*Tag); ok {
cf.Name.Local = "application"
app = cf
break
}
}
if app == nil {
return fmt.Errorf("<application> not found in AndroidManifest.xml")
}
app.Attr = append(app.Attr, iconAttr)
fp.Close()
fp, err = os.Create(manifest)
if err != nil {
return err
}
if err := xml.NewEncoder(fp).Encode(&v); err != nil {
return err
}
_ = os.RemoveAll(filepath.Join("build", "android", "apk", "res"))
if len(customIcon) > 0 {
if err := Cmd(ctx, "icons", "--device", "android", "-o",
filepath.Join("build", "android", "apk", "res"),
customIcon,
); err != nil {
return err
}
}
_ = os.Remove(filepath.Join("build", "android", "apk", "res", "playstore.png"))
_ = os.RemoveAll(output)
if err := Cmd(ctx, "apktool", "build", "-o", output,
"-f", filepath.Join("build", "android", "apk")); err != nil {
return err
}
if err := Cmd(ctx, "jarsigner", "-verbose",
"-keystore", filepath.Join("build", "android", "app.keystore"),
"-storepass", "secret",
"-sigalg", "MD5withRSA",
"-digestalg", "SHA1",
"-tsa", "http://timestamp.digicert.com",
output, name,
); err != nil {
return err
}
return nil
}