In this tutorial, you will learn how to develop an Android application using Kotlin that plays sound effects using the `MediaPlayer` class. The tutorial will guide you through implementing features to play, stop, and pause sound effects, supporting both local and web-based MP3 files. You'll create a user interface with a `ListView` inside cards to list and select different sound files for playback. Key steps include setting up `MediaPlayer` instances, handling play, stop, and pause controls, loading MP3 files from local storage or URLs, and integrating these functionalities into a responsive and user-friendly Kotlin-based Android application. By following this guide, you'll gain practical experience in managing media playback and enhancing user interaction through sound effects in your Android apps.
Submitted on July 07, 2024
To create an Android app that plays sound effects using ‘MediaPlayer’, with controls to play, stop, and pause, and supports both local and web MP3 files listed in a ‘ListView’ inside cards, you can follow these steps. This example will demonstrate how to implement this functionality in Kotlin.
If you're targeting API level 23 (Android 6.0) or higher, you might need to request permissions to access the internet for playing web MP3 files. Add the following to your ‘AndroidManifest.xml’ inside the <manifest> tag:
<uses-permission android:name="android.permission.INTERNET" />
Open ‘res/layout/activity_main.xml’ and define the layout for the main activity. It will contain a ‘ListView’ to display the sound effects with play controls.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:dividerHeight="0dp" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardCornerRadius="8dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/textTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="Sound Effect"
android:textSize="18sp"
android:textStyle="bold" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="8dp">
<Button
android:id="@+id/btnPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Play" />
<Button
android:id="@+id/btnPause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pause"
android:layout_marginStart="8dp"
android:visibility="gone" />
<Button
android:id="@+id/btnStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop"
android:layout_marginStart="8dp" />
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
data class SoundItem(val title: String, val uri: String)
import android.content.Context
import android.media.MediaPlayer
import android.view.LayoutInflater
import import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.Button
import android.widget.TextView
import androidx.cardview.widget.CardView
import kotlinx.android.synthetic.main.list_item_card.view.*
class SoundAdapter(private val context: Context, private val soundItems: List<SoundItem>) : BaseAdapter() {
private var mediaPlayer: MediaPlayer? = null
private var isPaused = false
override fun getCount(): Int {
return soundItems.size
}
override fun getItem(position: Int): Any {
return soundItems[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
val view: View = convertView ?: LayoutInflater.from(context).inflate(R.layout.list_item_card, parent, false)
val soundItem = soundItems[position]
view.textTitle.text = soundItem.title
view.btnPlay.setOnClickListener {
playSound(soundItem.uri)
}
view.btnPause.setOnClickListener {
pauseSound()
}
view.btnStop.setOnClickListener {
stopSound()
}
return view
}
private fun playSound(uri: String) {
mediaPlayer?.release()
mediaPlayer = MediaPlayer().apply {
setDataSource(uri)
prepare()
start()
}
isPaused = false
updateButtonVisibility()
}
private fun pauseSound() {
mediaPlayer?.let {
if (it.isPlaying) {
it.pause()
isPaused = true
updateButtonVisibility()
}
}
}
private fun stopSound() {
mediaPlayer?.let {
if (it.isPlaying || isPaused) {
it.stop()
it.reset()
isPaused = false
updateButtonVisibility()
}
}
}
private fun updateButtonVisibility() {
if (isPaused) {
view.btnPause.visibility = View.GONE
view.btnPlay.visibility = View.VISIBLE
} else {
view.btnPause.visibility = View.VISIBLE
view.btnPlay.visibility = View.GONE
}
}
}
package com.example.soundeffects
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private val soundItems = listOf(
SoundItem("Local Sound 1", "android.resource://${packageName}/${R.raw.sound1}"),
SoundItem("Local Sound 2", "android.resource://${packageName}/${R.raw.sound2}"),
SoundItem("Web Sound 1", "https://www.soundeffects.com/1.mp3"),
SoundItem("Web Sound 2", "https://www.soundeffects.com/2.mp3")
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val adapter = SoundAdapter(this, soundItems)
listView.adapter = adapter
}
}
This example provides a foundation for building a more robust sound effects player in your Android app, including both local and web-based MP3 files, with basic playback controls. Adjustments can be made based on your specific requirements or additional functionality needed in your application.
Android application implemented in Java that allows playing sound effects using ‘MediaPlayer’. It supports both local MP3 files (from ‘res/raw’ directory) and web URLs, displayed in a ListView inside cards with play, pause, and stop controls.
public class SoundItem {
private String title;
private String uri;
public SoundItem(String title, String uri) {
this.title = title;
this.uri = uri;
}
public String getTitle() {
return title;
}
public String getUri() {
return uri;
}
}
import android.content.Context;
import android.media.MediaPlayer;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import androidx.cardview.widget.CardView;
import java.io.IOException;
import java.util.List;
public class SoundAdapter extends BaseAdapter {
private Context context;
private List<SoundItem> soundItems;
private MediaPlayer mediaPlayer;
private boolean isPaused;
public SoundAdapter(Context context, List<SoundItem> soundItems) {
this.context = context;
this.soundItems = soundItems;
}
@Override
public int getCount() {
return soundItems.size();
}
@Override
public Object getItem(int position) {
return soundItems.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = LayoutInflater.from(context);
view = inflater.inflate(R.layout.list_item_card, null);
holder = new ViewHolder();
holder.textTitle = view.findViewById(R.id.textTitle);
holder.btnPlay = view.findViewById(R.id.btnPlay);
holder.btnPause = view.findViewById(R.id.btnPause);
holder.btnStop = view.findViewById(R.id.btnStop);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
final SoundItem soundItem = soundItems.get(position);
holder.textTitle.setText(soundItem.getTitle());
holder.btnPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playSound(soundItem.getUri());
}
});
holder.btnPause.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
pauseSound();
}
});
holder.btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
stopSound();
}
});
return view;
}
private void playSound(String uri) {
stopSound();
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(uri);
mediaPlayer.prepare();
mediaPlayer.start();
isPaused = false;
updateButtonVisibility();
} catch (IOException e) {
e.printStackTrace();
}
}
private void pauseSound() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
isPaused = true;
updateButtonVisibility();
}
}
private void stopSound() {
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
isPaused = false;
updateButtonVisibility();
}
}
private void updateButtonVisibility() {
// Update button visibility based on playback state
if (isPaused) {
// Show Play button and hide Pause button
holder.btnPlay.setVisibility(View.VISIBLE);
holder.btnPause.setVisibility(View.GONE);
} else {
// Show Pause button and hide Play button
holder.btnPlay.setVisibility(View.GONE);
holder.btnPause.setVisibility(View.VISIBLE);
}
}
static class ViewHolder {
TextView textTitle;
Button btnPlay;
Button btnPause;
Button btnStop;
}
}
package com.example.soundeffects;
import android.os.Bundle;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ListView listView;
private List<SoundItem> soundItems;
private SoundAdapter soundAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listView);
// Initialize sound items
soundItems = new ArrayList<>();
soundItems.add(new SoundItem("Local Sound 1", "android.resource://" + getPackageName() + "/" + R.raw.sound1));
soundItems.add(new SoundItem("Local Sound 2", "android.resource://" + getPackageName() + "/" + R.raw.sound2));
soundItems.add(new SoundItem("Web Sound 1", "https://www.soundeffects.com/1.mp3"));
soundItems.add(new SoundItem("Web Sound 2", "https://www.soundeffects.com/2.mp3"));
// Initialize adapter and set it to ListView
soundAdapter = new SoundAdapter(this, soundItems);
listView.setAdapter(soundAdapter);
}
@Override
protected void onDestroy() {
super.onDestroy();
// Release MediaPlayer resources
if (soundAdapter != null) {
soundAdapter.releaseMediaPlayer();
}
}
}