Gitea URL removed from source code. UpdateChecker now only hardcodes
GitHub API; the Gitea mirror URL is embedded in release notes as an
HTML comment (<!-- update-source: ... -->) and discovered at runtime.
Keeps self-hosted server address out of the public codebase.
version 1.8.0 -> 1.8.1 (code 17 -> 18)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
All four forwarding channels now support multiple configurations (add/
edit/delete/reorder/enable per item, matching Bark server UX):
- model: NtfyServer, EmailServer, SmsTarget data classes
- SettingsStore: ntfyServers/emailServers/smsTargets as List; full CRUD
(add/update/delete/move/setEnabled); legacy single-config auto-migrated
to list via config_version; 4 stopOnFirst toggles (bark=true, others
false)
- BarkSender/NtfySender/EmailSender: pushToEnabled(configs, stopOnFirst)
— stopOnFirst=true: first success stops; false: send to all
- SmsFallbackForwarder: forward iterates smsTargets per stopOnFirst
- UI: each channel SectionCard has toggle + stopOnFirst switch + config
list + add button; ConfigRow + ConfigDialog reusable components
- version 1.7.3 -> 1.8.0 (code 16 -> 17)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- start(): check on every launch (no 24h throttle) so the banner shows
after restart even if checked manually moments ago; plus a 24h loop
while app is resident
- check both Gitea and GitHub release APIs, skip whichever is
unreachable, notify the higher version
- version 1.7.2 -> 1.7.3 (code 15 -> 16)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ntfy.sh now treats any request body (PUT/POST, text/plain) as a file
attachment, so messages never showed in the app. Switch to ntfy's JSON
publish API: POST / with {topic,title,message}.
version 1.7.1 -> 1.7.2 (code 14 -> 15)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- HomeScreen update banner: gradient background (tertiary→primary), white
text, large version number, rocket emoji CTA button
- UpdateChecker now auto-notifies via all enabled channels (Bark/ntfy/
email) when a new version is discovered, with version/size/notes
- Periodic check every 24h via coroutine delay loop (replaces one-shot
startup check only); also honors updateCheckEnabled toggle
- version 1.7.0 -> 1.7.1 (code 13 -> 14)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Parallel to Bark: when email forwarding is enabled and a recipient is set,
notifications are also sent via SMTP over SSL (port 465, SMTPS). Works
standalone — no Bark server required.
- core/EmailSender: SMTP over SSL (implicit TLS, port 465), AUTH LOGIN,
UTF-8 subject/body via Base64/MIME; trySend() fire-and-forget helper
- SettingsStore: 7 email settings (enabled, host, port, user, password,
from, to)
- NotifyListenerService + PhoneCallMonitor: call EmailSender.trySend in
parallel with Bark forwarding; fires even if no Bark servers configured
- UI: new "电邮转发" SectionCard in settings (toggle + host/port/user/
password/from/to fields + save button)
- version 1.6.0 -> 1.6.1 (code 10 -> 11); CLAUDE.md synced
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bark servers now form an ordered failover chain: forwarding tries each
enabled server in list order, stopping at the first success.
- model: BarkServer.enabled (defaults true; legacy JSON compatible)
- core/BarkSender.pushToFirst: ordered try-until-success helper, shared
by NotifyListenerService / PhoneCallMonitor / RetryWorker
- BarkClient.push uses msg.copy(deviceKey=server.deviceKey) so each
server pushes its own key
- SettingsStore: drop currentServer/setCurrent; add moveServer +
setServerEnabled; NotificationProcessor no longer sources deviceKey
- UI: ServerRow RadioButton -> Checkbox + per-row test/move-up/move-down;
remove top "send test push" button; HomeScreen shows enabled count
- version 1.5.1 -> 1.6.0 (code 9 -> 10); CLAUDE.md synced
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Investigated 9 failed forwards on device: all "connection closed" to
api.day.app, while ping/curl to the server succeed -> not network-blocked,
but OkHttp transient connection drops that aren't retried (POST read-phase
connection close is not covered by retryOnConnectionFailure).
- BarkClient.push: manual retry up to 3x (600/1200ms backoff) on
IOException (connection closed/timeout/TLS reset); HTTP 4xx/5xx not retried.
- AppRulesStore: add recorder/gallery/find-device/password-manager to default
blacklist; versioned migration (bl_version) merges the new entries into
existing users' blacklist (add-only).
- version 1.5.0 -> 1.5.1 (code 8 -> 9); CLAUDE.md synced.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Auto-check GitHub Releases latest on launch (24h throttle), show an
update banner on the home screen, download the APK in-app with progress,
and trigger the system installer via FileProvider + REQUEST_INSTALL_PACKAGES.
- core/UpdateChecker: fetch releases/latest, semver compare, stream APK
to externalFilesDir, install via FileProvider (handles MIUI unknown-sources).
- SettingsStore: updateCheckEnabled / lastUpdateCheckTime / ignoredVersion.
- HomeScreen: update banner + UpdateDialog.
- SettingsScreen: "关于与更新" card with auto-check toggle and manual check.
- manifest: REQUEST_INSTALL_PACKAGES + FileProvider; new res/xml/file_paths.xml.
- version 1.4.2 -> 1.5.0 (versionCode 7 -> 8).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>