7

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

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

在 KitKat 模拟器上测试。亚行外壳:

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;
        }
    }
}

来自文档

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 的子目录。

4

3 回答 3

17

原因是 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;
        }
    }
}
于 2013-12-16T11:19:32.460 回答
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 时,这两个都成功接收。

于 2016-05-25T15:56:29.403 回答
1

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

在这个答案上Android: FileObserver 只监视 某个人发布了一个递归文件观察器的顶级目录,它应该适合你

于 2013-12-16T09:12:11.187 回答