1、创建目录监听器
class MyFileObserver extends FileObserver {
// 这种构造方法是默认监听所有事件的,如果使用super(String,int)这种构造方法,则int参数是要监听的事件类型。
// 为了防止嵌套消息调用,建议使用 super(String,int) 按需创建监控消息值
public MyFileObserver(String path) {
super(path, FileObserver.CLOSE_WRITE | FileObserver.CREATE | FileObserver.DELETE
| FileObserver.DELETE_SELF );
//super(path,FileObserver.ALL_EVENTS);
}
@Override
public void onEvent(int event, String path) {
synchronized (mutex) {
// 这里注意 event 值是与 0x40000000或上后的值,所以需要case时需要先进行 &FileObserver.ALL_EVENTS
int el = event & FileObserver.ALL_EVENTS;
Log.i(TAG, "onEvent event:" + el + " path:" + path);
switch(el){
//TODO 这里case所有的监听的事件类型 FileObserver.xx 静态属性
//如果要在onEvent中做较多操作,最好使用线程去做 ,以免因为阻塞接收不到后面的事件。
//try {
// handler.obtainMessage(el, path).sendToTarget();
//} catch (Exception e) {
// Log.e(TAG, "Monitor FileObserver.onEvent error:" + e);
//}
}
}
}
}
};
使用线程处理:
private Handler handler = null;
private HandlerThread th = null;
th = new HandlerThread("sectionStorage");
th.start();
handler = new Handler(th.getLooper(), callback);
fobs = new MyFileObserver(root);
消息处理:
Handler.Callback callback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.i(TAG, "callback msg.what=" + msg.what + " msg.obj:" + msg.obj);
synchronized (mutex) {
try {
switch (msg.what) {
case FileObserver.CLOSE_WRITE:
onFileWriteClosed((String) msg.obj);
break;
case FileObserver.CREATE:
onFileCreate((String) msg.obj);
break;
case FileObserver.DELETE:
onFileDeleted((String) msg.obj);
break;
case FileObserver.DELETE_SELF:
onRootDeleted();
break;
}
} catch (Throwable e) {
Log.e(TAG, "handleMessage error:" + e);
}
}
}
};
2、对于递归监听的实现代码,可参考这里:
https://code.google.com/p/collimator/source/browse/trunk/src/com/toraleap/collimator/util/RecursiveFileObserver.java?spec=svn22&r=22
摘抄如下:
为了监听整个文件系统的变化,必须得实现这个递归监听,怎么办呢?先查查大家是怎么用 inotify 实现递归监听的,
搜索结果说明了一切,对每个子目录递归的调用 inotify,也就是说在 Android 中,也得通过遍历目录树,建立一系列
FileObserver 对象来实现这个功能,很笨吧。本来很担心这样做对系统的效率影响极大,但是大家都是这么实现的,
我也本着实践出真知的原则,写下了如下的 RecursiveFileObserver 类:
====================================================================================================================
不过拿下来后编译发现一点问题,我的代码如下:(修改了一下编译错误而已,代码抄自上面)
package com.test.fileobserver;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import android.os.FileObserver;
import android.util.Log;
@SuppressWarnings(value = { "rawtypes", "unchecked" })
public class RecursiveFileObserver extends FileObserver {
/** Only modification events */
public static int CHANGES_ONLY = CREATE | DELETE | CLOSE_WRITE
| DELETE_SELF | MOVE_SELF | MOVED_FROM | MOVED_TO;
List mObservers;
String mPath;
int mMask;
public RecursiveFileObserver(String path) {
this(path, ALL_EVENTS);
}
public RecursiveFileObserver(String path, int mask) {
super(path, mask);
mPath = path;
mMask = mask;
}
@Override
public void startWatching() {
if (mObservers != null)
return;
mObservers = new ArrayList();
Stack stack = new Stack();
stack.push(mPath);
while (!stack.isEmpty()) {
String parent = (String)stack.pop();
mObservers.add(new SingleFileObserver(parent, mMask));
File path = new File(parent);
File[] files = path.listFiles();
if (null == files)
continue;
for (File f : files) {
if (f.isDirectory() && !f.getName().equals(".")
&& !f.getName().equals("..")) {
stack.push(f.getPath());
}
}
}
for (int i = 0; i < mObservers.size(); i++) {
SingleFileObserver sfo = (SingleFileObserver) mObservers.get(i);
sfo.startWatching();
}
};
@Override
public void stopWatching() {
if (mObservers == null)
return;
for (int i = 0; i < mObservers.size(); i++) {
SingleFileObserver sfo = (SingleFileObserver) mObservers.get(i);
sfo.stopWatching();
}
mObservers.clear();
mObservers = null;
};
@Override
public void onEvent(int event, String path) {
switch (event) {
case FileObserver.ACCESS:
Log.i("RecursiveFileObserver", "ACCESS: " + path);
break;
case FileObserver.ATTRIB:
Log.i("RecursiveFileObserver", "ATTRIB: " + path);
break;
case FileObserver.CLOSE_NOWRITE:
Log.i("RecursiveFileObserver", "CLOSE_NOWRITE: " + path);
break;
case FileObserver.CLOSE_WRITE:
Log.i("RecursiveFileObserver", "CLOSE_WRITE: " + path);
break;
case FileObserver.CREATE:
Log.i("RecursiveFileObserver", "CREATE: " + path);
break;
case FileObserver.DELETE:
Log.i("RecursiveFileObserver", "DELETE: " + path);
break;
case FileObserver.DELETE_SELF:
Log.i("RecursiveFileObserver", "DELETE_SELF: " + path);
break;
case FileObserver.MODIFY:
Log.i("RecursiveFileObserver", "MODIFY: " + path);
break;
case FileObserver.MOVE_SELF:
Log.i("RecursiveFileObserver", "MOVE_SELF: " + path);
break;
case FileObserver.MOVED_FROM:
Log.i("RecursiveFileObserver", "MOVED_FROM: " + path);
break;
case FileObserver.MOVED_TO:
Log.i("RecursiveFileObserver", "MOVED_TO: " + path);
break;
case FileObserver.OPEN:
Log.i("RecursiveFileObserver", "OPEN: " + path);
break;
default:
Log.i("RecursiveFileObserver", "DEFAULT(" + event + " : " + path);
break;
}
}
/**
* Monitor single directory and dispatch all events to its parent, with full
* path.
*/
class SingleFileObserver extends FileObserver {
String mPath;
public SingleFileObserver(String path) {
this(path, ALL_EVENTS);
mPath = path;
}
public SingleFileObserver(String path, int mask) {
super(path, mask);
mPath = path;
}
@Override
public void onEvent(int event, String path) {
String newPath = mPath + "/" + path;
RecursiveFileObserver.this.onEvent(event, newPath);
}
}
}