Tono de tono juega una y otra vez (bucle infinitamente)

Tengo una aplicación de Android que reproduce un tono de notificación ( RingtoneManager.TYPE_NOTIFICATION ) cuando se envían ciertos eventos a un BroadcastReceiver.

El código que reproduce el tono de llamada básicamente lo hace:

  onReceive(Context context, Intent intent) { ... Uri ringtoneUri = someFunctionToLookupAValidNotificationRingtoneUri(); ... Ringtone tone = RingtoneManager.getRingtone(context, uri); Log.v(TAG, "About to play ringtone"); tone.play(); } 

De vez en cuando, cuando se ejecuta este código, el tono de llamada comienza a reproducirse una y otra vez infinitamente. A veces sucede cuando un gran número de eventos están agrupados juntos, pero también ha ocurrido cuando sólo un evento entró tone.play() El mensaje de registro (y depuración) verifica que la llamada tone.play() está ocurriendo sólo una vez por evento, y No hay una corriente infinita de acontecimientos.

La única manera de detener el bucle infinito es matar a mi aplicación.

Es casi como si de vez en cuando, Android olvida a nivelar el búfer de salida de sonido y por lo que sigue haciendo bucle a través de jugar lo que está dentro.

¿Alguna idea de cómo depurar y / o solucionar este problema?

Tuve un problema similar. Resultó que cuando se toca un tono de llamada , se repetirá indefinidamente hasta que se detenga, mientras que cuando se reproduce un sonido de notificación , se reproducirá una sola vez. Así que mi conjetura es que la diferencia en su caso radica en si un tono de llamada o un sonido de notificación se seleccionó en someFunctionToLookupAValidNotificationRingtoneUri() . Como usted no proporciona el código para someFunctionToLookupAValidNotificationRingtoneUri() , no puedo saber qué sucede allí.

Selección de un sonido de notificación

Si utiliza un selector de tonos para que el usuario seleccione un sonido de notificación, este código iniciará la intención de seleccionar un sonido de notificación en lugar de un tono de llamada:

  private void PickANotificationSound() { Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER); // We want a notification sound picked. If we don't add this to the // intent, a ringtone is picked; this means that when it is played, // it will keep on playing until it is explicitly stopped. A // notification sound, however, plays only once. intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION); // Start the intent to pick a notification sound. The result will show // up later when onActivityResult() is called. startActivityForResult(intent, REQUESTCODE_NOTIFICATION_SOUND); } 

Donde REQUESTCODE_NOTIFICATION_SOUND es sólo una constante local con cualquier nombre y valor, identificando la solicitud:

  private static final int REQUESTCODE_NOTIFICATION_SOUND = 1; 

Una función de devolución de llamada onActivityResult() como esta recogerá entonces el URI de sonido de notificación y lo reproducirá:

  @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUESTCODE_NOTIFICATION_SOUND) { try { if (resultCode == RESULT_OK) { Uri ringtoneUri = data.getParcelableExtra( RingtoneManager.EXTRA_RINGTONE_PICKED_URI); if (ringtoneUri != null) { PlayRingtoneOrNotificationSoundFromUri(ringtoneUri); } } } catch (Exception e) { e.printStackTrace(); } } else super.onActivityResult(requestCode, resultCode, data); } private void PlayRingtoneOrNotificationSoundFromUri(Uri ringtoneUri) { Ringtone ringtone = RingtoneManager.getRingtone( getApplicationContext(), ringtoneUri); if (ringtone != null) { ringtone.play(); } } 

Como dijimos con la intención de que queríamos seleccionar un sonido de notificación, el sonido resultante es un sonido de notificación y, por lo tanto, solo se reproduce una vez después de la llamada a ringtone.play() .

Si hubiéramos dicho en la intención que queríamos elegir un tono de timbre, como esto:

  intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE); 

El selector devolvería un tono de llamada que se reproduciría indefinidamente después de la ringtone.play() – hasta que se detuviera por ringtone.stop() o se matara la aplicación.

Dos significados de 'ringtone'

Tenga en cuenta que la terminología de la API de Android se suma a la confusión, ya que la palabra "tono de llamada" se utiliza con dos significados diferentes ( consulte la documentación de RingtoneManager ):

  1. Cualquier sonido destinado a captar la atención del usuario, como un sonido que se reproduzca repetidamente cuando suene el teléfono, un sonido de notificación o un sonido similar. Este significado se utiliza en el nombre de RingtoneManager .

  2. Un sonido para reproducir repetidamente cuando suena el teléfono, en contraposición a un sonido de notificación o un sonido similar. Este significado se utiliza en el nombre TYPE_RINGTONE en RingtoneManager.TYPE_RINGTONE .

  • Lista de selector de favoritos de Android con la opción predeterminada seleccionada
  • ¿Cómo obtener preferencias de tono en tiempo de ejecución?
  • Eliminación de un tono de llamada mediante programación en android
  • ¿Cómo obtener el tono de llamada actual en Android?
  • Añadir tonos de llamada en el emulador de Android
  • Reproducción de un tono de timbre de una actividad se detiene abruptamente
  • ¿Puedo insertar un rasgo android: defaultValue para RingtonePreference, a través de XML?
  • Cómo obtener el nombre del tono en Android?
  • ¿Cómo acceder a todas las listas de tonos en el teléfono Android?
  • Configurar el tono de llamada personalizado de contacto, ¿cómo?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.