先介绍一下FileObserver
FileObserver监听事件的类型:
1.CREATE:有新文件创建时触发
2.OPEN:有文件被打开时触发
3.ACCESS:有文件内容被读取时触发,如通过流读取文件内容等
4.MODIFY:文件内容被修改时触发,如粘贴文件等
5.ATTRIB:文件属性被修改,如 chmod、chown、touch 等
6.CLOSE_NOWRITE:打开了文件但是没有编辑后关闭
7.CLOSE_WRITE:打开了文件并且编辑后关闭
8.DELETE:有文件被删除
9.MOVE_FROM:剪切文件的来源
10.MOVE_TO:粘贴剪切的文件
11.ALL_EVENTS:所有上述事件都会触发此事件
12.DELETE_SELF:自删除,即一个可执行文件在执行时删除自己。
13.MOVE_SELF:自移动,即一个可执行文件在执行时移动自己。
14.CLOSE:文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)。
说明:FileObserver并不是只有上述的事件才能触发onEvent事件。
创建文件夹的事件在上述的类型中并不包括,需要自己根据onEvent事件的path参数来判断得出。这里提供一个方法:在遍历文件夹内的内容时,将所有的文件filePath目录存入mFilePaths中,首先判断onEvent事件的path参数是否是上述事件中的一种,如果不是的话使用path创建File对象,如果判断出File对象是目录,则此为新建文件夹的FilePath,进行需要的操作。
FileObserver所监听的某一文件夹下的子文件夹中的文件信息被改变时,提供的path只是该子文件夹的path,并不是具体文件的path,所以要监听所有文件的操作时,最好是给每一个文件夹都设置FileObserver监听,可以具体到每一个文件的修改,否则某些应用对文件进行修改后会监听不到,例如已监听SDCARD文件目录,当Gallery对/sdcard/xxx进行修改等操作时,会监听到,当Gallery对/sdcard/test/xxxx进行操作时不会被监听到,最好是对/sdcard以及/sdcard/test两个文目录分别设置FileObserver监听就可以解决这个问题。
下面看一个例子,监听SDCard的目录创建事件:
1.新建一个类SDCardListener继承FileObserver,参考代码如下:
public class SDCardListener extends FileObserver {
public SDCardListener(String path) {
// 这种构造方法是默认监听所有事件的,如果使用super(String,int)这种构造方法,则int参数是要监听的事件类型。
super(path);
}
@Override
public void onEvent(int event, String path) {
switch (event) {
case FileObserver.ALL_EVENTS:
Log.d("all", "path:" + path);
break;
case FileObserver.CREATE:
Log.d("Create", "path:" + path);
break;
}
}
}
onEvent是回调,系统监听到事件后会触发此事件,参数event就是上面所说的事件类型,根据类型,我们可以做相应的处理,参数path就是触发事件的目录。
2.如何使用它,参考代码如下:
SDCardListener listener = new SDCardListener("/sdcard");
// 开始监听
listener.startWatching();
/**
* 在这里做一些操作
*/
//最后停止监听
listener.stopWatching();
此处特地给出了一个对文件和文件夹下所有内容监听的Listener
package com.testrom.tools;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import android.os.FileObserver;
import android.util.Log;
class DirChangedListener extends FileObserver {
private final static String TAG = "DirChangedListener";
public static final int MULTI_DIRS_TYPE = 0;
public static final int ONE_DIR_TYPE = 1;
private List mFileObserverList = new ArrayList();
private String mAbsolutePath;
public DirChangedListener(String path, int type) {
super(path);
mAbsolutePath = path;
if (type == MULTI_DIRS_TYPE) {
setFileObserver(path);
}
}
@Override
public void onEvent(int event, String path) {
final int action = event & FileObserver.ALL_EVENTS;
switch (action) {
// case FileObserver.ACCESS:
// Log.i(TAG, "event: 文件或目录被访问, path: " + path);
// break;
case FileObserver.DELETE:
Log.i(TAG, "event: 文件或目录被删除, path: " + mAbsolutePath + "/"
+ path);
if (path.startsWith("aee")) {
Log.i(TAG, "event: aee 文件或目录被删除, path: " + mAbsolutePath
+ "/" + path);
}
break;
// case FileObserver.OPEN:
// Log.d(TAG, "event: 文件或目录被打开, path: " + path);
// break;
// case FileObserver.MODIFY:
// Log.d(TAG, "event: 文件或目录被修改, path: " + path);
// break;
case FileObserver.CREATE:
if (path.contains("aee")) {
Log.i(TAG, "event: AEE文件或目录被创建, path: " + mAbsolutePath
+ "/" + path);
}
Log.i(TAG, "event: 文件或目录被创建, path: " + mAbsolutePath + "/"
+ path);
break;
}
}
// 获取目标文件夹下所有文件夹
private List setFileObserver(String dir) {
ArrayList fileList = new ArrayList();
LinkedList list = new LinkedList();
File fileDir = new File(dir);
File file[] = fileDir.listFiles();
mFileObserverList.add(this);
for (int i = 0; i < file.length; i++) {
if (file[i].isDirectory()) {
list.add(file[i]);
DirChangedListener fileObserver = new DirChangedListener(
file[i].getAbsolutePath(),
DirChangedListener.ONE_DIR_TYPE);
mFileObserverList.add(fileObserver);
}
}
File tmp;
while (!list.isEmpty()) {
tmp = list.removeFirst();
if (tmp.isDirectory()) {
DirChangedListener fileObserver = new DirChangedListener(
tmp.getAbsolutePath(),
DirChangedListener.ONE_DIR_TYPE);
mFileObserverList.add(fileObserver);
file = tmp.listFiles();
if (file == null)
continue;
for (int i = 0; i < file.length; i++) {
if (file[i].isDirectory()) {
list.add(file[i]);
DirChangedListener fileObserver1 = new DirChangedListener(
file[i].getAbsolutePath(),
DirChangedListener.ONE_DIR_TYPE);
mFileObserverList.add(fileObserver1);
}
}
}
}
return fileList;
}
public void startDirWatch() {
// TODO Auto-generated method stub
for (DirChangedListener listener : mFileObserverList) {
listener.startWatching();
}
}
public void stopDirWatch() {
// TODO Auto-generated method stub
for (DirChangedListener listener : mFileObserverList) {
listener.stopWatching();
}
}
}
调用
listener = new DirChangedListener("/sdcard/autotest",
DirChangedListener.MULTI_DIRS_TYPE);
listener.startDirWatch();
// 最后停止监听
listener.stopDirWatch();