i'm having trouble playing a sound in android.
My first attempt was all inside my onButtonClick function which worked really well for about 20 clicks. then the sound stopped. and i believe it used the entire sound pool of android because all my other apps stopped having sounds.
public void onButtonClick(View view)
{
MediaPlayer clickSound = MediaPlayer.create(this, R.raw.click);
clickSound.start();
//... other onButtonCode
}
i have since changed this up a little bit so that this is now a global variable
MediaPlayer clickSound;
and it is instantiated inside my onCreate() method. the onbuttonClick now has the clickSound.start()
but this doesn't work the way i thought it should. the sound is seemingly random. sometimes the click will be there. sometimes there will be no sound. or sometimes the sound is there for a little blip and ends before the sound is complete. On the good side it doesn't seem to completely fill up the sound pool so i can keep getting 'some' sounds while i am testing.
What am i missing to make the sound function properly?
I tried to add a clickButton.stop() but that made my sound not function at all, probably because it stops before it is noticeable.
You should release the ressource after use.
clickSound.release();
clickSound = null;
I would suggest following:
Initialize the Player in onResume:
clickSound = MediaPlayer.create(this, R.raw.click);
Release ressources in onPause:
clickSound.release();
clickSound = null;
Use button to play sound:
clickSound.start();
Use SoundPool instead.
soundPool = new SoundPool(1, AudioManager.STREAM_SYSTEM, 0);
resId = soundPool.load(context, R.raw.click, 1);
for play :
private void playSpecSound(int resId)
{
if(soundPool != null)
{
if(0 == soundPool.play(resId, 1f, 1f, 0, 0, 1.0f))
{
Log.e(TAG, "Play specified sound failed !");
}
}
}
Related
I am a completely begginer guy in Android Studio and mobile apps in general. I used to create websites on Wordpress and i don't have so much experience on coding. Recently i started experimenting with mobile apps and mostly Android Studio. I bought a template for a Logo Quiz game and i managed to make it run without errors and publish it in Play Store as my first game. The player can see a part of the logo and guess the brand name using the given letters
But i would like to use the same template with new graphics and create a music quiz.
Instead of the logo guess game, the player will be able to listen a part of a song and guess the song's title.
The current project is getting the file names from a database stored in assets/databases folder.
So i managed to add start, pause and stop buttons in my activity_play.xml and succesfully created a mediaplayer in activityPlay.java file like:
public void music(View view) {
switch (view.getId()){
case R.id.button:
// Check if mediaPlayer is null. If true, we'll instantiate the MediaPlayer object
if(mediaPlayer == null){
mediaPlayer = MediaPlayer.create(this, R.raw.music);
}
// Then, register OnCompletionListener that calls a user supplied callback method onCompletion() when
// looping mode was set to false to indicate playback is completed.
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
// Here, call a method to release the MediaPlayer object and to set it to null.
stopMusic();
}
});
// Next, call start() method on mediaPlayer to start playing the music.
mediaPlayer.start();
break;
case R.id.button2:
if(mediaPlayer != null) {
// Here, call pause() method on mediaPlayer to pause the music.
mediaPlayer.pause();
}
break;
case R.id.button3:
if(mediaPlayer != null){
// Here, call stop() method on mediaPlayer to stop the music.
mediaPlayer.stop();
// Call stopMusic() method
stopMusic();
}
break;
}
}
private void stopMusic() {
mediaPlayer.release();
mediaPlayer = null;
}
// Call stopMusic() in onStop() overridden method as well.
#Override
protected void onStop() {
super.onStop();
stopMusic();
}
The above code can succesfully play the music.mp3 file located in raw folder. The app i bought is using the following code to load the images and display them for each level:
String image_a = listDataBase.get(1);
String image_q = listDataBase.get(2);
if (isTrue == 1) {
String imgPath;
if (numImage == 0) {
imgPath = "file:///android_asset/logos/" + image_a;
} else {
imgPath = "file:///android_asset/logos/" + image_q;
}
Picasso.get().load(imgPath).into(imageView);
linearLayoutNullClick.setVisibility(View.VISIBLE);
recyclerViewKeys.setVisibility(View.GONE);
trueLogo = 2;
} else {
String imgPath = "file:///android_asset/logos/" + image_q;
Picasso.get().load(imgPath).into(imageView);
recyclerViewKeys.setVisibility(View.VISIBLE);
recyclerViewLogoKeys.setVisibility(View.VISIBLE);
}
So is it possible to use the same code and load the imgPath into mediaPlayer = MediaPlayer.create(this, R.raw.music);
I tried loading imgPath directly to mediaplayer like this but didn't work:
mediaPlayer = MediaPlayer.create(this, imgPath);
Then i tried:
private String audioPath;
audioPath = imgPath;
mediaPlayer = MediaPlayer.create(this, audioPath);
but also didn't work.
Tried many more methods i found on the web, but always i am missing something
As i said before i am a newbie in coding and programming so the solution probably will be very easy .
Anyone can help please?
Are you sure you are getting a audio path in your imgPath object?
Then you can try getting actual storage path from device using code mentioned
here
If you change the value in the database of pic_1.png with audio_1.mp3
then path will start like:
"file:///android_asset/logos/" + YOUR_AUDIO;
So are you sure audio exists in this path?
I'm trying to create a mock radio app with about 100 songs that'll be played randomly, and occasionally interrupt the music with other audio files.
This is the snippet that's giving me trouble:
mp.start();
while(true)
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mPlayer) {
radio.playRadio();
}
});
I've gotten the code to work with some infinite loops that would hang the app (I couldn't even change volume), which is why I thought the OnCompletionListener would break that up. Instead, it doesn't even seem to go into the radio.PlayRadio function.
What I'm expecting to happen is that the program starts with the starting audio, then while that's playing goes into the while loop and stops at the OnCompletionListener. When it completes, goes into the function, performs the actions in there (sets media, plays them), exits, then loops back to the wait for complete.
If I take out the while(true), it goes into the function, so somehow the while loop is stopping everything, and reading documentation and other questions isn't explaining why.
You can use recursive method to tackle the problem. For example, if you are playing the song, you can create the following method:
private void playSong(Uri uri) {
// this is just example, don't expect the code to works.
MediaPlayer mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setDataSource(getApplicationContext(), uri);
mp.prepare();
mp.start();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mPlayer) {
// get the next uri here
// assume there is next uri.
playSong(nextUri);
}
});
}
You should not use while loop to block your code. Instead, you need to rely on the message sent by the listener.
I'm trying to create my own version of iTunes. I am trying to create a music player and this is my method:
public void audioPlayerButtons(ActionEvent actionEvent) {
if (actionEvent.getSource() == playbtn) {
String bip = "/Users/april121/Work/MyMusic!/src/sample/Songs/01 Clarity.m4a";
Media hit = new Media(bip);
MediaPlayer mediaPlayer = new MediaPlayer(hit);
MediaPlayer.play();
}
else (actionEvent.getSource()== pausebtn){
MediaPlayer.pause();
}
else (actionEvent.getSource()==forwardbtn){
MediaPlayer.seek(MediaPlayer.getStartTime());
MediaPlayer.stop();
}
else (actionEvent.getSource()==backwardbtn){
//to be finished
}
But I have tried for hours now - be it through importing libraries from Maven or hard coding and it's not working.
I'd like it show what's playing and have basic functions ie. play, pause, rewind and forward and have a progress bar.
this is the error it is showing:
non-static method can't be accessed in static context. And the part that is causing the error is the ".stop()" or ".play()" bits
but I don't understand why - because my method is non-static anyways
Look at these lines:
MediaPlayer mediaPlayer = new MediaPlayer(hit);
MediaPlayer.play();
That second line is calling a static play() function, which doesn't work. The play() function is non-static. That's why you're getting the error you're getting.
You probably mean this instead:
MediaPlayer mediaPlayer = new MediaPlayer(hit);
mediaPlayer.play();
If you have other questions, post them as separate questions and try to be as specific as possible.
Try naming it something else ie.
MediaPlayer mp = new MediaPlayer (hit);
mp.play();
That way you won't have a confusion!
What i am trying to acomplish is for me to click on a button and then play a sound based on a substring.
This is my current code for pressing the button :
display.setText("start");
thefull = thef.getText().toString();
for(int a=0;a<thefull.length();a++)
{
letter=thefull.substring(a,a+1);
if(letter=="m")
{
oursong = MediaPlayer.create(MainActivity.this, R.raw.m);
oursong.start();
while(oursong.isPlaying())
{
display.setText("start");
}
oursong.release();
}
else if(letter=="a")
{
oursong = MediaPlayer.create(MainActivity.this, R.raw.a);
oursong.start();
while(oursong.isPlaying())
{
display.setText("start");
}
oursong.release();
}
display.setText("done");
but for some reason when i click my button no sound is played.
I am also new to android and java programming, so am i going right about doing this?
Because what i really want is for the program to keep checking if a sound is playing(in this case "oursound) when the button is clicked and if the sound is playing i want the program to wait for it to finish to start another sound right after it.
But for now my code doesn´t play any sounds
First of all you need to stop the media player before releasing it(its safer.)
Second, instead of using while(oursong.isPlaying())
{
display.setText("start");
} ; you have to register OnCompletionListener using setOnCompletionListener method. When the song is played endCompletion will be called. Like so;
MediaPlayer mp = new MediaPlayer();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer player) {
player.release();
}});
and inside the onComplete should reset the text "done"
I am working on an app, wherein when a new activity is started, it should start playing a sound.
So I used mediaplayer to play the sound in oncreate and It worked fine. But when I tried to use soundpool instead, by loading and playing it in oncreate of the activity.
Its is not playing.
I choose soundpool, since its better than mediaplayer.
what might be the issue? doesn't soundpool work in oncreate?
Maybe you just need to put a sleep in the onCreate method.
I had pretty much same problem trying to write an app that would sometimes need to play a sound as soon as it woke up. Eventually after much trial and error I discovered that it was putting the error "sample NOT READY" in the log output. The problem was that loading a sound file happens asynchronously, and if you try to play the sound before it has loaded it fails.
There is supposedly a mechanism you can use called setOnLoadCompleteListener, but I've yet to see an example of how this is actually useful. In the example shown above from mirroredAbstraction (assuming it works as advertised) all that would happen if the sound is not loaded yet is that it would not play the sound, which is pretty much the same as what you have now.
If that example somehow magically "fixed" your problem then I would suggest that it was only because all the extra overhead in the two method calls basically give your sound time to load before it was played. You could probably have achieved the same outcome with a simple SystemClock.sleep(100) in your onCreate between the load the play.
Depending on the size of your sound you might need to lengthen the delay, but a bit of experimentation with differing delays should tell you how much you need.
Alternatively , you could override OnWindowFocusChanged to play the file when the Activity starts ...
Something like this ...
public class YourActivity extends Activity {
.
.
.
private Handler mHandler;
public void onCreate(Bundle savedInstanceState) {
.
.
.
this.mHandler = new Handler();
.
.
.
}
public void onWindowFocusChanged(boolean paramBoolean)
{
if (paramBoolean)
{
this.mHandler.postDelayed(new Runnable()
{
public void run()
{
// Refer to the answer above to create the play function for your soundfile ...
YourActivity.this.play("The sound from the sound pool");
}
}
, 1000L);
}
}
You can play it anywhere,
Ill demonstrate with a simple example
Create a method initializeSoundPool
private void initializeSoundPool(){
mSoundPool = new SoundPool(2, AudioManager.STREAM_MUSIC, 0);
mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
loaded = true;
}
});
soundID = mSoundPool.load(this, R.raw.glassbreak, 1);
}
Then create a method playFile
private void playFile(){
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
float actualVolume = (float) audioManager
.getStreamVolume(AudioManager.STREAM_MUSIC);
float maxVolume = (float) audioManager
.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
float volume = actualVolume / maxVolume;
if (loaded) {
mSoundPool.play(soundID, volume, volume, 1, 0, 1f);
Log.e("Test", "Played sound");
}
}
Then in onCreate call them like this
private SoundPool mSoundPool;
private int soundID;
boolean loaded = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spxml);
initializeSoundPool();
playFile();
}
Or even better call initializeSoundPool in onCreate and then call playFile in onResume.