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

        
  • 相关阅读:
    Android自己定义组件系列【2】——Scroller类
    ostringstream的使用方法
    什么是Spring?Spring是什么?
    天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱其所为,所以动心忍性,增益其所不能
    伤不起的戴尔台式机XPS8700脆弱的蓝牙
    cocos2d-x-3.1 事件分发机制 (coco2d-x 学习笔记七)
    SSL工作原理
    AfxMessageBox和MessageBox差别
    oninput,onpropertychange,onchange的使用方法和差别
    Bootstrap网站模板
  • 原文地址:https://www.cnblogs.com/happyxiaoyu02/p/6818990.html
Copyright © 2020-2023  润新知