user805623
user805623

Reputation: 65

FileObserver doesn't react to changes

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!

Upvotes: 1

Views: 1472

Answers (2)

user486646
user486646

Reputation:

Another thing to be aware of is that creating more than one FileObserver instance for the same path is not supported and can lead to some race conditions. So if there is a chance that this code could get called more than once for the same directory you can run into problems.

Upvotes: 2

Osmium USA
Osmium USA

Reputation: 1786

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.

Upvotes: 0

Related Questions