Android 多文件监听的实现

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目录下所有文件的操作都能监听到了。

    
posted @ 2012-07-16 17:00  HappyCode002  阅读(600)  评论(0编辑  收藏  举报