我正在尝试侦听外部存储目录中的任何事件,即通过Android FileObserver添加,删除或修改文件,但其onEvent方法永远不会被调用。
我已经尝试了以下所有解决方案:
Android FileObserver [duplicate]
FileObserver instance is being garbage collected
How do you implement a FileObserver from an Android Service
至于我的代码,下面给出了它:
清单
@extends('layout')
@section ('content')
This page is last visited on Apr 16
@endsection
服务
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.grapgame.fileobserverdemo">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:name=".AppClass"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".FileObserverService" />
</application>
</manifest>
AppClass.java
public class FileObserverService extends Service {
public static final String TAG = "FileObserverService";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStart");
final String pathToWatch = android.os.Environment.getExternalStorageDirectory().toString();
Toast.makeText(this, "My Service Started and trying to watch " + pathToWatch, Toast.LENGTH_LONG).show();
AppClass.fileObserver = new FileObserver(pathToWatch) { // set up a file observer to watch this directory on sd card
@Override
public void onEvent(int event, String file) {
Log.d(TAG, "File created [" + pathToWatch + file + "]");
}
};
AppClass.fileObserver.startWatching();
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
MainActivity.java
public class AppClass extends Application {
public static FileObserver fileObserver;
@Override
public void onCreate() {
super.onCreate();
}
}
我也尝试过没有AppClass.java,我在Stackoverflow上找到了这个解决方案并尝试过。我也试过这个GitHub代码但似乎没什么用。
我知道FileObserver不是递归的,因为现在我只是想听一个目录。
非常感谢任何帮助。
答案 0 :(得分:1)
使用RecursiveFileObserver下面的类
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import android.os.FileObserver;
import android.util.Log;
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.CREATE:
Log.i("RecursiveFileObserver", "CREATE: " + path);
break;
case FileObserver.MODIFY:
Log.i("RecursiveFileObserver", "MODIFY: " + 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);
}
}
}
您的服务将如下所示
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import java.io.File;
public class FileObserverService extends Service {
public static final String TAG = "FileObserverService";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand: Service Started");
File sdCard = Environment.getExternalStorageDirectory();
AppClass.fileObserver = new RecursiveFileObserver(sdCard.getAbsolutePath());
AppClass.fileObserver.startWatching();
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy: Service Destroyed");
}
}
和AppClass一样
public class AppClass extends Application {
public static RecursiveFileObserver fileObserver;
@Override
public void onCreate() {
super.onCreate();
Intent intent = new Intent(this, FileObserverService.class);
startService(intent);
}
}