stopservice servicio saber intent implement how esta ejemplo create corriendo como java android service

java - servicio - service android ejemplo



¿Cómo implementar un FileObserver desde un servicio de Android? (4)

¿Cómo se estructura una aplicación de Android para iniciar un Service para usar un FileObserver modo que cuando se modifica el directorio observado (es decir, el usuario toma una foto) se ejecuta algún otro código? Al depurar, el método onEvent nunca se activa.

Aquí está el evento onStart que tengo en mi Servicio. La Toast dispara para "Mi servicio comenzó ..."

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

Pero después de ese Toast, si tomo una foto, el Evento de nunca se dispara. Esto se determina mediante la depuración. Nunca llega a ese punto de ruptura y la tostada nunca se dispara.

Cuando se navega ese directorio, la nueva imagen se guarda allí.

¿Cómo lograr que un FileObserver funcione en un Service ?


Añadir .show() después de toast , es decir

Toast.makeText(getBaseContext(), file + " was saved!", toast.LENGTH_LONG).show();


Aquí está el código completo para crear un servicio que escuche el nuevo archivo en un directorio.

En primer lugar, debe crear el servicio que escuche la entrada de un nuevo archivo en el directorio. (Ej. Cámara)

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 //E.g 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(); } }

El siguiente paso, debe declarar el servicio en la etiqueta interna AndroidManifest.xml

<service android:name=".service.MediaListenerService" android:enabled="true" android:exported="false" > </service>

Y también no olvides añadir un permiso:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Si está escribiendo para Android 6 o superior, también deberá solicitar el permiso dinámicamente, según estas instrucciones: https://developer.android.com/training/permissions/requesting

Ahora inicia el servicio desde tu Actividad.

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); startService(new Intent(getBaseContext(), MediaListenerService.class)); }

Si desea que su servicio se inicie durante el inicio, simplemente cree un receptor que escuche android.intent.action.BOOT_COMPLETED y luego inicie el servicio desde ahí.

Espero que esto ayude.


Por favor, see este post. Creo que le falta la llamada observer.startWatching() después de configurar su observador.

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


Una cosa más que FileObserver no observa subdirectorio. Si desea observar también los subdirectorios, consulte this publicación.

Un RecursiveFileObserver de código abierto actúa como FileObserver avanzado que es recursivo para todos los directorios debajo del directorio que eligió

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

Fuente en GitHub