Android Stop Music de fondo

EDIT – ¡ENCONTRÉ UNA SOLUCIÓN DE LÍNEA 5-10 FÁCIL! ¡Vea MI PROPIA RESPUESTA A CONTINUACIÓN! ¡¡¡¡¡¡¡¡¡HURRA!!!!!!!!!

He buscado durante 5 horas, docenas de publicaciones de SO, sin respuestas, y esto parece ser la cosa más simple y obvia.

EDITAR- por cierto, esta NO es una aplicación de reproductor de música, solo una aplicación para ver fotos y texto, abre múltiples actividades como menú y acerca, ver tipos de imágenes diferentes, etc. Solo quiero tocar música de fondo simple mientras veo las fotos y texto, ¿por qué es tan difícil?

otro EDIT – parece que la pregunta principal es en realidad: “¿POR QUÉ NO PRESIONA EL BOTÓN HOME al llamar o detener?” -¿Puedo saber cuándo parar el reproductor multimedia? y ¿cómo los juegos que descargo en el mercado logran esto?

la actividad en el hogar comienza

entonces

reproductor de medios comienza:

player = MediaPlayer.create(this, R.raw.idil); player.setLooping(true); player.setVolume(100,100); player.start(); 

Jugador declarado fuera de onCreate

 MediaPlayer player; 

Cuando se abren otras actividades, la música de fondo continúa ininterrumpidamente, lo cual es BUENO, eso es lo que quiero.

Ahora, cuando termino con mi aplicación muy simple (que solo muestra algunas fotos y textos en actividades de diff), hago clic en ATRÁS varias veces para llegar a la actividad de inicio / original, y luego una vez más para “salir”, O , Simplemente presiono inicio para “salir” porque he terminado con esta aplicación y ya no necesito escuchar esa música.


OPCIÓN 1

Llamar player.stop(); en una anulación onPause , esto no es lo que quiero porque la música de fondo se detiene cuando dejo la actividad hogareña para otras actividades como ‘menú’ y ‘sobre’, también no sé qué usar pausar y reanudar cuando abro nuevas actividades porque lo hago No quiero que la bonita música de fondo se “salte” o se interrumpa.


OPCION 2

 @Override protected void onPause() { super.onPause(); if (this.isFinishing()){ player.stop(); } } 

Esto es mejor porque la música de fondo no se detiene entre las actividades, y cuando presiono ATRÁS mi actividad hogareña, la música se detiene, y puedo seguir disfrutando de mi teléfono Android divertido en paz y tranquilidad, pero el problema es cuando presiona el HOME para “salir” de mi aplicación, esa molesta música de fondo sigue sonando.


EXTRAÑAMENTE

 @Override protected void onStop() { super.onStop(); if (this.isFinishing()){ player.stop(); } } 

Hace lo mismo que en Pausa (y entiendo las diferencias reales)

EDITAR- TAMBIÉN no parece importar si player.stop (); está por encima o por debajo de super.onStop (); pero afecta algo que no puedo ver, de cualquier manera, todavía no SOLUCIÓN 🙁

ooooo

ooooo

EDITAR- OTRA OPCIÓN- PERO NO FUNCIONA

 public void onUserLeaveHint() { player.stop(); super.onUserLeaveHint(); } 

esto detiene la música cuando presiono INICIO pero también lo detiene cuando comienzo nuevas actividades 🙁

EDITAR – UN TRABAJO MUY COMÚN ALREDEDOR DE IVE VISTO MÚLTIPLES LUGARES, pero parece ridículo tener que hacer:

Mantenga la cuenta de la cantidad de actividades que se han abierto y cerrado (onResume y OnPause probablemente serían las mejores, pero eso apunta a irrelevante) y cuando ese conteo llegue a 0, detenga la música de fondo. SÍ, eso es bastante simple, pero ¿por qué tengo que hacer esto programáticamente? De hecho, la PREGUNTA MÁS GRANDE PARA ESTE POST ES:

¿POR QUÉ EL PULSAR EL BOTÓN DE INICIO NO LLAMA ONPause o ONStop ???

Ponerlo en Destroy no es una opción porque onDestroy solo se invoca cuando el sistema tiene poca memoria, o fuerza el cierre de la aplicación, y eso está bien documentado.

Ignorar el botón INICIO tampoco es una opción ya que he leído que “no es posible” y he leído que es “extremadamente desaprobado”, de cualquier manera lo evito.

No veo la necesidad de crear SERVICE, e incluso si lo hiciera, ¿cuándo detendría el servicio ?, parece que tendré el mismo problema

AHORA AQUÍ ES LA COSA que me deslumbra por completo, cada juego y cada aplicación que descargué del mercado Android tiene una música de fondo muy hermosa, y cuando presiono ATRÁS o INICIO porque ya terminé de jugar ese juego encantador, la música se detiene , sin mantener jugando en el fondo.

Estoy muy frustrado, y creo que es porque siento que me falta algo muy simple, porque este es uno de los problemas más básicos del ciclo de vida con cualquier aplicación.

Pasé un mes leyendo cada página de developer.android.com, incluida la Guía de desarrollo, los tutoriales, ejemplos de proyectos e investigando la sección de Referencia, además de buscar este tema en Google durante 5 horas.

Tampoco entiendo por qué los 6 o 7 hilos SO con el mismo problema no han sido respondidos, cada aplicación descargable en el mercado deja de reproducir su música (a menos que sea un reproductor de música de fondo) cuando presiona INICIO o ATRÁS o lo que sea para “salir” de la aplicación para hacer otra cosa en su teléfono.

¿Qué me estoy perdiendo?

Estoy muy feliz hoy, y todavía tengo pelo 🙂 ¡He probado esto y funciona!

Primero, agregue esto a su Manifiesto:

  

Segundo, agregue esto a su Actividad / Clase ‘Principal / Principal’:

  @Override protected void onPause() { if (this.isFinishing()){ //basically BACK was pressed from this activity player.stop(); Toast.makeText(xYourClassNamex.this, "YOU PRESSED BACK FROM YOUR 'HOME/MAIN' ACTIVITY", Toast.LENGTH_SHORT).show(); } Context context = getApplicationContext(); ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List taskInfo = am.getRunningTasks(1); if (!taskInfo.isEmpty()) { ComponentName topActivity = taskInfo.get(0).topActivity; if (!topActivity.getPackageName().equals(context.getPackageName())) { player.stop(); Toast.makeText(xYourClassNamex.this, "YOU LEFT YOUR APP", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(xYourClassNamex.this, "YOU SWITCHED ACTIVITIES WITHIN YOUR APP", Toast.LENGTH_SHORT).show(); } } super.onPause(); } 

Y obviamente reemplace xYourClassNamex con, bueno, su nombre de clase 🙂

Ahora, obviamente, no necesita las “Tostadas”, pero le dirá lo que está sucediendo. Lo que más molesta es cuando presiona ATRÁS desde su actividad ‘Principal / Principal’, obviamente obtiene 2 Tostadas, “USTED PRESIONA DETRÁS DE SU ‘ACTIVIDAD’ HOGAR / PRINCIPAL ‘, y el 2 ° Brindis es” ACTIVIDADES CONMUTADAS DENTRO DE SU APLICACIÓN “. Creo que sé por qué sucede esto, pero no importa porque llamo “player.stop ();” de los 2 escenarios que significan que mi aplicación ya no se ‘usa’. Obviamente hacer más trabajo que “player.stop ();” si lo necesita 🙂 Y también es obvio que no necesita el “else” para “ACTIVIDADES CONMUTADAS DENTRO DE SU APLICACIÓN”, porque no hay ninguna razón para “detener / pausar” la música de fondo, que es lo que necesitaba, pero si SI es necesario hacer algo cuando se inician nuevas actividades, bueno, aquí tienes 🙂

Espero que esto ayude a cualquiera que quiera saber cuándo el usuario “deja / sale / ha terminado” la aplicación 🙂

GRACIAS POR TODOS LOS COMENTARIOS Y AYUDA A TODOS! ¡HURRA!

EDITAR-

Esta parte debe estar en CADA actividad en Pausa:

 Context context = getApplicationContext(); ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List taskInfo = am.getRunningTasks(1); if (!taskInfo.isEmpty()) { ComponentName topActivity = taskInfo.get(0).topActivity; if (!topActivity.getPackageName().equals(context.getPackageName())) { player.stop(); Toast.makeText(xYourClassNamex.this, "YOU LEFT YOUR APP", Toast.LENGTH_SHORT).show(); } } 

para que sepa si el usuario abandonó su aplicación de CUALQUIERA de las actividades. Esto es bueno saberlo 🙂

La forma en que funciona el reproductor multimedia es que se ejecuta como un servicio y luego se detiene MANUALMENTE cuando el usuario lo detiene en la aplicación.

Ejemplo:

Cuando el reproductor de medios está reproduciendo una canción y el usuario toca la pantalla de inicio, obviamente el usuario aún desea escuchar la canción como una tarea de fondo. Después de que el usuario haya terminado de escuchar, el usuario lo detiene manualmente yendo a la aplicación y deteniéndose (Aka deteniendo el servicio que está reproduciendo la canción) o si la lista de reproducción está lista, luego se detiene. Sencillo.

Este es el comportamiento esperado. Y es exactamente cómo funciona la aplicación de música.

ACTUALIZAR

 @Override protected void onPause() { super.onPause(); if (this.isFinishing()){ player.stop(); } } 

Necesita ser cambiado a

 @Override protected void onPause() { super.onPause(); if (mediaPlayer != null){ mediaPlayser.stop(); if (isFinishing()){ mediaPlayer.stop(); mediaPlayer.release(); } } } 

Una explicación:

La razón por la que estamos verificando que el objeto no sea nulo es obvio. Sin embargo; cuando ingresamos a la pausa, queremos asegurarnos de que el reproductor multimedia se está deteniendo. PERO si nos vamos y la canción casi termina, entonces deténgalo y suéltelo.

ACTUALIZACIÓN 2

Verifique el enlace aquí:

https://stackoverflow.com/a/6704844/529691

Esto puede usarse para detectar si su aplicación se ha movido fuera de la punta actual de la stack de la aplicación.

Me enfrenté al mismo problema. Te diré mi solución. Anoté OnStop, onStart cada actividad y conté mi actividad iniciada con un poco de retraso y el recuento llega a cero, pausé la música.

cómo es sobre un / registrarse como oyente @ el servicio en el onStart() y onStop() de sus actividades y cada vez que un oyente es (no) registrado, su servicio verifica si le quedan algunos oyentes en su ArrayList . si listOfListeners.size() es 0 entonces su servicio llama a su método stopSelf() y se mata a sí mismo.

al menos así es como implementaría esto …

entonces, las cosas que necesitarías son:

  • 2 interfaces ( Observer , Observable )

  • implementar Observer en Activity , Observable en Service

  • ArrayList en Service

  • registerObserver(Observer o) y unregisterObserver(Observer o) en el Service

pero ese es solo mi punto de vista …

¿Por qué no haces un botón para detener la música es mucho más fácil y no tienes que forzar el cierre cada vez que lo haces?

 Button exit =(Button) findViewById(R.id.exit); exit.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // TODO: Implement this method startActivity(new Intent("com.justme.worldexplorer.EXIT")); finish(); Music I'd.stop();}});} 

Ahí lo tienes y el botón de hardware clave vuelve dosenté, si lo presionas por accidente

 public boolean onKeyDown(int KeyCode,KeyEvent event){ return false; } 

Y eso es configurarlo en el manifiesto y ejecutar si algún problema me deja saber

 private static HashMap focus = new HashMap(); public static void check(Context context, boolean hasFocus) { handler.removeMessages(0); focus.put(((Activity)context).getLocalClassName(), hasFocus); handler.sendEmptyMessageDelayed(0, 500); } public static void check(String classname, boolean hasFocus) { handler.removeMessages(0); focus.put(classname, hasFocus); handler.sendEmptyMessageDelayed(0, 500); } private static Handler handler = new Handler() { @Override public void handleMessage(Message msg) { Iterator it = focus.values().iterator(); while(it.hasNext()) { if(it.next()) return; } pause(); super.handleMessage(msg); } }; 

este es un método de clase de gerente.

cada actividad implementando como código después

 @Override public void onWindowFocusChanged(boolean hasFocus) { MusicManager.check(this, hasFocus); super.onWindowFocusChanged(hasFocus); } 

Estoy usando este código con mi juego que está publicado y funciona muy bien.

¿Qué parte de este código es terrible? y ¿dónde está la mejor solución? Quiero saber si existe.

Mike, tu me respondiste que mi respuesta es terrible y no funciona, ¿Qué pasa con esto?

En cada actividad, enlazar al servicio en onStart () y desvincular desde el servicio en onStop (). Cuando inicie el servicio, únase a él y no llame a startService (…).

Al llamar a startService (), el servicio continuará ejecutándose hasta que se llame a stopService (), independientemente de la cantidad de actividades asociadas. Si no llama al servicio de inicio, el servicio se detendrá automáticamente una vez que todas las actividades se hayan liberado de él.

Así que al vincular y desvincular los métodos onStart () y onStop () de cada actividad, encontrará que el servicio (música) continuará hasta que salga de la aplicación con el botón de inicio, la tecla de retroceso, el tiempo de espera de la pantalla, etc.

Para aquellos que todavía están buscando una solución en lollipop o simplemente sin usar algo de permiso, se me ocurrió otra solución como último recurso. Podemos medir el tiempo que el usuario ha estado afk. Si fue más de X ms, entonces puede considerar que dejó la aplicación y detener la música.

Así que estoy usando Application child donde guardo el tiempo afk y BaseActivity para anular onPause y onResume de todas mis actividades.

He encontrado el mismo problema con mi proceso de desarrollo.

Lo resolví usando onPause y onResume y con los métodos pause () y start () en el reproductor que guardé en mi contenedor principal, llamando a fragmentos en lugar de actividades.

Guardé una bandera en un singleton para saber cuándo el usuario desconectó la música.

Otro problema que encontré es que mi aplicación (identifique si es parte de la versión de Android o no) estaba ejecutando el método onResume justo antes de volver a poner el reproductor, así que ejecuté un ciclo while para recibir el reproductor no como un nulo puntero, y funciona porque se ejecuta en un hilo diferente, lo que permite que la aplicación ejecute onResume sin colgar y la música a su lado.

Lo encuentro mejor (código más pequeño para escribir) y no es un permiso invasivo;).