Changelog
v0.52
2026-07-23
Added
- Manual JSON Backup & Restore: Added local JSON file export and import under Settings for saved senseBoxes, app preferences, and widget configurations. Ideal for de-Googled ROMs (GrapheneOS, CalyxOS, LineageOS) and offline data transfers.
- Widget Restore Support: Implemented
AppWidgetManager.ACTION_APPWIDGET_RESTOREDhandling inSenseBoxWidgetProvider(onRestored) to seamlessly remap widget IDs and database configurations when restoring Google or system backups on a new phone. - Widget Template Pre-filling: Added fallback template pre-filling in
WidgetConfigScreenso that manually re-added widgets on a restored device automatically load settings from backed-up widget configurations.
v0.51
2026-07-22
Added
- Expanded System Diagnostics: System Diagnostics copy action now includes active home screen widget counts, system locale, app preferences, database state, and saved crash stack traces.
- 7 New Locales Added: Integrated complete translations from POEditor for Czech (
cs), Spanish (es), French (fr), Hungarian (hu), Italian (it), Dutch (nl), and Polish (pl), expanding in-app language picker and system locale support to 8 languages total.
Fixed
- Widget Inflation Fix: Fixed RemoteViews inflation failure ("Can't load widget") on Android 12–15 devices by removing non-remotable progress spinner calls.
- Temperature Adaptive Coloring: Fixed temperature value color resolver to support locale-formatted numbers with decimal commas (e.g., German
"15,2"), preventing improper fallback to orange. - API Logger Header Sync: API log header now updates dynamically to reflect the current app version when the app is updated.
v0.50
2026-07-21
Added
- Multi-Language Support: Added full Android localization infrastructure with POEditor-managed translations. English is the source/fallback language; German is the first target language.
- Per-App Language Picker: New in-app language setting defaults to the system locale and supports English and German. Integrated with Android 13+ system app-language settings via
locale_config.xml. - Automated Translation Sync: Added
.github/workflows/sync-translations.ymlto pull completed POEditor translations into the repository. - App-Wide Text Scale: New setting to adjust app interface text size from 60% to 200%, helpful for tablets and Android Automotive OS. Scales only text (
sp), not layout (dp). - Numeric Localization: Temperature, pressure, wind, coordinate, and percentage values now format with the user's locale-aware decimal/thousands separators.
Changed
- German Tone of Voice: Standardized the German translation to use the informal "du" address throughout.
- Theme Base: Switched the app theme parent to
Theme.AppCompat.DayNight.NoActionBarto support AppCompat per-app locales.
v0.45
2026-07-12
Changed
- Project Home Moved to GitHub: The canonical repository is now
https://github.com/nichu42/boxviewer. Issue tracking, source browsing, and release downloads have moved from Codeberg to GitHub. This was necessary because the project was not wanted on Codeberg by their community. - Web Hosting Moved to bunny.net: The sharing/deep-link landing page is now hosted on bunny.net (European provider) at
https://share.boxviewer.appusing the high-volume global CDN tier. The previous Codeberg Pages workflow has been replaced by an automated bunny.net Storage Zone sync. - Sharing URLs Updated: senseBox share links now point to
https://share.boxviewer.app/?id=<boxId>. This is a breaking change. Previous links do no longer work! - CI/CD Migration: Replaced Woodpecker/Forgejo workflows with GitHub Actions —
.github/workflows/release.ymlfor signed APK releases and.github/workflows/deploy-bunny.ymlfor web asset deployment.
Updated
PRIVACY.md(English and German) now discloses bunny.net hosting and global CDN processing.README.md,web/index.html,web/app.js, andweb/.well-known/security.txtnow reference GitHub andshare.boxviewer.app.
v0.43
2026-07-05
Fixed
- Widget Vertical Fill / Blank Space: Fixed a layout issue where the list-style widget left wasted blank space at the top and bottom of the values container, omitting content that would have fit in the widget. Sensor rows are now weight-distributed (
layout_weight="1") so they expand to evenly fill the widget's full height, regardless of how many rows are visible (3–6). The container gravity also switched fromcenter_verticaltotopto anchor rows at the top when fewer rows are present. - Widget Row-Count Sizing Thresholds: Switched the row-count computation from the conservative
OPTION_APPWIDGET_MIN_HEIGHTto the larger of the widget's MIN/MAX height bounds, and added the previously missing 5-row tier. Thresholds are now slightly more generous (140/170/200 dp) so taller widgets show as many rows as actually fit, instead of under-utilizing available space.
v0.42
2026-06-29
Added
- Coherent Local Synchronization: Added instant database-to-widget updates whenever measurements are updated in the app (e.g., during startup synchronization, dashboard refreshes, detail screen sync, or toggling favorites) or when unit and formatting preferences are changed (temperature, pressure, wind units, conditional formatting, and AQI systems). This ensures home screen widgets, the dashboard, and details pages are instantly kept in sync without triggering redundant network calls.
- Forced Update Rate-Limiting: Implemented a 15-second rate-limit throttle on manual forced updates per senseBox to prevent hammering the openSenseMap API. Displays a debounced Toast warning if spammed, and gracefully degrades to resolving from the local SQLite cache.
- Legacy Launcher Icon Fallbacks: Added legacy square (
ic_launcher.png) and round (ic_launcher_round.png) launcher icons across all density buckets (mdpitoxxxhdpi) generated from the updated logo. This ensures clean, high-quality, and consistent app icon presentation on older Android versions and system-level components (such as Toast notification headers on Android 12+).
Changed
- Launcher Icon Border & Margin Refinement: Cleaned up the app icon artwork to remove the outer blue frame and built a 60% artwork scale safety margin directly into the source logo WebP file. This ensures the branding crops cleanly inside circular, squircle, and rounded-rectangle launcher shapes, and remains fully unclipped inside system-rendered Toast headers.
- Launcher & Splash Icon Scaling: Adjusted the adaptive launcher foreground insets to
8dpand the startup splash screen icon insets to32dpto optimize visibility and render both icons at highly readable, prominent sizes on all devices.
Fixed
- Widget Layout Jump: Fixed a layout jump during widget updates when the header is disabled. The header container and the loading spinner are now hidden entirely if all header elements (box name, update time, and buttons) are disabled by the user or hidden due to widget size constraints.
- Widget Physical Refresh Force Flag: Fixed a bug where the
forceparameter was not forwarded to the database repository inSenseBoxWidgetProvider, which previously caused manual widget refreshes to be ignored if the database cache was fresh.
v0.41
2026-06-28
Added
- Small and Large Home Screen Widgets: Added two new widget sizes,
senseBox Info (Small 2x1)andsenseBox Info (Large 4x3), in addition to the standardMedium 3x2widget. - Responsive & Size-Adaptive Widgets:
- Widgets dynamically adapt their layout to the size constraints. When a widget's height is too short (< 74dp), it automatically forces the Metric Highlight (GRID) view.
- Header elements (box name, update time, and action buttons) show or hide dynamically based on the widget's current width constraints to prevent clipping.
- A visual loading spinner replaces the refresh button while network requests are active.
- Improved layout background transparency handling.
- Resilient Alarm Scheduling & Boot Autostart:
- Reschedules all widget update alarms automatically upon system reboot (
BOOT_COMPLETED) or app update (MY_PACKAGE_REPLACED). - Added
RECEIVE_BOOT_COMPLETEDpermission declaration inAndroidManifest.xml. - QR & Barcode Scanning Integration:
- Added QR code scanner integration to the Discovery screen search bar. Users can now scan senseBox IDs or URLs containing box IDs using any external ZXing-compatible barcode scanner app.
- API Error Toasts: Displays an error toast when openSenseMap API calls fail, showing the HTTP status code (if applicable) or the network error message.
- Geocoding & Data Service Attributions: Added explicit attribution entries for openSenseMap, Photon, and Nominatim (with OpenStreetMap contributors licensing details) in both
AboutScreen(under 'Data & Geocoding Services') andREADME.md('Data, Geocoding & Attribution').
Changed
- Geocoding Fallback Prioritization: Prioritized Photon (komoot GmbH, Germany) as the primary geocoding fallback, and Nominatim (OSM Foundation) as the secondary fallback.
- User-Agent Headers: Set appropriate dynamic headers identifying
BoxViewer/versionnameon all geocoding (viaSenseBoxViewModel) and openSenseMap (via Retrofit'sOkHttpClient) network queries, resolving the version name dynamically fromBuildConfig.VERSION_NAME. - Third-Party Licenses UI: Restructured the third-party licenses list in
AboutScreento be grouped into logical categories (Core UI, Networking, Concurrency, Utilities, Testing) and sorted alphabetically within each category for better organization. - Privacy Disclosures: Updated
PRIVACY.mdto disclose IP address transmission to external services (openSenseMap, Photon, Nominatim) under the GDPR and linked the privacy policies of Photon, Nominatim, and openSenseMap.
Fixed
- Cleaned Up Compose State Delegations: Replaced generic
mutableStateOfreferences with type-specificmutableIntStateOfandmutableFloatStateOfdelegates on the Discovery screen to prevent boxing. - Refactored NowCast & InstantCast Signature: Simplified parameter signatures by removing unused
boxIdparameters.
v0.40
2026-06-27
Added
- Air Quality Index (AQI) Engine: Six international standards (US EPA, UK DAQI, EU EAQI, Canada AQHI, India, China). A virtual AQI sensor is synthesized for every box with PM2.5/PM10 readings, and a 12-hour NowCast weighted average is computed from openSenseMap sensor stats.
- Dedicated AQI Info Screen: New
AqiInfoScreenexplains each supported AQI standard, breakpoints, and health guidance. - Unit Conversion System: Per-sensor unit switching for temperature (°C/°F/K), pressure (hPa/mbar/Pa/inHg/mmHg), and wind (m/s/km/h/mph/kn). Unit unification normalizes common openSenseMap unit strings before conversion. Includes a JUnit/Robolectric test suite (
ConverterTest.kt). - Settings Screen Rewrite: New app-level
SettingsScreenreachable from the dashboard, grouping general app settings, diagnostics/bug reporting, and local-only API debug logging. Diagnostics and API logs can be copied to the clipboard or shared via the native share sheet. - Widget Conditional Formatting & AQI Display: Widget config now supports
useConditionalFormattingandaqiDisplayMode, with matching database migrations (MIGRATION_6_7,MIGRATION_7_8, schema version 8).
Changed
- Discovery "Last Updated" Filter: Reworked to use minute-level steps (15, 30, 60, 180, 360, 720, 1440, All Time) instead of hours, matching the slider UI.
- Third-Party Licenses: Updated
AboutScreenattribution list for the new dependency set. - Canonical Sensor Ordering: Newly added senseBoxes now default to a consistent sensor order (Temperature → Humidity → PM10 → PM2.5 → AQI → Pressure → Wind → other) on both the dashboard and in widget configuration, rather than the raw API order.
Fixed
- Clipboard API: Replaced the non-existent
LocalClipboard/toClipEntry()calls in the new Settings screen with the standardLocalClipboardManager+AnnotatedStringAPI. - AQI Missing from Default Selection: The synthesized virtual AQI sensor is now included in the default pre-selected metrics when adding a senseBox to the dashboard or configuring a new widget, provided PM2.5/PM10 data is available.
- Discovery List Geocoding on De-Googled Devices:
resolveLocationsFornow falls back to Nominatim when the native AndroidGeocoderreturns no results. - Widget Wake-to-Refresh: Force-triggered updates (
ACTION_SCREEN_ON/ACTION_USER_PRESENT) now bypass theisInteractiveshort-circuit so they don't silently skip on devices where the interactive state lags behind the broadcast. - Foreground Polling Lifecycle: Box detail and dashboard auto-refresh loops are now gated by
repeatOnLifecycle(STARTED)so they stop when the UI is not in the foreground. - Sensor Value Color Thresholds:
SensorTheme.getValueColornow applies thresholds to converted canonical units, so values in Kelvin, °F, Pa, inHg, etc. are colored correctly. - "All Time" Discovery Filter: The discovery slider can now select the "All Time" option.
v0.30
2026-06-24
Added
- SenseBox Sharing via QR & Deep Links: Long-press a senseBox on the dashboard or detail screen to open the new Share sheet — generate a QR code (ZXing), share it as a PNG via the native Android share sheet (backed by a new
FileProvider), or save it directly to the gallery on Android 10+. Recipients scan the QR or open the HTTPS link and land on a newAddBoxConfirmScreenpreviewing the box with explicit Add to Dashboard / View Details options. - Deep Link Entry Points: Registered
boxviewer://box/{id}(custom scheme) and an auto-verified HTTPS App Linkhttps://nichu42.codeberg.page/BoxViewerso shared links open BoxViewer directly from any chat app or browser, with a graceful web fallback page (web/index.html+ Open Graph metadata) hosted on Codeberg Pages (web/.well-known/assetlinks.jsonfor App Links verification). - First-Time User Onboarding: Comprehensive empty-state on the dashboard for users with no saved senseBoxes — friendly icon, "No senseBoxes added yet" heading, explanatory copy, and an "Add a senseBox" primary CTA, followed by a "What is openSenseMap?" infocard explaining the platform and the role of BoxViewer. On the detail screen, an "Add to Dashboard" call-to-action card appears for unfavorited stations, plus a "Home Screen Widgets" infobox explaining how to add a widget on the home screen. Reorder mode also gained an instructional infocard for drag/remove/save actions.
- Splash Screen: Adopted
androidx.core.splashscreenwith a themedTheme.App.Starting, dedicatedic_splash_icondrawable, and asplash_backgroundcolor that respects dark mode (values-night/colors.xml). MainActivity set tosingleToplaunch mode to keep deep-link navigation stable. - Widget Localization & RTL Support: Externalized all hard-coded widget placeholder strings (
Temperatur,Feuchte,Updated just now, sensor category labels,--no-value markers, content descriptions) intostrings.xml. Widget layout now usesmarginStart/Endinstead ofmarginLeft/Rightfor proper right-to-left rendering on supported locales.
Changed
- Application Identity: Renamed the entire application package from
com.exampletode.nichu42.boxviewer(namespace,applicationId, manifest, widget broadcast action prefix, all source files). Aligns the on-disk package with the published app identifier. - Signing Key: Future Codeberg releases are signed with the same release key used for the Google Play closed-testing track. Existing Codeberg users (0.10) will need to uninstall before installing 0.30 due to the certificate change.
- Dependency Refresh: compileSdk & targetSdk bumped to 37. Kotlin 2.4.0, Compose BOM 2026.06, Room 2.8.4, Navigation 2.9.8, Lifecycle 2.11.0, Activity-Compose 1.13.0, core-ktx 1.19.0.
- Widget Timestamp Legibility: Bumped the widget "last updated" text from 9sp to 11sp for improved readability at a glance.
Fixed
- Keystore Gitignore Hygiene: Replaced the narrow
release-upload-key.jksignore pattern with*.jks/*.b64wildcards to prevent any signing key or base64 export from being committed, regardless of filename. ---
Removed
- Unused Dependencies: Dropped Firebase BOM, Google Play Services Location (
play-services-location), Accompanist Permissions, and the AndroidX Camera libraries — none were linked at runtime, and their removal completes the de-Googled dependency profile mandated by the project charter (no GMS dependencies, no telemetry). - Stale Debug Signing Config: Removed the now-unneeded
debugConfigsigning block frombuild.gradle.kts; debug builds now use Android's default debug keystore as intended.
v0.20
2026-05-29
Added
- Widget Customization Options: Users can now configure the widget layout to show Full Details, Value & Unit (hiding category labels), or Value Only (hiding both labels and units).
- Proportional Scaling: Both text and sensor icons in the widget now scale up to 200% on Android 12+ (API 31+).
- Widget Header Toggles: Switch toggles added to show or hide the manual refresh button, settings configuration gear, senseBox name, and last updated timestamp in the widget header.
- Home-Screen Reconfigurability: Enabled Android 12+ widget long-press settings, allowing users to reconfigure placed widgets directly from the home screen.
- Clean Widget Setup UX: Removed numbered section headers and introduced horizontal dividers between option sections. Reordered all settings into a logical, natural user flow (Data Choice -> Styling -> UI elements -> Sync Frequency).
- Graceful Downgrade Protection: Manually inspects the SQLite database file on launch. If an app downgrade is detected (via sideloading), users are prompted to either clear the database (Start Over) or visit Codeberg to install the matching update.
- Migration & Upgrade Notices: Bumps database schema to version 6 and adds
MIGRATION_3_4,MIGRATION_4_5, andMIGRATION_5_6paths. Implemented a feature-agnostic notification popup if a destructive schema reset ever occurs.
Fixed
- Drag-and-Drop Reordering: Wrapped metric rows in Compose key blocks to preserve drag gesture states, allowing users to reorder metrics freely without cancellation.
- Settings Card Alignments: Constrained visualization format and metric display style choice cards to a uniform height of 80.dp to ensure clean layout alignment regardless of text wrapping. ---
v0.10
2026-05-26
Added
- De-Googled Location Integration: Removed Google Play Services (GMS) dependencies. Replaced
FusedLocationProviderClientwith native AndroidLocationManager(GPS, Network, Passive) for GrapheneOS/LineageOS compatibility. - Local Diagnostics & Diagnostics Card: Integrated local uncaught exceptions crash capture and added a diagnostics card on the About screen with options to view and share logs.
- OpenStreetMap Nominatim Fallback: Dual-geocoding supporting Android native geocoder with OSM Nominatim fallback for location coordinates.
- Smart SQLite Caching: Implemented a 60-second database query cache cooldown in the repository to prevent redundant openSenseMap API hits.
- Licenses Screen: Added a custom open-source libraries license attribution screen.
Fixed
- Widget Update Scheduling: Standardized repeating widget alarms and forced immediate updates when screen turns on or user is present. ---
v0.10-prerelease
2026-05-24