Skip to content

Commit 30cf653

Browse files
committed
further cleanup
1 parent 8415b89 commit 30cf653

File tree

9 files changed

+388
-213
lines changed

9 files changed

+388
-213
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
*.apk
33
*.aab
44

5+
# Keystore files (keep private!)
6+
*.keystore
7+
*.jks
8+
59
# Files for the ART/Dalvik VM
610
*.dex
711

Makefile

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,40 @@
1-
.PHONY: all release sideload clean rebuild-icons
1+
.PHONY: all release sideload clean lint format rebuild-icons
22

33
# Default target: build debug APK
44
all:
55
./gradlew assembleDebug
6+
@mkdir -p out
7+
@cp app/build/outputs/apk/debug/app-debug.apk out/heisenberg-debug.apk
8+
@echo "\nDebug APK built and copied to out/:"
9+
@ls -lh out/heisenberg-debug.apk
610

7-
# Build release APK
11+
# Build release APK (signs with ~/android.jks or $ANDROID_KEYSTORE if present)
812
release:
13+
@KEYSTORE_PATH=$${ANDROID_KEYSTORE:-$$HOME/android.jks}; \
14+
if [ ! -f "$$KEYSTORE_PATH" ]; then \
15+
echo "Warning: Keystore not found at $$KEYSTORE_PATH"; \
16+
echo "Creating default debug keystore..."; \
17+
keytool -genkeypair -v \
18+
-keystore "$$HOME/android.jks" \
19+
-alias key0 \
20+
-keyalg RSA \
21+
-keysize 2048 \
22+
-validity 10000 \
23+
-storepass android \
24+
-keypass android \
25+
-dname "CN=Android Debug, OU=Android, O=Android, L=Unknown, ST=Unknown, C=US"; \
26+
echo "Created debug keystore at $$HOME/android.jks with alias 'key0'"; \
27+
fi
928
./gradlew assembleRelease
29+
@mkdir -p out
30+
@if [ -f app/build/outputs/apk/release/app-release.apk ]; then \
31+
cp app/build/outputs/apk/release/app-release.apk out/heisenberg-release.apk; \
32+
echo "\nSigned release APK built and copied to out/:"; \
33+
else \
34+
cp app/build/outputs/apk/release/app-release-unsigned.apk out/heisenberg-release-unsigned.apk; \
35+
echo "\nUnsigned release APK built and copied to out/:"; \
36+
fi
37+
@ls -lh out/heisenberg-release*.apk
1038

1139
# Build and install debug APK via adb
1240
sideload:
@@ -15,6 +43,15 @@ sideload:
1543
# Clean build artifacts
1644
clean:
1745
./gradlew clean
46+
@rm -rf out
47+
48+
# Run ktlint checks
49+
lint:
50+
./gradlew ktlintCheck
51+
52+
# Auto-format code with ktlint
53+
format:
54+
./gradlew ktlintFormat
1855

1956
# Generate launcher icons from source PNG (expects icon.png in project root)
2057
rebuild-icons:

README.md

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,38 @@ A minimalist Android app that wakes your device screen when motion or ambient li
2525
### Build Commands
2626

2727
```bash
28-
make # Build debug APK
29-
make release # Build release APK
30-
make sideload # Build and install via adb
31-
make clean # Clean build artifacts
28+
make # Build debug APK → out/heisenberg-debug.apk
29+
make release # Build release APK → out/heisenberg-release.apk (auto-signed)
30+
make sideload # Build and install debug APK via adb
31+
make lint # Run ktlint code style checks
32+
make format # Auto-format code with ktlint
33+
make clean # Clean build artifacts (including out/ directory)
3234
```
3335

36+
All built APKs are automatically copied to the `out/` directory for easy access.
37+
38+
### Signing Configuration
39+
40+
Release builds use `~/android.jks` by default. Configure signing credentials via:
41+
42+
**Option 1: Environment variables** (recommended for CI/CD)
43+
```bash
44+
export ANDROID_KEYSTORE=/path/to/your/keystore.jks # Optional, defaults to ~/android.jks
45+
export ANDROID_KEYSTORE_PASSWORD=your_store_password
46+
export ANDROID_KEY_ALIAS=your_key_alias # e.g., key0, androiddebugkey
47+
export ANDROID_KEY_PASSWORD=your_key_password # Optional, defaults to store password
48+
```
49+
50+
**Option 2: gradle.properties** (for local development)
51+
```properties
52+
# ~/.gradle/gradle.properties or ./gradle.properties
53+
android.keystorePassword=your_store_password
54+
android.keyAlias=your_key_alias
55+
android.keyPassword=your_key_password
56+
```
57+
58+
If `~/android.jks` doesn't exist, a debug keystore will be auto-generated.
59+
3460
Or use Gradle directly:
3561
```bash
3662
./gradlew assembleDebug

app/build.gradle.kts

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
plugins {
22
id("com.android.application")
33
id("org.jetbrains.kotlin.android")
4+
id("org.jlleitschuh.gradle.ktlint") version "12.1.0"
45
}
56

67
android {
@@ -11,17 +12,51 @@ android {
1112
applicationId = "com.heisenberg.lux"
1213
minSdk = 26
1314
targetSdk = 34
14-
versionCode = 1
15-
versionName = "1.0"
15+
versionCode = 4
16+
versionName = "0.4.1"
17+
}
18+
19+
signingConfigs {
20+
create("release") {
21+
// Use keystore from environment variable or default locations
22+
val keystorePath = System.getenv("ANDROID_KEYSTORE")
23+
?: "${System.getProperty("user.home")}/android.jks"
24+
val keystoreFile = file(keystorePath)
25+
26+
if (keystoreFile.exists()) {
27+
println("Using keystore: $keystorePath")
28+
storeFile = keystoreFile
29+
// Try environment variables first, then Gradle properties, then defaults
30+
storePassword = System.getenv("ANDROID_KEYSTORE_PASSWORD")
31+
?: project.findProperty("android.keystorePassword") as String?
32+
?: "android"
33+
keyAlias = System.getenv("ANDROID_KEY_ALIAS")
34+
?: project.findProperty("android.keyAlias") as String?
35+
?: "key0"
36+
keyPassword = System.getenv("ANDROID_KEY_PASSWORD")
37+
?: project.findProperty("android.keyPassword") as String?
38+
?: storePassword // Use store password as key password if not specified
39+
println("Using key alias: $keyAlias")
40+
} else {
41+
println("Warning: Keystore not found at $keystorePath - release build will be unsigned")
42+
}
43+
}
1644
}
1745

1846
buildTypes {
1947
release {
2048
isMinifyEnabled = true
2149
proguardFiles(
2250
getDefaultProguardFile("proguard-android-optimize.txt"),
23-
"proguard-rules.pro"
51+
"proguard-rules.pro",
2452
)
53+
// Sign if keystore exists, otherwise build unsigned
54+
signingConfig =
55+
if (rootProject.file("heisenberg.keystore").exists()) {
56+
signingConfigs.getByName("release")
57+
} else {
58+
null
59+
}
2560
}
2661
}
2762

@@ -39,6 +74,16 @@ android {
3974
}
4075
}
4176

77+
ktlint {
78+
version.set("1.0.1")
79+
android.set(true)
80+
ignoreFailures.set(false)
81+
reporters {
82+
reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.PLAIN)
83+
reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE)
84+
}
85+
}
86+
4287
dependencies {
4388
// Minimal dependencies - only what's needed for CameraX and lifecycle
4489
implementation("androidx.appcompat:appcompat:1.6.1")

app/src/main/kotlin/com/heisenberg/lux/BootReceiver.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ import android.util.Log
77
import androidx.core.content.ContextCompat
88

99
class BootReceiver : BroadcastReceiver() {
10-
override fun onReceive(context: Context, intent: Intent) {
10+
override fun onReceive(
11+
context: Context,
12+
intent: Intent,
13+
) {
1114
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
1215
Log.i(TAG, "Boot completed, checking if service should start")
1316

0 commit comments

Comments
 (0)