How do you implement a FileObserver from an Android Service
Please see this post. I think you are missing the observer.startWatching()
call after you setup your observer.
observer = new FileObserver(pathToWatch) { // set up a file observer to watch this directory on sd card
@Override
public void onEvent(int event, String file) {
//if(event == FileObserver.CREATE && !file.equals(".probe")){ // check if its a "create" and not equal to .probe because thats created every time camera is launched
Log.d(TAG, "File created [" + pathToWatch + file + "]");
Toast.makeText(getBaseContext(), file + " was saved!", Toast.LENGTH_LONG).show();
//}
}
};
observer.startWatching(); //START OBSERVING
FileObserver callback won't trigger (Related topics on stackoverflow mentioned in details)
Use class below RecursiveFileObserver
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import android.os.FileObserver;
import android.util.Log;
public class RecursiveFileObserver extends FileObserver {
/**
* Only modification events
*/
public static int CHANGES_ONLY = CREATE | DELETE | CLOSE_WRITE | MOVE_SELF | MOVED_FROM | MOVED_TO;
List<SingleFileObserver> mObservers;
String mPath;
int mMask;
public RecursiveFileObserver(String path) {
this(path, ALL_EVENTS);
}
public RecursiveFileObserver(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 (SingleFileObserver sfo : mObservers) {
sfo.startWatching();
}
}
@Override
public void stopWatching() {
if (mObservers == null) return;
for (SingleFileObserver sfo : mObservers) {
sfo.stopWatching();
}
mObservers.clear();
mObservers = null;
}
@Override
public void onEvent(int event, String path) {
switch (event) {
case FileObserver.CREATE:
Log.i("RecursiveFileObserver", "CREATE: " + path);
break;
case FileObserver.MODIFY:
Log.i("RecursiveFileObserver", "MODIFY: " + path);
break;
}
}
/**
* Monitor single directory and dispatch all events to its parent, with full path.
*
* @author uestc.Mobius <mobius@toraleap.com>
* @version 2011.0121
*/
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;
RecursiveFileObserver.this.onEvent(event, newPath);
}
}
}
Your Service will look like this
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import java.io.File;
public class FileObserverService extends Service {
public static final String TAG = "FileObserverService";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand: Service Started");
File sdCard = Environment.getExternalStorageDirectory();
AppClass.fileObserver = new RecursiveFileObserver(sdCard.getAbsolutePath());
AppClass.fileObserver.startWatching();
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy: Service Destroyed");
}
}
and AppClass like this
public class AppClass extends Application {
public static RecursiveFileObserver fileObserver;
@Override
public void onCreate() {
super.onCreate();
Intent intent = new Intent(this, FileObserverService.class);
startService(intent);
}
}
Can't use FileObserver to Observe Files Inside a Folder
I solved this problem by myself. I think the problem is because my Android Studio API level is 30, which "Environment.getExternalStorageDirectory()" is deprecated. So, to solve that I added the following attribute to the application tag in AndroidManifest.xml
android:requestLegacyExternalStorage="true"
Now, my FileObserver is working as expected
FileObserver listening on background, Android O
but how could we apply it for FileObserver?
You can't.
Is there any way to analyze data in background?
That has not changed with Android 8.0 (O). Create a sticky foreground service, then live with the unreliability, as your process still will not run forever. Also, live with the user complaints that your app is running all of the time.
Or maybe it's fail to use File Observer since now?
Using FileObserver
has never been reliable, as Android can terminate any process at any time, by user choice (e.g., "Force Stop" in Settings) or to free up system RAM. Using a sticky foreground service is as close as you can get to having an everlasting service/process, and even it will not last forever.
Android 8.0 has not changed any of this.
Depending on your use case, you could try switching to JobScheduler
and using it to monitor a MediaStore
Uri
via addTriggerContentUri()
.
Related Topics
Android Recyclerview Scrolling Performance
Android Layout with Listview and Buttons
Android Studio Error: "Manifest Merger Failed: Apps Targeting Android 12"
Opencv Template Matching Example in Android
What Exactly Does Urlconnection.Setdooutput() Affect
Android - Activity Constructor VS Oncreate
Get Filepath and Filename of Selected Gallery Image in Android
How to Parse Date from Gmt Timezone to Ist Timezone and Vice Versa in Android
Source Code Does Not Match the Bytecode' When Debugging on a Device
Android Firestore Convert Array of Document References to List<Pojo>
Access Resource Files in Android
Getstring Outside of a Context or Activity
How One Interface Can Be Used for Different Background Android Tasks
Concise Way of Writing New Dialogpreference Classes
Collections Sort(List<T>,Comparator<? Super T>) Method Example