I am new to coding and at this point, I made a media player that starts and pauses the audio, has a working seekbar, duration, etc. Now I faced a big issue. The audio can't be played in the background and I found out that I can do this with service but this changes things. I read all kinds of topics on how to control the audio in service with seekbar and all kinds of stuff but nothing helped me. The main problem I face is having the seekbar to control the audio and a text to read the time. If there is someone to help me find a code for this it would be much appreciated.
The layout:
<SeekBar
android:id="@+id/seekBarMusic1"
android:layout_width="match_parent"
android:layout_height="@dimen/_20sdp"
android:layout_marginTop="@dimen/_12sdp"
android:layout_marginLeft="@dimen/_20sdp"
android:layout_marginRight="@dimen/_20sdp"
app:layout_constraintTop_toBottomOf="@+id/cardView"
tools:layout_editor_absoluteX="10dp" />
<TextView
android:id="@+id/playerPositionMusic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="00:00"
android:textColor="@color/remain_black"
android:textSize="25dp"
android:layout_marginBottom="@dimen/_80sdp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/cardView"
app:layout_constraintTop_toBottomOf="@+id/seekBarMusic1" />
<TextView
android:id="@+id/text_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/_80sdp"
android:text="15:00"
android:textColor="@color/remain_black"
android:textSize="25dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/cardView"
app:layout_constraintTop_toBottomOf="@+id/seekBarMusic1" />
<ImageView
android:id="@+id/btPlayMusic"
android:layout_width="80dp"
android:layout_height="80dp"
android:alpha="0.9"
android:background="@drawable/play"
android:theme="@style/Button.White"
app:layout_constraintEnd_toStartOf="@+id/text_time"
app:layout_constraintStart_toEndOf="@+id/playerPositionMusic"
app:layout_constraintTop_toBottomOf="@+id/seekBarMusic1"
app:tint="@color/remain_black" />
<ImageView
android:visibility="gone"
android:id="@+id/btPauseMusic"
android:layout_width="80dp"
android:layout_height="80dp"
android:alpha="0.9"
android:background="@drawable/pause"
android:theme="@style/Button.White"
app:layout_constraintEnd_toStartOf="@+id/text_time"
app:layout_constraintStart_toEndOf="@+id/playerPositionMusic"
app:layout_constraintTop_toBottomOf="@+id/seekBarMusic1"
app:tint="@color/remain_black" />
The code I used before:
public class m1 extends AppCompatActivity {
ImageView btPlay, btPause;
TextView playerPosition, playerDuration;
CircularSeekBar seekBar;
MediaPlayer mediaPlayer;
Handler handler = new Handler();
Runnable runnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_m1);
findViewById(R.id.backm1).setOnClickListener(v -> onBackPressed());
playerPosition = findViewById(R.id.playerPosition);
playerDuration = findViewById(R.id.playerDuration);
replay = findViewById(R.id.replay);
forward = findViewById(R.id.forward);
seekBar = findViewById(R.id.seekBar);
btPause = findViewById(R.id.btPause);
btPlay = findViewById(R.id.btPlay);
mediaPlayer = MediaPlayer.create(this,R.raw.ding_dong);
runnable = new Runnable() {
@Override
public void run() {
seekBar.setProgress(mediaPlayer.getCurrentPosition());
handler.postDelayed(this,500);
}
};
int duration = mediaPlayer.getDuration();
String sDuration = convertFormat(duration);
playerDuration.setText(sDuration);
btPlay.setOnClickListener(v -> {
mediaPlayer.start();
btPlay.setVisibility(View.GONE);
btPause.setVisibility(View.VISIBLE);
seekBar.setMax(mediaPlayer.getDuration());
handler.postDelayed(runnable, 0)
});
btPause.setOnClickListener(v -> {
mediaPlayer.stop();
btPause.setVisibility(View.GONE);
btPlay.setVisibility(View.VISIBLE);
handler.removeCallbacks(runnable);
});
seekBar.setOnSeekBarChangeListener(new CircularSeekBar.OnCircularSeekBarChangeListener() {
@Override
public void onProgressChanged(CircularSeekBar circularSeekBar, float v, boolean b) {
if (b) {
mediaPlayer.seekTo((int) v);
}
playerPosition.setText(convertFormat(mediaPlayer.getCurrentPosition()));
}
@Override
public void onStopTrackingTouch(CircularSeekBar circularSeekBar) {
}
@Override
public void onStartTrackingTouch(CircularSeekBar circularSeekBar) {
}
});
mediaPlayer.setOnCompletionListener(mp -> {
btPause.setVisibility((View.GONE));
btPlay.setVisibility(View.VISIBLE);
mediaPlayer.seekTo(0);
});
}
}
@SuppressLint("DefaultLocale")
private String convertFormat(int duration) {
return String.format("%02d:%02d"
,TimeUnit.MILLISECONDS.toMinutes(duration)
,TimeUnit.MILLISECONDS.toSeconds(duration) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration)));
}
@Override
public void onPause()
{
if(mediaPlayer != null && mediaPlayer.isPlaying())
{
mediaPlayer.stop();
}
super.onPause();
}
}
The code I am using now:
btPause = findViewById(R.id.btPauseMusic);
btPlay = findViewById(R.id.btPlayMusic);
btPlay.setOnClickListener(v -> {
startService(new Intent(this, BackgroundMusicService.class));
btPlay.setVisibility(View.GONE);
btPause.setVisibility(View.VISIBLE);
});
btPause.setOnClickListener(v -> {
stopService(new Intent(this, BackgroundMusicService.class));
btPause.setVisibility(View.GONE);
btPlay.setVisibility(View.VISIBLE);
});
}
And the service class:
public class BackgroundMusicService extends Service {
private MediaPlayer mediaPlayer;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer = MediaPlayer.create(this, R.raw.ding_dong);
mediaPlayer.start();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
}
}
