Как вы реализуете FileObserver из службы Android
Как вы структурируете приложение для Android, чтобы запустить Service
для использования FileObserver
чтобы при изменении наблюдаемого каталога (например, пользователь делает снимок) FileObserver
другой код. При отладке метод onEvent никогда не запускается.
Вот событие onStart, которое у меня есть в моей службе. Toast
запускается для «My Service Started …»
public final String TAG = "DEBUG"; public static FileObserver observer; @Override public void onStart(Intent intent, int startid) { Log.d(TAG, "onStart"); final String pathToWatch = android.os.Environment.getExternalStorageDirectory().toString() + "/DCIM/Camera/"; Toast.makeText(this, "My Service Started and trying to watch " + pathToWatch, Toast.LENGTH_LONG).show(); 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); //} } }; }
Но после этого Тоста, если я сделаю снимок, onEvent никогда не срабатывает. Это определяется путем отладки. Он никогда не попадает в точку останова, и Тост никогда не срабатывает.
- Android: как изменить цвет разделителя datepicker?
- Чтение Android из streamа ввода эффективно
- Как обновить TextView от другого classа
- Передача данных с помощью Serializable
- Не удалось импортировать новый проект Gradle: не удалось найти версию Build Tools * .0.0
Когда этот каталог просматривается, новое изображение сохраняется там.
Как вы получаете FileObserver
работающий в Service
?
- Как установить задержку в Android?
- Использование статических переменных в Android
- ListView random IndexOutOfBoundsException на Froyo
- Как я могу генерировать случайное число в определенном диапазоне в Android?
- JSONParser из учебника androidhive, NoSuchMethodError в DefaultHttpClient
- Как отображать навигационный ящик во всех действиях?
- В чем смысл $ в имени переменной?
- Android FTP Library
Пожалуйста, просмотрите этот пост. Я думаю, что вам не хватает вызова observer.startWatching()
после настройки вашего наблюдателя.
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
Добавить .show()
после toast
, т.е.
Toast.makeText(getBaseContext(), file + " was saved!", toast.LENGTH_LONG).show();
Еще одна вещь FileObserver не наблюдает подкаталог. Если вы хотите понаблюдать за подкаталогами, то проверьте этот пост.
Открытый рекурсивныйFileObserver с открытым исходным кодом действует как расширенный FileObserver, который является рекурсивным для всех каталогов под выбранным вами каталогом
package com.owncloud.android.utils; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Stack; import android.os.FileObserver; public class RecursiveFileObserver extends FileObserver { public static int CHANGES_ONLY = CLOSE_WRITE | MOVE_SELF | MOVED_FROM; List 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 (); Stack stack = new Stack (); 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); } } }
Источник на GitHub
Вот полный код для создания службы, которая прослушивает новый файл в каталоге.
Во-первых, вам нужно создать службу, которая прослушивает запись нового файла в каталоге. (Например, камера)
MediaListenerService.java import android.app.Service; import android.content.Intent; import android.os.FileObserver; import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.util.Log; import android.widget.Toast; import java.io.File; public class MediaListenerService extends Service { public static FileObserver observer; public MediaListenerService() { } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); startWatching(); } private void startWatching() { //The desired path to watch or monitor //Eg Camera folder final String pathToWatch = android.os.Environment.getExternalStorageDirectory().toString() + "/DCIM/Camera/"; Toast.makeText(this, "My Service Started and trying to watch " + pathToWatch, Toast.LENGTH_LONG).show(); observer = new FileObserver(pathToWatch, FileObserver.ALL_EVENTS) { // set up a file observer to watch this directory @Override public void onEvent(int event, final String file) { if (event == FileObserver.CREATE || event == FileObserver.CLOSE_WRITE || event == FileObserver.MODIFY || event == FileObserver.MOVED_TO && !file.equals(".probe")) { // check that it's not equal to .probe because thats created every time camera is launched Log.d("MediaListenerService", "File created [" + pathToWatch + file + "]"); new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { Toast.makeText(getBaseContext(), file + " was saved!", Toast.LENGTH_LONG).show(); } }); } } }; observer.startWatching(); } }
Следующий шаг: вам нужно объявить службу в теге AndroidManifest.xml
А также не забудьте добавить разрешение:
Если вы пишете для Android 6 или выше, вам также нужно будет запросить разрешение динамически, в соответствии с этими инструкциями: https://developer.android.com/training/permissions/requesting
Теперь запустите сервис из своей деятельности.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startService(new Intent(getBaseContext(), MediaListenerService.class)); }
Если вы хотите, чтобы ваш сервис запускался при загрузке, просто создайте ресивер, который прослушивает android.intent.action.BOOT_COMPLETED, а затем запустите службу.
Надеюсь это поможет.