android.os下的FileObserver类是一个用于监听文件访问、创建、修改、删除、移动等操作的监听器,但是该监听只针对监听的那个文件目录下的一级子文件起作用,
而对它子目录下的文件目录则不能够实现。如下示例:
import com.example.androidemail.R;
import com.example.androidemail.R.layout;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileObserver;
public class AndroidFileListenerActivity extends Activity {
private FileObserver mFileObserver;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(null == mFileObserver) {
mFileObserver = new SDCardFileObserver(Environment.getExternalStorageDirectory().getPath());
mFileObserver.startWatching(); //开始监听
}
}
public void onDestory() {
if(null != mFileObserver) mFileObserver.stopWatching(); //停止监听
}
static class SDCardFileObserver extends FileObserver {
//mask:指定要监听的事件类型,默认为FileObserver.ALL_EVENTS
public SDCardFileObserver(String path, int mask) {
super(path, mask);
}
public SDCardFileObserver(String path) {
super(path);
}
@Override
public void onEvent(int event, String path) {
final int action = event & FileObserver.ALL_EVENTS;
switch (action) {
case FileObserver.ACCESS:
System.out.println("event: 文件或目录被访问, path: " + path);
break;
case FileObserver.DELETE:
System.out.println("event: 文件或目录被删除, path: " + path);
break;
case FileObserver.OPEN:
System.out.println("event: 文件或目录被打开, path: " + path);
break;
case FileObserver.MODIFY:
System.out.println("event: 文件或目录被修改, path: " + path);
break;
case FileObserver.CREATE:
System.out.println("event: 文件或目录被创建, path: " + path);
break;
}
}
}
}
onEvent是回调,系统监听到事件后会触发此事件,参数event就是上面所说的事件类型,参数path就是触发事件的目录,鉴定只针对于该层目录,其他层次无效。
我们大多数需要监听path目录下的所有文件对象的相关操作,那该如何是好呢?解决问题方法之一就是重新实现FileObserver类,
下面是对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 MultiFileObserver extends FileObserver {
/** Only modification events */
public static int CHANGES_ONLY = CREATE | MODIFY |DELETE | CLOSE_WRITE
| DELETE_SELF | MOVE_SELF | MOVED_FROM | MOVED_TO;
private List<SingleFileObserver> mObservers;
private String mPath;
private int mMask;
public MuityFileObserver(String path) {
this(path, ALL_EVENTS);
}
public MuityFileObserver(String path, int mask) {
super(path, mask);
mPath = path;
mMask = mask;
}
@Override
public void startWatching() {
if (mObservers != null)
return;
mObservers = new ArrayList<SingleFileObserver>();
Stack<String> stack = new Stack<String>();
stack.push(mPath);
while (!stack.isEmpty()) {
String parent = 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 = mObservers.get(i);
sfo.startWatching();
}
};
@Override
public void stopWatching() {
if (mObservers == null)
return;
for (int i = 0; i < mObservers.size(); i++) {
SingleFileObserver sfo = 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);
}
}
}
修改之后的FileObserver就可以实现对path目录下所有文件的操作都能监听到了。