Android. the fileobserver class in OS is a listener for listening to file access, creation, modification, deletion, and movement operations, however, this listener only works for the level-1 sub-files under the monitored file directory,
The file directory under its subdirectory cannot be implemented. Example:
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 (); // start listening} public void ondestory () {If (null! = Mfileobserver) mfileobserver. stopwatching (); // stop listening} static class sdcardfileobserver extends fileobserver {// mask: Specifies the event type to listen to. The default value is 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: file or directory accessed, path:" + path); break; Case fileobserver. delete: system. out. println ("event: the file or directory is deleted, path:" + path); break; Case fileobserver. open: system. out. println ("event: the file or directory is opened, path:" + path); break; Case fileobserver. modify: system. out. println ("event: the file or directory is modified, path:" + path); break; Case fileobserver. create: system. out. println ("Event: file or directory created, path:" + path); break ;}}}}
Onevent is a callback, and the system will trigger this event after listening to the event. The parameter event is the event type mentioned above, and the parameter path is the directory for triggering the event. The authentication is only for the directory at this layer, other levels are invalid.
Most of us need to listen to operations related to all file objects in the path directory. What should we do? One solution is to re-implement the fileobserver class,
The following describes how to override the fileobserver class.
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); } } }
The modified fileobserver can monitor all the files in the path directory.