I am having the following problem:
In my Activity, I have a listview that lists the content of the external files directory.
i want the list to be updated as soon as any kind of change occurs in the content, so I have:
public class FileAdapter implements ListAdapter {
private File mDirectory;
private FileObserver mFileObserver;
private DataSetObservable mDataSetObservable;
public FileAdapter() {
super();
this.mDirectory =
new ContextWrapper(ImportList.this).getExternalFilesDir(null);
if (this.mDirectory != null) {
this.mFileObserver =
new FileObserver(this.mDirectory.getAbsolutePath()) {
@Override
public void onEvent(int event, String path) {
new Handler().post(new Runnable() {
public void run() {
FileAdapter.this.mDataSetObservable.notifyChanged();
}
});
}
};
}
this.mDataSetObservable = new DataSetObservable();
}
public void startWatching() {
this.mFileObserver.startWatching();
}
public void stopWatching() {
this.mFileObserver.stopWatching();
}
public boolean areAllItemsEnabled() {
return true;
}
public boolean isEnabled(int position) {
return true;
}
public int getCount() {
return this.mDirectory == null ? 0 : this.mDirectory.listFiles().length;
}
public Object getItem(int arg0) {
return this.mDirectory.listFiles()[arg0];
}
public long getItemId(int position) {
return position;
}
public int getItemViewType(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
ItemView itemView;
if (convertView == null) {
itemView = new ItemView(ImportList.this, 1);
} else {
itemView = (ItemView) convertView;
}
File file = (File) this.getItem(position);
itemView.setValue(0, file.getName());
return itemView;
}
public int getViewTypeCount() {
return 1;
}
public boolean hasStableIds() {
return false;
}
public boolean isEmpty() {
return this.getCount() < 1;
}
public void registerDataSetObserver(DataSetObserver observer) {
this.mDataSetObservable.registerObserver(observer);
}
public void unregisterDataSetObserver(DataSetObserver observer) {
this.mDataSetObservable.unregisterObserver(observer);
}
public String getPath() {
return this.mDirectory == null ?
ImportList.this.getResources().getString(R.string.no_external_files) :
this.mDirectory.getAbsolutePath();
}
}
as an inner class of my Activity
and in my onCreate I do:
this.mFileBrowser = (ListView) this.findViewById(R.id.listview_filebrowser);
....
this.mFileAdapter = new FileAdapter();
this.mFileBrowser.setAdapter(this.mFileAdapter);
And in onResume() I do:
this.mFileAdapter.startWatching();
So as I understand, this should cause my ListView to automatically reload as soon as a file is deleted from the external files directory, for example.
But it doesn’t work!
As DJC said, the fileobserver is not recursive. If you do a good search on google, you’ll find a RecursiveFileObserver Class that works very well. One thing I did with it, however, is thread the startWatching method because it takes forever to set up, especially with complex directory trees, so I would advise threading it as to not bind up the UI thread.