2013-08-08 11 views
6

Come recommended by the doc, mi piacerebbe utilizzare il metodo setvolume() per controllare il volume del mio MediaPlayer, ma sono un po 'confuso su come gestirlo.Come gestire MediaPlayer.setVolume() + SeekBar per impostarlo + controllo volume dispositivo

Sto impostando il volume utilizzando un SeekBar, inizializzato sul volume corrente nel flusso AudioManager.STREAM_MUSIC.

Questo ha senso se l'utente non modifica il controllo del volume del dispositivo, ma quando lo fa, io non sono sicuro che cosa devo fare, e ho molti dubbi:

  • Come è il MediaPlayer volume relativo al volume del dispositivo? Fa il valore massimo (1) posta in setVolume() corrispondono a mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)

  • se è il caso, il valore di avanzamento del SeekBar dovrebbe essere resettare ogni volta che il controllo del volume del dispositivo è impostato, ma poi, qual è il punto di usare MediaPlayer.setVolume() invece di AudioManager.setStreamVolume()?

  • qual è il modo standard di utilizzare MediaPlayer.setVolume() con un SeekBar?

private final static int MAX_VOLUME = 100; 
private AudioManager mAudioManager; 
private SeekBar mVolumeControl; 

mVolumeControl = (SeekBar) getActivity().findViewById(R.id.volume_control); 
mAudioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE); 
mVolumeControl.setMax(MAX_VOLUME); 
mVolumeControl.setProgress(MAX_VOLUME*mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC)/mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)); 
mVolumeControl.setOnSeekBarChangeListener(mVolumeControlChangeListener); 

private SeekBar.OnSeekBarChangeListener mVolumeControlChangeListener = new SeekBar.OnSeekBarChangeListener() { 

    @Override 
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 

     float volume = (float) (1 - (Math.log(MAX_VOLUME - progress)/Math.log(MAX_VOLUME))); 
     mediaPlayer.setVolume(volume, volume); 
    } 

    @Override 
    public void onStartTrackingTouch(SeekBar seekBar) {} 

    @Override 
    public void onStopTrackingTouch(SeekBar seekBar) { 
    } 
}; 
+0

come si è risolto? – Erum

risposta

11

MediaPlayer.setVolume imposta il volume di quel giocatore in percentuale del volume complessivo per questo flusso. Non influisce sul volume del flusso. Pertanto, se si desidera impostare solo il volume di quel lettore, impostarlo su un valore compreso tra 0 e 1 (un valore frazionario che rappresenta la percentuale) e consentire all'utente di controllare il volume del sistema separatamente utilizzando i controlli del volume dell'hardware. Per collegare un SeekBar, puoi ridimensionarlo di un fattore pari a 100 come hai fatto nel codice di esempio, poiché SeekBar non supporta valori frazionari. Oh, e un'altra cosa per il beneficio degli altri (visto che l'hai già capito): i documenti dicono "I controlli dell'interfaccia utente dovrebbero essere ridimensionati logaritmicamente", il che significa che se si imposta il volume senza alcun ridimensionamento, il controllo del volume sentirsi innaturale. Fondamentalmente, dimezzare l'ampiezza dell'onda NON è percepita dall'orecchio umano come "metà del volume", quindi è necessario scalare logaritmicamente per farlo sentire più naturale all'orecchio umano, come hai fatto nel codice di esempio.

Se si desidera impostare il volume di sistema per il flusso specificato (e non solo per il lettore specificato), è possibile utilizzare AudioManager.setStreamVolume con un valore compreso tra 0 e il valore restituito da AudioManager.getStreamMaxVolume. Ma tieni presente che quello è generalmente un controllo del volume a bassa risoluzione - getMaxStreamVolume di solito restituisce un valore relativamente basso, come 10 o 15, quindi hai solo alcune possibili posizioni per il volume. Ciò significa che il controllo del volume non sarà agevole come se si controllasse direttamente il volume dello MediaPlayer. Inoltre, ovviamente, impostando il volume in questo modo si imposta per l'intero sistema e influisce su tutte le applicazioni, che potrebbero non essere ciò che l'utente desidera.

+0

hey, questo è stato davvero informativo. Mi ha aiutato a capire una soluzione per un problema su cui ero bloccato. Grazie :) – Zen

1

In aggiunta alla risposta di TodorK.

Ciò che ho fatto è stato impostare inizialmente StreamVolume su Max e consentire all'utente di controllare SeekBar. Al termine, ho impostato lo StreamVolume allo stato originale. Ciò consente all'utente di controllare il volume di MediaPlayer e non influisce su altre applicazioni.

prima impostare l'Stream per il tuo desiderato uno & inizializzazione AudioManager

setVolumeControlStream(AudioManager.STREAM_MUSIC); 
audioManager = (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE); 

Prendi l'InitialVolume (in modo che si imposta di nuovo a questo una volta che il gioco è fatto) e impostarlo su maxvolume

final int initVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 
final int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); 
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,maxVolume, 0); 

fare l'AudioStuff nella parte onProgress del SeekBarChangedListener

 @Override 
     public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) 
     { 
      float volume = (float) (1 - (Math.log(100 - progress)/Math.log(100))); 
      mp.setVolume(volume, volume); 
      mp.start(); 
     } 

Una volta fatto, impostare di nuovo al initialVolume, in modo che l'utente non ottiene incazzato (nel mio caso, im utilizzando un AlertDialog, quindi la sua nella cosa onDismiss

 @Override 
     public void onDismiss(DialogInterface dialog) 
     { 
      audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,initVolume, 0); 

      //Stop Playing the Song 
      stopSong();    
     } 

Si noti inoltre, ho ha fatto la roba di registro nella parte onProgress

+0

Ehi, scusa per il disturbo, ma ho visto questa tua risposta e ho pensato che forse potresti aiutarmi (se non ti dispiace). Ho postato la mia domanda [qui] (http://stackoverflow.com/questions/40322485/change-the-volume-of-a-specif-player-and-get-its-current-volume), ho bisogno di finire questo progetto e manca solo questo 2 metodi. Ho provato mp.setVolume e funziona, ma solo per un po ', dopo che il volume torna di nuovo normale. Ma imposta il progresso come volume prima di mostrare la barra di ricerca Non ho idea, perché se uso AudioManager otterrò il volume di tutti i giocatori. Per favore, se potessi aiutarmi lo ringrazierò. – EmilyR

0

Prima effettuare una ricercaBar nel file XML. Quindi copiare questo codice (seekBar2 è l'ID per la barra di ricerca):

private final static int MAX_VOLUME = 100; 
SeekBar seekBar = (SeekBar) findViewById(R.id.seekBar2); 
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 
    @Override 
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 
     float volume = (float) (1 - (Math.log(MAX_VOLUME - progress)/Math.log(MAX_VOLUME))); 
     mediaPlayer.setVolume(volume, volume); 
    } 

    @Override 
    public void onStartTrackingTouch(SeekBar seekBar) { 

    } 

    @Override 
    public void onStopTrackingTouch(SeekBar seekBar) { 

    } 
}); 
Problemi correlati