2010-10-28 24 views
6

Tengo un servicio que rastrea la ubicación del usuario. Actualmente, el Servicio se inicia cuando la aplicación se inicia y se detiene cuando finaliza la aplicación. Desafortunadamente, si los usuarios mantienen la aplicación en segundo plano, el Servicio nunca se detiene y consume la batería.Detener e iniciar un servicio según el estado de la aplicación

Me gustaría que el Servicio se detenga cuando mi aplicación no esté en primer plano. Esperaba que la clase Application me permitiera anular los controladores onPause y onResume, pero no los tiene. ¿Hay alguna otra forma en que pueda lograr esto?

+0

Cuando dices "tu aplicación no está en primer plano", ¿te refieres a una actividad que es diferente de tu servicio (aunque estoy seguro de que forma parte de la misma)? – Brandon

+0

Dentro del ciclo interminable del servicio, agregue un cheque para ver si su aplicación está en primer plano. Pero le costará el permiso 'GET_TASKS' en el manifiesto. –

Respuesta

0

Debe anular los métodos onPause y onResume en su Activity. Si tiene múltiples actividades, puede que quiera tener una clase base común para ellos y poner la lógica de inicio/detención en la clase base.

+0

¿Desea que mi servicio de ubicación se detenga y se inicie cada vez que vaya a una nueva pantalla? No creo que sea eso lo que estoy buscando. – Andrew

+0

Puede establecer un indicador al iniciar una actividad dentro de su propia aplicación y solo detener su servicio si no se establece el indicador de inicio de actividad propia. – fornwall

5

No he probado esto todavía, pero parece que si usa Context#bindService() (en lugar de Context#startService()), el servicio se detendrá cuando no haya más actividades relacionadas. (ver Service lifecycle).

Luego use onPause()/onResume() en cada actividad para enlazar/desvincular del servicio.

Como alternativa, puede agregar un par de métodos en su servicio que le indiquen que comience/deje de escuchar actualizaciones de ubicación y que lo llame desde cada actividad onResume()/onPause(). El servicio todavía se estaría ejecutando, pero las actualizaciones de ubicación no consumirían la batería.

método
+0

Interesante. Mi único problema con el enfoque onPause/onResume es que, al iniciar una nueva actividad, la actividad actual se pausa antes de que se reanude la nueva actividad. Por lo tanto, iniciar una nueva actividad detendría el servicio. Sin embargo, su segunda sugerencia puede funcionar. – Andrew

0

No he probado este enfoque, pero creo que se puede anular la tecla de inicio del dispositivo Android mediante el uso de KeyEvent.KEYCODE_HOME y se puede utilizar stopService(Intent) para detener su servicio y cuando de nuevo se reanuda la aplicación, puede escribir startService(Intent) en el onResume() de tu actividad.

De esta forma, creo que su servicio solo se detendrá cuando el usuario presione explícitamente el botón de inicio para tomar la aplicación en segundo plano y no cuando cambie de una actividad a otra.

-1

Crear métodos registerActivity() y unRegisterActivity() en su objeto de aplicación y ejecutar primer método en todo lo que actúa onResume() y segundo en los actos onPause().

primer método agregar actividad a List<Activity> instancia en su objeto de la aplicación, unRegisterActivity() comprueba el tamaño de la lista en cada llamada if==0 stopService();.

+0

Interesante, pero ¿cómo funcionará? Si lanzo una nueva actividad, la actividad previa onPause() se ejecutará antes de que la nueva actividad onResume(). Por lo tanto, el recuento será == 0 momentáneamente y el Servicio se detendrá cada vez que inicie una nueva Actividad. – Andrew

+0

u r derecho usted puede verificar el tamaño en un handler.postDelayed (Runnable, 500); o un retraso suficiente para todas las actividades para detenerse; intente esto y hágamelo saber – asaad399

+0

Este concepto es bueno, pero agregar referencias de actividad a la instancia de aplicación estática es la forma más fácil de causar pérdidas de memoria. Incrementar un contador en sus métodos de registro/anulación de registro sería un mejor enfoque y cuando el contador es menor a 0 detenga su servicio. –

1

lectura todas las respuestas anteriores que sugeriría Basta con añadir un indicador global booleano para cada actividad & ponerlo en su onResume & onPause & también durante el lanzamiento de un Algo actividad como esta

public void onPause() 
{ 
super.onPause(); 
activity1IsResumed = true; 
} 

& mismo para onResume

& de manera similar cuando el lanzamiento de una nueva actividad

startActivityForResult(myintent ,0); 
activity2IsResumed = true; 
activity1IsResumed = false; 

entonces en su servicio simplemente marque

if(activity1IsResumed || activity2IsResumed || activity3IsResumed) 
{ 
//your logic 
} 
else 
{ 
//another logic 
//or dont run location tracker 
} 

& ya está!

0

Lo que yo sugeriría es anular los métodos onPause/onReume como han dicho otros. Sin saber más sobre el flujo de su aplicación y las interacciones entre Actividades, no puedo brindar mucha más información más allá de las conjeturas.

Si sus actividades son persistentes, sin embargo, mi recomendación sería utilizar las Intents mejor cuando cambie de Actividades.

Por ejemplo, cada actividad debe tener un indicador booleano de "transición". Por lo tanto, cuando se pasa de una actividad a otra, se configura un extra de Intención:

intent.putExtra("transition",true); 

utilizada en la actividad que reciba por: (en onCreate)

intent.getBooleanExtra("transition",false); 

De esta manera, para cada actividad que se inicia, puede saber si proviene de otra actividad o si se inició desde un iniciador de pantalla de inicio. Por lo tanto, si obtiene una transición verdadera, entonces onPause NO debe detener el servicio, lo que significa que volverá a la actividad anterior después de que regrese. Si no recibe ninguna extra de "transición", o una transición falsa, entonces puede asumir con seguridad que no hay ninguna Actividad debajo esperando a tomar el relevo por la actual.

En la primera actividad, simplemente tendrá que detener el servicio si está cambiando a otra actividad, que podrá descubrir mediante programación si una actividad se inicia desde otra.

0

Parece que el verdadero problema es cómo detener el servicio solo cuando va a una actividad que no es la suya. Una forma sería en su método onPause para detener la actividad. Haz esto para todas tus actividades. Luego, anule su método startActivity. Y aquí haga una prueba condicional para confirmar que está navegando a propósito a uno de los suyos. Si se establece una bandera en verdadero.

Ahora regrese a su método sobre la pausa reemplazada. Y solo detenga su servicio si la bandera no es verdadera. Establezca la bandera en falso.

Todos los eventos que naveguen cerrarán su servicio. Navegar por el tuyo lo dejará intacto.

Realice la anulación en una clase base que extiendan todas sus actividades.

Escribe en mi andolroid. Publicaremos ezaple después.

0

Intente utilizar la técnica de servicios enlazados para lograr esto.

Bound Services | Android Developers

Puede utilizar los servicios ligados de tal manera que el servicio se detendrá cuando no hay actividades están obligados a ello. De esta forma, cuando la aplicación no está en primer plano, el servicio no se ejecutará. Cuando el usuario vuelve a poner la aplicación en primer plano, la actividad se vinculará al servicio y el servicio se reanudará.

Cuestiones relacionadas