How to Control Volume using Android SeekBar in Java
Nitish Kumar Singh
Nov 16, 2023Hello Developers! In this blog post, we will learn how to change volume using SeekBar in Android using Java. Basically we increase or decrease system volume of phone when progress of SeekBar chnages and show a TextView for volume level.
To change the volume of phone, we add SeekBar.OnSeekChangeListener
on SeekBar to get progress and use AudioManager
and it's methods to change phone volume in following steps:
Setup SeekBar
Add following xml in your activity layout file and you can design it as your requirements.
.....
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/volumeLevel"
android:layout_width="60dp"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="15sp"/>
<SeekBar
android:id="@+id/volumeSlider"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="30dp"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_gravity="center"/>
</LinearLayout>
.....
Initialize TextView and SeekBar, add SeekBar.OnSeekChangeListener
on SeekBar and setMax value on SeekBar as you want in onCreate of activity java file.
TextView volumeLevel = findViewById(R.id.volumeLevel);
SeekBar volumeSlider = findViewById(R.id.volumeSlider);
volumeSlider.setMax(maxProgress); // it will come from maxProgress variable
// There are more code available
volumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
Change Volume Using AudioManager
We use getStreamMaxVolume
, getStreamMinVolume
, getStreamVolume
and setStreamVolume
methods of AudioManager to change volume of MUSIC_STREAM
, but you can change any stream volume with the same way.
Declare three variables above onCreate as below:
private final int maxProgress = 25; // you can set it as you want
private int minVolumeIndex,maxVolumeIndex;
The above variables maxProgress
use for setting max value on seekbar (here i use 25), minVolumeIndex
and maxVolumeIndex
use to store min and max volume index. So we calculate volume index based on progress of seekbar.
Add follwing code in onCreate above setOnSeekBarChangeListener
:
// initialize min and max volumeIndex
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
maxVolumeIndex = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
minVolumeIndex = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ?
audioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC) : 0;
// sync progress of seekbar and textview with current volume
int currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int progress = getSeekBarProgressFromVolume(currentVolume);
volumeSlider.setProgress(progress);
volumeLevel.setText(String.valueOf(progress));
Add following code in onProgressChanged
method of SeekBar.OnSeekBarChangeListener
:
if (fromUser){
int volumeIndex = getRightVolume(progress);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,volumeIndex,0);
volumeLevel.setText(String.valueOf(progress));
}
If you want to change volume of different stream then use that stream constant at all places where used AudioManager.STREAM_MUSIC
.
Create two method in activity java file as below code:
private int getRightVolume(int input) {
// Ensure that the input is within the valid range (0 to a maxValue)
input = Math.max(0, Math.min(input, maxProgress));
// Calculate the right volume index from minVolumeIndex(x) to maxVolumeIndex(y)
double ratio = (double) input / (maxProgress + 1);
return (int) Math.round(minVolumeIndex + (maxVolumeIndex - minVolumeIndex) * ratio);
}
private int getSeekBarProgressFromVolume(int value) {
// Calculate the reverse interpolated input based on the value
double ratio = (double) (value - minVolumeIndex) / (maxVolumeIndex - minVolumeIndex);
int result = (int) Math.round(ratio * maxProgress);
// Ensure that the result is within the valid range (0 to maxValue)
return Math.max(0, Math.min(result, maxProgress));
}
getRightVolume
method use to get right volume index based on progress and max of seekbar, and getSeekBarProgressFromVolume
use to get progress of seekbar based on current volume index (level) of phone so we set progress of seekbar and text on textview on first time when activity created.
So below is final code of activity java file:
private final int maxProgress = 25; // you can set it as you want
private int minVolumeIndex,maxVolumeIndex;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView volumeLevel = findViewById(R.id.volumeLevel);
SeekBar volumeSlider = findViewById(R.id.volumeSlider);
volumeSlider.setMax(maxProgress); // it will come from maxProgress variable
// initialize min and max volumeIndex
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
maxVolumeIndex = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
minVolumeIndex = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ?
audioManager.getStreamMinVolume(AudioManager.STREAM_MUSIC) : 0;
// sync progress of seekbar and textview with current volume
int currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
int progress = getSeekBarProgressFromVolume(currentVolume);
volumeSlider.setProgress(progress);
volumeLevel.setText(String.valueOf(progress));
volumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser){
int volumeIndex = getRightVolume(progress);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,volumeIndex,0);
volumeLevel.setText(String.valueOf(progress));
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
private int getRightVolume(int input) {
// Ensure that the input is within the valid range (0 to a maxValue)
input = Math.max(0, Math.min(input, maxProgress));
// Calculate the right volume index from minVolumeIndex(x) to maxVolumeIndex(y)
double ratio = (double) input / (maxProgress + 1);
return (int) Math.round(minVolumeIndex + (maxVolumeIndex - minVolumeIndex) * ratio);
}
private int getSeekBarProgressFromVolume(int value) {
// Calculate the reverse interpolated input based on the value
double ratio = (double) (value - minVolumeIndex) / (maxVolumeIndex - minVolumeIndex);
int result = (int) Math.round(ratio * maxProgress);
// Ensure that the result is within the valid range (0 to maxValue)
return Math.max(0, Math.min(result, maxProgress));
}
I hope you learned how to change volume of any stream using seekbar and enjoyed this blog post.