Skip to content

Commit e01d114

Browse files
docs: add android info
1 parent ad12d35 commit e01d114

1 file changed

Lines changed: 265 additions & 0 deletions

File tree

docs/android.md

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
# Android Build & Release
2+
3+
This document covers building and releasing LunchJS for Android using Task and Fastlane.
4+
5+
---
6+
7+
## Prerequisites
8+
9+
### Environment Variables
10+
11+
Add to `~/.bash_profile` or `~/.zshrc`:
12+
13+
```bash
14+
# Java
15+
export PATH="/opt/homebrew/opt/openjdk@24/bin:$PATH"
16+
export JAVA_HOME="/opt/homebrew/opt/openjdk@24"
17+
18+
# Android SDK
19+
export ANDROID_HOME="/opt/homebrew/share/android-commandlinetools"
20+
export PATH="$ANDROID_HOME/platform-tools:$ANDROID_HOME/cmdline-tools/latest/bin:$PATH"
21+
22+
# Android NDK
23+
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/28.2.13676358"
24+
```
25+
26+
### Rust Targets
27+
28+
```bash
29+
rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android
30+
```
31+
32+
---
33+
34+
## Project Configuration
35+
36+
| Setting | Value |
37+
|---------|-------|
38+
| Package name | `com.lunch.app` |
39+
| Min SDK | 24 (Android 7.0) |
40+
| Target SDK | 36 |
41+
| Build location | `src-tauri/gen/android/` |
42+
43+
---
44+
45+
## Development
46+
47+
### Emulator
48+
49+
```bash
50+
# Run on Android emulator (default: pixel_7)
51+
task android:dev
52+
53+
# Configure emulator keyboard settings
54+
task android:emulator:setup
55+
```
56+
57+
### Physical Device
58+
59+
```bash
60+
# Hot-reload development on connected device
61+
task android:dev:device
62+
63+
# Build release APK, sign with debug key, install on device
64+
task android:run:device
65+
```
66+
67+
---
68+
69+
## Building
70+
71+
### Debug Builds
72+
73+
```bash
74+
# Build APK for testing/sideloading
75+
task android:build:apk
76+
```
77+
78+
Output: `src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release-unsigned.apk`
79+
80+
### Release Builds
81+
82+
```bash
83+
# Build signed AAB for Google Play
84+
task android:build:aab
85+
```
86+
87+
Output: `src-tauri/gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab`
88+
89+
### Full Distribution Build
90+
91+
```bash
92+
# Build both APK and AAB
93+
task android:build
94+
```
95+
96+
---
97+
98+
## Release Signing
99+
100+
### Create Keystore (One-Time Setup)
101+
102+
```bash
103+
λ keytool -genkey -v -keystore ~/lunchjs-release.jks \
104+
-keyalg RSA -keysize 2048 -validity 10000 -alias lunch \
105+
-dname "CN=Lunch App, OU=Mobile, O=LunchJS, L=Unknown, ST=Unknown, C=US"
106+
Enter keystore password:
107+
Re-enter new password:
108+
Generating 2048-bit RSA key pair and self-signed certificate (SHA384withRSA) with a validity of 10,000 days
109+
for: CN=Lunch App, OU=Mobile, O=LunchJS, L=Unknown, ST=Unknown, C=US
110+
[Storing ~/lunchjs-release.jks]
111+
```
112+
113+
### Configure Signing
114+
115+
1. Add to `.env`:
116+
```
117+
ANDROID_KEYSTORE_PASSWORD=<your-password>
118+
ANDROID_KEYSTORE_PATH=/path/to/lunchjs-release.jks
119+
```
120+
121+
2. Generate `keystore.properties`:
122+
```bash
123+
task android:keystore:setup
124+
```
125+
126+
This creates `src-tauri/gen/android/keystore.properties` with your credentials.
127+
128+
### Verify Signature
129+
130+
```bash
131+
jarsigner -verify src-tauri/gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab
132+
```
133+
134+
---
135+
136+
## Google Play Release
137+
138+
### Prerequisites
139+
140+
1. Create app in [Google Play Console](https://play.google.com/console) with package name `com.lunch.app`
141+
2. Create service account for API access:
142+
- Go to Setup > API access > Service accounts
143+
- Create new service account with "Release Manager" permissions
144+
- Download JSON key file
145+
3. Add to `.env`:
146+
```
147+
SUPPLY_JSON_KEY=/path/to/service-account.json
148+
```
149+
150+
### First Release (Manual)
151+
152+
The first AAB must be uploaded manually through Google Play Console:
153+
154+
1. Build signed AAB: `task android:build:aab`
155+
2. Go to Play Console > Release > Production > Create new release
156+
3. Upload `app-universal-release.aab`
157+
4. Complete store listing, content rating, and pricing
158+
159+
### Automated Releases
160+
161+
After the first manual upload, use Fastlane for subsequent releases:
162+
163+
```bash
164+
# Upload to internal testing track
165+
task android:internal
166+
167+
# Upload to beta track
168+
task android:testflight
169+
170+
# Upload to production
171+
task android:release
172+
```
173+
174+
---
175+
176+
## Fastlane Lanes
177+
178+
| Lane | Description | Task Command |
179+
|------|-------------|--------------|
180+
| `android build` | Build AAB and APK | `bundle exec fastlane android build` |
181+
| `android internal` | Upload to internal testing | `task android:internal` |
182+
| `android beta` | Upload to beta track | `task android:testflight` |
183+
| `android release` | Upload to production | `task android:release` |
184+
185+
All lanes automatically:
186+
- Update version from `Cargo.toml`
187+
- Generate unique build number (seconds since 2024-01-01)
188+
- Build using Tauri CLI
189+
- Upload to specified Play Store track
190+
191+
---
192+
193+
## Task Commands Reference
194+
195+
| Command | Description |
196+
|---------|-------------|
197+
| `task android:init` | Initialize Android project |
198+
| `task android:dev` | Run on emulator |
199+
| `task android:dev:device` | Run on device (hot-reload) |
200+
| `task android:run:device` | Build and install release APK on device |
201+
| `task android:build` | Build APK and AAB |
202+
| `task android:build:apk` | Build APK only |
203+
| `task android:build:aab` | Build signed AAB |
204+
| `task android:keystore:setup` | Generate keystore.properties from env vars |
205+
| `task android:internal` | Upload to internal testing |
206+
| `task android:testflight` | Upload to beta track |
207+
| `task android:release` | Upload to production |
208+
| `task android:clean` | Clean build artifacts |
209+
| `task android:emulator:keyboard` | Enable hardware keyboard for emulator |
210+
| `task android:emulator:setup` | Full emulator configuration |
211+
212+
---
213+
214+
## Build Artifacts
215+
216+
| Type | Path |
217+
|------|------|
218+
| Unsigned APK | `src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release-unsigned.apk` |
219+
| Signed APK (debug key) | `src-tauri/gen/android/app/build/outputs/apk/universal/release/app-universal-release-signed.apk` |
220+
| Signed AAB | `src-tauri/gen/android/app/build/outputs/bundle/universalRelease/app-universal-release.aab` |
221+
222+
---
223+
224+
## Troubleshooting
225+
226+
### Build Fails with Signing Error
227+
228+
Ensure `keystore.properties` exists and contains valid paths:
229+
```bash
230+
task android:keystore:setup
231+
```
232+
233+
### Emulator Keyboard Not Working
234+
235+
Run keyboard configuration:
236+
```bash
237+
task android:emulator:setup
238+
```
239+
240+
### Upload Fails with Package Name Mismatch
241+
242+
Verify package name is `com.lunch.app` in:
243+
- `src-tauri/gen/android/app/build.gradle.kts` (namespace and applicationId)
244+
- Google Play Console app settings
245+
246+
### Version Code Too Low
247+
248+
Fastlane uses timestamp-based version codes. If Play Console rejects the build, wait a second and rebuild - each build gets a unique version code.
249+
250+
---
251+
252+
## File Structure
253+
254+
```
255+
src-tauri/gen/android/
256+
├── app/
257+
│ ├── build.gradle.kts # Package name, signing config
258+
│ ├── src/main/java/com/lunch/app/
259+
│ │ └── MainActivity.kt # Entry point
260+
│ └── build/outputs/
261+
│ ├── apk/ # APK builds
262+
│ └── bundle/ # AAB builds
263+
├── keystore.properties # Signing credentials (gitignored)
264+
└── keystore.properties.example
265+
```

0 commit comments

Comments
 (0)