Skip to content

Commit 65aaeeb

Browse files
eriedclaude
andcommitted
release signing config, privacy policy page for Play Store
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 77e66a2 commit 65aaeeb

3 files changed

Lines changed: 123 additions & 0 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ local.properties
1010
*.apks
1111
*.keystore
1212
*.jks
13+
keystore.properties
1314

1415
# IDE
1516
.idea/

app/build.gradle.kts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import java.io.FileInputStream
12
import java.text.SimpleDateFormat
23
import java.util.Date
4+
import java.util.Properties
35
import java.util.TimeZone
46

57
plugins {
@@ -10,6 +12,13 @@ plugins {
1012
alias(libs.plugins.hilt)
1113
}
1214

15+
val keystorePropsFile = rootProject.file("keystore.properties")
16+
val keystoreProps = Properties().apply {
17+
if (keystorePropsFile.exists()) {
18+
FileInputStream(keystorePropsFile).use { load(it) }
19+
}
20+
}
21+
1322
android {
1423
namespace = "com.eried.eucplanet"
1524
compileSdk = 35
@@ -27,13 +36,27 @@ android {
2736
buildConfigField("String", "BUILD_STAMP", "\"$buildStamp\"")
2837
}
2938

39+
signingConfigs {
40+
if (keystoreProps.isNotEmpty()) {
41+
create("release") {
42+
storeFile = rootProject.file(keystoreProps.getProperty("storeFile"))
43+
storePassword = keystoreProps.getProperty("storePassword")
44+
keyAlias = keystoreProps.getProperty("keyAlias")
45+
keyPassword = keystoreProps.getProperty("keyPassword")
46+
}
47+
}
48+
}
49+
3050
buildTypes {
3151
release {
3252
isMinifyEnabled = false
3353
proguardFiles(
3454
getDefaultProguardFile("proguard-android-optimize.txt"),
3555
"proguard-rules.pro"
3656
)
57+
if (keystoreProps.isNotEmpty()) {
58+
signingConfig = signingConfigs.getByName("release")
59+
}
3760
}
3861
}
3962

docs/privacy.html

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1">
6+
<title>EUC Planet — Privacy Policy</title>
7+
<meta name="description" content="Privacy policy for the EUC Planet Android app.">
8+
<link rel="icon" type="image/svg+xml" href="favicon.svg">
9+
<style>
10+
body {
11+
margin: 0;
12+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
13+
background: #0d1117;
14+
color: #e6edf3;
15+
line-height: 1.6;
16+
min-height: 100vh;
17+
padding: 48px 24px;
18+
}
19+
.container { max-width: 720px; margin: 0 auto; }
20+
header { margin-bottom: 32px; }
21+
h1 { font-size: 32px; margin: 0 0 8px; font-weight: 700; letter-spacing: -0.5px; }
22+
.sub { color: #8b949e; font-size: 14px; margin: 0; }
23+
h2 { font-size: 20px; margin: 32px 0 12px; font-weight: 600; }
24+
p, li { color: #c9d1d9; }
25+
ul { padding-left: 22px; margin: 0 0 12px; }
26+
li { margin-bottom: 6px; }
27+
a { color: #58a6ff; }
28+
code { background: #161b22; padding: 2px 6px; border-radius: 4px; font-size: 90%; }
29+
footer { margin-top: 48px; padding-top: 20px; border-top: 1px solid #30363d; color: #8b949e; font-size: 13px; }
30+
</style>
31+
</head>
32+
<body>
33+
<div class="container">
34+
<header>
35+
<h1>Privacy Policy</h1>
36+
<p class="sub">EUC Planet Android app · Last updated 2026-04-19</p>
37+
</header>
38+
39+
<p>EUC Planet is an open-source companion app for electric unicycles. It is published and maintained by Erwin Ried. This page describes what the app accesses on your device and what happens to that data.</p>
40+
41+
<h2>Short version</h2>
42+
<ul>
43+
<li>The app does not have a server. It runs entirely on your phone.</li>
44+
<li>It does not send your data to the developer or to any third party.</li>
45+
<li>It does not contain advertising, analytics, or tracking SDKs.</li>
46+
<li>Trip recordings, settings, and telemetry stay on your device unless you explicitly choose to sync them to a cloud folder <em>you</em> own (via Android's Storage Access Framework).</li>
47+
</ul>
48+
49+
<h2>What the app accesses</h2>
50+
<ul>
51+
<li><strong>Bluetooth</strong> — to scan for and connect to your wheel.</li>
52+
<li><strong>Precise location (GPS)</strong> — only while a trip is being recorded or while the Recording screen is open, so the recorded CSV contains coordinates, altitude, and GPS speed. Location is <em>never</em> used for advertising, identification, or sent to any server by the app.</li>
53+
<li><strong>Notifications</strong> — to show the ongoing connection notification and deliver alarm alerts.</li>
54+
<li><strong>Foreground service</strong> — to keep the BLE connection and GPS tracking alive while the screen is off during a ride.</li>
55+
<li><strong>Storage access (optional)</strong> — if you enable cloud sync, you pick a folder yourself through Android's file picker (Google Drive, OneDrive, Dropbox, local, etc.). The app only reads/writes inside that folder. You can revoke access at any time through Android settings.</li>
56+
</ul>
57+
58+
<h2>What is collected or stored</h2>
59+
<ul>
60+
<li><strong>On your device:</strong> your app settings, the Bluetooth MAC address of the last connected wheel (so auto-connect works), and any trip CSV files you record.</li>
61+
<li><strong>In your cloud folder (optional, only if you enable sync):</strong> a copy of your app settings and your trip files. This folder belongs to you; the developer has no access to it.</li>
62+
</ul>
63+
64+
<h2>What is <em>not</em> collected</h2>
65+
<ul>
66+
<li>No account, no login, no email, no phone number.</li>
67+
<li>No analytics events, crash reports, or usage metrics sent off-device.</li>
68+
<li>No advertising identifiers.</li>
69+
<li>No contact list, call log, SMS, camera, microphone, or photo access.</li>
70+
</ul>
71+
72+
<h2>Permissions explained</h2>
73+
<ul>
74+
<li><code>BLUETOOTH_SCAN</code>, <code>BLUETOOTH_CONNECT</code> — required to find and control the wheel. The scan is flagged <code>neverForLocation</code>.</li>
75+
<li><code>ACCESS_FINE_LOCATION</code>, <code>ACCESS_COARSE_LOCATION</code> — only used to record your position while a trip is being recorded.</li>
76+
<li><code>FOREGROUND_SERVICE</code>, <code>FOREGROUND_SERVICE_CONNECTED_DEVICE</code>, <code>FOREGROUND_SERVICE_LOCATION</code> — to keep the wheel connection and GPS running in the background while you ride.</li>
77+
<li><code>POST_NOTIFICATIONS</code> — to show the connection status and alerts.</li>
78+
<li><code>VIBRATE</code> — for alarm haptic feedback.</li>
79+
<li><code>INTERNET</code> — used only when you explicitly upload trip files to your chosen cloud provider through the Android sync stack.</li>
80+
</ul>
81+
82+
<h2>Data retention and deletion</h2>
83+
<p>All data is local. Uninstalling the app removes everything stored in the app's private data directory. Trip files that you exported or synced to your own cloud folder remain under your control.</p>
84+
85+
<h2>Children</h2>
86+
<p>The app is not directed at children under 13.</p>
87+
88+
<h2>Open source</h2>
89+
<p>The full source code is public at <a href="https://github.com/eried/eucplanet">github.com/eried/eucplanet</a>, so the claims above can be independently verified.</p>
90+
91+
<h2>Contact</h2>
92+
<p>Questions or concerns: open an issue at <a href="https://github.com/eried/eucplanet/issues">github.com/eried/eucplanet/issues</a>.</p>
93+
94+
<footer>
95+
<a href="/">&larr; Back to EUC Planet</a>
96+
</footer>
97+
</div>
98+
</body>
99+
</html>

0 commit comments

Comments
 (0)