I'm trying to build an Android App where the user can play audiofiles labeled with an id from a database.
//get id from database and turn it into a string, add letter a, because its a res file
stringId = "a" + String.valueOf(standard.getId());
//find playbutton
final FloatingActionButton play = (FloatingActionButton) findViewById(R.id.play);
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//to be able to feed mediaplayer a variable I put it in another function called playAudio
playAudio(stringId, true); }
});
final FloatingActionButton pause = (FloatingActionButton) findViewById(R.id.pause);
play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
playAudio(stringId, false); }
});
The playAudio looks like this:
private void playAudio(String nameOfFile, Boolean booleanPlay){
MediaPlayer mediaPlayer = MediaPlayer.create(this, getResources().getIdentifier(nameOfFile, "raw", getPackageName()));
if (booleanPlay = true){
if (!mediaPlayer.isPlaying())
mediaPlayer.start();
}
if (booleanPlay = false){
mediaPlayer.pause();
}
}
When I run my code every time I press play it creates a new mediaplayer which starts playing at the same time as the other mediaplayer, the pause button doesn't work for the same reason. I can't figure out how to make it work.
Do not create a new MediaPlayer instance each time you play a new file. Create an instance at the beginning and reuse it:
private static MediaPlayer mediaPlayer = new MediaPlayer ();
When changing the file to play, try this piece of code:
AssetFileDescriptor afd = getApplicationContext ().getResources ().openRawResourceFd (R.raw.sound);
if (afd != null)
{
mediaPlayer.reset()
mediaPlayer.setDataSource(afd.getFileDescriptor (), afd.getStartOffset (), afd.getLength ());
mediaPlayer.setLooping (true);
mediaPlayer.prepare ();
mediaPlayer.start ();
}
Replace R.raw.sound with the filename of the sound to play (this would be in the res/raw folder) or use a different way to reference the file as needed.
That works for me -- tested on Android 8.1 (targeted). Hope this helps.
EDITED TO ADD: I just noticed you have wrong operators in the if(booleanPlay = false) and if (booleanPlay = true) statements. They should be == (comparison, instead of assignment).
And one last thing: When exiting, you should call mediaPlayer.release() to free up the resources, but you probably knew that. Glad I could help.
Related
I would like to add a sound whenever the user clicks the apps button, any idea how can I do that?
I have tried to create a "raw" directory on the res/ file with different names, like for example "test.mp3", which did not work...
Playing sound is not difficult.
And as long as these are short sounds during app foreground operations it fine.
You need to use the MediaPlayer.
First, prepare it.
private MediaPlayer mMediaPlayer = null;
private MediaPlayer.OnCompletionListener mOnCompletionListener = new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
};
Now on click:
public void onItemClick(.........) {
releaseMediaPlayer();
mMediaPlayer = MediaPlayer.create(getActivity(),getSoundFileResID());
mMediaPlayer.setOnCompletionListener(mOnCompletionListener);
mMediaPlayer.start();
}
You need to implement the getSoundFileResID().
For more info read the MediaPlayer OverView
I have come across another error along my first app journey :) I want to play a sound when the app loads. Which is a .wav file. It lasts 2 seconds long yet it does not play when I run the app on my old Samsung S4. There is no errors within the IDE or anything I can see, I have checked if 'mp' has a value and it does. Looking around on posts most people have the problem that 'mp' is = null. Whereas mine has a value just no sound comes out of the phone... Again, any help is appreciated!
public class OpeningScreen extends Activity {
#Override
// create the screen state
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// connect the xml layout file
setContentView(R.layout.activity_opening_screen);
final MediaPlayer mp = new MediaPlayer();
mp.create(this, R.raw.welcome_message);
mp.start();
// create the on touch listener
ConstraintLayout layout = (ConstraintLayout) findViewById(R.id.opening_layout);
layout.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// change the screen to a new state
Intent intent = new Intent(OpeningScreen.this, GameScreen.class);
// start the new activity
startActivity(intent);
// stop welcome sound (if still playing)
mp.stop();
return true;
}
});
}
}
public static MediaPlayer create(Context context, int resid) is a static method to create a MediaPlayer for a given resource id.
It means that by calling create you are creating a new instance of media player with no reference usage.
Try to change
final MediaPlayer mp = new MediaPlayer();
mp.create(this, R.raw.welcome_message);
to
final MediaPlayer mp = MediaPlayer.create(this, R.raw. welcome_message);
And the player should work.
It's better to register for OnPreapredListener via MediaPlayer.setOnPreaparedListener and after preparation you start your media playback.
http://developer.android.com/guide/topics/media/mediaplayer.html
Why do you use final?
You can play a mp3 with
MediaPlayer mp = MediaPlayer.create(OpeningScreen.this, R.raw.welcome_message);
mp.start();
Also stopping mediaplayer is better if you stop in onDestroy.
public void onDestroy() {
mp.stop();
super.onDestroy();
}
I created an onClick methord PlaySound in which an if statement checks weather the sound is playing or not , if it is playing it stops it or else it starts it.The problem i face is that the if statement is always false and never true.
CODE
public void PlaySound(View view) {
final MediaPlayer clickSound = MediaPlayer.create(this, R.raw.abcd);
if(clickSound.isPlaying()) {
clickSound.stop();
}
else{
clickSound.setLooping(true);
clickSound.start();
}
}
Remove
final MediaPlayer clickSound = MediaPlayer.create(this, R.raw.abcd);
from play method and create it outside of the method.
Edit for your convenince follow the steps:
You can take a global variable of MediaPlayer
public MediaPlayer clickSound ;
and then create in onCreate method:
clickSound = MediaPlayer.create(this, R.raw.abcd);
and thus your play method will be:
public void PlaySound(View view) {
if(clickSound.isPlaying()) {
clickSound.stop();
}
else{
clickSound.setLooping(true);
clickSound.start();
}
}
I am writing a small practice app that plays a sound clip when a button is tapped. In my previous code, this amounts to just the creation of a MediaPlayer object and a call to mp.start() to start the audio.
This works, but now I would like that same button to play only when no sound is playing yet. If sound is playing, stop the audio. A play/stop button.
I tried to do this using the following code:
```
public class MainActivity extends Activity {
MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void goButtonClicked(View v) {
if(mp == null) {
MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.wordt);
}
if(mp.isPlaying()) {
mp.stop();
mp.release();
}
else {
mp.start();
}
}
}
```
However now when I run the app, the app crashes when I tap the button. Where did I go wrong?
Just change your code like this,
public void goButtonClicked(View v) {
if(mp == null) {
mp = MediaPlayer.create(getApplicationContext(), R.raw.wordt);
}
....
}
What happens here is, MediaPlayer mp = ... means you are creating a local variable inside if condition. But still your field variable is null. And when the app executes the second if condition, it throws a NullPointerException.
You didn't initialize your first mp object, so you see nullPointerException,
and you can delete second mp object
How can I have an on and off state for an Image Button? My goal is to have sound play when the image button is clicked, and for sound to stop when the button is clicked again. Thank you!
you can use event's. like on click listener.
get your imageView and setOnClickListener for this.
ImageView mImageView = (ImageView) findViewById(R.id.sound_imageView);
Boolean flag = false;
mImageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(flag) {
//play sound
flag = false;
} else {
//stop sound
flag = true;
}
}
});
There are a few Views that exist in Android that provide toggle functionality like you are looking for. You might want to research the android.widget.CompoundButton class for ideas, or reference this tutorial.
You can do it manually. First when you will click the button you will check whether the music is running or not. If it is running then stop it , if not running then play it.
Something like that -
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(musicPlayer!=null && musicPlayer.isPlaying()){
musicPlayer.stop();
}else{
musicPlayer=new MediaPlayer();
AssetFileDescriptor afd = getActivity().getAssets().openFd("AudioFile.mp3");
musicPlayer.setDataSource(afd.getFileDescriptor());
musicPlayer.prepare();
musicPlayer.start();
}
}
});