Android如何监测文件夹内容变化详解

目录
  • 一. 概述:
  • 二. 监听的事件类型:
  • 三.实例
  • 总结

一. 概述:

android.os包下的FileObserver类是一个用于监听文件访问、创建、修改、删除、移动等操作的监听器,基于linux的INotify。FileObserver是个抽象类,必须继承它才能使用。每个FileObserver对象监听一个单独的文件或者文件夹,如果监视的是一个文件夹,那么文件夹下所有的文件和级联子目录的改变都会触发监听的事件。

FileObserver简介Android.os包下的FileObserver类是一个用于监听文件访问、创建、修改、删除、移动等操作的监听器,基于Linux的INotify。

FileObserver是个抽象类,必须继承它才能使用。每个FileObserver对象监听一个单独的文件或者文件夹,如果监视的是一个文件夹,那么文件夹下所有的文件和级联子目录的改变都会触发监听的事件。

二. 监听的事件类型:

ACCESS,即文件被访问

     MODIFY,文件被 修改

     ATTRIB,文件属性被修改,如 chmod、chown、touch 等

     CLOSE_WRITE,可写文件被 close

     CLOSE_NOWRITE,不可写文件被 close

     OPEN,文件被 open

     MOVED_FROM,文件被移走,如 mv

     MOVED_TO,文件被移来,如 mv、cp

     CREATE,创建新文件

     DELETE,文件被删除,如 rm

     DELETE_SELF,自删除,即一个可执行文件在执行时删除自己

     MOVE_SELF,自移动,即一个可执行文件在执行时移动自己

     CLOSE,文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)

     ALL_EVENTS,包括上面的所有事件

三.实例

import com.example.androidemail.R;
import com.example.androidemail.R.layout;  

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.FileObserver;  

public class AndroidFileListenerActivity extends Activity {
    private FileObserver mFileObserver;  

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);  

        if(null == mFileObserver) {
            mFileObserver = new SDCardFileObserver(Environment.getExternalStorageDirectory().getPath());
            mFileObserver.startWatching(); //开始监听
        }
    }  

    public void onDestory() {
        if(null != mFileObserver) mFileObserver.stopWatching(); //停止监听
    }  

    static class SDCardFileObserver extends FileObserver {
        //mask:指定要监听的事件类型,默认为FileObserver.ALL_EVENTS
        public SDCardFileObserver(String path, int mask) {
            super(path, mask);
        }  

        public SDCardFileObserver(String path) {
            super(path);
        }  

        @Override
        public void onEvent(int event, String path) {
            final int action = event & FileObserver.ALL_EVENTS;
            switch (action) {
            case FileObserver.ACCESS:
                System.out.println("event: 文件或目录被访问, path: " + path);
                break;  

            case FileObserver.DELETE:
                System.out.println("event: 文件或目录被删除, path: " + path);
                break;  

            case FileObserver.OPEN:
                System.out.println("event: 文件或目录被打开, path: " + path);
                break;  

            case FileObserver.MODIFY:
                System.out.println("event: 文件或目录被修改, path: " + path);
                break;  

            case FileObserver.CREATE:
                System.out.println("event: 文件或目录被创建, path: " + path);
                break;
            }
        }  

    }
}  

onEvent是回调,系统监听到事件后会触发此事件,参数event就是上面所说的事件类型,参数path就是触发事件的目录,鉴定只针对于该层目录,其他层次无效。

我们大多数需要监听path目录下的所有文件对象的相关操作,那该如何是好呢?解决问题方法之一就是重新实现FileObserver类,

下面是对FileObserver类的重写实现过程

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;  

import android.os.FileObserver;
import android.util.Log;  

@SuppressWarnings(value = { "rawtypes", "unchecked" })
public class MultiFileObserver extends FileObserver {   

   /** Only modification events */
    public static int CHANGES_ONLY = CREATE | MODIFY |DELETE | CLOSE_WRITE
            | DELETE_SELF | MOVE_SELF | MOVED_FROM | MOVED_TO;   

    private List<SingleFileObserver> mObservers;
    private String mPath;
    private int mMask;   

    public MuityFileObserver(String path) {
        this(path, ALL_EVENTS);
    }   

    public MuityFileObserver(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 (int i = 0; i < mObservers.size(); i++) {
            SingleFileObserver sfo =  mObservers.get(i);
            sfo.startWatching();
        }
    };   

    @Override
    public void stopWatching() {
        if (mObservers == null)
            return;   

        for (int i = 0; i < mObservers.size(); i++) {
            SingleFileObserver sfo = mObservers.get(i);
            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.
     */
    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;
            MultiFileObserver .this.onEvent(event, newPath);
        }
    }
}

总结

到此这篇关于Android如何监测文件夹内容变化的文章就介绍到这了,更多相关Android监测文件夹内容内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android如何监测文件夹内容变化详解

    目录 一. 概述: 二. 监听的事件类型: 三.实例 总结 一. 概述: android.os包下的FileObserver类是一个用于监听文件访问.创建.修改.删除.移动等操作的监听器,基于linux的INotify.FileObserver是个抽象类,必须继承它才能使用.每个FileObserver对象监听一个单独的文件或者文件夹,如果监视的是一个文件夹,那么文件夹下所有的文件和级联子目录的改变都会触发监听的事件. FileObserver简介Android.os包下的FileObserve

  • Android String资源文件插入值实例详解

    Android String资源文件插入值实例详解 我们在用string字符串资源文件引用的时候,有时候会遇到一串字符串要在中间插入一个值的问题, 比如 登录名: XXX,这里XXX是变化的.这时候我们可能会想到拼接.其实也可以使用格式化方式处理.比如 <string name="alert">I am %1$d years old</string> 在代码中使用的话: nt nAge=23; String sAgeFormat = getResources()

  • centos下samba文件夹共享服务器配置详解

    1. 前言   最近发现在centos下开发有诸多不便,windows/mac的代码改的必须选同步到centos的文件夹下,然后才能编译.导致工作效率低,不少时间都消耗在window/mac和centos系统的代码同步上.于是就想在把centos中的文件夹共享到windows/mac上,这样便可以直接在window/mac上修改centos下的代码能够快速提高效率.samba服务器能很好的解决这个问题,它能够让windows和mac用户访问局域网的共享文件夹一样访问centos下的文件夹. 2.

  • java 解压与压缩文件夹的实例详解

     java 解压与压缩文件夹的实例详解 注意:JDK7支持设置编码设置编码格式 zipFile,zipInputStream,zipOutputStream都增加了编码格式,如果是jdk1.6需要其他的包辅助 下面为自带jdk压缩文件夹代码: public void dozip(String srcfile, String zipfile) throws IOException { String temp = ""; File src = new File(srcfile); File

  • Android开发中libs和jinLibs文件夹的作用详解

    前言 相信各位Android开发中们在Android 开发中经常和这两个文件夹打交道,以前一直迷迷糊糊的使用,没去想过.最近遇到了一些问题,仔细研究了一下,特此记录分享.下面话不多说了,来一起看看详细的介绍吧. libs: librarys 用来存放三方库的地方,比如 *.jar 和 *.aar. 在 Project 视图下能看到, Android 视图下看不到. jniLibs: java native interface librarys Android Studio 新添加的,默认用来存放

  • Android编程之文件的读写实例详解

    本文实例分析了Android编程之文件的读写方法.分享给大家供大家参考,具体如下: Android的文件读写与JavaSE的文件读写相同,都是使用IO流.而且Android使用的正是JavaSE的IO流,下面我们通过一个练习来学习Android的文件读写. 1.创建一个Android工程 Project name:File     BuildTarget:Android2.2     Application name:文件读写     Package name:test.file     Cre

  • vue项目总结之文件夹结构配置详解

    前言 之前一段时间都在使用 vue 开发后台管理系统,在摸索的过程中对 vue 本身和模块化.规范化开发有了更深的认知,现在记录下来,希望对其他需要开发项目的人有帮助. 基于 vue.js 的前端开发环境,用于前后端分离后的单页应用开发,可以在开发时使用 ES Next.scss 等最新语言特性.下面随着小编来一起学习学习吧. 项目配置 首先,在确定好使用的框架和组件库后,先要大致了解它们,做到文档基本熟悉.本次开发使用到的有: vue , vuex , axios , elementUI .

  • Python实现拷贝/删除文件夹的方法详解

    本文实例讲述了Python实现拷贝 删除文件夹的方法.分享给大家供大家参考,具体如下: 1. 拷贝文件夹 from shutil import copytree, ignore_patterns copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*')) 注:shutil.copytree实现 def copytree(src, dst, symlinks=False, ignore=None): names =

  • Android遍历所有文件夹和子目录搜索文件

    本文实例为大家分享了android遍历所有文件夹和子目录来搜索文件,供大家参考,具体内容如下 java代码: import java.io.File; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget

  • Android获取assets文件夹中的数据并写入SD卡示例

    本文示例主要实现了Android获取assets文件夹中的数据并将其写入到SD卡中,该程序实现的步骤主要为:首先读取assets文件夹中的数据库,再将其写入到SD存储卡中. 完整示例代码如下: import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import android.content.Context; /*将assets文件

随机推荐