Allow registration of multiple content observers.
Also send a hint if this was an update due to a scan or not.
This commit is contained in:
parent
b22a0424b8
commit
0c65294f7d
@ -97,7 +97,7 @@ public class MediaLibrary {
|
|||||||
/**
|
/**
|
||||||
* The observer to call-back during database changes
|
* The observer to call-back during database changes
|
||||||
*/
|
*/
|
||||||
private static ContentObserver sContentObserver;
|
private static final ArrayList<ContentObserver> sContentObservers = new ArrayList<ContentObserver>(2);
|
||||||
/**
|
/**
|
||||||
* The lock we are using during object creation
|
* The lock we are using during object creation
|
||||||
*/
|
*/
|
||||||
@ -264,14 +264,20 @@ public class MediaLibrary {
|
|||||||
/**
|
/**
|
||||||
* Registers a new content observer for the media library
|
* Registers a new content observer for the media library
|
||||||
*
|
*
|
||||||
|
* The MediaLibrary will call `onChange(boolean ongoing)` if
|
||||||
|
* the media library changed.
|
||||||
|
*
|
||||||
|
* `ongoing` will be set to `true` if you are expected to receive
|
||||||
|
* more updates soon. A value of `false` indicates that no
|
||||||
|
* scan is going on.
|
||||||
|
*
|
||||||
* @param observer the content observer we are going to call on changes
|
* @param observer the content observer we are going to call on changes
|
||||||
*/
|
*/
|
||||||
public static void registerContentObserver(ContentObserver observer) {
|
public static void registerContentObserver(ContentObserver observer) {
|
||||||
if (sContentObserver == null) {
|
if (sContentObservers.contains(observer))
|
||||||
sContentObserver = observer;
|
|
||||||
} else {
|
|
||||||
throw new IllegalStateException("ContentObserver was already registered");
|
throw new IllegalStateException("ContentObserver was already registered");
|
||||||
}
|
|
||||||
|
sContentObservers.add(observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -281,23 +287,19 @@ public class MediaLibrary {
|
|||||||
* @param observer the content observer to unregister.
|
* @param observer the content observer to unregister.
|
||||||
*/
|
*/
|
||||||
public static void unregisterContentObserver(ContentObserver observer) {
|
public static void unregisterContentObserver(ContentObserver observer) {
|
||||||
if (sContentObserver == null)
|
boolean removed = sContentObservers.remove(observer);
|
||||||
throw new IllegalStateException("No ContentObserver was registered!");
|
|
||||||
|
|
||||||
if (!sContentObserver.equals(observer))
|
if (!removed)
|
||||||
throw new IllegalArgumentException("Passed content observer was not the one you registered!");
|
throw new IllegalArgumentException("This content observer was never registered!");
|
||||||
|
|
||||||
// Sanity check passed: unregister observer.
|
|
||||||
sContentObserver = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Broadcasts a change to the observer, which will queue and dispatch
|
* Broadcasts a change to all registered observers
|
||||||
* the event to any registered observer
|
|
||||||
*/
|
*/
|
||||||
static void notifyObserver() {
|
static void notifyObserver(boolean ongoing) {
|
||||||
if (sContentObserver != null)
|
ArrayList<ContentObserver> list = sContentObservers;
|
||||||
sContentObserver.onChange(true);
|
for (int i = list.size(); --i != -1; )
|
||||||
|
list.get(i).onChange(ongoing);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -326,7 +328,7 @@ public class MediaLibrary {
|
|||||||
|
|
||||||
if (rows > 0) {
|
if (rows > 0) {
|
||||||
getBackend(context).cleanOrphanedEntries(true);
|
getBackend(context).cleanOrphanedEntries(true);
|
||||||
notifyObserver();
|
notifyObserver(false);
|
||||||
}
|
}
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
@ -357,7 +359,7 @@ public class MediaLibrary {
|
|||||||
long id = getBackend(context).insert(MediaLibrary.TABLE_PLAYLISTS, null, v);
|
long id = getBackend(context).insert(MediaLibrary.TABLE_PLAYLISTS, null, v);
|
||||||
|
|
||||||
if (id != -1)
|
if (id != -1)
|
||||||
notifyObserver();
|
notifyObserver(false);
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,7 +377,7 @@ public class MediaLibrary {
|
|||||||
boolean removed = (rows > 0);
|
boolean removed = (rows > 0);
|
||||||
|
|
||||||
if (removed)
|
if (removed)
|
||||||
notifyObserver();
|
notifyObserver(false);
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,7 +415,7 @@ public class MediaLibrary {
|
|||||||
int rows = getBackend(context).bulkInsert(MediaLibrary.TABLE_PLAYLISTS_SONGS, null, bulk);
|
int rows = getBackend(context).bulkInsert(MediaLibrary.TABLE_PLAYLISTS_SONGS, null, bulk);
|
||||||
|
|
||||||
if (rows > 0)
|
if (rows > 0)
|
||||||
notifyObserver();
|
notifyObserver(false);
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,7 +431,7 @@ public class MediaLibrary {
|
|||||||
int rows = getBackend(context).delete(MediaLibrary.TABLE_PLAYLISTS_SONGS, selection, selectionArgs);
|
int rows = getBackend(context).delete(MediaLibrary.TABLE_PLAYLISTS_SONGS, selection, selectionArgs);
|
||||||
|
|
||||||
if (rows > 0)
|
if (rows > 0)
|
||||||
notifyObserver();
|
notifyObserver(false);
|
||||||
return rows;
|
return rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -452,7 +454,7 @@ public class MediaLibrary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (newId != -1)
|
if (newId != -1)
|
||||||
notifyObserver();
|
notifyObserver(false);
|
||||||
return newId;
|
return newId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,7 +499,7 @@ public class MediaLibrary {
|
|||||||
selection = MediaLibrary.PlaylistSongColumns._ID+"="+from;
|
selection = MediaLibrary.PlaylistSongColumns._ID+"="+from;
|
||||||
getBackend(context).update(MediaLibrary.TABLE_PLAYLISTS_SONGS, v, selection, null);
|
getBackend(context).update(MediaLibrary.TABLE_PLAYLISTS_SONGS, v, selection, null);
|
||||||
|
|
||||||
notifyObserver();
|
notifyObserver(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -195,7 +195,7 @@ public class MediaScanner implements Handler.Callback {
|
|||||||
|
|
||||||
switch (rpc) {
|
switch (rpc) {
|
||||||
case MSG_NOTIFY_CHANGE: {
|
case MSG_NOTIFY_CHANGE: {
|
||||||
MediaLibrary.notifyObserver();
|
MediaLibrary.notifyObserver(true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MSG_SCAN_FINISHED: {
|
case MSG_SCAN_FINISHED: {
|
||||||
@ -207,9 +207,15 @@ public class MediaScanner implements Handler.Callback {
|
|||||||
mPendingCleanup = false;
|
mPendingCleanup = false;
|
||||||
mBackend.cleanOrphanedEntries(true);
|
mBackend.cleanOrphanedEntries(true);
|
||||||
}
|
}
|
||||||
// make sure to notify about changes which cleanOrphanedEntries
|
|
||||||
// might have caused
|
// Send a last change notification to all observers.
|
||||||
mHandler.sendEmptyMessage(MSG_NOTIFY_CHANGE);
|
// This lets all consumers know about (possible)
|
||||||
|
// cleanups of orphaned files. The `false' value
|
||||||
|
// also signals that this will be our last update
|
||||||
|
// for this scan.
|
||||||
|
mHandler.removeMessages(MSG_NOTIFY_CHANGE);
|
||||||
|
MediaLibrary.notifyObserver(false);
|
||||||
|
|
||||||
updateNotification(false);
|
updateNotification(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user