如何在后台监视文件夹中的文件更改? [英] How to monitor folder for file changes in background?

查看:74
本文介绍了如何在后台监视文件夹中的文件更改?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在后台监视用户磁盘上的文件夹,就像您可以使用JobSchedulercontentobserver监视画廊更改一样.我想对任何指定目录执行此操作.但是,当目录有任何文件更改时,我无法弄清楚如何接收广播.

I am trying to monitor a folder on the users disk in the background, much like how you can monitor gallery changes with a JobScheduler and contentobserver. I want to do this for any specified directory. However, I cannot figure out how to receive a broadcast when the directory has any file changes.

推荐答案

要创建系统范围的文件查看器,您需要做几件事.

There are several things you have to do in order create a system wide file observer.

首先

您必须创建一个将在引导时启动并始终运行的服务. 为此,您必须创建一个BroadcastReceiver,将其注册以接收ACTION_BOOT_COMPLETED和对Manifest

You have to create a service that will start up at boot and will always be running. In order for this to happen you have to create a BroadcastReceiver, register it to receive ACTION_BOOT_COMPLETED and the RECEIVE_BOOT_COMPLETED permission to your Manifest

public class StartupReceiver extends BroadcastReceiver {   

    @Override
    public void onReceive(Context context, Intent intent) {

     Intent myIntent = new Intent(context, FileSystemObserverService.class);
     context.startService(myIntent);

    }
}

在您的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>

第二

该服务必须实现android.os.FileObserver类.由于android.os.FileObserver仅观察发送给它的路径,而不观察该路径的子目录,因此您必须对其进行扩展并向其添加SingleFileObserver观察者.您还必须在另一个优先级设置为低的线程中运行观察

The service has to implement the android.os.FileObserver class. As android.os.FileObserver only observes the path you send to it and does not observe the path's subdirectories, you have to extend it and add SingleFileObserver observers to it. You also have to run the observation in another thread with priority set to low

        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);
         }

     }

 }

就这样 使用此代码,您将能够观察到整个文件系统,包括内部和外部文件系统

That's it With this code you'll be able to observe the entire file system, both the internal and external file systems

这篇关于如何在后台监视文件夹中的文件更改?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆