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 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); } } }
修改之後的FileObserver就可以實現對path目錄下所有檔案的操作都能監聽到了。