我正在尝试在后台监视用户磁盘上的文件夹,就像你可以使用JobScheduler和监视库更改一样contentobserver.我想为任何指定的目录执行此操作.但是,当目录有任何文件更改时,我无法弄清楚如何接收广播.
Niz*_*ale 13
为了创建系统范围的文件观察器,您需要做几件事.
首先
您必须创建一个将在启动时启动并始终运行的服务.为了实现这一点,你必须创建一个BroadcastReceiver,注册它以接收你ACTION_BOOT_COMPLETED的RECEIVE_BOOT_COMPLETED权限Manifest
public class StartupReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, FileSystemObserverService.class);
context.startService(myIntent);
}
}
Run Code Online (Sandbox Code Playgroud)
在你的 Manifest
<manifest >
<application >
<service
android:name=".FileSystemObserverService"
android:enabled="true"
android:exported="true" >
</service>
<!-- Declaring broadcast receiver for BOOT_COMPLETED event. -->
<receiver android:name=".StartupReceiver" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
</application>
<!-- Adding the permission -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
</manifest>
Run Code Online (Sandbox Code Playgroud)
其次
该服务必须实现android.os.FileObserver该类.由于android.os.FileObserver只观察发送给它的路径并且没有观察路径的子目录,因此必须对其进行扩展SingleFileObserver并向其添加观察者.您还必须在优先级设置为低的另一个线程中运行观察
public class FileSystemObserverService extends Service {
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
observe();
return super.onStartCommand(intent, flags, startId);
}
public File getInternalStoragePath() {
File parent = Environment.getExternalStorageDirectory().getParentFile();
File external = Environment.getExternalStorageDirectory();
File[] files = parent.listFiles();
File internal = null;
if (files != null) {
for (int i = 0; i < files.length; i++) {
if (files[i].getName().toLowerCase().startsWith("sdcard") && !files[i].equals(external)) {
internal = files[i];
}
}
}
return internal;
}
public File getExtenerStoragePath() {
return Environment.getExternalStorageDirectory();
}
public void observe() {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
//File[] listOfFiles = new File(path).listFiles();
File str = getInternalStoragePath();
if (str != null) {
internalPath = str.getAbsolutePath();
new Obsever(internalPath).startWatching();
}
str = getExtenerStoragePath();
if (str != null) {
externalPath = str.getAbsolutePath();
new Obsever(externalPath).startWatching();
}
}
});
t.setPriority(Thread.MIN_PRIORITY);
t.start();
}
class Obsever extends FileObserver {
List < SingleFileObserver > mObservers;
String mPath;
int mMask;
public Obsever(String path) {
// TODO Auto-generated constructor stub
this(path, ALL_EVENTS);
}
public Obsever(String path, int mask) {
super(path, mask);
mPath = path;
mMask = mask;
// TODO Auto-generated constructor stub
}
@Override
public void startWatching() {
// TODO Auto-generated method stub
if (mObservers != null)
return;
mObservers = new ArrayList < SingleFileObserver > ();
Stack < String > stack = new Stack < String > ();
stack.push(mPath);
while (!stack.empty()) {
String parent = stack.pop();
mObservers.add(new SingleFileObserver(parent, mMask));
File path = new File(parent);
File[] files = path.listFiles();
if (files == null) continue;
for (int i = 0; i < files.length; ++i) {
if (files[i].isDirectory() && !files[i].getName().equals(".") && !files[i].getName().equals("..")) {
stack.push(files[i].getPath());
}
}
}
for (int i = 0; i < mObservers.size(); i++) {
mObservers.get(i).startWatching();
}
}
@Override
public void stopWatching() {
// TODO Auto-generated method stub
if (mObservers == null)
return;
for (int i = 0; i < mObservers.size(); ++i) {
mObservers.get(i).stopWatching();
}
mObservers.clear();
mObservers = null;
}
@Override
public void onEvent(int event, final String path) {
if (event == FileObserver.OPEN) {
//do whatever you want
} else if (event == FileObserver.CREATE) {
//do whatever you want
} else if (event == FileObserver.DELETE_SELF || event == FileObserver.DELETE) {
//do whatever you want
} else if (event == FileObserver.MOVE_SELF || event == FileObserver.MOVED_FROM || event == FileObserver.MOVED_TO) {
//do whatever you want
}
}
private class SingleFileObserver extends FileObserver {
private String mPath;
public SingleFileObserver(String path, int mask) {
super(path, mask);
// TODO Auto-generated constructor stub
mPath = path;
}
@Override
public void onEvent(int event, String path) {
// TODO Auto-generated method stub
String newPath = mPath + "/" + path;
Obsever.this.onEvent(event, newPath);
}
}
}
Run Code Online (Sandbox Code Playgroud)
就是这样, 使用此代码,您将能够观察整个文件系统,包括内部和外部文件系统
小智 5
只需启动一个使用 Fileobserver 的服务来检测指定目录的文件更改。
服务等级:
public class FileObserverService extends Service {
private FileObserver mFileObserver;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if((intent.hasExtra(INTENT_EXTRA_FILEPATH))) // we store the path of directory inside the intent that starts the service
mFileObserver = new FileObserver(intent.getStringExtra(INTENT_EXTRA_FILEPATH)) {
@Override
public void onEvent(int event, String path) {
// If an event happens we can do stuff inside here
// for example we can send a broadcast message with the event-id
Log.d("FILEOBSERVER_EVENT", "Event with id " + Integer.toHexString(event) + " happened") // event identifies the occured Event in hex
}
};
mFileObserver.startWatching(); // The FileObserver starts watching
return Service.START_NOT_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
使用您想要观察的 YOUR_FILEPATH/DIRECTORY 从应用程序内的某个位置启动服务:
Intent intent = new Intent(this, FileObserverService.class);
intent.putExtra(INTENT_EXTRA_FILEPATH, "YOUR_FILEPATH");
this.startService(intent);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5092 次 |
| 最近记录: |