FileObserver仅为文件接收CREATE或DELETE

Yar*_*lyk 7 android fileobserver

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

this.observer = new DirectoryObserver(requested.getAbsolutePath(),
        FileObserver.CREATE | FileObserver.DELETE | FileObserver.DELETE_SELF);
this.observer.startWatching();
Run Code Online (Sandbox Code Playgroud)

在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 
Run Code Online (Sandbox Code Playgroud)

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

来自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 
Run Code Online (Sandbox Code Playgroud)

所以对于CREATE,我应该收到文件和目录,只有文件的DELETE?好吧,我仍然没有收到CREATE的子目录.

Eug*_*Loy 16

这样做的原因是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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)