fix: preserve GPS metadata in uploaded photos and videos - #234
Open
bluecasita wants to merge 1 commit into
Open
bluecasita wants to merge 1 commit into
bluecasita wants to merge 1 commit into
Conversation
Since Android 10 the system redacts location EXIF from media read through the media store or SAF unless the app holds ACCESS_MEDIA_LOCATION and asks for the original with MediaStore.setRequireOriginal(). The app never declared the permission, so automatic uploads (and uploads of shared or picked media) lost their GPS tags while the rest of the EXIF survived. - declare ACCESS_MEDIA_LOCATION in the manifest - request it only from the picture/video automatic-uploads settings, when uploads are enabled (not on app start), with a snackbar on denial - add MediaLocationUtils to resolve a content URI to its unredacted original (media store URIs directly, SAF document URIs via MediaStore.getMediaUri) and use it where upload sources are read: UploadFileFromContentUriWorker and CopyAndUploadContentUrisTask; any failure falls back to the previous behaviour - Robolectric tests for MediaLocationUtils Fixes opencloud-eu#218 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #218
Problem
Since Android 10, the system redacts location metadata (the GPS EXIF block) from photos and videos an app reads through the media store or the Storage Access Framework, unless the app holds
ACCESS_MEDIA_LOCATIONand asks for the original viaMediaStore.setRequireOriginal(). The app never declared that permission, so every automatic upload (and every upload of a shared/picked media file) arrived on the server with all EXIF intact except the GPS tags. Details and reproduction in #218; Nextcloud's client had the identical bug (nextcloud/android#12188).Fix
ACCESS_MEDIA_LOCATION.MediaLocationUtilsresolves the content URI to its unredacted original when possible — a media store URI directly, a SAF document URI (what automatic uploads use) viaMediaStore.getMediaUri()— and appliessetRequireOriginal(). Used at the two places upload sources are read:UploadFileFromContentUriWorker(automatic uploads) andCopyAndUploadContentUrisTask(files shared to / picked in the app). Any failure to open the original falls back to the previous behaviour, so an upload can never fail because of this change; below Android 10 or without the permission the code path is a no-op.Testing
MediaLocationUtils(Robolectric): implicit grant below API 29, no-op without permission,requireOriginalapplied to media store URIs, non-media URIs untouched.DCIM/Camera): the permission prompt appears once in the picture-uploads settings screen; a photo taken afterwards was uploaded automatically and the server copy retains the complete GPS block (GPSLatitude,GPSLongitude,GPSAltitude,GPSDateStamp, checked with exiftool) with the rest of the EXIF unchanged — the same setup that reproduced GPS metadata stripped from uploaded photos #218 before the fix. Denying the permission keeps uploads working (location stripped, as before).Notes for review
MediaStore.getMediaUri()throws for non-media documents and for providers other than the external storage / media documents providers — that is caught and the plain URI is used.