Como notificar corretamente o MediaScanner sobre uma pasta, mesmo em dispositivos Nexus / Kitkat?

fundo

Estou criando um aplicativo que baixa algumas imagens da Internet em uma pasta específica definida como:

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

Desejo fazer a galeria e qualquer aplicativo que mostre mídia, ser notificado dessas imagens e poder mostrá-las.

Infelizmente, estou tendo problemas no Nexus 4, que tem a versão Kitkat (4.4.2 para ser exato). Às vezes funciona e às vezes não.

O problema

Existem muitas postagens sobre esse problema, e eu tentei muitas delas e nenhuma funcionou usando um caminho simples de pasta:

usando uma intenção de Intenção.ACTION_MEDIA_SCANNER_SCAN_FILE , como mostradoaqui . Isso não funcionou em nenhum dispositivocriando uma instância do MediaScannerConnectionClient e chamada de varredura depois que a conexão foi concluída, conforme mostradoaqui eaqui . Não tenho certeza do que há de errado com isso, pois ele consegue se conectar.ligarscanFile , como mostradoaqui , com e sem um ouvinte. Isso funcionou bem no Galaxy S3, mas não no Nexus 4. Foi o que eu escolhi fazer, mas notei que ele não pode funcionar com um único caminho de pasta. Em vez disso, ele precisa de uma matriz de arquivos para notificar.O que eu tentei

Foi o que fiz (novamente, funciona bem no Galaxy S3, que possui Android 4.3, mas às vezes não funciona no Nexus 4, que possui o 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);
        }
    }
}
A questão

Como devo notificar sobre uma pasta inteira para digitalizar?

Por que esse método funciona apenas algumas vezes no Kitkat? São apenas dispositivos Nexus ou outros dispositivos também?

O que deve ser usado para oferecer suporte a todos os dispositivos e versões do Android?

questionAnswers(1)

yourAnswerToTheQuestion