I am currently building an app that has a button that once the user clicks the button, media recorder is initiated and records for five seconds and then stops. This recording is then loaded into media player which the user can then playback by pressing the button once again. Here is my code so far:
OUTPUT_FILE = Environment.getExternalStorageDirectory() + "/tempRecord.3gpp";
audioSample1 = (Button) findViewById(R.id.sample1);
// button background drawable is grey_button
final Drawable buttonBackground = audioSample1.getBackground();
audioSample1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (audioSample1.getBackground().equals(buttonBackground)) {
Log.d("Button", "Start Record");
try {
startRecord();
} catch (Exception e) {
e.printStackTrace();
}
}
else if (audioSample1.getBackground() != null) {
Log.d("Button", "Start Playback");
try {
startPlayback();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
public void startRecord() throws Exception {
if (recorder != null) {
recorder.release();
}
File fileOut = new File(OUTPUT_FILE);
if (fileOut != null) {
fileOut.delete();
}
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(OUTPUT_FILE);
recorder.setAudioSamplingRate(44100);
recorder.setMaxDuration(5000);
recorder.prepare();
recorder.start();
audioSample1.setBackgroundResource(R.drawable.red_button);
recorder.setOnInfoListener(new OnInfoListener() {
public void onInfo(MediaRecorder recorder, int timer, int extra) {
if (timer == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
Log.v("Recorder", "Maximum Duration Reached");
recorder.stop();
audioSample1.setBackgroundResource(R.drawable.green_button);
}
}
});
}
public void startPlayback() throws Exception {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(OUTPUT_FILE);
mediaPlayer.prepare();
mediaPlayer.start();
}
}
Basically the issue I am having is the onClick method detects the state of the button and depending on the background drawable it either start recording or starts playback. If the button is in its first state drawable.grey_button the media recorder will start recording and change the background drawable to a red_button and once it is finished recording it will change to a green_button for playback. This code works fine generally but if the user presses the button while the media recorder is recording the media player will be unable to create a media player. I know the problem is because I am calling audioSample1.getBackground() != null but I can't figure out any other way to detect the backgroundResources that has been changed
Please can someone give me some advice on how to detect each backgroundResource?
Also once the Media Player is loaded with a audio sample I now want the same button to be able to implement an onTouchListener and gesture detector. Is this possible and how do you implement such a method?
Thanks
you approach is really tedious, but this is it getBackgroundDrawable(); use this instead getBackground() Returns the drawable set for the button.
but you can also use the string for the button, that might be simple...
EDIT 1 this approach is better
Button b = new Button(this); // now this is your button
b.setText("Play"); //the button has a name as 'play' when its not clicked
// and in your case is drawable.grey_button
b.setBackgroundResource(R.drawable.grey_button);
b.setOnClickListener(new OnClickListener() {//setting your onclick
#Override
public void onClick(View arg0) {
Button bb = (Button) arg0; // getting your clicked button
if(bb.getText().toString().equals("play")){ // checking if the text on your bb is play
//start your playback and change the background
bb.setText("pause"); // setting the text to pause
}else if(bb.getText().toString().equals("pause")){
//pause playback and change your background
bb.setText("play");
}else{
//stop play and reset mediaplayer and change your background..
// this is not even captured
}
}
});
this approach is better.. let me know if it helps
Related
This is my code, I want to keep music playing when the app is in background. And I want to be able to pause it when I re-open the app. The music should play in the background, but for some reason media player returns null pointer when I re-open it. So, when I pause it, it crashes.
public void play(View view) {
if (status) {
status = false;
requestRecordAudioPermission();//audio permission
startPlay();//start mediaplayer
} else {
status = true;
mediaPlayer.pause();
}
}
public void startPlay() {
mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(URL_LINK);
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(HomeActivity.this, "CAN'T PLAY!",Toast.LENGTH_LONG).show();
}
mediaPlayer.start();
}
Why Media Player returns null after pressing the home button and reopening the app?
Thanks for help
If you are streaming audio from an url then try to load the Media Player asynchronously.
String url = "YOUR_URL";
MediaPlayer myMediaPlayer = new MediaPlayer();
myMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
myMediaPlayer.setDataSource(url);
myMediaPlayer.prepareAsync();
} catch (IOException e) {
Toast.makeText(this, "mp3 not found", Toast.LENGTH_SHORT).show();
}
myMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer player) {
player.start();
}
});
I want to send view to another class with parameters
for example :
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
EventHandlerClass.startMediaPlayer(view, soundID);
}
});
you can see this line where i'm sending View
EventHandlerClass.startMediaPlayer(view, soundID);
Service Class
public static void startMediaPlayer(View view, Integer soundID){
try {
// Check if the sound id was set correctly
if (soundID != null){
// Check if the MediaPlayer maybe is in use
// If so the MediaPlayer will be reset
if (mp != null && mp.isPlaying()){
mp.stop();
mp = null;
view.setVisibility(View.INVISIBLE);
}
else{
mp = MediaPlayer.create(view.getContext(), soundID);
mp.start();
}
// Create and start the MediaPlayer on the given sound id
}
} catch (Exception e){
// Log error if process failed
Log.e(LOG_TAG, "Failed to start the MediaPlayer: " + e.getMessage());
}
}
It only sends when you press the button , I want to send the offer but without pressing the button how?
I've two radio buttons in a radiogroup and on selection of one radio button it will start music and stop the other sound and on selection of other it will start the next song and stop the previous song. The problem is I'm unable to stop the music. The song keeps on playing in the background. I'm using dialog box to show radio buttons and getting the input from user on button'c click.
The length of each song is greater than 3 minutes.
I've searched the internet and tried multiples solution but no solution is working. Below is the code I've used:
btnDone.setOnClickListener(view.onClickListener)
{
#Override
public void onClick(View view)
{
boolean checked = radioButton1.isChecked();
boolean checked1 = radioButton2.isChecked();
MediaPlayer mediaPlayer = MediaPlayer.create(this,R.raw.song1);
MediaPlayer mediaPlayer2 = MediaPlayer.create(this,R.raw.song2);
if(checked && !checked1)
{
mediaPlayer.start();
}else if(checked1 && !checked)
{
try{
if(mediaPlayer !=null)
{
if(mediaPlayer.isPlaying())
{mediaPlayer.stop;
mediaPlayer.release;
mediaPlayer = null;
}
}
}
catch(Exception e)
{e.printStackTrace(); }
}
}
}
IMO your else if(checked1 && !checked1) condition not working properly so try else if(checked1 && !checked) try below code
btnDone.setOnClickListener(view.onClickListener)
{
#Override
public void onClick(View view)
{
boolean checked = radioButton1.isChecked();
boolean checked1 = radioButton2.isChecked();
MediaPlayer mediaPlayer = MediaPlayer.create(this,R.raw.song1);
MediaPlayer mediaPlayer2 = MediaPlayer.create(this,R.raw.song2);
if(checked && !checked1)
{
mediaPlayer.start();
}else if(checked1 && !checked) //change here
{
try{
if(mediaPlayer !=null)
{
if(mediaPlayer.isPlaying())
{mediaPlayer.stop(); // also change here
mediaPlayer.release(); //change here
mediaPlayer = null;
}
}
}
catch(Exception e)
{e.printStackTrace(); }
}
}
}
I am building an app which plays several videos, and I have two different user scenarios :
Scenario 1. While video 'A' is playing, if user clicks next button, then it stops and play the next video 'B'.
Scenario 2. Play video 'A', and if it's done, user clicks next button and it plays video 'B'.
For the first scenario, I used mediaPlayer.isPlaying() method to detect if it is in Started state and it works fine. However, if I use the same code for the second scenario, isPlaying() throws IllegalStateException.
Here's my code for playing videos :
private void playVideos(SurfaceHolder holder) {
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDisplay(holder);
Uri uri = Uri.parse("android.resource://" + getPackageName() + "/" + video_files[mCounter]);
mediaPlayer.setDataSource(this, uri);
mediaPlayer.prepare();
mediaPlayer.start();
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (mCounter <= 8) {
onVideoCompletion(mediaPlayer);
} else {
mediaPlayer.stop();
mediaPlayer.release();
}
}
});
} catch (IOException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalStateException e) {
}
}
Also, here's my button listener to play next video :
nextBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(mediaPlayer != null) {
if(mediaPlayer.isPlaying()) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
mCounter += 1;
if (mCounter <= 8) {
playVideos(holder);
}
}
});
One way that I tried to hack this issue was using a boolean variable instead of isPlaying() method. For example,
boolean mIsPlaying = false;
...
// in button listener
if(mIsPlaying) {
mediaPlayer.stop();
mediaPlayer.release();
}
...
// in playVideos() function
mediaPlayer.start();
mIsPlaying = true;
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (mCounter <= 8) {
onVideoCompletion(mediaPlayer);
} else {
mediaPlayer.stop();
mediaPlayer.release();
}
}
});
That works for my both of scenario, but I'm not sure if it's the correct way to do it. Isn't there any way to detect whether mediaPlayer is in Stopped state?
I took a look at Google's Documentation which you can find here. You can only know if the player isPlaying(); or isLooping(); ... So no, there is not an "easy" or "short" way to achieve what you want. Hope it helped.
I make one app in android, my problem is that when i play the stream it is playing well but when i click on stop button and then click on play button then song is not playing, how to do that ? please help me if anybody know. below is code that i write :-
// method for play stream after stop it.
public void startradio(View v) {
try{
if(mp.isPlaying()){
return;
}
mp.start();
} catch(IllegalStateException ex){
ex.printStackTrace();
}
}
// method for stop stream.
public void stopradio(View v) {
if(mp.isPlaying()){
mp.stop();
}
mp.release();
}
#Eluvatar's comment is pretty close but no cigar.
If you do that, your app still would be in the wrong state, and would need to call prepare() before calling start() again. You should look at the event cycle for MediaPlayer.
In other words a possible change would be
// method for play stream after stop it.
public void startradio(View v) {
try{
if(mp.isPlaying()){
return;
}
mp.prepare();
mp.start();
} catch(IllegalStateException ex){
ex.printStackTrace();
}
}
// method for stop stream.
public void stopradio(View v) {
if(mp.isPlaying()){
mp.stop();
}
}