2014-02-25 8 views
7

Ich habe die Anforderung, neue Image-Dateien des Typs .jpg auf dem Gerät erstellt zu verfolgen. Ich habe dies mit ContentObserver auf MediaStore unter Verwendung der Klasse MediaStoreObserver und Registrierung in einem meiner Service getan.ContentObserver onChange() -Methode wird oft aufgerufen

Ich habe festgestellt, dass onChange() Methode oft für eine einzelne Dateierstellung aufgerufen wird. Ich verstehe, dass die erstellte Mediendatei in vielen Tabellen von MediaStore aktualisiert wird, daher wird onChange() oft aufgerufen.

Meine Frage: Wie zu MediaStore für ONLY Bilddatei erstellen/bearbeiten Vorgang registrieren?

-Danke im Voraus, Manju

private class MediaStoreObserver extends ContentObserver { 
    public MediaStoreObserver() { 
     super(null); 
    } 

    @Override 
    public void onChange(boolean selfChange) { 
     super.onChange(selfChange); 

     //check image file changes in MediaStore 
     readFromMediaStore(_context,MediaStore.Images.Media.EXTERNAL_CONTENT_URI); 
    } 
} 

//register for external media changes for image files 
if(mediaStoreObserver!=null){ 
    _context.getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
     false,mediaStoreObserver); 
+0

Wo haben Sie diesen Beobachter abmelden? Wenn Sie nicht überprüft haben, ob Ihr Code diesen Beobachter mehrere Male registriert. –

+0

Dies ist in einem Dienst onCreate() registriert, und das gleiche wird in onDestroy() meines Dienstes de-registriert. – Manju

Antwort

2

Kurze Antwort: Sie können nicht, es ist der Anbieter die notifyChange (mit Beobachter onChange empfangen) sendet, wenn etwas ist: aktualisiert/eingefügt/gelöscht

Längere Antwort: Dies ist, was getan hätte, um zu erreichen, was Sie wollen (Wie registriert man sich bei MediaStore für NUR Image-Datei erstellen/bearbeiten?):

Lesen Sie Image-Tabelle von MediaStore beim Start und speichern Sie die _data-Spalte (Dateipfade), in einer sortierten collection, eine sortierte collection mit Pfaden (Strings). Und wenn Sie einen onChange Aufruf erhalten, erstellen Sie eine neue Sammlung der obigen Sortierung, dann durchlaufen Sie die neue Sammlung und durchsuchen die erstellte Originalsammlung mit der Binärsuche (da die Sammlung sortiert ist und wir die Zeitkomplexität niedrig halten wollen). Dies würde zu einer recht effektiven Implementierung mit einer Laufzeit von O (n * logn) führen.

oder in Pseudo-Code:

1. Read current image columns from media store (the `_data column as projection) 
2. Store result in a collection, with string type 
3. Sort collection 
4. Upon `onChange` is received, make a new collection as step 1-3 
5. Loop over collection created in 4 and search each string you take out with 
binary search in the sorted collection you got from step 3, if item is not found 
then the item is new 
6. Make the collection in 4 the current cached version of mediastore 
7. Time complexity is O(n*log n) for the above algorithm 

bearbeiten für die Datei Teil aktualisiert i das Datum geändert Feld von Mediastor lesen würde, wenn meine Suche 5 Treffer in Schritt, dass, dass Sie tatsächlich Geschäft bedeuten würde, sollten Sowohl die Datei (uri) als auch das Datum wurden in einer Datenklasse geändert, aber als Suchnachschlag verwenden Sie den Dateipfad. Wann immer eine Datei gefunden wird, sollten Sie überprüfen, ob die geänderten Daten übereinstimmen, andernfalls ist es eine aktualisierte Datei.

0

Ich hatte das gleiche Problem und behoben es durch Entfernen super.onchange von meinem onchange Override.

+0

Das funktioniert nicht für mich. Ich bekomme eine ANR, wenn ich das tue. – barq