Disparar mediascanner en una ruta específica (carpeta), ¿cómo?

Tengo esta clase:

import android.content.Context; import android.media.MediaScannerConnection; import android.net.Uri; import android.util.Log; public class MediaScannerWrapper implements MediaScannerConnection.MediaScannerConnectionClient { private MediaScannerConnection mConnection; private String mPath; private String mMimeType; // filePath - where to scan; // mime type of media to scan ie "image/jpeg". // use "*/*" for any media public MediaScannerWrapper(Context ctx, String filePath, String mime){ mPath = "/sdcard/DCIM/Camera"; mMimeType = "jpg"; mConnection = new MediaScannerConnection(ctx, this); } // do the scanning public void scan() { mConnection.connect(); } // start the scan when scanner is ready public void onMediaScannerConnected() { mConnection.scanFile(mPath, mMimeType); Log.w("MediaScannerWrapper", "media file scanned: " + mPath); } public void onScanCompleted(String path, Uri uri) { // when scan is completes, update media file tags } } 

¿Cómo usarlo en la otra clase? No sé cómo usar correctamente las clases, lo intenté pero nada funciona. Hago algo mal, pero no sé qué, alguien puede ayudarme con esto.

La historia

Antes de Android 4.4, podíamos simplemente enviar una transmisión para activar el escáner de medios en cualquier archivo o carpeta en particular, o incluso en la raíz del almacenamiento. Pero desde 4.4 KitKat, esto ha sido arreglado por los Desarrolladores de Android.

¿Por qué digo fijo? El motivo es simple Enviar una transmisión usando MEDIA_MOUNTED en el directorio raíz es muy costoso. La ejecución de Media Scanner es una operación costosa y la situación empeora cuando el usuario tiene muchos archivos en las estructuras de almacenamiento y de carpetas profundas.

Antes de Android 4.4

Mantenlo recto y simple. Si está orientando su aplicación a Android 4.4. Pero tenga en cuenta que no debe usarlo en el directorio raíz a menos que sea absolutamente necesario.

 sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); 

Desde Android 4.4

Hay dos formas para ti.

i) El primero es muy similar al ejemplo anterior, pero puede no funcionar de manera eficiente y tampoco se recomienda.

 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); 

ii) Ahora, pasemos a la solución más recomendada y eficiente para este problema.

Agregue las rutas de archivos de los archivos que se han actualizado, como este, en un ArrayList de tipo String.

 ArrayList toBeScanned = new ArrayList(); toBeScanned.add(item.getFilePath()); 

Ahora necesita ejecutar el método estático scanFile () de la clase MediaScannerConnection y pasar la matriz String que contiene la lista de todos los archivos que se han actualizado y necesitan ser escaneados.

También puede poner un oyente que responda cuando el escaneo haya finalizado para los archivos individuales.

 String[] toBeScannedStr = new String[toBeScanned.size()]; toBeScannedStr = toBeScanned.toArray(toBeScannedStr); MediaScannerConnection.scanFile(getActivity(), toBeScannedStr, null, new OnScanCompletedListener() { @Override public void onScanCompleted(String path, Uri uri) { System.out.println("SCAN COMPLETED: " + path); } }); 

Hola, descubrí cómo hacerlo con un código muy simple.

Simplemente llame a esta línea de código:

 sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); 

Esto debería disparar mediascanner.

En Android, hay una base de datos de contenido que el escáner de medios utiliza para realizar un seguimiento de todo el contenido multimedia presente en el dispositivo.

Cuando se inicia Android, se lanza el servicio mediascanner y se ejecuta en todo el almacenamiento externo para encontrar si hay algún contenido multimedia nuevo si encuentra uno,

  • Agrega una entrada de ese contenido multimedia en la base de datos de contenido
  • Cada entrada en la base de datos de contenido contiene metadatos del contenido multimedia como Nombre, fecha, tamaño del archivo, tipo de archivo, etc.
  • Por lo tanto, cuando realice una modificación en un contenido de medios, también deberá actualizar la base de datos de contenido.
  • Si la base de datos de contenido no se actualiza, entonces otras aplicaciones tampoco podrán acceder a ese contenido de medios en particular.
  • La ejecución del escáner de medios solo actualiza la base de datos de contenido

En lugar de ejecutar el escáner de medios, puede actualizar la base de datos de contenido usted mismo y debería resolver el problema.

Aquí hay una explicación sobre cómo insertar, borrar, actualizar usando el solucionador de contenido. (Busque la sección “Insertar, actualizar y borrar datos”)

Editar: hay un código de muestra en esta respuesta . Busque la respuesta de Janusz.

  File file = new File(absolutePath); Uri uri = Uri.fromFile(file); Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri); sendBroadcast(intent); 
 private void galleryAddPic() { Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); File f = new File(mCurrentPhotoPath); Uri contentUri = Uri.fromFile(f); mediaScanIntent.setData(contentUri); this.sendBroadcast(mediaScanIntent); } 

Referencia: http://developer.android.com/training/camera/photobasics.html#TaskGallery

La sección Add the Photo to a Gallery

Como respuesta de @Aritra Roy, decido hacer un experimento sobre este tema. Lo que obtuve aquí son:

  • Intent.ACTION_MEDIA_MOUNTED e Intent.ACTION_MEDIA_SCANNER_SCAN_FILE pueden aceptar una ruta de archivo individual, por lo que sendBroadcast (nuevo Intent (Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse (filePath))); o sendBroadcast (nuevo Intento (Intención.ACTION_MEDIA_MOUNTED, Uri.parse (filePath))); será válido
  • Si utiliza una ruta de archivo individual con Intent.ACTION_MEDIA_MOUNTED en Kitkat o superior, su aplicación aún se bloqueará
  • Si usa Intent.ACTION_MEDIA_SCANNER_SCAN_FILE o MediaScannerConnection en un dispositivo inferior a Kitkat, su aplicación no se cerrará, pero el método simplemente no funcionará como usted lo desee.

A partir de ese experimento, creo que el mejor método para manejar es

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { MediaScannerConnection.scanFile(context, new String[]{imagePath}, null, new MediaScannerConnection.OnScanCompletedListener() { public void onScanCompleted(String path, Uri uri) { //something that you want to do } }); } else { context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + imagePath))); } 

Avísame si me perdí algo