This is just a simple android app I am developing, it's meant to play a sound every time you click the button....it works when I click the button at a slow pace, but always crashes if I click the button at a fast pace due to a runtime error - NullPointerException!.....I don't know what I am doing wrong.
public class OSDC_Mini_ProjectActivity extends Activity implements MediaPlayer.OnCompletionListener {
private ImageButton play,pause,stop;
private MediaPlayer mp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
play = (ImageButton)findViewById(R.id.play);
pause = (ImageButton)findViewById(R.id.pause);
stop = (ImageButton)findViewById(R.id.stop);
play.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
play();
}
});
pause.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
pause();
}
});
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
stop();
}
});
setup();
}
#Override
public void onDestroy() {
super.onDestroy();
if (stop.isEnabled()) {
mp.stop();
}
}
public void onCompletion(MediaPlayer mp) {
stop();
}
private void play() {
mp.start();
play.setEnabled(false);
pause.setEnabled(true);
stop.setEnabled(true);
}
private void stop() {
mp.stop();
pause.setEnabled(false);
stop.setEnabled(false);
try {
mp.prepare();
mp.seekTo(0);
play.setEnabled(true);
}
catch (Throwable t) {
error(t);
}
}
private void pause() {
mp.pause();
play.setEnabled(true);
pause.setEnabled(false);
stop.setEnabled(true);
}
private void loadClip() {
try {
mp=MediaPlayer.create(this, R.raw.test);
mp.setOnCompletionListener(this);
}
catch (Throwable t) {
error(t);
}
}
private void setup() {
loadClip();
play.setEnabled(true);
pause.setEnabled(false);
stop.setEnabled(false);
}
private void error(Throwable t) {
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder
.setTitle("報錯啦!")
.setMessage(t.toString())
.setPositiveButton("確定", null)
.show();
}
}
Add null check in every method. Also start media play only if mp is currently not playing anything
Related
I tried to make a small music file reader project , I used the code below sow i can play the music and pause it but once I stop it and click on a button to play it from the begining the music is not played
I used the code below and I don t know how to solve that problem :
final MediaPlayer mp=new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mp.setDataSource(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) +String.valueOf("/myfile.mp3"));
} catch (IOException e) {
e.printStackTrace();
}
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!mp.isPlaying()){
try{
mp.prepare();
}catch(Exception e){e.printStackTrace();}
mp.start();
btn1.setText("pause");
}else{
mp.pause();
btn1.setText("play");
}
}
});
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp.stop();
mp.reset();
btn2.setVisibility(btn2.INVISIBLE);
btn1.setText("play");
}
});
}
Option 1 : you can go back from the beginning with mp.seekTo(0); after calling mp.stop(); also remove the mp.reset(); like this:
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp.stop();
mp.seekTo(0);
btn2.setVisibility(btn2.INVISIBLE);
btn1.setText("play");
}
});
Option 2 : When calling mp.reset(); you are restoring the object into it's Idle state that's why the music cannot be played. You have to transfer the object into the Initialized state by calling mp.setResource(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) +String.valueOf("/myfile.mp3")); and then mp.prepare(); like this:
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp.stop();
mp.reset();
btn2.setResource(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) +String.valueOf("/myfile.mp3"));
mp.prepare();
btn1.setText("play");
}
});
I suggest that you go for Option 1
I hope this helps. I haven't done any android programming but I know some Java and read the details about the MediaPlayer right here.
From the state machine of the documentation, it seems that you have to use
mp.stop()
mp.prepare()
mp.start()
This would complete the state machine.
Add these lines of code in your btn2 onClick
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp.stop();
mp.reset();
btn2.setVisibility(btn2.INVISIBLE);
btn1.setText("play");
mp=new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mp.setDataSource(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) +String.valueOf("/myfile.mp3"));
} catch (IOException e) {
e.printStackTrace();
}
}
});
It will repair the media player to play again after you reset it.
This is my code implemented as you desired except I am loading music from RAW folder
public class MainActivity extends AppCompatActivity {
private MediaPlayer mediaPlayer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button stopButton = (Button) findViewById(R.id.button_stop);
final Button playButton = (Button) findViewById(R.id.button_play);
mediaPlayer = MediaPlayer.create(getApplicationContext(),R.raw.file);
playButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
playButton.setText("pause");
stopButton.setVisibility(View.VISIBLE);
}else{
mediaPlayer.pause();
playButton.setText("play");
}
}
});
stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mediaPlayer.stop();
mediaPlayer.reset();
stopButton.setVisibility(INVISIBLE);
playButton.setText("play");
mediaPlayer = MediaPlayer.create(getApplicationContext(),R.raw.file);
}
});
}
}
How do I make this to play only the sound I selected until I press another ImageButton so they don't sound over each other.
public class MainActivity extends AppCompatActivity {
MediaPlayer leaf,water,fire,wind;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
leaf=MediaPlayer.create(MainActivity.this,R.raw.forest);
water=MediaPlayer.create(MainActivity.this,R.raw.sea);
fire=MediaPlayer.create(MainActivity.this,R.raw.fire);
wind=MediaPlayer.create(MainActivity.this,R.raw.wind);
}
public void playleaf(View view ) {
leaf.setLooping(true);
leaf.start();
}
public void playwater(View view ) {
water.setLooping(true);
water.start();
water.start();
}
public void playfire(View view ) {
fire.setLooping(true);
fire.start();
}
public void playwind(View view ) {
wind.setLooping(true);
wind.start();
}
}
Do something like this.
MediaPlayer player;
public void playleaf(View view) {
stopMedia();
player = new MediaPlayer();
player.setDataSource(R.raw.leaf);
player.prepareAsync();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
player.setLooping(true);
player.start();
}
});
}
public void playwater(View view) {
stopMedia();
player = new MediaPlayer();
player.setDataSource(R.raw.leaf);
player.prepareAsync();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
player.setLooping(true);
player.start();
}
});
}
private void stopMedia() {
if (player != null) {
player.release();
player = null;
}
}
public void playfire(View view) {
stopMedia();
player = new MediaPlayer();
player.setDataSource(R.raw.leaf);
player.prepareAsync();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
player.setLooping(true);
player.start();
}
});
}
public void playwind(View view) {
stopMedia();
player = new MediaPlayer();
player.setDataSource(R.raw.leaf);
player.prepareAsync();
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
player.setLooping(true);
player.start();
}
});
}
I was having some bugs with playing a music in my app. It wont stop playing even if I exit the app. It will only stop if I hit pause or terminate the app. Here's my code for music. What should I do code to stop it.
public void play_brain(View g){
final MediaPlayer brainMP = new MediaPlayer();
try {
brainMP.setDataSource("https://firebasestorage.googleapis.com/v0/b/capstone-katugna-001.appspot.com/o/meditation%20music%201%20minute%20peaceful%20music%201%20minute%20mindfulness%20meditation%201%20minute%20relax%20music%201.mp3?alt=media&token=f34fe7c7-54f1-4645-88cf-5e7a21f401d8");
brainMP.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
brainMP.prepare();
} catch (IOException e) {
e.printStackTrace();
}
pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
brainMP.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
mp.pause();
}
});
brainMP.pause();
}
});
}
You can try using this code:
public class MainActivity extends AppCompatActivity {
private MediaPlayer mediaPlayer;
private Button buttonStartPause;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
// Initialize your MediaPlayer object here
Uri myUri = ....; // initialize Uri here
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.prepare();
}
buttonStartPause.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (mediaplayer.isPlaying()) {
mediaplayer.pause();
// here you can set the play icon to your button
} else {
mediaplayer.start();
// here you can set the pause icon to your button
}
}
});
// To capture back button's pression you can override onBackPressed() in your Activity:
#Override
public void onBackPressed() {
if (mediaplayer.isPlaying()) {
mediaplayer.pause();
}
super.onBackPressed();
}
}
Actually i have 2 activities , in the main activity i am displaying all the songs using recycler view and setup an onClickListner on it, and when someone taps on it , it launches a new activity(MediaPlayer Activity) and start playing the song along with media controls like (paly, pause and seekBar).
But when i get back to the main activity and click on a button (which basically takes to the MediaPlayer activity again) all the mediaPlayer and seekBar progress are gone also the (play, pause, next and previous buttons) are not responding to the clicks.
This is from where i am starting the MediaPlayer activity :
#Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
holder.Song.setText(mData.get(position).title);
holder.Artist.setText(mData.get(position).artist);
Glide.with(mcontext).load(mData.get(position).imagePath).
placeholder(R.drawable.unknown_art).into(holder.PhotoId);
holder.Options.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(mcontext, "You clicked on options", Toast.LENGTH_SHORT).show();
}
});
holder.RL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mcontext, MediaPlayerActivity.class);
intent.putExtra("songPosition",position);
mcontext.startActivity(intent);
}
});
These are the codes in the MediaPlayerActivity :
public class MediaPlayerActivity extends AppCompatActivity {
static MediaPlayer mediaPlayer=null;
static int pos=0;
SeekBar seekBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media_player);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Intent intent = getIntent();
pos = intent.getIntExtra("songPosition",pos);
seekBar = (SeekBar)findViewById(R.id.seekBar);
Button next = (Button)findViewById(R.id.button_1);
Button previous = (Button)findViewById(R.id.button_2);
final Button play_pause = (Button)findViewById(R.id.button_3);
final TextView info = (TextView)findViewById(R.id.songInfo);
info.setText(VerticalRecyclerViewAdapter.mData.get(pos).title);
if(mediaPlayer!=null&&mediaPlayer.isPlaying()){
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
}
playMedia(pos);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
playMedia(++pos);
info.setText(VerticalRecyclerViewAdapter.mData.get(pos).title);
}catch (IndexOutOfBoundsException e){
Toast.makeText(MediaPlayerActivity.this,"Already the last song!!!",Toast.LENGTH_SHORT).show();
}
}
});
previous.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
mediaPlayer.stop();
mediaPlayer.reset();
mediaPlayer.release();
playMedia(--pos);
info.setText(VerticalRecyclerViewAdapter.mData.get(pos).title);
}catch (IndexOutOfBoundsException e){
Toast.makeText(MediaPlayerActivity.this,"Already the first song!!!",Toast.LENGTH_SHORT).show();
}
}
});
play_pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mediaPlayer!=null&&mediaPlayer.isPlaying()){
play_pause.setText(R.string.mp_play);
mediaPlayer.pause();
}
else{
play_pause.setText(R.string.mp_Pause);
mediaPlayer.start();
}
}
});
}
public void playMedia(int pos){
try {
mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(VerticalRecyclerViewAdapter.mData.get(pos).songPath);
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
seekBar.setProgress(0);
seekBar.setMax(mp.getDuration());
mediaPlayer.start();
}
});
} catch (IOException e) {
e.printStackTrace();
}
setSeekbarProgress();
onSeekbarChange();
playNext();
}
public void playNext(){
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
try {
mediaPlayer.release();
playMedia(++MediaPlayerActivity.pos);
}catch (IndexOutOfBoundsException e){
Toast.makeText(MediaPlayerActivity.this, "Already the last song", Toast.LENGTH_SHORT).show();
}
}
});
}
public void setSeekbarProgress(){
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
try {
if (mediaPlayer != null) {
seekBar.setProgress(mediaPlayer.getCurrentPosition());
}
}
catch (RuntimeException e){
Log.i("CRASH",""+e.getMessage());
}
}
},0,1000);
}
public void onSeekbarChange(){
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
if(b) {
mediaPlayer.seekTo(i);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
And this is where from i wanted to go back to the MediaPlayer Activity (on button click ) :
mFloatingToolbar.setClickListener(new FloatingToolbar.ItemClickListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.music:
Intent intent = new Intent(getActivity(),MediaPlayerActivity.class);
startActivity(intent);
break;
case R.id.pause :
break;
case R.id.next :
Toast.makeText(getContext(), "Next", Toast.LENGTH_SHORT).show();
break;
default:
Toast.makeText(getContext(), "Back", Toast.LENGTH_SHORT).show();
verticalRecyclerViewAdapter.notifyDataSetChanged();
break;
}
}
#Override
public void onItemLongClick(MenuItem item) {
}
});
I have a problem with pausing a MediaPlayer. When I play it, and click the pause button it's working, but when it's playing longer than 10 seconds it's not pausing.
Here is my code:
private TextView tvState;
private MediaPlayer mediaPlayer = new MediaPlayer();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_player);
ImageButton btnPlay = (ImageButton) findViewById(R.id.btnPlay);
ImageButton btnPause = (ImageButton) findViewById(R.id.btnPause);
TextView tvAuthor = (TextView) findViewById(R.id.tvAuthor);
TextView tvSong = (TextView) findViewById(R.id.tvSong);
tvState = (TextView) findViewById(R.id.tvState);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
String json = bundle.getString("songModel");
final SongModel songModel = new Gson().fromJson(json, SongModel.class);
tvAuthor.setText(songModel.getAuthor());
tvSong.setText(songModel.getName());
PrepareMediaPlayer(songModel);
}
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
} else if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
if (mediaPlayer.isPlaying()) {
tvState.setText("Played");
}
}
});
btnPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
}
if (!mediaPlayer.isPlaying()) {
tvState.setText("Paused");
}
}
});
}
public void PrepareMediaPlayer(SongModel song) {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(song.getLink());
} catch (IOException e) {
e.printStackTrace();
}
mediaPlayer.prepareAsync();
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
if (!mp.isPlaying()) {
mp.start();
}
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
});
}
My OS: Android 4.0.4, API 15