互联网上有一个非常流行的类RecursiveFileObserver
,可用于检测文件系统上进行的任何读/写更改,以递归方式可以在here,here和here中找到该类。 >。但是问题是如何使用此校准?我将其复制到我的项目中,但它没有任何作用。我该如何开始呢?
我是初学者。
package com.toraleap.collimator.util;
//from w w w .j a v a 2s.c o m
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import android.os.FileObserver;
import android.util.Log;
/**
* Enhanced FileObserver to support recursive directory monitoring basically.
* @author uestc.Mobius <mobius@toraleap.com>
* @version 2011.0121
*/
public class RecursiveFileObserver extends FileObserver {
/** Only modification events */
public static int CHANGES_ONLY = CREATE | DELETE | CLOSE_WRITE | MOVE_SELF | MOVED_FROM | MOVED_TO;
List<SingleFileObserver> 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<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 (SingleFileObserver sfo : mObservers) {
sfo.startWatching();
}
}
@Override
public void stopWatching() {
if (mObservers == null) return;
for (SingleFileObserver sfo : mObservers) {
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.
* @author uestc.Mobius <mobius@toraleap.com>
* @version 2011.0121
*/
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);
}
}
}
最佳答案
我对RecursiveFileObserver
进行了一些更改:
添加成员变量activity
。 activity
传递给构造函数。然后在创建或修改文件时将其用于输出Toast
消息。
在onEvent()
切换的情况下,只要创建新文件或修改现有文件,就会显示Toast
消息。
您可以按照以下步骤设置文件观察器:
1)如果您已经在Android Studio中拥有一个项目,请在与MainActivity.java
文件相同的文件夹/目录中添加一个新的Java文件。将新类命名为RecursiveFileObserver
。将以下内容复制并粘贴到您的RecursiveFileObserver.java
文件中。
注意第一行是package com.example.shuwnyuan.barchart;
。您必须将其替换为您自己的程序包名称,然后从MainActivity.java
文件的第一行获取您的程序包名称。
// replace this below 1 line with your own package name.
package com.example.shuwnyuan.barchart;
//from w w w .j a v a 2s.c o m
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import android.app.Activity;
import android.os.FileObserver;
import android.util.Log;
import android.widget.Toast;
/**
* Enhanced FileObserver to support recursive directory monitoring basically.
* @author uestc.Mobius <mobius@toraleap.com>
* @version 2011.0121
*/
public class RecursiveFileObserver extends FileObserver {
/** Only modification events */
public static int CHANGES_ONLY = CREATE | DELETE | CLOSE_WRITE | MOVE_SELF | MOVED_FROM | MOVED_TO;
List<SingleFileObserver> mObservers;
String mPath;
int mMask;
Activity activity;
public RecursiveFileObserver(String path, Activity activity) {
super(path, ALL_EVENTS);
mPath = path;
mMask = ALL_EVENTS;
this.activity = activity;
}
public RecursiveFileObserver(String path, int mask, Activity activity) {
super(path, mask);
mPath = path;
mMask = mask;
this.activity = activity;
}
@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 (SingleFileObserver sfo : mObservers) {
sfo.startWatching();
}
}
@Override
public void stopWatching() {
if (mObservers == null) return;
for (SingleFileObserver sfo : mObservers) {
sfo.stopWatching();
}
mObservers.clear();
mObservers = null;
}
@Override
public void onEvent(int event, final 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);
// show Toast message
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "File created: " + path, Toast.LENGTH_LONG).show();
}
});
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);
// show Toast message
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, "File modified: " + path, Toast.LENGTH_LONG).show();
}
});
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.
* @author uestc.Mobius <mobius@toraleap.com>
* @version 2011.0121
*/
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);
}
}
}
2)我们将监视Android
ExternalStorageDirectory
中的文件更改。为此,我们需要明确要求用户授予文件读/写权限。我们在onCreate
的MainActivity
中执行此操作。授予权限后,我们将监视文件更改的路径。然后,我们写入名为“ MyTestFile”的文件以测试RecursiveFileObserver
。首次写入时,将创建新文件。之后,如果已经存在,则修改相同的文件。创建或修改文件时将显示Toast
消息。在您的
MainActivity
类中,进行了以下更改:public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
.....
if (Settings.System.canWrite(this) == false) {
// for first time, request user to grant file permission
requestPermissions(new String[] {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
}, 3000
);
} else {
// permission is already granted
// start watching path & write to file for test
watchPathAndWriteFile();
}
}
.....
......
// This function does 2 things:
// 1) watch path for files changes using "RecursiveFileObserver"
// 2) write to a file for testing
public void watchPathAndWriteFile() {
// the following path depends on your Android device. On my system, it is: "/storage/emulated/0/"
String path = Environment.getExternalStorageDirectory().getPath() + "/";
RecursiveFileObserver observer = new RecursiveFileObserver(path, this);
// start watching the path
observer.startWatching();
// if file "MyTestFile" not exist, new file is created. Else file is modified
try {
FileWriter out = new FileWriter(new File(Environment.getExternalStorageDirectory() + "MyTestFile"));
out.write("my file content for test...");
out.close();
} catch (IOException e) {
android.util.Log.e("writeStringAsFile", "Exception: " + e);
}
}
// in "onCreate", user is prompted to grant file read / write permission
// this function is invoked automatically after user allowed / denied permission
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 3000: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// user granted permission
// start watching for path & write to file for testing.
watchPathAndWriteFile();
} else {
// user denied permission
android.util.Log.e("Permission", "Denied");
}
return;
}
}
}