FileObserver仅为文件接收CREATE或DELETE

时间:2013-12-08 15:57:29

标签: android fileobserver

我已经为目录注册了一个FileObserver。

this.observer = new DirectoryObserver(requested.getAbsolutePath(),
        FileObserver.CREATE | FileObserver.DELETE | FileObserver.DELETE_SELF);
this.observer.startWatching();

在KitKat模拟器上测试。 adb shell:

root@generic:/sdcard # echo "test" >> test.txt //notified CREATE
root@generic:/sdcard # rm test.txt //notified DELETE
root@generic:/sdcard # mkdir test //no events received
root@generic:/sdcard # rmdir test //no events received 

DirectoryObserver供参考

private final class DirectoryObserver extends FileObserver {

    private DirectoryObserver(String path, int mask) {
        super(path, mask);
    }

    @Override
    public void onEvent(int event, String pathString) {
        switch (event) {
            case FileObserver.DELETE_SELF:
                //do stuff
                break;

            case FileObserver.CREATE:
            case FileObserver.DELETE:
                //do stuff
                break;
        }
    }
}

来自docs

CREATE
Event type: A new file or subdirectory was created under the monitored directory 

DELETE
Event type: A file was deleted from the monitored directory 

因此对于CREATE,我应该收到文件和目录,并且仅针对文件使用DELETE? 好吧,我仍然没有收到CREATE的子目录。

3 个答案:

答案 0 :(得分:15)

这样做的原因是android不能很好地抽象底层文件系统并返回底层事件代码,其中引发了一些标志(event的一些较高位)。这就是为什么直接将 event事件类型进行比较不起作用的原因。

要解决此问题,您可以通过将FileObserver.ALL_EVENTS 事件掩码(使用bitwise and)应用于实际 event来删除额外的标记将其剥离为事件类型

使用您在问题中提供的代码,看起来像这样:

private final class DirectoryObserver extends FileObserver {

    private DirectoryObserver(String path, int mask) {
        super(path, mask);
    }

    @Override
    public void onEvent(int event, String pathString) {
        event &= FileObserver.ALL_EVENTS;
        switch (event) {
            case FileObserver.DELETE_SELF:
                //do stuff
                break;

            case FileObserver.CREATE:
            case FileObserver.DELETE:
                //do stuff
                break;
        }
    }
}

答案 1 :(得分:2)

我在两个设备上进行了测试,一个使用冰淇淋三明治,另一个使用棒棒糖。它们总是出现相同的int,所以我只定义了两个新的常量:

/**
 * Event type: A new subdirectory was created under the monitored directory<br>
 * For some reason this constant is undocumented in {@link FileObserver}.
 */
public static final int CREATE_DIR = 0x40000100;
/**
 * Event type: A subdirectory was deleted from the monitored directory<br>
 * For some reason this constant is undocumented in {@link FileObserver}.
 */
public static final int DELETE_DIR = 0x40000200;

在过滤CREATE和DELETE时成功收到了这两个。

答案 2 :(得分:0)

有一个问题。似乎文档是错误的 https://code.google.com/p/android/issues/detail?id=33659

关于这个答案Android: FileObserver monitors only top directory 有人发布了一个适合你的递归文件观察器