Hello there, i have just created a basic android app which plays different musics on button tap..
The app just worked fine for the first couple of seconds but when i just keep on tapping and tapping , at some point it stops playing the music and just crashed...
I am unable to figure out what the problem is ..Please help me make it work..
Thanks.
Here is my code :-
public class MainActivity extends AppCompatActivity {
MediaPlayer mediaPlayer;
public void PlayMusic(View view)
{
int ID = view.getId();
String NameID = view.getResources().getResourceEntryName(ID);
int sound= getResources().getIdentifier(NameID,"raw","com.example.pickachu.mypatatap");
mediaPlayer = MediaPlayer.create(this,sound);
mediaPlayer.start();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
The sound is not playing after multiple taps because you must be getting IllegalStateException because you are not releasing the Mediaplayer object and Mediaplayer Lifecycles are not managed properly when you tap multiple times.
You can use setOnCompletionListener(MediaPlayer.OnCompletionListener listener) to release mediaPlayer after completion of sound as:
mediaPlayer = MediaPlayer.create(this,sound);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mp.reset();
mp.release();
mediaplayer = null;
}
});
mediaPlayer.start();
pass uri instead string
mediaPlayer= MediaPlayer.create(this, Uri.parse(Environment.getExternalStorageDirectory().getPath()+ "/Music/music.mp3"));
mediaPlayer.setLooping(true);
mpintro.start();
Related
The code I have so far is:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void SoundPlayer(View view) {
MediaPlayer soundMediaPlayer1 = MediaPlayer.create(this, R.raw.gun_sound);
soundMediaPlayer1.start();
}
public void DogSound(View view) {
MediaPlayer soundMediaPlayer2 = MediaPlayer.create(this, R.raw.cat_sound);
soundMediaPlayer2.start();
}
public void NewSound(View view) {
MediaPlayer soundMediaPlayer3 = MediaPlayer.create(this, R.raw.new_sound);
soundMediaPlayer3.start();
}
public void LaughTrack(View view) {
MediaPlayer soundMediaPlayer12 = MediaPlayer.create(this, R.raw.laugh_sound);
soundMediaPlayer12.start();
}
public void HorseSound(View view) {
MediaPlayer soundMediaPlayer4 = MediaPlayer.create(this, R.raw.horse_sound);
soundMediaPlayer4.start();
}
public void HeySound(View view) {
MediaPlayer soundMediaPlayer5 = MediaPlayer.create(this, R.raw.hey_sound);
soundMediaPlayer5.start();
}
private void Stop() {
startActivity(new Intent(this, MainActivity.class));
}
public void stop(View view) {
Stop();
}
}
The problem I face is that all the sounds overlaps and plays. I have a STOP button set up, but have no idea has to how to make it stops the media. Any feedback is helpful.
Thank you.
First of all, I would use only one Instance of the MediaPlayer. You can then use mediaPlayer.stop() to stop a sound and prepare the next one.
See the state diagram on https://developer.android.com/reference/android/media/MediaPlayer.html
1) Make the object of MediaPlayer in onCreate method don't create in every new method.
2) Before playing the music in another method first use stop() function to stop current playing sound(like mediaPlayer.stop(); ) then play the sound by start().
I am a beginner. So far I have created an app that counts. I created a button which displays the text but it should also play the whistle sound.
I displayed my java code below.
/**
* Displays the winning team.
*/
public void displayForWinner(String score) {
TextView scoreView = (TextView) findViewById(R.id.textView);
scoreView.setText(String.valueOf(score));
}
To play a short sound effect, create an empty MediaPlayer object:
MediaPlayer mMediaPlayer;
Next, assign a MediaPlayer to it using your context, and sound (Place your sound file under app/src/main/res/raw/) :
mMediaPlayer = MediaPlayer.create(MyActivity.this,R.raw.whistle_sound);
Finally, when you're ready to play your sound, call:
mMediaPlayer.start();
-EDIT-
To make the text change after your sound has completed, use this:
public class MyActivity extends Activity {
MediaPlayer mMediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
mMediaPlayer = MediaPlayer.create(MyActivity.this,R.raw.whistle_sound);
}
public void displayForWinner(String score) {
final String FinalScore = score;
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
TextView scoreView = (TextView) findViewById(R.id.textView);
scoreView.setText(String.valueOf(FinalScore));
}
});
}
}
Also, consider trimming your audio clip to reduce delay.
I want to get paths for videos from server and then play them using a surfaceView.
I can do it if I use another activity class to play videos after received paths. But I am trying to play in the same activity.
I am getting paths in the background using an AsyncTask. This AsyncTask is executed in onCreate() method. After got paths in onPostExecute(), I want to play videos in SurfaceView.
But SurfaceView is created before I receive those paths. So I tried to use SurfaceView's addCallback() in onPostExecute(). But it looks not possible.
How I do this? Using SurfaceView, is there no way to play videos on the same activity after got resource paths from server?
Oh yeah, I found a solution. I will post it here so that it will help to someone like me. Because everywhere I check a solution for this, didn't followed this way.
Your activity class:
public class PlayActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private SurfaceHolder sh;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//getResource is your AsyncTask
//I will not post it here because it is not the problem we had
getResource _gR = new attemptGetStream(p1, p2);
_gR.execute();
//initiate components
SurfaceView sV = (SurfaceView) findViewById(R.id.main);
assert null != sV : "Surface is null";
sV.getHolder().addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder sHolder) {
//this is the solution.
//only assign holder to a variable but don’t initiate MediaPlayer here
//because we don’t have resource paths yet
//we will initiate MediaPlayer in postExecute method and
//attach to this holder from there
sh = sHolder;
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
log("Surface changed");
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
log("Surface destroyed");
}
//this is our method called from onPostExecute() in our getResource AsyncTask
public void play(String path){
//here initiate the MediaPlayer and assign dataSource
//attach the player to sh(which is our surface holder
try{
MediaPlayer mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDisplay(sh);//sh is the surface holder
mMediaPlayer.setDataSource(getApplicationContext(), path);//path is what we got from onPostExecute method in AsyncTask
mMediaPlayer.prepareAsync();//i use prepareAsync method here so it will not hog the phone
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mP.start();
}
});
}catch (Exception e){//use exception types as you like
e.printStackTrace();
}
}
}
I tried most of options avialable on stackoverflow, could you please help me!
I have a button which plays MediaPlayer instance when clicked, but the problem if I click double-click or clicked during playing media it will play two times even i set the button.setEnable(false) and button.setClickable(false), below is the code in Main.java, and I have set in xml android:onClick="playMedia"
MediaPlayer playMedia;
private void playGeneric(MediaPlayer mp, int name, Button button) {
button.setEnabled(false);
button.setClickable(false);
mp = MediaPlayer.create(this, name);
mp.start();
while (mp.isPlaying()) {
}
mp.stop();
mp.release();
mp = null;
button.setEnabled(false);
button.setClickable(false);
}
// play the Media
public void playMedia(View button) {
playGeneric(Media, R.raw.Media, (Button) findViewById(R.id.button1));
}
thanks a lot
1- You should have a single (preferably static) MediaPlayer instance per your activity/service
2- This loop while (mp.isPlaying()) is extremely bad practice, you just need to listen to the appropriate event
3- Before creating a new MediaPlayer instance you have to check that if the current one is not null then stop and release it
To solve your code you can do the following:
1- Let your class implements OnCompletionListener and override the method onCompletion(MediaPlayer mp) to be notified when the MediaPlayer finished and clean the resources (but you need to clean it as well when your activity/service get destroyed)
2-
static MediaPlayer playMedia;
private void playGeneric(MediaPlayer mp, int name, Button button) {
button.setEnabled(false);
button.setClickable(false);
if(mp !=null){
mp.stop();
mp.release();
}
mp = MediaPlayer.create(this, name);
mp.start();
}
#Override
public void onCompletion(MediaPlayer mp) {
mp.release();
playMedia = null;
button.setEnabled(true);
button.setClickable(true);
}
I have some videos using videoView. everything is running well, but when the video is finished nothing happens, the phone stay on dark screen waiting to pres play again or the blink back on the phone.
I want that when videos is finished, go back to the activity before. this is my code.
public class chapterone extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.videoplayer);
VideoView videoView =
(VideoView)this.findViewById(R.id.videoView);
MediaController mc = new MediaController(this);
videoView.setMediaController(mc);
videoView.setVideoURI(Uri.parse(
"http://video.com/episode/" +
"cotton1.mp4"));
/* videoView.setVideoPath(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES) +
"/movie.mp4");
*/
videoView.requestFocus();
videoView.start();
}
}
the URL is only an example.
videoView.setOnCompletionListener(completionListener);
OnCompletionListener completionListener=new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mp.stop();
chapterone.this.finish();
}
};
i hope can help i found this, but i am not sure if is correct uset it
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
#Override
public void onCompletion(MediaPlayer mp){
// invoke your activity here
Intent i = new Intent(chapterone.this, videoserie.class);
startActivity(i);
}
});