Skip to content

Releases: sander-git/piwigo-flutter-app

v2.4.3-fix-gps-preview - UNOFFICIAL PREVIEW: Fix EXIF/GPS Metadata (#274)

Choose a tag to compare

@sander-git sander-git released this 06 Sep 00:50

⚠️ UNOFFICIAL PRE-RELEASE / PREVIEW BUILD

Warning

IMPORTANT NOTICE FOR TESTERS: YOU MUST UNINSTALL THE OFFICIAL APP FIRST

Because this unofficial preview APK is signed with a standalone testing key rather than the official Google Play Store private key, Android will reject an in-place upgrade with INSTALL_FAILED_UPDATE_INCOMPATIBLE.

To install and test this build:

  1. Uninstall the existing official Piwigo NG application from your device.
  2. Download and install app-release.apk attached below.
  3. Log in to your Piwigo instance and test uploading with/without "Strip Private Metadata".

🎯 Summary of Changes & Fixes

This build addresses upstream Issue #274 (Pull Request Piwigo/piwigo-flutter-app#279) to preserve photo EXIF and GPS coordinates when picking or sharing media on Android 10+ (API 29+), while guaranteeing data safety and respecting user privacy preferences.

Key Highlights & Critical Fixes:

  1. Zero Destructive Actions on Local Files:
    • Original local photos on device storage (camera roll, DCIM, downloads) are strictly read-only and never modified or overwritten in place.
    • When metadata removal is requested, files are copied into isolated temporary subdirectories in cacheDir first, and only the temporary copy uploaded to Piwigo is scrubbed.
  2. Clean Filenames & Gallery Titles Preserved:
    • Original filenames (e.g. IMG_20240101_123456.jpg) are kept clean on disk by isolating files inside dedicated unique subfolders (original_media/<uuid>/filename.jpg and compressed/<uuid>/filename.jpg) instead of prepending prefixes, ensuring Piwigo displays pristine photo titles.
  3. Upload Retry Protection:
    • Temporary cache files are deleted only upon verified successful upload. Failed uploads retain their temporary source files so users can tap "Retry" without encountering FileSystemException.
  4. SAF Document URI Resolution for MediaStore.setRequireOriginal:
    • Resolves Storage Access Framework (SAF) document URIs back to their underlying MediaStore content URIs (EXTERNAL_CONTENT_URI) before applying MediaStore.setRequireOriginal(), ensuring Android 10+ does not redact GPS.
  5. System Media Picker Avoiding Photo Picker GPS Redaction:
    • Uses Intent.ACTION_GET_CONTENT with the system chooser across all Android versions. This ensures Android 13/14 does not route media through the system Photo Picker which enforces hardcoded GPS location stripping by design.
  6. Lossy Compression EXIF Preservation:
    • When user-configured upload quality (<100%) triggers compression, EXIF tags (including GPS latitude, longitude, altitude, and timestamp) are explicitly re-injected into the compressed output via ExifInterface if metadata removal is disabled.
  7. Cross-Platform Metadata Removal (HEIC, JPEG, PNG, WEBP):
    • Pairs androidx.exifinterface with FlutterImageCompress(keepExif: false) to reliably strip metadata from HEIC, JPEG, PNG, and WEBP files across both Android and iOS when "Strip Private Metadata" is ON.
  8. Case-Insensitive Extension Support:
    • File extensions are normalized to lowercase (.jpg, .jpeg, .png, .heic, .webp), preventing .JPG / .PNG camera photos from being dropped.
  9. Cold-Start Share Intent & Authentication Safety:
    • Resolves incoming shares via ReceiveSharingIntent.instance.getInitialMedia() with intent reset, and holds pending media until authentication succeeds if the app is launched into a logged-out state.
  10. Android 14 (API 34) Partial Photo Access:
    • Supports Permission.photos.isLimited so "Select photos and videos" does not abort upload.
  11. Activity Lifecycle Resilience & Memory Leak Prevention:
    • Removed static companion object references for MethodChannel.Result. Result callbacks are bound to the instance lifecycle, preventing memory leaks and avoiding hanging method channels if Android recreates the activity.
  12. External Share Intent GPS Preservation:
    • Automatically requests/checks runtime ACCESS_MEDIA_LOCATION permissions before resolving incoming shared media in receive_sharing.dart and upload.dart, preventing Android 10+ from throwing SecurityException and falling back to redacted location-free media when shared directly from external gallery apps.
  13. Cache Storage Hygiene & Zero Disk Leaks:
    • Automatically purges intermediate uncompressed copies in original_media/ as soon as compression and EXIF transfer complete, preventing orphaned cache files and eliminating risk of out-of-space (ENOSPC) errors during large batch uploads.

Upstream PR Reference: