Android Media Store API does not find image which have been created by Google Photo in External Storage

845 views Asked by At

I try to implement a gallery app which also shows all locally stored images files grouped by their containing directories. To this end I build upon the MediaStore API.

My code does not find local image directories, if these directories and the image files were created by Google Photos. But if I use Google Files, to copy/move/create an image file in the affected directory, then my app finds that image.

What am I doing wrong?

Note: I am talking about real filesystem directories below the Pictures/ directory on the externals storage. I am not talking about albums which Google Photos creates in the cloud. According to the developer documentation the MediaStore API should find all images below the Pictures/ directory.

Images, including photographs and screenshots, which are stored in the DCIM/ and Pictures/ directories. The system adds these files to the MediaStore.Images table.

Simplified code:

Manifest

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Simplified data class

public class LocalFolder {
  public final long id;
  public final Uri coverUri;

  public LocalFolder( final long id, final Uri coverUri ) {
    this.id = id;
    this.coverUri = coverUri;
  }
}

Simplified code to seed the internal database

protected TreeMap< Long, LocalFolder > database;

public void run() {
  final Uri collection = ( Build.VERSION.SDK_INT < Build.VERSION_CODES.Q ) ?
    MediaStore.Images.Media.EXTERNAL_CONTENT_URI :
    MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);

  final String[] projection = {
    MediaStore.Images.Media._ID,
    MediaStore.Images.Media.BUCKET_ID };
  final Cursor cursor = contentResolver.query(
    collection, projection, null, null, null
  );
  if(cursor == null) return;

  // Cache column indices
  final int imageIdColumn = cursor.getColumnIndexOrThrow( MediaStore.Images.Media._ID );
  final int folderIdColumn = cursor.getColumnIndexOrThrow( MediaStore.Images.Media.BUCKET_ID );

  while( cursor.moveToNext() ) {
    // Compile all required attributes
    final long imageId = cursor.getLong( imageIdColumn );
    final long folderId =  cursor.getLong( folderIdColumn );
    final Uri coverUri = ContentUris.withAppendedId( collection, imageId );

    // If the image is contained in a folder, which already has been processed, skip
    if( database.containsKey( folderId ) )
      continue;

    // Create the folder and take the current image as cover image
    final LocalFolder localFolder = new LocalFolder( folderId, coverUri );
    database.put( folderId, localFolder );
  }
  cursor.close();
}

Steps to reproduce:

  1. Create a new, shared image file
    1. Open your favorite web browser and download an image file
    2. The image file is put into the shared Downloads/ directory
  2. Above code finds the image (good!)
  3. Move image file into a new real, file-system based directory with Google Photos
    1. Open Google Photos
    2. Open the register "Library"
    3. Open the album "Downloads"
    4. Open the recently added image
    5. Tap "Settings" (thee dots in the upper right corner)
    6. Tap "Move to folder"
    7. Tap "New folder"
    8. Create a new folder
  4. Above code does not find the image (bad!)
  5. "Re-create" the image file using Google Files
    1. Open Google Files
    2. Tap hamburger menu
    3. Tap device
    4. Open the directory Pictures/
    5. Open the sub-directoy which corresponds to the newly created directory by Google Photos
    6. Long-tap the recently added image file
    7. Move the image file and move the image file back into the folder
  6. Above code finds the new folder and the image (good!)
0

There are 0 answers