¿Cómo notificar correctamente a MediaScanner acerca de una carpeta, incluso en dispositivos Nexus / Kitkat?

Fondo

Estoy creando una aplicación que descarga algunas imágenes de Internet en una carpeta específica que se define como:

final String pathToPutFiles = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
            + File.separator + DOWNLOAD_FOLDER_NAME;

Deseo hacer la galería y cualquier aplicación que muestre los medios, recibir notificaciones de esas imágenes y poder mostrarlas.

Lamentablemente, estoy teniendo problemas con Nexus 4, que tiene la versión de Kitkat (4.4.2 para ser exactos). A veces funciona y otras no.

El problema

Hay un montón de publicaciones sobre este problema, y ​​he probado muchas de ellas y ninguna funcionó con una ruta de carpeta simple:

usando una intención de Intención.ACTION_MEDIA_SCANNER_SCAN_FILE , como se muestraaquí . Esto no funcionó en ningún dispositivocreando una instancia de MediaScannerConnectionClient y escaneo de llamadas una vez que se realizó la conexión, como se muestraaquí yaquí . No estoy seguro de lo que está mal con esto, ya que logra conectarse.llamadaescanear archivo , como se muestraaquí , con y sin oyente. Esto funcionó bien en Galaxy S3, pero no en Nexus 4. Esto es lo que elegí hacer, pero he notado que no puede funcionar con una sola ruta de carpeta. En su lugar, necesita una matriz de archivos para notificar.Lo que he intentado

Esto es lo que he hecho (de nuevo, funciona bien en Galaxy S3, que tiene Android 4.3, pero a veces no funciona en Nexus 4, que tiene Android 4.4.2):

protected void notifyMediaScannerOfNewImageFiles(final String folderPathToScan) {
        final ArrayList<String> newFilesToScan = new ArrayList<String>();
        preparePaths(folderPathToScan, newFilesToScan, true);
        final String[] newFilesToScanArr = newFilesToScan.toArray(new String[newFilesToScan.size()]);
        MediaScannerConnection.scanFile(getApplicationContext(), newFilesToScanArr, null, null);
}

public static void preparePathsForMediaScanning(final String folderPathToScan, final Collection<String> pathsToFill,
        final boolean recursive) {
    if (TextUtils.isEmpty(folderPathToScan))
        return;
    final File folderToScan = new File(folderPathToScan);
    if (!folderToScan.exists())
        return;
    pathsToFill.add(folderPathToScan);
    if (!folderToScan.isDirectory())
        return;
    final File[] childrenFiles = folderToScan.listFiles();
    if (childrenFiles == null || childrenFiles.length == 0)
        return;
    for (final File childFile : childrenFiles) {
        if (childFile.exists()) {
            final String childFilePath = childFile.getAbsolutePath();
            pathsToFill.add(childFilePath);
            if (recursive && childFile.isDirectory())
                preparePathsForMediaScanning(childFilePath, pathsToFill, true);
        }
    }
}
La pregunta

¿Cómo debo notificar una carpeta completa para escanear?

¿Por qué este método funciona solo a veces en Kitkat? ¿Es solo dispositivos Nexus u otros dispositivos también?

¿Qué se debe usar para soportar todos los dispositivos y versiones de Android?

Respuestas a la pregunta(1)

Su respuesta a la pregunta