Dynamically create play audio buttons - java

I have code that creates smaller wav file "events" from one larger wav file based on energy levels.
Depending on the structure of the orignial wav file the amount of wav file events created will vary.
I would like to create a dynamic amount of play buttons for each event that will play each event out loud.
The method to create an event has the following signature:
public void createEventWav(ArrayList<Double> event, String fileName, Context context) {
This will create a wav file with a unique filename.
This is the code I have currently that plays an event:
public Button playEvent;
playEvent= (Button) findViewById(R.id.btnPlayEvent);
playEvent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playEvent( );
}
});
public static void playEvent(){
try {
MediaPlayer player = new MediaPlayer();
player = new MediaPlayer();
player.setDataSource("/data/data/com.example.androidaudiorecorder/files/recording_DOG.wav");
player.prepare();
player.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (Exception e) {
System.out.println("Exception of type : " + e.toString());
e.printStackTrace();
}
I would like to have one for each event created.
Please see attched for layout of app
I have already tried many of the solutions found at : How to add a button dynamically in Android?
None have worked so far.

Related

MediaPlayer: Sounds playing over the top of each other

I have a soundboard with multiple buttons (approx 17), each linked to a .mp3 sound.
The issue is that when a sound is playing and I press another button, both are then playing in the background.
I would like to be able to stop the playing sound and start the new one when a different button is pressed. Also, is there the ability to stop the current playing sound by pressing on its button again?
Also, I don't really like the section of code that states: private MediaPlayer[] mPlayers = new MediaPlayer[17];
The number (in this case 17), determines the amount of times sounds can be played. After that, no further sounds can be played it seems. Is there a way of making this indefinite?
Rather than paste all of the code from my activity, I have attached the salient code and numbered it in the order in which it appears on my main activity .java file.
Thanks for your help all.
private int mNextPlayer = 0;
2) a.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.startAnimation(animAlpha);
startSound(R.raw.likethebattle);
}
});
3) public void onDestroy() {
super.onDestroy(); // <---------------------- This needed to be there
for (int i = 0; i < mPlayers.length; ++i)
if (mPlayers[i] != null)
try {
mPlayers[i].release();
mPlayers[i] = null;
} catch (Exception ex) {
// handle...
}
}
4) private void startSound(int id) {
try {
if (mPlayers[mNextPlayer] != null) {
mPlayers[mNextPlayer].reset();
mPlayers[mNextPlayer].prepare();
mPlayers[mNextPlayer].stop();
mPlayers[mNextPlayer].release();
mPlayers[mNextPlayer] = null;
}
mPlayers[mNextPlayer] = MediaPlayer.create(this, id);
mPlayers[mNextPlayer].start();
} catch (Exception ex) {
// handle
} finally {
++mNextPlayer;
mNextPlayer %= mPlayers.length;
}
}
It looks like you are not stoping currently playing MediaPlayer. startSound(id) does not stop currently playing sound. In
finally {
++mNextPlayer;
mNextPlayer %= mPlayers.length;
}
you move you counter to next player in array and next time you enter startSound() method your counter does not point to previously started player so it can not stop it.

App that plays audio file from internal Storage, Android Studio (JAVA)

I have attempted to create an App that plays wavfiles that have been created from another app I have made that records wavFiles.
The wav files I would like to play are stored in the following directory with my android device.
"/data/data/com.example.androidaudiorecorder/files/"
Here is the code I have attempted so far :
public class MainActivity extends AppCompatActivity {
Button playEvent ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playEvent= (Button) findViewById(R.id.btnPlayEvent);
playEvent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playEvent( );
}
});
}
public static void playEvent(){
try {
MediaPlayer player = new MediaPlayer();
player = new MediaPlayer();
player.setDataSource("/data/data/com.example.androidaudiorecorder/files/recording_DOG.wav");
player.prepare();
player.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (Exception e) {
System.out.println("Exception of type : " + e.toString());
e.printStackTrace();
}
}
}
}
Unfortunatley when I load the app and press play, nothing happens.
I am not sure if this is the correct way to use a file directory.
Any advice on how to fix this would be greatly appreciated.
1) You need to give permissions in the android manifest file to access storage before reading/writing any content int the storage .
2) To read the file,
File dir = Environment.getExternalStorageDirectory();
File yourFile = new File(dir, "path/filename.extension");

Android media player not working as expected

I am very new to android just started with Android currently referring the below code from past 2 days, not able to fix the issue.
Code:
https://github.com/quocnguyenvan/media-player-demo
Issue: Let's say we 4 Songs in the ListView when we click on the first song play it for some time and pause it without clicking on stop.
As soon as we click on the second song the first song starts playing we cannot play the second song unless we click on stop of the first song How to solve this issue.
The issue with code not able to figure out and fix it.I have referred many posts before posting on StackOverflow but could not make it, any suggestion or guidance is highly appreciated.
Problematic code:
// play music
viewHolder.ivPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(flag){
mediaPlayer = MediaPlayer.create(context, music.getSong());
flag = false;
}
if(mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewHolder.ivPlay.setImageResource(R.drawable.ic_play);
} else {
mediaPlayer.start();
viewHolder.ivPlay.setImageResource(R.drawable.ic_pause);
}
}
});
// stop
viewHolder.ivStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!flag) {
mediaPlayer.stop();
mediaPlayer.release();
flag = true;
}
viewHolder.ivPlay.setImageResource(R.drawable.ic_play);
}
});
These are the steps I used for playing song you can try to sync with my steps to resolve the error.
private void initMembers() {
//initialize the members here
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
//media prepare
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(final MediaPlayer mediaPlayer) {
//media player prepared
togglePlayPausePlayer();
}
});
//media completion
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(final MediaPlayer mediaPlayer) {
//handle the media play completion
handleOnCompletionLogic();
}
});
}
after that whenever I try to play the song. I call this method.
public void playMusic(final MusicModel musicModel) {
//here play the music with data in below
try {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
mMediaPlayer.reset();
mMediaPlayer.setDataSource(musicModel.getUrl());
mMediaPlayer.prepareAsync();
} catch (IOException | IllegalStateException exp) {
exp.printStackTrace();
showMessage(getString(R.string.error_unable_play));
}
}
above resets the playing song and prepare the player for another song.
and OnPreparedListener it calls the togglePlayPausePlayer() which play and pause the song accordingly.
private void togglePlayPausePlayer() {
//here handle the logic for play and pause the player
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
setPlayAndPause(false);
} else {
mMediaPlayer.start();
setPlayAndPause(true);
}
}
The key is we initialize the player and set an onPrepareListener for the media player to get prepared and then play the song, which will check if it's playing then it will stop and else it will play.
hope this may help you.
For on click on ListView you need to reset the media player, change the data source and start playing with new song.
mp.reset();
mp.setDataSource("song you selected from ListView");
mp.prepare();
mp.start();

Unexpected behavior: immediate completion of media player

I am trying to restore audio to the position it was and the file it was when the user left the fragment. To do this I save the location of the audio file, and the seek position using personal prefs, along with a boolean for whether or not the audio was playing when the user left. I save this info first thing in onPause().
When I resume, I initialize the views etc. and the very last thing I do in onResume is read from personal prefs and play the audio stored there is appropriate.
However when I try to play from onResume, the media completion listener gets called immediately and the file gets skipped.
I have been running tests and I know that the media player is handed the right data, is prepared correctly and set to play.
The way I am trying to play the audio is the same way I do it if a user clicks manually to play audio, and that works flawlessly.
Only when trying to 'restore' the audio to where it was when a user left does the completion listener get called immediately.
Has anyone seen this before?
public void setAudioURLAndPLay(Context context, String url)
{
Log.d(TAG, "setAudioURLAndPLay");
CacheQueue.getInstance().addImmediateTaskToQueue(CacheQueue.AUDIO_TASK, context, url, 0, handler);
}
private void playCahcedFile(String location)
{
Log.d(TAG, "playCahcedFile");
try
{
this.reset();
this.setAudioStreamType(AudioManager.STREAM_MUSIC);
this.setDataSource(location);
this.setOnPreparedListener(new OnPreparedListener()
{
#Override
public void onPrepared(MediaPlayer mp)
{
setPlay();
}
});
this.prepareAsync();
}
catch (Exception e)
{
Log.d(TAG, "Exception", e);
}
}
public void setPlay()
{
Log.d(TAG, "setPlay");
this.start();
this.setProgressHandler(this.listener);
}
and where the calls are being made
public void initializeFromResume()
{
PersonalPrefs prefs = new PersonalPrefs(getActivity());
if (!prefs.isPLaying())
{
return;
}
else
{
playNewAudio(prefs.getURL());
// ((ActivityMain) getActivity()).getMediaManager().setSeek(prefs.getSeek());
}
}
private void playNewAudio(String url)
{
getMediaManager().setAudioURLAndPLay(getActivity(), url)
mediaState = MediaState.playing;
initializeSeekBar();
getMediaManager().setOnCompletionListener(this);
mediaController.togglePlayButton(mediaState);
}
I figured it out and will post the answer to anyone who has similar troubles in the future.
Just need to run a post delayed. Not exactly amazing, but it works.
h.postDelayed(new Runnable()
{
#Override
public void run()
{
PersonalPrefs prefs = new PersonalPrefs(getActivity());
playNewAudio(prefs.getURL());
}
}, 1000);

Android ListView MediaPlayer

I am trying to loop through my listView and hightlight the textviews and play the text being highlighted.
Problem is all the audio files play at a same time and highlight and unhighlight at a same time as well. and the whole app seems to feeeze while the audio gets played..
I know I have to use Threads maybe but still not sure how to this.
Here is my code
//This is how I call it
Player plOptions = new Player(sound,tf);
plOptions.start();
// this is the thread
private class Player extends Thread
{
String sPlayerPath;
TextView tf;
public Player(String sPath_, TextView tv_) {
sPlayerPath = sPath_;
tf= tv_;
}
#Override
public void run()
{
final MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(sPlayerPath);
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
TextHighLight(tf);
}
});
mp.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
TextUnHighLight(tf);
}
});
}
}
You should provide the code in onListItemSelected to answer the question why all items are being played,highlighted at the same time.
But what I understand from what you did provide, is that you dont need a thread. just use prepareAsync() instead of prepare(), android will handle the threading for you.This will greatly simplify your code.
Initialize your media player when in create method.Implement onCompletionListener event and provide the method to play the next song.In the next method reset the media player then it will work perfectly.
for eg and some imp note:
If you are clicking in the listview and the media file plays in another activity it will play multiple songs. for eg ActivityA contains ur list and ActivityB contains mediacontrols. In this case it will play multiple song to avoid this situation u must use service

Categories