我已经为目录注册了一个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的子目录。
答案 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 有人发布了一个适合你的递归文件观察器