Опускать или исчезать звук в андроиде

Я делаю простую мелочи и запускаю цикл ~ 1 мин mp3-файла, когда пользователь приходит в главное меню. Звук отключается, когда пользователь нажимает на любую из кнопок в меню (например, Play Game).

Моя проблема в том, что когда звук останавливается, его сотрясение прерывается. Вместо того, чтобы делать .pause () или .stop (), есть ли способ заставить звук медленно исчезать после нажатия кнопки?

благодаря

Solutions Collecting From Web of "Опускать или исчезать звук в андроиде"

EDIT (3/13/13): Обновлен с новым кодом QA'd

Это мой весь класс обработчика для Android MediaPlayer. Посмотрите на функции play () и pause (). Оба имеют способность либо исчезать, либо нет. Функция updateVolume () была ключом к тому, чтобы звук увеличивался / уменьшался линейно.

public class MusicHandler { private MediaPlayer mediaPlayer; private Context context; private int iVolume; private final static int INT_VOLUME_MAX = 100; private final static int INT_VOLUME_MIN = 0; private final static float FLOAT_VOLUME_MAX = 1; private final static float FLOAT_VOLUME_MIN = 0; public MusicHandler(Context context) { this.context = context; } public void load(String path, boolean looping) { mediaPlayer = MediaPlayer.create(context, Uri.fromFile(new File(path))); mediaPlayer.setLooping(looping); } public void load(int address, boolean looping) { mediaPlayer = MediaPlayer.create(context, address); mediaPlayer.setLooping(looping); } public void play(int fadeDuration) { //Set current volume, depending on fade or not if (fadeDuration > 0) iVolume = INT_VOLUME_MIN; else iVolume = INT_VOLUME_MAX; updateVolume(0); //Play music if(!mediaPlayer.isPlaying()) mediaPlayer.start(); //Start increasing volume in increments if(fadeDuration > 0) { final Timer timer = new Timer(true); TimerTask timerTask = new TimerTask() { @Override public void run() { updateVolume(1); if (iVolume == INT_VOLUME_MAX) { timer.cancel(); timer.purge(); } } }; // calculate delay, cannot be zero, set to 1 if zero int delay = fadeDuration/INT_VOLUME_MAX; if (delay == 0) delay = 1; timer.schedule(timerTask, delay, delay); } } public void pause(int fadeDuration) { //Set current volume, depending on fade or not if (fadeDuration > 0) iVolume = INT_VOLUME_MAX; else iVolume = INT_VOLUME_MIN; updateVolume(0); //Start increasing volume in increments if(fadeDuration > 0) { final Timer timer = new Timer(true); TimerTask timerTask = new TimerTask() { @Override public void run() { updateVolume(-1); if (iVolume == INT_VOLUME_MIN) { //Pause music if (mediaPlayer.isPlaying()) mediaPlayer.pause(); timer.cancel(); timer.purge(); } } }; // calculate delay, cannot be zero, set to 1 if zero int delay = fadeDuration/INT_VOLUME_MAX; if (delay == 0) delay = 1; timer.schedule(timerTask, delay, delay); } } private void updateVolume(int change) { //increment or decrement depending on type of fade iVolume = iVolume + change; //ensure iVolume within boundaries if (iVolume < INT_VOLUME_MIN) iVolume = INT_VOLUME_MIN; else if (iVolume > INT_VOLUME_MAX) iVolume = INT_VOLUME_MAX; //convert to float value float fVolume = 1 - ((float) Math.log(INT_VOLUME_MAX - iVolume) / (float) Math.log(INT_VOLUME_MAX)); //ensure fVolume within boundaries if (fVolume < FLOAT_VOLUME_MIN) fVolume = FLOAT_VOLUME_MIN; else if (fVolume > FLOAT_VOLUME_MAX) fVolume = FLOAT_VOLUME_MAX; mediaPlayer.setVolume(fVolume, fVolume); } } 

https://stackoverflow.com/a/29246026/922514

 private static void crossFade() { MediaPlayerManager.fadeOut(currentPlayer, 2000); MediaPlayerManager.fadeIn(auxPlayer, 2000); currentPlayer = auxPlayer; auxPlayer = null; } public static void fadeOut(final MediaPlayer _player, final int duration) { final float deviceVolume = getDeviceVolume(); final Handler h = new Handler(); h.postDelayed(new Runnable() { private float time = duration; private float volume = 0.0f; @Override public void run() { if (!_player.isPlaying()) _player.start(); // can call h again after work! time -= 100; volume = (deviceVolume * time) / duration; _player.setVolume(volume, volume); if (time > 0) h.postDelayed(this, 100); else { _player.stop(); _player.release(); } } }, 100); // 1 second delay (takes millis) } public static void fadeIn(final MediaPlayer _player, final int duration) { final float deviceVolume = getDeviceVolume(); final Handler h = new Handler(); h.postDelayed(new Runnable() { private float time = 0.0f; private float volume = 0.0f; @Override public void run() { if (!_player.isPlaying()) _player.start(); // can call h again after work! time += 100; volume = (deviceVolume * time) / duration; _player.setVolume(volume, volume); if (time < duration) h.postDelayed(this, 100); } }, 100); // 1 second delay (takes millis) } public static float getDeviceVolume() { int volumeLevel = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); return (float) volumeLevel / maxVolume; } 

Вы можете использовать AudioManager :

 public static final int STEP_DOWN = 5; // how far each step goes down // later on, and in a backgroud thread like an AsyncTask AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); int targetVol = 0; // or whatever you wanted. int currentVol = am.getStreamVolume(AudioManager.STREAM_MUSIC); while(currentVol > targetVol) { am.setStreamVolume(AudioManager.STREAM_MUSIC, currentVol - STEP_DOWN, 0); currentVol = am.getStreamVolume(AudioManager.STREAM_MUSIC); thread.sleep(100); } 

Возможно, вам также захочется записать исходный том, на который они были установлены, и сбросить его до того, как вы исчезли, чтобы отключить звук и остановить музыку.

Этот код может быть не точным, у меня нет доступа к каким-либо способам его тестирования, но я надеюсь, что он приведет вас в правильном направлении ….