2012-04-10 10 views
9

Estoy escribiendo una aplicación de alarma de Android que utiliza un servicio para reproducir el tono de alarma. Actualmente, puedo reproducir el audio, pero se reproduce de forma que se puede silenciar bajando el volumen del dispositivo. Por lo tanto, estoy tratando de agregar una llamada al setAudioStreamType(AudioManager.STREAM_ALARM); para evitar esto.(Android MediaPlayer) ¿Cómo se supone que debo llamar a setAudioStreamType() si MediaPlayer.create() llama implícitamente a prepare()?

que tienen la siguiente función para mi onStartCommand() para el servicio:

MediaPlayer mMP;  
@Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     try 
     { 
      mMP = MediaPlayer.create(this, R.raw.alarm); 
      mMP.setAudioStreamType(AudioManager.STREAM_ALARM); 
      mMP.setLooping(true); 
      //mMP.prepare(); commented out since prepare() is called in create 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
     if (mMP != null) mMP.start(); 

     return START_STICKY; 
    } 

Mi problema es que con la llamada a setAudioStreamType(), el MediaPlayer nunca se reproduce el audio. Si comento esa línea, el audio se reproduce.

Con la entrada de línea, me sale el siguiente error de ejecución (s):

04-10 19: 32: 03,115: E/MediaPlayer (3411): setAudioStream llamada en el estado 8

04-10 19: 32: 03,115: E/MediaPlayer (3411): error (-38, 0)

04-10 19: 32: 03,115: E/MediaPlayer (3411): Comienzo llamada en el estado 0

04-10 19: 32: 03.115: E/MediaPlayer (3411): error (-38, 0)

04-10 19: 32: 03,115: E/MediaPlayer (3411): Error (-38,0)

04-10 19: 32: 03,115: E/MediaPlayer (3411): Error (- 38,0)

Algunas investigaciones (no puedo encontrar el enlace ahora) me dijo que setAudioStreamType() no puede ser llamado después de prepare() se ha llamado, y que create() llama implícitamente prepare().

En cualquier caso, ¿cómo se supone que setAudioStreamType() sin un error?

Respuesta

12

Puede llamar al mp.reset() y luego establecer el tipo de flujo, fuente de datos y luego preparar. Alternativamente solo use el constructor predeterminado y maneje la inicialización usted mismo.

EDIT:

Resources res = getResources(); 
AssetFileDescriptor afd = res.openRawResourceFd(R.raw.alarm); 

mp.reset(); 
mp.setAudioStreamType(AudioManager.STREAM_ALARM); 
mp.setLooping(true); 
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); 
mp.prepare(); 
mp.start(); 
+0

Parece que usted está sugiriendo algo en este sentido (empezando después de la llamada a 'create()'): 'reset();' 'setAudioStreamType();' 'setLooping();' 'prepare();' ¿Estoy en lo correcto? Si es así, aparece el siguiente error en la llamada para preparar: '04-10 20: 06: 25.515: E/MediaPlayer (845): inicio llamado en el estado 1' ' 04-10 20: 06: 25.515: E/MediaPlayer (845): error (-38, 0) ' – finiteloop

+0

Parece que está obteniendo el error en la llamada a' start() 'en realidad, no' prepare() '. ¿Puedes agregar tu código actualizado a la pregunta? – kcoppock

+0

Tiene razón, ese error en particular surgió después de la llamada al inicio, también hay un error en la llamada para preparar que omití en el registro cuando estaba publicando mi comentario. '04-10 21: 42: 11.896: E/MediaPlayer (593): prepareAsync llamado en el estado 1'. – finiteloop

2

respuesta aceptada estaba lanzando un IllegalStateException. Esto está trabajando

MediaPlayer mediaPlayer = new MediaPlayer(); 

try { 
    mediaPlayer.setDataSource(
      this, 
      getCustomToneUri() 
); 

    mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION); 

    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { 
    @Override 
    public void onPrepared(MediaPlayer mp) { 
     mp.start(); 
    } 
    }); 

    mediaPlayer.prepareAsync(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
Cuestiones relacionadas