Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 16, 2025

AssetEntity.latlngAsync() was returning zero for videos on Android because ExifInterface only supports images. This PR fixes video location extraction and improves the LatLng API with better null safety.

Changes

Android (Kotlin)

IDBUtils.kt

  • Added getLatLong(context: Context, id: String): DoubleArray? as a default interface method
  • Consolidated video location extraction logic for both Android Q+ and pre-Q versions
  • Implements MediaMetadataRetriever for videos to extract location from METADATA_KEY_LOCATION
  • Continues using ExifInterface for images
  • Added parseLocationString() helper to parse ISO 6709 format ("+37.4219-122.0840/")
  • Returns null for audio files

PhotoManager.kt

  • Simplified getLocation() to delegate to dbUtils.getLatLong(context, id)

AndroidQDBUtils.kt

  • Minor formatting improvements

Dart/Flutter API

lib/src/types/entity.dart

  • Breaking API improvements for LatLng:
    • Constructor now requires non-null, non-zero latitude and longitude
    • Added LatLng.fromValues() factory method for nullable/zero values (returns null for invalid coordinates)
    • Added toString() method returning "latitude,longitude" format
    • Made latitude and longitude final non-nullable fields
  • Breaking changes for AssetEntity:
    • Deprecated individual latitude and longitude constructor parameters (use latLng instead)
    • Added latLng parameter and getter
    • Changed latlngAsync() return type from LatLng to LatLng?
    • Changed latitude and longitude getters to derive from latLng
    • Changed constructor from const to regular constructor

lib/src/internal/plugin.dart

  • Updated getLatLngAsync() to return LatLng? instead of LatLng
  • Use LatLng.fromValues() factory for safe construction
  • Improved null checking for Android Q+ responses

lib/src/utils/convert_utils.dart

  • Filter out zero values when parsing latitude/longitude from native responses

Example App

example/lib/page/image_list_page.dart

  • Added "latLngAsync" button to test async location retrieval

example/lib/util/common_util.dart

  • Added showResultDialog() helper method for displaying async results
  • Updated showInfoDialog() to handle nullable LatLng return from latlngAsync()

Other

CHANGELOG.md

  • Added entry documenting the fix

analysis_options.yaml

  • Added linter rules for constructor formatting

Test files

  • Updated tests to accommodate new LatLng constructor requirements

Implementation Details

Videos store location in ISO 6709 format (e.g., "+37.4219-122.0840/" or "+37.4219-122.0840"). The parser:

  1. Removes trailing slash if present
  2. Finds the second sign (+ or -) which marks the start of longitude
  3. Splits and parses latitude and longitude as doubles
  4. Returns null for any parsing errors

Architecture

The implementation follows proper layering by placing the video location extraction logic in the database utilities layer (IDBUtils as a default interface method) rather than the plugin interface (PhotoManager), consistent with other similar methods like getExif().

Breaking Changes

LatLng class:

  • Constructor now requires non-null, non-zero values
  • latitude and longitude are now non-nullable
  • Use LatLng.fromValues() for nullable/zero coordinates (returns LatLng?)

AssetEntity:

  • latlngAsync() now returns LatLng? instead of LatLng
  • Individual latitude and longitude constructor parameters are deprecated (use latLng instead)
  • Constructor is no longer const

Migration Guide

Before:

final LatLng coords = await entity.latlngAsync();
if (coords.latitude != null && coords.latitude != 0) {
  // Use coordinates
}

After:

final LatLng? coords = await entity.latlngAsync();
if (coords != null) {
  // coords.latitude and coords.longitude are guaranteed non-zero
  print('Location: ${coords.latitude}, ${coords.longitude}');
}
Original prompt

This section details on the original issue you should resolve

<issue_title>[Feature request] Extract location data from videos on Android</issue_title>
<issue_description>### Platforms

Android

Description

AssetEntity.latlngAsync always return zero for video, ExifInterface just support images format. If location is needed, MediaMetadataRetriever should be used.

Why

I want extract location for video.</issue_description>

Comments on the Issue (you are @copilot in this section)

@fluttercandies-dev **AI Summary:** The user requests a feature to extract location data from videos on Android, as the current `AssetEntity.latlngAsync` method only works for images.

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Add feature to extract location data from videos on Android Fix video location extraction on Android using MediaMetadataRetriever Nov 16, 2025
Copilot AI requested a review from AlexV525 November 16, 2025 04:29
@AlexV525
Copy link
Member

@copilot You should put the implementation deeper into dbutils rather than the plugin interface.

Copy link
Contributor Author

Copilot AI commented Nov 16, 2025

@copilot You should put the implementation deeper into dbutils rather than the plugin interface.

Refactored the implementation to the DBUtils layer in commit fbe2c38. The video location extraction logic is now in AndroidQDBUtils and DBUtils with a new getLatLong() interface method, keeping the plugin interface clean.

@github-actions
Copy link

Download apk from here for 4e930c6

@AlexV525 AlexV525 marked this pull request as ready for review November 17, 2025 00:08
@github-actions
Copy link

Download apk from here for 41f3de2

@github-actions
Copy link

Download apk from here for 409b100

@github-actions
Copy link

Download apk from here for 02a5cc8

@github-actions
Copy link

Download apk from here for f0be60a

@AlexV525
Copy link
Member

@copilot Update the top comment to reflect all changes in this PR

Copy link
Contributor Author

Copilot AI commented Nov 17, 2025

@copilot Update the top comment to reflect all changes in this PR

Updated PR description to reflect all changes:

Fix video location extraction on Android using MediaMetadataRetriever

AssetEntity.latlngAsync() was returning zero for videos on Android because ExifInterface only supports images.

Changes

Android (Kotlin)

IDBUtils.kt

  • Added getLatLong(context: Context, id: String): DoubleArray? as a default interface method
  • Consolidated video location extraction logic for both Android Q+ and pre-Q versions
  • Implements MediaMetadataRetriever for videos to extract location from METADATA_KEY_LOCATION
  • Continues using ExifInterface for images
  • Added parseLocationString() helper to parse ISO 6709 format ("+37.4219-122.0840/")
  • Returns null for audio files

PhotoManager.kt

  • Simplified getLocation() to delegate to dbUtils.getLatLong(context, id)

Dart/Flutter API

lib/src/types/entity.dart

  • Breaking API improvements for LatLng:
    • Constructor now requires non-null, non-zero latitude and longitude
    • Added LatLng.fromValues() factory method for nullable/zero values (returns null for invalid coordinates)
    • Added toString() method returning "latitude,longitude" format
    • Made latitude and longitude final non-nullable fields
  • Breaking changes for AssetEntity:
    • Deprecated individual latitude and longitude parameters (use latLng instead)
    • Added latLng parameter and getter
    • Changed latlngAsync() return type to LatLng?

lib/src/internal/plugin.dart

  • Updated getLatLngAsync() to return LatLng?
  • Use LatLng.fromValues() factory for safe construction

lib/src/utils/convert_utils.dart

  • Filter out zero values when parsing latitude/longitude from native responses

Example App

example/lib/page/image_list_page.dart

  • Added "latLngAsync" button to test async location retrieval

example/lib/util/common_util.dart

  • Added showResultDialog() helper method
  • Updated showInfoDialog() to handle nullable LatLng

Implementation Details

Videos store location in ISO 6709 format (e.g., "+37.4219-122.0840/"). The parser handles this by finding the second sign (+ or -) which marks the start of longitude, then splits and parses both coordinates.

Breaking Changes

LatLng class:

  • Constructor now requires non-null, non-zero values
  • Use LatLng.fromValues() for nullable/zero coordinates (returns LatLng?)

AssetEntity:

  • latlngAsync() now returns LatLng? instead of LatLng
  • Individual latitude and longitude constructor parameters are deprecated

Fixes #1224

@AlexV525 AlexV525 merged commit 1568299 into main Nov 17, 2025
13 of 14 checks passed
@AlexV525 AlexV525 deleted the copilot/extract-location-data-videos branch November 17, 2025 23:57
Copilot AI changed the title Fix video location extraction on Android using MediaMetadataRetriever Fix video location extraction on Android and improve LatLng API Nov 17, 2025
@AlexV525 AlexV525 added this to the 3.8 milestone Nov 21, 2025
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.

[Feature request] Extract location data from videos on Android

2 participants