Reputation: 227
I know to some this might be an easy question or rather stupid but I cannot seem to get my head around this, how can I adjust volume via percentage lets say setting it to 70%? I know I have to get Maximum Stream Volume by using:
int streamMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
and We set it by using:
audioManager.setStreamVolume(AudioManager.STREAM_RING, streamMaxVolume);
but how can I set using Percentage? all answers will be highly appreciated, thank you.
Upvotes: 7
Views: 15720
Reputation: 22958
Hello in the year 2022!
In my word game app the approach is not to touch the AudioManager at all!
That means I never call the code below:
AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
The reason is that the user would be unpleasantly surprised, if she would try to change the volume of sounds in the app - but the overall volume for phone calls and music would be changed as well.
So I just save a factor value between 0.1 and 1.0 into the shared prefs and then multiply the overall phone volume by that factor, when playing any sounds in my game.
In the settings fragment of my app I have a Material slider:
<com.google.android.material.slider.Slider
android:id="@+id/volumeFactorSlider"
android:layout_weight="8"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:contentDescription="Volume"
android:valueFrom="0.1"
android:valueTo="1.0" />
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(requireContext());
View v = inflater.inflate(R.layout.fragment_settings, container, false);
Slider volumeFactorSlider = v.findViewById(R.id.volumeFactorSlider);
float volumeFactor = prefs.getFloat(KEY_VOLUME, 1.0f);
// clamp the value read from shared prefs to avoid IllegalStateException
volumeFactor = Math.max(volumeFactorSlider.getValueFrom(), volumeFactor);
volumeFactor = Math.min(volumeFactor, volumeFactorSlider.getValueTo());
volumeFactorSlider.setValue(volumeFactor);
volumeFactorSlider.addOnSliderTouchListener(new Slider.OnSliderTouchListener() {
@Override
public void onStartTrackingTouch(@NonNull Slider slider) {
// ignore
}
@Override
public void onStopTrackingTouch(@NonNull Slider slider) {
prefs.edit().putFloat(KEY_VOLUME, slider.getValue()).apply();
}
});
return v;
}
And then in the game fragment where the sounds are played I use:
private SoundPool mSoundPool;
private float mVolumeFactor;
private int mShuffleSound;
private int mBonusSound;
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(requireContext());
mVolumeFactor = prefs.getFloat(KEY_VOLUME, 1.0f);
mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
mShuffleSound = mSoundPool.load(requireContext(), R.raw.shuffle, 1);
mBonusSound = mSoundPool.load(requireContext(), R.raw.magic, 1);
....
}
@Override
public void onDestroy() {
super.onDestroy();
mSoundPool.release();
mSoundPool = null;
}
Finally, when playing a sound I just multiply by the factor:
private void playSound(int soundId) {
mSoundPool.play(soundId, mVolumeFactor, mVolumeFactor, 1, 0, 1f);
}
For example, when shuffling letter tiles: playSound(mShuffleSound);
Upvotes: 1
Reputation: 5542
This should work
AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
int currentVolume = audio.getStreamVolume(AudioManager.STREAM_MUSIC);
int maxVolume = audio.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float percent = 0.7f;
int seventyVolume = (int) (maxVolume*percent);
audio.setStreamVolume(AudioManager.STREAM_MUSIC, seventyVolume, 0);
Upvotes: 27