2013-05-08 1 views
8

Согласно документации,Android: FileObserver контролирует только верхний каталог

"Each FileObserver instance monitors a single file or directory. If a directory is monitored, 
events will be triggered for all files and subdirectories inside the monitored directory." 

Мой код выглядит,

FileObserver fobsv = new FileObserver("/mnt/sdcard/") { 

    @Override 
    public void onEvent(int event, String path) { 
     System.out.println(event+" "+path); 
    } 
    }; 
    fobsv.startWatching(); 

Однако onEvent() является запуск только тогда, когда файл был изменен в /mnt/sdcard/. Если я создам файл в /mnt/sdcard/downloads/, метод не запускается.

Есть проблемы с кодом?

ответ

7

Согласно документации

Документация, неверен, как отмечено в this issue.

Есть проблемы с кодом?

Нет, но FileObserver не является рекурсивным, несмотря на документацию об обратном.

+0

FYI, приведенная выше документация больше не упоминает рекурсивность, как это когда-то ошибочно, хотя было бы неплохо, если бы она явно говорила, что она не рекурсивна - то, что личная страница Linux для лежащего в основе inotify добавляет примечание к конец. –

+0

Что делать, если я хочу контролировать раздел для изменений хранилища? Есть ли способ сделать это? –

29

Существует открытый исходный код RecursiveFileObserver, который работает так же, как обычный FileObserver должен ... Я использую в настоящее время является то, что она называется, она действует как FileObserver, который рекурсивен для всех каталогов под директорию, которую вы выбрали ...

Вот он:

public class RecursiveFileObserver extends FileObserver { 

public static int CHANGES_ONLY = CLOSE_WRITE | MOVE_SELF | MOVED_FROM; 

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.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() { 
    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, String path) { 

} 

private class SingleFileObserver extends FileObserver { 
    private String mPath; 

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

} 
} 

Создайте новый класс в своем приложении и скопировать этот код на него, и использовать его, как вам нравится! Голосовать, если вы считаете это полезным!

+0

спасибо, никогда не думал о публикации источника. – Seaskyways

+4

Будьте осторожны: это не является полностью рекурсивным, так как оно не будет автоматически запускать новую созданную папку и не будет останавливать просмотр папок, которые выведены из дерева ... Поскольку это лицензированный GPLv2, любой, кто решает эти проблемы на основе текущая реализация должна передать код. –

+0

Я использовал код, и он говорит: «Невозможно создать обработчик в потоке, если Looper.create() не называется»: / –

 Смежные вопросы

  • Нет связанных вопросов^_^