如何使用FileObserver?RecursiveFileObserver启动及使用问题咨询
Hey there! I totally get it—copying a popular class into your project only to have it do nothing is super frustrating. Let’s break down exactly how to set up and use RecursiveFileObserver step by step, so you can start detecting file system changes right away.
Step 1: Confirm Your RecursiveFileObserver Implementation
First, double-check that the RecursiveFileObserver you copied actually extends Android’s native FileObserver and handles subdirectories. A standard, functional version looks like this (if yours is missing key parts, you’ll want to adjust it):
public class RecursiveFileObserver extends FileObserver { private List<RecursiveFileObserver> observers; private String path; public RecursiveFileObserver(String path) { super(path, ALL_EVENTS); this.path = path; } public RecursiveFileObserver(String path, int mask) { super(path, mask); this.path = path; } @Override public void startWatching() { super.startWatching(); if (observers == null) { observers = new ArrayList<>(); File file = new File(path); File[] files = file.listFiles(); if (files != null) { for (File f : files) { if (f.isDirectory() && !f.getName().equals(".") && !f.getName().equals("..")) { observers.add(new RecursiveFileObserver(f.getAbsolutePath(), getMask())); } } } for (RecursiveFileObserver observer : observers) { observer.startWatching(); } } } @Override public void stopWatching() { super.stopWatching(); if (observers != null) { for (RecursiveFileObserver observer : observers) { observer.stopWatching(); } observers.clear(); observers = null; } } @Override public void onEvent(int event, String path) { // This will be overridden by your custom implementation } }
Step 2: Initialize the Observer with Your Target Directory
Pick the directory you want to monitor (e.g., your app’s private folder or a public storage directory) and create an instance of RecursiveFileObserver, overriding the onEvent method to handle changes:
// Example: Monitor the public Documents directory String targetDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath(); RecursiveFileObserver fileObserver = new RecursiveFileObserver(targetDirectory) { @Override public void onEvent(int event, String filePath) { // Handle different file system events here switch (event) { case CREATE: Log.d("FileWatcher", "New file/directory created: " + filePath); break; case MODIFY: Log.d("FileWatcher", "File modified: " + filePath); break; case DELETE: Log.d("FileWatcher", "File/directory deleted: " + filePath); break; case MOVED_FROM: Log.d("FileWatcher", "File moved out: " + filePath); break; case MOVED_TO: Log.d("FileWatcher", "File moved in: " + filePath); break; // Add more cases if you need to handle other events } } };
Step 3: Start the Observer (Don’t Forget This!)
This is the most common mistake—you have to explicitly start watching for changes with the startWatching() method:
fileObserver.startWatching();
Step 4: Stop the Observer When You’re Done
To avoid memory leaks or unnecessary resource usage, stop the observer when your component (like an Activity or Fragment) is destroyed:
@Override protected void onDestroy() { super.onDestroy(); if (fileObserver != null) { fileObserver.stopWatching(); } }
Critical: Handle Permissions
If you’re monitoring external storage (not your app’s private directory), you need to request the right permissions:
- Add permissions to your
AndroidManifest.xml:<!-- For Android 12 and below --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- For Android 13+, use media-specific permissions if needed --> <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> - Request permissions dynamically (required for Android 6.0+):
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 1001); // Use any request code you like }
Common Pitfalls to Avoid
- Invalid Directory Path: Make sure the directory you’re monitoring actually exists. Use
new File(targetDirectory).exists()to check. - Android 10+ Scoped Storage: You can’t monitor other apps’ private directories. Stick to your app’s internal storage or public media directories.
- Testing: Don’t forget to trigger a file change (create/edit/delete a file) and check Logcat for your debug messages—sometimes it’s easy to think it’s not working when you just haven’t tested it correctly!
内容的提问来源于stack exchange,提问作者user9161645

