Skip to content

Improved EXIF parsing for Android App#1602

Open
difanta wants to merge 3 commits intopulsejet:masterfrom
difanta:improved-exif-parsing
Open

Improved EXIF parsing for Android App#1602
difanta wants to merge 3 commits intopulsejet:masterfrom
difanta:improved-exif-parsing

Conversation

@difanta
Copy link

@difanta difanta commented Jan 17, 2026

Put the mobile app in line with the changes of #1588.

Basically a port of the changes of to the mobile application. The image.dateTaken of a SystemImage is now taken from (in order of priority) any exif field as given by ExifInterface, DATE_TAKEN from MediaStore, or DATE_MODIFIED from MediaStore.
The Exif fields are normalized and parsed with a formatter, then the oldest date is chosen. If no date is available from Exif, it falls back to dateTaken or mtime, logging the decision as it does.

Unlike #1588 there is no simple and efficient way, that I see at least, for GPS timezone inference as the places database is not available on mobile.

Just like #1144, before this I had a lot of local images defaulting to 1970 and being duplicated from local to remote, this solved all my problems, along with the web version from #1588.

Also add null checks while accessing MediaStore columns, this seems to solve problems for certain buckets not synchronizing.

@SilentNightx
Copy link

SilentNightx commented Jan 18, 2026

Thank you so much for doing this, I hope our PRs are merged but I'll be using this myself regardless.

It's kind of wild that Android videos still require GPS timezone inference just to get the correct time in 2026. I'm not an Android dev so I could be wrong but here's some options I found when looking at it:

  1. Lat/Lon String -> Geocoder.getFromLocation to get an address and work back from there to get a timezone. But depending on the Android device (I suspect most devices) the Geocoder may use the internet for it which might not be appreciated by Nextcloud users due to privacy reasons, any online geocoding options should probably be a toggle option that's off by default.
  2. The solution in my PR is offline and uses pure python so it should be possible to run it on Android although slightly more difficult. Here's what I found regarding that https://docs.python.org/3/using/android.html

@difanta difanta force-pushed the improved-exif-parsing branch 3 times, most recently from 7400158 to e9a44d6 Compare February 1, 2026 16:20
@difanta
Copy link
Author

difanta commented Feb 1, 2026

I have updated the PR, I moved the date parsing logic into a separate file since it was starting to be a bit too long, and I added some tests for the class so that eventually these are added in the server version so that we can assure they work in the same way.

I added a feature to parse date time information from filenames, this is because all whatsapp images do not carry exif information and always default to mtime, but they usually contain an earlier datetime in their filename which is more accurate in general and specifically in the case of importing whatsapp images from another device.

Now all the date sources are put together into a list of candidates and the earliest one (if >0 seconds from epoch) is selected, regardless of the source (exif fields had priority before).

@difanta difanta force-pushed the improved-exif-parsing branch from e9a44d6 to f7ab3f6 Compare February 1, 2026 16:40
Put the mobile app in line with the changes of pulsejet#1588.
Add null checks to solve problems for certain buckets not synchronizing.
remove modified date from exif candidate fields;
add filename date parsing;
choose earliest among EXIF fields, dateTaken, mtime, filename without priority to any one;
add tests for DateParser;
@difanta difanta force-pushed the improved-exif-parsing branch from f7ab3f6 to 3cc970e Compare February 2, 2026 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments