2012-02-23 14 views
11

Ho avuto questa classe:Trigger mediascanner su percorso specifico (cartella), come?

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 i.e. "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 
    } 
} 

come usarlo in altra classe? Non so come usare correttamente le classi, ho provato ma non funziona nulla. Faccio qualcosa di sbagliato, ma non so cosa, qualcuno può aiutarmi con questo.

+1

Stai parlando [quel post] (http: // StackOverflow. com/domande/4753252/scan-android-sd-card-per-nuove-files)? – XMoby

+0

Oh, non ho trovato quel post, grazie! – Bigflow

+0

Potresti ancora aiutarmi, sono davvero pessimo con le lezioni e cose simili in Java. – Bigflow

risposta

9

Hey ho scoperto come farlo con un codice molto semplice.

basta chiamare questa riga di codice:

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

Questo dovrebbe far scattare MediaScanner.

+4

Attiverà il mediascanner ma eseguirà la scansione di tutti i file (eccetto la cartella con il file .nomedia) nella scheda SD. Ci vorrà del tempo per eseguire la scansione in base al numero di file nella scheda SD. – artsylar

+4

Intent.ACTION_MEDIA_MOUNTED si interromperà sui dispositivi Android 4.4+ poiché l'intento è ora limitato alle applicazioni di sistema. –

5

In Android, esiste un database del contenuto che viene utilizzato dallo scanner multimediale per tenere traccia di tutti i contenuti multimediali presenti sul dispositivo.

Quando stivali Android, il servizio MediaScanner viene lanciato e attraversa l'intero storage esterno da trovare se non v'è alcun nuovo contenuto multimediale, se ne trova uno, allora,

  • Si aggiunge una voce di quel contenuto multimediale nel database del contenuto
  • Ogni voce nel database del contenuto contiene metadati del contenuto multimediale come Nome, data, dimensione del file, tipo di file, ecc.
  • Così quando si modifica un contenuto multimediale, si necessità di aggiornare anche il database del contenuto.
  • Se il database del contenuto non è aggiornato, anche altre applicazioni non saranno in grado di accedere a quel particolare contenuto multimediale.
  • viene eseguito un controllo dei media solo aggiorna il database del contenuto

Invece di eseguire lo scanner dei media, è possibile aggiornare il database del contenuto da soli e dovrebbe risolvere il problema.

Ecco uno explanation su come inserire, eliminare, aggiornare utilizzando il risolutore di contenuto. (Ricerca per la sezione "Inserimento, aggiornamento e l'eliminazione dei dati")

Edit: esiste un codice di esempio in questo answer. Controlla la risposta di Janusz.

+0

Grazie, ci andrò quando avrò finito con qualcos'altro. – Bigflow

+0

Lui, ha aggiunto la mia risposta, ha appena trovato questo codice, ancora più facile da usare :) – Bigflow

5
File file = new File(absolutePath); 
    Uri uri = Uri.fromFile(file); 
    Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri); 
    sendBroadcast(intent); 
+0

Interromperò in android 7.0 –

42

La storia

Prima di Android 4.4, potremmo semplicemente inviare una trasmissione per attivare lo scanner media su qualsiasi particolare file, o una cartella o anche sulla radice dello stoccaggio. Ma da 4.4 KitKat, questo è stato risolto dagli sviluppatori Android.

Perché dico fisso? La ragione è semplice. L'invio di una trasmissione utilizzando MEDIA_MOUNTED nella directory principale è molto costoso. L'esecuzione di Media Scanner è un'operazione costosa e la situazione peggiora ulteriormente quando l'utente ha molti file nelle strutture di archiviazione e cartelle profonde.

Prima di Android 4.4

Resta semplice e lineare. Se hai scelto come target la tua app prima di Android 4.4. Ma tieni a mente di non usarlo nella directory root se non assolutamente necessario.

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

da Android 4.4

Ci sono due modi per voi.

i) Il primo è molto simile all'esempio precedente, ma potrebbe non funzionare in modo efficiente e non è consigliato.

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

ii) Ora passiamo alla soluzione più consigliata ed efficiente per questo problema.

Aggiungere i percorsi di file dei file che sono stati aggiornati, in questo modo, in un tipo String ArrayList

ArrayList<String> toBeScanned = new ArrayList<String>(); 
toBeScanned.add(item.getFilePath()); 

Ora è necessario eseguire SCANFILE() metodo statico della classe MediaScannerConnection e passare la matrice String contenente l'elenco di tutti i file che sono stati aggiornati e devono essere sottoposti a scansione dei supporti.

È anche possibile mettere un ascoltatore a rispondere quando la scansione è stata completata per i singoli file.

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); 

        } 
       }); 
+1

modo ii converte le directory in file, vedere http://stackoverflow.com/questions/31157882/mediascannerconnectionscanfile-converts-directories-into-files-when-accessing-t – OneWorld

+2

modo in cui non ha effetto (entrambi i commenti si riferiscono ad Android 5) – OneWorld

+0

Quando copio un file nella cartella Suonerie e lo scannerisco, Scanner Media lo visualizza subito sul selezionatore di suoni! Tuttavia, dopo che la mia app ha eliminato il file dalla cartella Suonerie, l'ho anche scansionato da Media Scanner (i trigger "onScanCompleted()" con uri = null), tuttavia, il selettore di supporti ** ancora ** mostra quel file. Cosa fare dopo aver eliminato il file in modo che il selettore multimediale non lo mostri più? –

1
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); 
} 

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

Il Add the Photo to a Gallery Sezione

0

Come risposta di @Aritra Roy, decido di fare un esperimento su questo problema. quello che ho ottenuto qui sono:

  • Intent.ACTION_MEDIA_MOUNTED e Intent.ACTION_MEDIA_SCANNER_SCAN_FILE può accettare percorso singolo file, in modo da sendBroadcast (nuova Intent (Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse (filePath))); o sendBroadcast (nuovo Intent (Intent.ACTION_MEDIA_MOUNTED, Uri.parse (filePath))); sarà valido
  • Se si utilizza il percorso del file individuo con Intent.ACTION_MEDIA_MOUNTED su KitKat o versioni successive, l'applicazione sarà ancora in crash
  • Se si utilizza Intent.ACTION_MEDIA_SCANNER_SCAN_FILE o MediaScannerConnection sul dispositivo inferiore Kitkat, l'applicazione non forzerà vicino, ma il metodo semplicemente non funzionerà come vorresti.

Da questo esperimento, penso che il metodo migliore per gestire è

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))); 
} 

fatemi sapere se ho perso qualcosa

Problemi correlati