├── .gitignore
├── FileObserver
├── .cproject
├── .settings
│ └── org.eclipse.cdt.core.prefs
├── AndroidManifest.xml
├── jni
│ ├── Android.mk
│ ├── Logger.h
│ └── fileobserver_jni.cpp
├── libs
│ ├── android-support-v4.jar
│ └── armeabi
│ │ ├── libFileObserver.so
│ │ └── libfileobserver_jni.so
├── lint.xml
├── proguard-project.txt
├── project.properties
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ ├── drawable-xhdpi
│ │ └── ic_launcher.png
│ ├── values-v11
│ │ └── styles.xml
│ ├── values-v14
│ │ └── styles.xml
│ └── values
│ │ ├── strings.xml
│ │ └── styles.xml
└── src
│ └── custom
│ └── fileobserver
│ ├── FileListener.java
│ ├── FileObserver.java
│ ├── FileWatcher.java
│ └── TestActivity.java
├── FileWatcher.java
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # generated files
12 | bin/
13 | gen/
14 |
15 | # Local configuration file (sdk path, etc)
16 | local.properties
17 |
18 | # Eclipse project files
19 | .classpath
20 | .project
21 |
--------------------------------------------------------------------------------
/FileObserver/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/FileObserver/.settings/org.eclipse.cdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | environment/project/com.android.toolchain.gcc.2076706790/API-LEVEL/delimiter=;
3 | environment/project/com.android.toolchain.gcc.2076706790/API-LEVEL/operation=replace
4 | environment/project/com.android.toolchain.gcc.2076706790/API-LEVEL/value=16
5 | environment/project/com.android.toolchain.gcc.2076706790/GCC-H-1/delimiter=;
6 | environment/project/com.android.toolchain.gcc.2076706790/GCC-H-1/operation=append
7 | environment/project/com.android.toolchain.gcc.2076706790/GCC-H-1/value=${ANDROID_NDK_HOME}\\toolchains\\arm-linux-androideabi-4.6\\prebuilt\\windows\\lib\\gcc\\arm-linux-androideabi\\4.6.x-google\\include;
8 | environment/project/com.android.toolchain.gcc.2076706790/GCC-H-2/delimiter=;
9 | environment/project/com.android.toolchain.gcc.2076706790/GCC-H-2/operation=append
10 | environment/project/com.android.toolchain.gcc.2076706790/GCC-H-2/value=${ANDROID_NDK_HOME}\\toolchains\\arm-linux-androideabi-4.6\\prebuilt\\windows\\lib\\gcc\\arm-linux-androideabi\\4.6.x-google\\include-fixed;
11 | environment/project/com.android.toolchain.gcc.2076706790/GCC-H-INCLUDE/delimiter=;
12 | environment/project/com.android.toolchain.gcc.2076706790/GCC-H-INCLUDE/operation=replace
13 | environment/project/com.android.toolchain.gcc.2076706790/GCC-H-INCLUDE/value=${GCC-H-1};${GCC-H-2};
14 | environment/project/com.android.toolchain.gcc.2076706790/JNI-H-1/delimiter=;
15 | environment/project/com.android.toolchain.gcc.2076706790/JNI-H-1/operation=replace
16 | environment/project/com.android.toolchain.gcc.2076706790/JNI-H-1/value=${ANDROID_NDK_HOME}/platforms/android-14/arch-arm/usr/include;
17 | environment/project/com.android.toolchain.gcc.2076706790/JNI-H-2/delimiter=;
18 | environment/project/com.android.toolchain.gcc.2076706790/JNI-H-2/operation=replace
19 | environment/project/com.android.toolchain.gcc.2076706790/JNI-H-2/value=${ANDROID_NDK_HOME}/platforms/android-14/arch-arm/usr/include/android;
20 | environment/project/com.android.toolchain.gcc.2076706790/JNI-H-INCLUDE/delimiter=;
21 | environment/project/com.android.toolchain.gcc.2076706790/JNI-H-INCLUDE/operation=replace
22 | environment/project/com.android.toolchain.gcc.2076706790/JNI-H-INCLUDE/value=${JNI-H-1};${JNI-H-2};
23 | environment/project/com.android.toolchain.gcc.2076706790/append=true
24 | environment/project/com.android.toolchain.gcc.2076706790/appendContributed=true
25 |
--------------------------------------------------------------------------------
/FileObserver/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
9 |
10 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/FileObserver/jni/Android.mk:
--------------------------------------------------------------------------------
1 | LOCAL_PATH := $(call my-dir)
2 |
3 | include $(CLEAR_VARS)
4 |
5 | LOCAL_MODULE := fileobserver_jni
6 | LOCAL_SRC_FILES := fileobserver_jni.cpp
7 | LOCAL_LDLIBS := -lc -lm -lstdc++ -ldl -llog
8 | include $(BUILD_SHARED_LIBRARY)
9 |
--------------------------------------------------------------------------------
/FileObserver/jni/Logger.h:
--------------------------------------------------------------------------------
1 | #ifndef _AM_FACE_LOG_H_____
2 | #define _AM_FACE_LOG_H_____
3 |
4 | #include
5 |
6 | #define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG,__VA_ARGS__)
7 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
8 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
9 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)
10 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
11 | #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)
12 | #endif//_AM_FACE_LOG_H_____
13 |
--------------------------------------------------------------------------------
/FileObserver/jni/fileobserver_jni.cpp:
--------------------------------------------------------------------------------
1 | /* //device/libs/android_runtime/android_util_FileObserver.cpp
2 | **
3 | ** Copyright 2006, The Android Open Source Project
4 | **
5 | ** Licensed under the Apache License, Version 2.0 (the "License");
6 | ** you may not use this file except in compliance with the License.
7 | ** You may obtain a copy of the License at
8 | **
9 | ** http://www.apache.org/licenses/LICENSE-2.0
10 | **
11 | ** Unless required by applicable law or agreed to in writing, software
12 | ** distributed under the License is distributed on an "AS IS" BASIS,
13 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | ** See the License for the specific language governing permissions and
15 | ** limitations under the License.
16 | */
17 |
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include "logger.h"
27 |
28 | #define HAVE_INOTIFY
29 | #ifdef HAVE_INOTIFY
30 | #include
31 | #endif
32 |
33 | #define LOG_TAG "libfileobserver"
34 |
35 | static jmethodID method_onEvent;
36 |
37 | static jint Native_init(JNIEnv* env, jobject object)
38 | {
39 | #ifdef HAVE_INOTIFY
40 |
41 | return (jint)inotify_init();
42 |
43 | #else // HAVE_INOTIFY
44 | return -1;
45 |
46 | #endif // HAVE_INOTIFY
47 | }
48 |
49 | static void Native_observe(JNIEnv* env, jobject object, jint fd)
50 | {
51 | #ifdef HAVE_INOTIFY
52 |
53 | char event_buf[512];
54 | struct inotify_event* event;
55 |
56 | while (1)
57 | {
58 | int event_pos = 0;
59 | int num_bytes = read(fd, event_buf, sizeof(event_buf));
60 |
61 | if (num_bytes < (int)sizeof(*event))
62 | {
63 | if (errno == EINTR)
64 | continue;
65 |
66 | LOGE("***** ERROR! Native_observe() got a short event!");
67 | return;
68 | }
69 |
70 | while (num_bytes >= (int)sizeof(*event))
71 | {
72 | int event_size;
73 | event = (struct inotify_event *)(event_buf + event_pos);
74 |
75 | jstring path = NULL;
76 |
77 | if (event->len > 0)
78 | {
79 | path = env->NewStringUTF(event->name);
80 | }
81 |
82 | env->CallVoidMethod(object, method_onEvent, event->wd, event->mask,event->cookie,path);
83 | if (env->ExceptionCheck())
84 | {
85 | env->ExceptionDescribe();
86 | env->ExceptionClear();
87 | }
88 | if (path != NULL)
89 | {
90 | env->DeleteLocalRef(path);
91 | }
92 |
93 | event_size = sizeof(*event) + event->len;
94 | num_bytes -= event_size;
95 | event_pos += event_size;
96 | }
97 | }
98 |
99 | #endif // HAVE_INOTIFY
100 | }
101 |
102 | static jint Native_startWatching(JNIEnv* env, jobject object, jint fd,
103 | jstring pathString, jint mask)
104 | {
105 | int res = -1;
106 |
107 | #ifdef HAVE_INOTIFY
108 |
109 | if (fd >= 0)
110 | {
111 | const char* path = env->GetStringUTFChars(pathString, NULL);
112 |
113 | res = inotify_add_watch(fd, path, mask);
114 |
115 | //LOGD("inotify_add_watch res %d,errno:%d",res,errno);
116 | env->ReleaseStringUTFChars(pathString, path);
117 | }
118 |
119 | #endif // HAVE_INOTIFY
120 | return res;
121 | }
122 |
123 | static void Native_stopWatching(JNIEnv* env, jobject object, jint fd, jint wfd)
124 | {
125 | #ifdef HAVE_INOTIFY
126 |
127 | inotify_rm_watch((int)fd, (uint32_t)wfd);
128 |
129 | #endif // HAVE_INOTIFY
130 | }
131 |
132 | static JNINativeMethod sMethods[] =
133 | {
134 | /* name, signature, funcPtr */
135 | { "init", "()I", (void*) Native_init },
136 | { "observe", "(I)V", (void*) Native_observe },
137 | { "startWatching", "(ILjava/lang/String;I)I", (void*) Native_startWatching },
138 | { "stopWatching", "(II)V", (void*) Native_stopWatching }
139 |
140 | };
141 |
142 |
143 | int register_os_android_FileWatcher(JNIEnv* env)
144 | {
145 | jclass clazz;
146 |
147 | clazz = env->FindClass("custom/fileobserver/FileObserver$ObserverThread");
148 |
149 | if (clazz == NULL)
150 | {
151 | LOGE("Can't find custom.fileobserver.FileObserver$ObserverThread");
152 | return -1;
153 | }
154 |
155 | method_onEvent = env->GetMethodID(clazz, "onEvent","(IIILjava/lang/String;)V");
156 | if (method_onEvent == NULL)
157 | {
158 | LOGE("Can't find FileObserver.onEvent(int, int, String)");
159 | return -1;
160 | }
161 |
162 | int res = env->RegisterNatives(clazz, sMethods,
163 | (sizeof(sMethods) / sizeof(sMethods[0])));
164 | return res;
165 | }
166 |
167 | jint JNI_OnLoad(JavaVM* vm, void* reserved)
168 | {
169 | JNIEnv* env = NULL;
170 | jint result = -1;
171 | jclass native = NULL;
172 |
173 | if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
174 | {
175 | LOGD("ERROR: GetEnv failed1\n");
176 | return -1;
177 | }
178 |
179 | result = register_os_android_FileWatcher(env);
180 | if (result < 0)
181 | {
182 | LOGD("ERROR: register_FileWatcher failed1\n");
183 | return -1;
184 | }
185 |
186 | return JNI_VERSION_1_4;
187 | }
188 |
--------------------------------------------------------------------------------
/FileObserver/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doyee/FileObserver-android/c3d51e84eee9412c44634e37e75ca55509f429b1/FileObserver/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/FileObserver/libs/armeabi/libFileObserver.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doyee/FileObserver-android/c3d51e84eee9412c44634e37e75ca55509f429b1/FileObserver/libs/armeabi/libFileObserver.so
--------------------------------------------------------------------------------
/FileObserver/libs/armeabi/libfileobserver_jni.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doyee/FileObserver-android/c3d51e84eee9412c44634e37e75ca55509f429b1/FileObserver/libs/armeabi/libfileobserver_jni.so
--------------------------------------------------------------------------------
/FileObserver/lint.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/FileObserver/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/FileObserver/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-17
15 | android.library=false
16 |
--------------------------------------------------------------------------------
/FileObserver/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doyee/FileObserver-android/c3d51e84eee9412c44634e37e75ca55509f429b1/FileObserver/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/FileObserver/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doyee/FileObserver-android/c3d51e84eee9412c44634e37e75ca55509f429b1/FileObserver/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/FileObserver/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/doyee/FileObserver-android/c3d51e84eee9412c44634e37e75ca55509f429b1/FileObserver/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/FileObserver/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/FileObserver/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/FileObserver/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | FileWather
4 |
5 |
--------------------------------------------------------------------------------
/FileObserver/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/FileObserver/src/custom/fileobserver/FileListener.java:
--------------------------------------------------------------------------------
1 | package custom.fileobserver;
2 |
3 | public interface FileListener {
4 | public void onFileCreated(String name);
5 | public void onFileDeleted(String name);
6 | public void onFileModified(String name);
7 | public void onFileRenamed(String oldName, String newName);
8 | }
9 |
--------------------------------------------------------------------------------
/FileObserver/src/custom/fileobserver/FileObserver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2006 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package custom.fileobserver;
18 | import android.os.Handler;
19 | import android.os.HandlerThread;
20 | import android.os.Process;
21 | import android.util.Log;
22 |
23 |
24 | import java.io.File;
25 | import java.io.FileFilter;
26 | import java.lang.ref.WeakReference;
27 | import java.util.HashMap;
28 | import java.util.Iterator;
29 |
30 | /**
31 | * Monitors files (using inotify)
32 | * to fire an event after files are accessed or changed by by any process on
33 | * the device (including this one). FileObserver is an abstract class;
34 | * subclasses must implement the event handler {@link #onEvent(int, String)}.
35 | *
36 | *
Each FileObserver instance monitors a single file or directory.
37 | * If a directory is monitored, events will be triggered for all files and
38 | * subdirectories (recursively) inside the monitored directory.
39 | *
40 | *
An event mask is used to specify which changes or actions to report.
41 | * Event type constants are used to describe the possible changes in the
42 | * event mask as well as what actually happened in event callbacks.
43 | *
44 | *
Warning: If a FileObserver is garbage collected, it
45 | * will stop sending events. To ensure you keep receiving events, you must
46 | * keep a reference to the FileObserver instance from some other live object.
47 | */
48 | /**
49 | *
50 | * @author Dai Dongsheng
51 | * Email: doyee@163.com
52 | *
53 | */
54 | public abstract class FileObserver {
55 | /** Event type: Data was read from a file */
56 | public static final int ACCESS = 0x00000001;
57 | /** Event type: Data was written to a file */
58 | public static final int MODIFY = 0x00000002;
59 | /** Event type: Metadata (permissions, owner, timestamp) was changed explicitly */
60 | public static final int ATTRIB = 0x00000004;
61 | /** Event type: Someone had a file or directory open for writing, and closed it */
62 | public static final int CLOSE_WRITE = 0x00000008;
63 | /** Event type: Someone had a file or directory open read-only, and closed it */
64 | public static final int CLOSE_NOWRITE = 0x00000010;
65 | /** Event type: A file or directory was opened */
66 | public static final int OPEN = 0x00000020;
67 | /** Event type: A file or subdirectory was moved from the monitored directory */
68 | public static final int MOVED_FROM = 0x00000040;
69 | /** Event type: A file or subdirectory was moved to the monitored directory */
70 | public static final int MOVED_TO = 0x00000080;
71 | /** Event type: A new file or subdirectory was created under the monitored directory */
72 | public static final int CREATE = 0x00000100;
73 | /** Event type: A file was deleted from the monitored directory */
74 | public static final int DELETE = 0x00000200;
75 | /** Event type: The monitored file or directory was deleted; monitoring effectively stops */
76 | public static final int DELETE_SELF = 0x00000400;
77 | /** Event type: The monitored file or directory was moved; monitoring continues */
78 | public static final int MOVE_SELF = 0x00000800;
79 |
80 |
81 | public static final int UNMOUNT = 0x00002000;
82 | public static final int Q_OVERFLOW = 0x00004000;
83 | public static final int IGNORED = 0x00008000;
84 |
85 | public static final int CLOSE = (CLOSE_WRITE | CLOSE_NOWRITE);
86 | public static final int MOVE = (MOVED_FROM | MOVED_TO);
87 |
88 | public static final int ONLYDIR = 0x01000000;
89 | public static final int DONT_FOLLOW = 0x02000000;
90 | public static final int MASK_ADD = 0x20000000;
91 | public static final int ISDIR = 0x40000000 ;
92 | public static final int ONESHOT = 0x80000000;
93 |
94 | /** Event mask: All valid event types, combined */
95 | public static final int ALL_EVENTS = ACCESS | MODIFY | ATTRIB | CLOSE_WRITE
96 | | CLOSE_NOWRITE | OPEN | MOVED_FROM | MOVED_TO | DELETE | CREATE
97 | | DELETE_SELF | MOVE_SELF;
98 | public static int FILE_CHANGED = CREATE | DELETE | MOVED_FROM | MOVED_TO | CLOSE_WRITE;/* MODIFY | ATTRIB*/;
99 |
100 | private static final String LOG_TAG = "FileObserver";
101 |
102 |
103 | private static class FolderFilter implements FileFilter{
104 | public boolean accept(File pathname) {
105 | return pathname.isDirectory();
106 | }
107 | }
108 | private static class ObserverThread extends Thread {
109 | private HashMap> mObservers = new HashMap>();
110 | private HashMap mListPath = new HashMap();
111 | private FolderFilter mFilter = new FolderFilter();
112 | private int m_fd;
113 |
114 | public ObserverThread() {
115 | super("FileObserver");
116 | m_fd = init();
117 | }
118 |
119 | public void run() {
120 | observe(m_fd);
121 | }
122 |
123 | public int startWatching(String observed, String path, int mask, FileObserver observer) {
124 | int wfd = startWatching(m_fd, path, mask);
125 |
126 | Integer i = new Integer(wfd);
127 | if (wfd <= 0) {
128 |
129 | return i;
130 | }
131 |
132 | synchronized (mObservers) {
133 | mObservers.put(i, new WeakReference