安卓监听某个文件夹内容更新--FileObserver

前言

在安卓开发过程中,难免会遇到对某个文件夹进行文件的操作(增删改查),如果需要监听这个文件夹中的文件变化情况,则可以用到android源码提供的接口类---FileObserver

描述

FileObserver是一个接口类,

abstract class FileObserver

使用过程中需要实现派生类(子类)。源码描述如下:

Monitors files (using inotify ) to fire an event after files are accessed or changed by any process on the device (including this one). FileObserver is an abstract class; subclasses must implement the event handler onEvent(int, String).
Each FileObserver instance can monitor multiple files or directories. If a directory is monitored, events will be triggered for all files and subdirectories inside the monitored directory.
An event mask is used to specify which changes or actions to report. Event type constants are used to describe the possible changes in the event mask as well as what actually happened in event callbacks.
Warning: If a FileObserver is garbage collected, it will stop sending events. To ensure you keep receiving events, you must keep a reference to the FileObserver instance from some other live object.

监视文件(使用inotify)以在设备上的任何进程(包括此进程)访问或更改文件后触发事件。FileObserver是一个抽象类;子类必须实现事件处理程序onEvent(int,String)。

每个FileObserver实例可以监视多个文件或目录。如果监视某个目录,将为监视目录内的所有文件和子目录触发事件。

事件掩码用于指定要报告的更改或操作。事件类型常量用于描述事件掩码中可能的更改以及事件回调中实际发生的情况。

警告:如果FileObserver被垃圾收集,它将停止发送事件。为了确保持续接收事件,必须保留对其他活动对象的FileObserver实例的引用。

用法

因为是接口类,所以需要先继承,在通过子类实现其功能,派生类的写法如下:

private static class MyFileObserver extends FileObserver {

        public MyFileObserver(String path) {
            super(path, FileObserver.ALL_EVENTS);
        }

        @Override
        public void onEvent(int event, @Nullable String path) {
            event = event & FileObserver.ALL_EVENTS;
            Log.e("TAG", "event = " + event + " path = " + path);
            switch (event) {
                case FileObserver.ACCESS:
                    Log.e("TAG", "打开文件后读取文件的操作");
                    break;
                case FileObserver.MODIFY:
                    Log.e("TAG", "文件被修改");
                    break;
                case FileObserver.ATTRIB:
                    Log.e("TAG", "属性变化");
                    break;
                case FileObserver.CLOSE_WRITE:
                    Log.e("TAG", "文件写入或编辑后关闭");
                    break;
                case FileObserver.CLOSE_NOWRITE:
                    //录音时,最后一个有效回调是这个
                    Log.e("TAG", "只读文件被关闭");
                    break;
                case FileObserver.OPEN:
                    Log.e("TAG", "文件被打开");
                    break;
                case FileObserver.MOVED_FROM:
                    Log.e("TAG", "移出事件");//试了重命名先MOVED_FROM再MOVED_TO
                    break;
                case FileObserver.MOVED_TO:
                    Log.e("TAG", "移入事件");
                    break;
                case FileObserver.CREATE:
                    Log.e("TAG", "新建文件");//把文件移动给自己先CREATE在DELETE
                    break;
                case FileObserver.DELETE:
                    Log.e("TAG", "有删除文件");//把文件移出去DELETE
                    break;
                case FileObserver.DELETE_SELF:
                    Log.e("TAG", "监听的这个文件夹被删除");
                    break;
                case FileObserver.MOVE_SELF:
                    Log.e("TAG", "监听的这个文件夹被移走");
                    break;
                case FileObserver.ALL_EVENTS:
                    Log.e("TAG", "全部操作");
                    break;
            }
        }
    }

类型说明

构造方法中,可以传入的是指定的文件夹路径和需要过滤的操作类型,其中操作类型的种类有:

@IntDef(flag = true, value = {
		ACCESS,
		MODIFY,
		ATTRIB,
		CLOSE_WRITE,
		CLOSE_NOWRITE,
		OPEN,
		MOVED_FROM,
		MOVED_TO,
		CREATE,
		DELETE,
		DELETE_SELF,
		MOVE_SELF
})
@Retention(RetentionPolicy.SOURCE)
public @interface NotifyEventType {}

/** Event type: Data was read from a file */
public static final int ACCESS = 0x00000001;
/** Event type: Data was written to a file */
public static final int MODIFY = 0x00000002;
/** Event type: Metadata (permissions, owner, timestamp) was changed explicitly */
public static final int ATTRIB = 0x00000004;
/** Event type: Someone had a file or directory open for writing, and closed it */
public static final int CLOSE_WRITE = 0x00000008;
/** Event type: Someone had a file or directory open read-only, and closed it */
public static final int CLOSE_NOWRITE = 0x00000010;
/** Event type: A file or directory was opened */
public static final int OPEN = 0x00000020;
/** Event type: A file or subdirectory was moved from the monitored directory */
public static final int MOVED_FROM = 0x00000040;
/** Event type: A file or subdirectory was moved to the monitored directory */
public static final int MOVED_TO = 0x00000080;
/** Event type: A new file or subdirectory was created under the monitored directory */
public static final int CREATE = 0x00000100;
/** Event type: A file was deleted from the monitored directory */
public static final int DELETE = 0x00000200;
/** Event type: The monitored file or directory was deleted; monitoring effectively stops */
public static final int DELETE_SELF = 0x00000400;
/** Event type: The monitored file or directory was moved; monitoring continues */
public static final int MOVE_SELF = 0x00000800;

/** Event mask: All valid event types, combined */
@NotifyEventType
public static final int ALL_EVENTS = ACCESS | MODIFY | ATTRIB | CLOSE_WRITE
		| CLOSE_NOWRITE | OPEN | MOVED_FROM | MOVED_TO | DELETE | CREATE
		| DELETE_SELF | MOVE_SELF;

ACCESS:文件被读取
MODIFY:文件写入
ATTRIB:元数据(权限、所有者、时间戳)已显式更改
CLOSE_WRITE:打开了一个文件或目录进行写入,并将其关闭
CLOSE_NOWRITE:以只读方式打开了文件或目录,并将其关闭
OPEN:已打开文件或目录
MOVED_FROM:已从受监视的目录中移动文件或子目录
MOVED_TO:件或子目录已移动到受监视的目录
CREATE:在受监视的目录下创建了新文件或子目录
DELETE:已从监控目录中删除文件
DELETE_SELF:已删除受监视的文件或目录;监控有效停止
MOVE_SELF:已移动受监视的文件或目录;监控继续进行

使用案例

需使用全局变量,否则可能无法监测到结果:

private MyFileObserver myFileObserver;

startWatching开启监测

开始关注事件。此时必须存在受监视的文件或目录,否则不会报告任何事件(即使稍后出现)。如果已启动监视,则此调用无效。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    String pictures = Environment.getExternalStorageDirectory() + File.separator + Environment.DIRECTORY_PICTURES;
    Log.e("TAG", "pictures = " + pictures);
    myFileObserver = new MyFileObserver(pictures);
    myFileObserver.startWatching();
}

stopWatching停止监测

停止关注事件。某些事件可能正在处理中,因此即使在该方法完成后,事件也可能继续报告。如果监控已停止,则此调用无效。

@Override
protected void onDestroy() {
    super.onDestroy();
    myFileObserver.stopWatching();
}

猜你喜欢

转载自blog.csdn.net/mozushixin_1/article/details/129059953