6

Perché voglio per assicurarsi che il MediaStore ha le informazioni più recenti senza dover riavviare vorrei innescare la MediaScanner utilizzando il modo popolare che ho trovato su SOCome attivare MediaScan su Nexus 7?

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

Questo funziona bene sul mio Samsung S2 w/ICS ma non sul mio Nexus 7 con JellyBean. Logcat mostra questo sul mio Nexus 7:

WARN/ActivityManager(480): Permission denied: checkComponentPermission() owningUid=10014 
WARN/BroadcastQueue(480): Permission Denial: broadcasting Intent { act=android.intent.action.MEDIA_MOUNTED dat=file:///storage/emulated/0 flg=0x10 } from com.example.foo.bar (pid=17488, uid=10046) is not exported from uid 10014 due to receiver com.android.providers.downloads/.DownloadReceiver 
INFO/ActivityManager(480): Start proc com.google.android.music:main for broadcast com.google.android.music/.store.MediaStoreImportService$Receiver: pid=17858 uid=10038 gids={50038, 3003, 1015, 1028} 
INFO/MusicStore(17858): Database version: 50 
INFO/MediaStoreImporter(17858): Update: incremental Added music: 0 Updated music: 0 Deleted music: 0 Created playlists: 0 Updated playlists: 0 Deleted playlists: 0 Inserted playlist items: 0 Deleted playlist items: 0 Removed orphaned playlist items: 0 

L'ultima riga suona incoraggiante, in teoria, ma i valori sono sempre 0 anche dopo che i nuovi file erano stati spinti sulla scheda SD (via adb push). Sul mio dispositivo più vecchio (S2) rimonta la scheda SD.

ho aggiunto le seguenti autorizzazioni al mio AndroidManifest.xml ma si comporta lo stesso che senza quei permesso:

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

Tutte le idee/alternative?


Edit 1:

nota che io non conosco i percorsi dei file di file nuovi o modificati o cancellati. Voglio solo assicurarmi che il MediaStore sia aggiornato.

+0

cosa questo ha a che fare con [la questione] (http://stackoverflow.com/questions/14346160/saving -files-on-external-storage-on-nexus-7-and-retrieving-from-pc) problema? –

+0

Questo è abbastanza possibile. Grazie per il link. Vado a vedere se riesco ad accedere ad altri dispositivi per vedere se è solo Nexus 4/7. –

+0

Non ho avuto alcun problema su Nexus 4 utilizzando [questa funzione per l'attivazione di un mediacan] (https://gist.github.com/danoz73/5061888) –

risposta

8

utilizzando il modo popolare che ho trovato su SO

Faking ACTION_MEDIA_MOUNTED trasmissioni non è mai stato un IMHO soluzione adeguata.

Qualche idea/alternative?

Use MediaScannerConnection, ad esempio via its scanFile() static method.

+0

Buon punto! Dopo alcuni esperimenti sembra funzionare solo quando so già quale file è stato aggiunto, cioè se fornisco il percorso completo del file incluso il nome del file. Nel mio caso non lo so. Se viene fornita una directory, tenta solo di aggiungere quella directory al MediaStore, ma non i file o le directory sottostanti. –

+0

@BerndS: "Nel mio caso non lo so" - ehm, allora perché stai scherzando con il "MediaStore"? – CommonsWare

+0

Perché è un modo semplice per ottenere informazioni su tutti i file multimediali sul dispositivo. È anche più veloce di eseguire personalmente la scansione del file system. –

12

Ecco il codice di esempio in base alla risposta del CommonsWare:

MediaScannerConnection.scanFile(activity, new String[]{path}, null, 
           new MediaScannerConnection.OnScanCompletedListener() { 
    @Override 
    public void onScanCompleted(final String path, final Uri uri) { 
     Log.i(TAG, String.format("Scanned path %s -> URI = %s", path, uri.toString())); 
    } 
}); 

Anche se nella maggior parte dei casi, in cui si conoscono i file da aggiungere/aggiornamento/etc. al MediaStore, si dovrebbe seguire la risposta di CommonsWare, volevo pubblicare la mia soluzione in cui ho bisogno di farlo in modo approssimativo perché non conosco i percorsi dei file. Io lo uso principalmente per test/demo:

Uri uri = Uri.fromFile(Environment.getExternalStorageDirectory()); 
activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, uri)); 

BTW, nessuna autorizzazione è necessaria per nessuna delle due soluzioni.

+11

Sembra che l'approccio "ACTION_MEDIA_MOUNTED" sia ora bloccato per le app non di sistema su Android 4.4. – CommonsWare

+1

Yup e app lo faranno in modo anomalo con "non è permesso inviare broadcast android.intent.action.MEDIA_MOUNTED":/ – markostamcar

+1

Grazie per il codice. Funziona alla grande. – Ray

7

La mia risposta è un po 'in ritardo, ma potrebbe aiutare quelli che salvano un nuovo file e vorrebbe estendere il media store solo con quel file su Android Kitkat: Su Android Kitkat l'intento ACTION_MEDIA_MOUNTED è bloccato per non- app di sistema (credo, perché la scansione dell'intero filesystem è piuttosto costosa). Ma è ancora possibile utilizzare l'ACTION_MEDIA_SCANNER_SCAN_FILE intento di aggiungere un file al media store:

File f = new File(path to the file you would like to add to the media store ...); 
try { 
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); 
    Uri uri = Uri.fromFile(f); 
    mediaScanIntent.setData(uri); 
    sendBroadcast(mediaScanIntent); 
} catch(Exception e) { 
    ... 
} 
+0

Grazie. Questa è la migliore risposta che ho visto e funziona bene per me. – Wookie