1

我正在使用 android FileObserver 来检测公共目录中文件的更改,包括重命名。一切正常,但重命名包含目录或其任何父目录不会触发正在观察的文件的 onEvent。我尝试将事件掩码设置为 ALL_EVENTS,但无济于事。实际上,可以重命名目录,这将有效地修改观察到的文件路径,但不会调度任何事件。这是它应该如何工作的吗?我能想到的唯一解决方案是将所有目录上的观察者添加到根目录,但这似乎有点奇怪。

这是代码:

    protected class ExternalFileObserver extends FileObserver {
    public ExternalFileObserver(String path) {
        super(path, ALL_EVENTS);
    }
    @Override
    public void onEvent(int event, String path) {
        Log.d("Files", String.format("Change %d for path %s", event, path)); 
    }
4

1 回答 1

0

如果您重命名观察到的文件,则可以使用。这是我的测试观察者:

    final FileObserver fo = new FileObserver(f.getPath()) {

        @Override
        public void onEvent(int event, String path) {
            System.out.println(">>> Event: " + event + "; path: " + path);

            if((event & FileObserver.ACCESS) > 0){
                System.out.println(">>> ACCESS");
            }

            if((event & FileObserver.ALL_EVENTS) > 0){
                System.out.println(">>> ALL_EVENTS");
            }

            if((event & FileObserver.ATTRIB) > 0){
                System.out.println(">>> ATTRIB");
            }

            if((event & FileObserver.CLOSE_NOWRITE) > 0){
                System.out.println(">>> CLOSE_NOWRITE");
            }

            if((event & FileObserver.CLOSE_WRITE) > 0){
                System.out.println(">>> CLOSE_WRITE");
            }

            if((event & FileObserver.CREATE) > 0){
                System.out.println(">>> CREATE");
            }

            if((event & FileObserver.DELETE) > 0){
                System.out.println(">>> DELETE");
            }

            if((event & FileObserver.DELETE_SELF) > 0){
                System.out.println(">>> DELETE_SELF");
            }

            if((event & FileObserver.MODIFY) > 0){
                System.out.println(">>> MODIFY");
            }

            if((event & FileObserver.MOVE_SELF) > 0){
                System.out.println(">>> MOVE_SELF");
            }

            if((event & FileObserver.MOVED_FROM) > 0){
                System.out.println(">>> MOVED_FROM");
            }

            if((event & FileObserver.MOVED_TO) > 0){
                System.out.println(">>> MOVED_TO");
            }

            if((event & FileObserver.OPEN) > 0){
                System.out.println(">>> OPEN");
            }
        }
    };

这是 logcat 输出:

    >>> Event: 2048; path: null
    >>> ALL_EVENTS
    >>> MOVE_SELF
    >>> Event: 32768; path: null

如您所见,收到了 2 个事件。第一个包含标志MOVE_SELFALL_EVENTS. 第二个很奇怪,不包含任何标志。

如果重命名目录,事件在目录而不是子文件上触发似乎是合乎逻辑的。您需要将观察者附加到目录。

编辑:根据文档FileObserver使用Inotify实现,根据维基:

Inotify 不支持递归监视目录,这意味着必须为每个子目录创建单独的 inotify 监视。

于 2014-05-06T10:06:47.647 回答