Timer NullPointerException - android

I received a NullPointerException to one of the last lines of an activity regarding a Timer. What happens in the activity is 5 .ogg files is played one after the other. The error points to the the last TimerTask. I post the whole code, please do not get scared, there are many repetitions in the code. I don't know what did the user before the error, it doesn't emerge on my phone.
java.lang.NullPointerException
at com.b2creativedesigns.eyetest.AmslerGrid1$5.run(AmslerGrid1.java:343)
at java.util.Timer$TimerImpl.run(Timer.java:284)
Partial code:
public class AmslerGrid1 extends Activity {
Button btnFinish;
Button btnMute;
ImageView imgAG;
TextView tvResult;
MediaPlayer help1, help2, help3, help4, help5;
int paused=0;
long del=250;
int intentcounter=0;
int p=10;
int length;
private Timer timer;
boolean out;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.amslergrid1);
out = false;
imgAG = (ImageView)findViewById(R.id.imgAG);
tvResult = (TextView)findViewById(R.id.tvAGResult);
btnFinish = (Button)findViewById(R.id.btnAGResult);
btnMute = (Button)findViewById(R.id.btnAGmute);
help1 = MediaPlayer.create(AmslerGrid1.this, R.raw.ag1);
help2 = MediaPlayer.create(AmslerGrid1.this, R.raw.ag2);
help3 = MediaPlayer.create(AmslerGrid1.this, R.raw.ag3);
help4 = MediaPlayer.create(AmslerGrid1.this, R.raw.ag4);
help5 = MediaPlayer.create(AmslerGrid1.this, R.raw.ag5);
timer = new Timer("AmslerGridTimer");
timer.schedule(TimerHelp1, 2000);
help1.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(final MediaPlayer cim) {
if (paused == 0)
{
}
help1.release();help1=null;
timer = new Timer("AmslerGridTimer");
timer.schedule(TimerHelp2, 1500);
}
});
help2.setOnCompletionListener(new OnCompletionListener() {...
help3.setOnCompletionListener(new OnCompletionListener() {...
help4.setOnCompletionListener(new OnCompletionListener() {...
help5.setOnCompletionListener(new OnCompletionListener() {...
#Override
public void onCompletion(final MediaPlayer cim) {
if (paused == 0)
{
}
help5.release();help5=null;
}
});
}
#Override
protected void onPause() {
super.onPause();
if (help1 != null)
{
help1.pause();
length=help1.getCurrentPosition();
}
...
else if (help5 != null)
{
help5.pause();
length=help5.getCurrentPosition();
}
p=0;
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (help1 != null)
{
if (p==0){
help1.seekTo(length); help1.start();
help1.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(final MediaPlayer cim) {
help1.release();help1=null;
}
});
paused=0;p=1;
}
}
...
else if (help5 != null)
{
if (p==0){
help5.seekTo(length); help5.start();
help5.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(final MediaPlayer cim) {
help5.release();help5=null;
}
});
paused=0;p=1;
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
timer.cancel();
timer = null;
}
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)
{
out = true;
if (help1 != null)
{
help1.stop();
}
else if (help2 != null)
{
help2.stop();
}
else if (help3 != null)
{
help3.stop();
}
else if (help4 != null)
{
help4.stop();
}
else if (help5 != null)
{
help5.stop();
}
Intent intentstart = new Intent(AmslerGrid1.this, MainActivity.class);
intentstart.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intentstart);
}
return super.onKeyDown(keyCode, event);
}
private TimerTask TimerHelp1 = new TimerTask() {
#Override
public void run() {
if (!out) help1.start();p=1;
}
};
private TimerTask TimerHelp2 = new TimerTask() {
#Override
public void run() {
if (!out) help2.start();p=1;
}
};
private TimerTask TimerHelp3 = new TimerTask() {
#Override
public void run() {
if (!out) help3.start();p=1;
}
};
private TimerTask TimerHelp4 = new TimerTask() {
#Override
public void run() {
if (!out) help4.start();p=1;
}
};
private TimerTask TimerHelp5 = new TimerTask() {
#Override
public void run() {
if (!out) help5.start();p=1; //error line. Maybe out is null?
}
};
}

Related

media player in recyclerview play at the same

I'm using media player in recycler view and the problem is when different item's play buttons are clicked they all play at the same time. How can I stop the previous one and start the new one?
public void onBindViewHolder(#NonNull MyAdapter.ViewHolder viewHolder, int position) {
final MediaPlayer mediaPlayer = new MediaPlayer();
try {
mediaPlayer.setDataSource(item.get(position).getAudio());
mediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
viewHolder.play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
viewHolder.play.setImageResource(R.drawable.play);
} else {
mediaPlayer.start();
viewHolder.play.setImageResource(R.drawable.pause);
}
This is my recyclerView adapter and you must put your arraylist in this adapter
public class MyAdapter2 extends RecyclerView.Adapter<MyAdapter2.AudioItemsViewHolder> {
static MediaPlayer mediaPlayer;
Activity activity;
private final ArrayList<GroupItems> audioItems;//change it() to your items
private int currentPlayingPosition;
private final SeekBarUpdater seekBarUpdater;
private AudioItemsViewHolder playingHolder;
public MyAdapter2(Activity activity, ArrayList<GroupItems> items_pro) {
this.audioItems = items_pro;
this.currentPlayingPosition = -1;
seekBarUpdater = new SeekBarUpdater();
this.activity = activity;
}
#Override
public AudioItemsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//put YourItemsLayout;
return new AudioItemsViewHolder(LayoutInflater.from(parent.getContext()).inflate(YourItemsLayout, parent, false));
}
#Override
public void onBindViewHolder(AudioItemsViewHolder holder, int position) {
if (position == currentPlayingPosition) {
playingHolder = holder;
updatePlayingView();
} else {
updateNonPlayingView(holder);
}
}
private void updateNonPlayingView(AudioItemsViewHolder holder) {
holder.sbProgress.removeCallbacks(seekBarUpdater);
holder.sbProgress.setEnabled(false);
holder.sbProgress.setProgress(0);
holder.ivPlayPause.setImageResource(R.drawable.ic_baseline_play_arrow_24);
}
private void updatePlayingView() {
playingHolder.sbProgress.setMax(mediaPlayer.getDuration());
playingHolder.sbProgress.setProgress(mediaPlayer.getCurrentPosition());
playingHolder.sbProgress.setEnabled(true);
if (mediaPlayer.isPlaying()) {
playingHolder.sbProgress.postDelayed(seekBarUpdater, 100);
playingHolder.ivPlayPause.setImageResource(R.drawable.ic_pause);
} else {
playingHolder.sbProgress.removeCallbacks(seekBarUpdater);
playingHolder.ivPlayPause.setImageResource(R.drawable.ic_baseline_play_arrow_24);
}
}
private class SeekBarUpdater implements Runnable {
#Override
public void run() {
if (null != playingHolder && null != mediaPlayer) {
playingHolder.sbProgress.setProgress(mediaPlayer.getCurrentPosition());
playingHolder.sbProgress.postDelayed(this, 100);
}
}
}
#Override
public int getItemCount() {
return audioItems.size();
}
class AudioItemsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, SeekBar.OnSeekBarChangeListener {
SeekBar sbProgress;
ImageView ivPlayPause;
AudioItemsViewHolder(View itemView) {
super(itemView);
ivPlayPause = itemView.findViewById(R.id.sound_btn);
ivPlayPause.setOnClickListener(this);
sbProgress = itemView.findViewById(R.id.seekBar);
sbProgress.setOnSeekBarChangeListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.seekBar:
break;
case R.id.sound_btn: {
if (getAdapterPosition() == currentPlayingPosition) {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
} else {
if (mediaPlayer != null)
mediaPlayer.start();
}
} else {
currentPlayingPosition = getAdapterPosition();
if (mediaPlayer != null) {
if (null != playingHolder) {
updateNonPlayingView(playingHolder);
}
mediaPlayer.release();
}
playingHolder = this;
PlaySound(YOUR AUDIO FILE);//put your audio file
}
if (mediaPlayer != null)
updatePlayingView();
}
break;
}
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
mediaPlayer.seekTo(progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
private void PlaySound(File filesound) {
mediaPlayer = MediaPlayer.create(activity, Uri.parse(String.valueOf(filesound)));
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
releaseMediaPlayer();
}
});
mediaPlayer.start();
}
private void releaseMediaPlayer() {
if (null != playingHolder) {
updateNonPlayingView(playingHolder);
}
if (outputFile.exists())
outputFile.delete();
mediaPlayer.release();
mediaPlayer = null;
currentPlayingPosition = -1;
}
}
Here is what you can do
Use a single global MediaPlayer rather than a player per view. Then when you click an item, stop the audio, set a new data source, and restart i.e. don't create a new MediaPlayer instance everytime in onBindViewHolder
MediaPlayer mediaPlayer = new MediaPlayer(); // Somewhere at the top of your code
Now you can use the mediaPlayer directly anywhere and don't assign a new instance to this
2.If for some reason you need to do it like so,
You first have to check if there is a sound that is already playing and if there is, you should stop it when the user decides to start a new sound.
viewholder.play.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mediaplayer.isPlaying ()) {
if (mediaplayer != null){
mediaplayer.stop ();
}
} else {
if (mediaplayer != null) {
mediaplayer.start ();
}
}
}
});
In setOnCompletionListner you release the sound if the user listens to the whole sound clip.
mediaplayer.setOnCompletionListner (new MediaPlayer.OnCompletionListner () {
public void OnCompletion (MediaPlayer mediaplayer) {
mediaplayer.release ();
}
});
I will personally recommend the first solution as your application will take much lesser memory in that case

Android back to main activity from MusicService notification

I'm working on a music player for android and i'm stuck at this problem.
By now i can play a song with musicservice and send it to background, i also display a notification with current playing song.
What i need is to re-open the main activity from the song notification and continue playing the song, it actually starts the desired activity but the music service is re-created and it stops the current playing song.
Here is my code.
MusicService.java
public class MusicService extends Service implements
MediaPlayer.OnPreparedListener,
MediaPlayer.OnErrorListener,
MediaPlayer.OnCompletionListener {
private final IBinder musicBind = new MusicBinder();
//media player
private MediaPlayer player;
//song list
private ArrayList<SongModel> songs;
//current position
private int songPosition;
public MusicService() {
}
public void onCreate() {
//create the service
super.onCreate();
//initialize position
songPosition = 0;
//create player
player = new MediaPlayer();
initMusicPlayer();
}
public void initMusicPlayer() {
//set player properties
player.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(this);
player.setOnCompletionListener(this);
player.setOnErrorListener(this);
}
public void setList(ArrayList<SongModel> theSongs) {
songs = theSongs;
}
public class MusicBinder extends Binder {
public MusicService getService() {
return MusicService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return musicBind;
}
#Override
public boolean onUnbind(Intent intent) {
player.stop();
player.release();
return false;
}
public int getPosition() {
return player.getCurrentPosition();
}
public int getCurrenListPosition() {
return songPosition;
}
public int getDuration() {
return player.getDuration();
}
public boolean isPlaying() {
return player.isPlaying();
}
public void pausePlayer() {
player.pause();
}
public void stopPlayer() {
player.stop();
}
public void seekToPosition(int posn) {
player.seekTo(posn);
}
public void start() {
player.start();
}
public void playSong() {
try {
//play a song
player.reset();
SongModel playSong = songs.get(songPosition);
String trackUrl = playSong.getFileUrl();
player.setDataSource(trackUrl);
player.prepareAsync();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onCompletion(MediaPlayer mp) {
if (mp.getCurrentPosition() == 0) {
mp.reset();
}
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();
return false;
}
#Override
public void onPrepared(MediaPlayer mp) {
//start playback
mp.start();
SongModel playingSong = songs.get(songPosition);
Intent intent = new Intent(this, NavDrawerMainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(this);
builder.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_action_playing)
.setTicker(playingSong.getTitle())
.setOngoing(true)
.setContentTitle(playingSong.getTitle())
.setContentText(playingSong.getArtistName());
Notification notification = builder.build();
startForeground((int) playingSong.getSongId(), notification);
}
#Override
public void onDestroy() {
stopForeground(true);
}
public void setSong(int songIndex) {
songPosition = songIndex;
}
}
DiscoverSongsFragment.java
public class DiscoverSongsFragment extends Fragment
implements MediaController.MediaPlayerControl {
JazzyGridView songsContainer;
SongsHelper songsHelper;
SongsAdapter songsAdapter;
ArrayList<SongModel> songsArrayList;
ConnectionState connectionState;
Context mContext;
private static View rootView;
SongModel currentSong;
SeekBar nowPlayingSeekBar;
final Handler handler = new Handler();
// this value contains the song duration in milliseconds.
// Look at getDuration() method in MediaPlayer class
int mediaFileLengthInMilliseconds;
View nowPlayingLayout;
boolean nowPlayingLayoutVisible;
TextView nowPlayingTitle;
TextView nowPlayingArtist;
ImageButton nowPlayingCover;
ImageButton nowPlayingStop;
private MusicService musicService;
private Intent playIntent;
private boolean musicBound = false;
private boolean playbackPaused = false;
private int mCurrentTransitionEffect = JazzyHelper.SLIDE_IN;
public static DiscoverSongsFragment newInstance() {
return new DiscoverSongsFragment();
}
public DiscoverSongsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_discover_songs, container, false);
mContext = rootView.getContext();
setupViews(rootView);
return rootView;
}
#Override
public void onStart() {
super.onStart();
if (playIntent == null) {
playIntent = new Intent(mContext, MusicService.class);
mContext.bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
mContext.startService(playIntent);
}
}
#Override
public void onResume() {
super.onResume();
if (isPlaying()) {
showNowPlayingLayout();
primarySeekBarProgressUpdater();
}
}
#Override
public void onDestroy() {
mContext.stopService(playIntent);
musicService = null;
super.onDestroy();
}
private void hideNowPlayingLayout() {
nowPlayingLayoutVisible = false;
nowPlayingLayout.setVisibility(View.GONE);
Animation animationFadeIn = AnimationUtils.loadAnimation(mContext, R.anim.fade_out);
nowPlayingLayout.startAnimation(animationFadeIn);
}
private void showNowPlayingLayout() {
nowPlayingLayoutVisible = true;
nowPlayingLayout.setVisibility(View.VISIBLE);
Animation animationFadeIn = AnimationUtils.loadAnimation(mContext, R.anim.fade_in);
nowPlayingLayout.startAnimation(animationFadeIn);
}
private void setupViews(View rootView) {
songsHelper = new SongsHelper();
songsArrayList = new ArrayList<SongModel>();
connectionState = new ConnectionState(mContext);
songsAdapter = new SongsAdapter(mContext, songsArrayList);
nowPlayingLayout = rootView.findViewById(R.id.nowPlayingLayout);
nowPlayingLayout.setVisibility(View.GONE);
nowPlayingLayoutVisible = false;
songsContainer = (JazzyGridView) rootView.findViewById(R.id.songsContainerView);
songsContainer.setTransitionEffect(mCurrentTransitionEffect);
songsContainer.setAdapter(songsAdapter);
songsContainer.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
musicService.setSong(position);
musicService.playSong();
if (playbackPaused) {
playbackPaused = false;
}
currentSong = songsArrayList.get(position);
// gets the song length in milliseconds from URL
mediaFileLengthInMilliseconds = getDuration();
if (currentSong != null) {
nowPlayingTitle.setText(currentSong.getTitle());
nowPlayingArtist.setText(currentSong.getArtistName());
nowPlayingCover.setImageBitmap(currentSong.getCoverArt());
}
primarySeekBarProgressUpdater();
if (!nowPlayingLayoutVisible) {
showNowPlayingLayout();
}
}
});
nowPlayingSeekBar = (SeekBar) rootView.findViewById(R.id.nowPlayingSeekbar);
nowPlayingSeekBar.setMax(99);
nowPlayingTitle = (TextView) rootView.findViewById(R.id.nowPlayingTitle);
nowPlayingArtist = (TextView) rootView.findViewById(R.id.nowPlayingArtist);
nowPlayingStop = (ImageButton) rootView.findViewById(R.id.nowPlayingStop);
nowPlayingStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (isPlaying()) {
currentSong = null;
playbackPaused = false;
musicService.stopPlayer();
mediaFileLengthInMilliseconds = 0;
nowPlayingSeekBar.setProgress(0);
hideNowPlayingLayout();
}
}
});
nowPlayingCover = (ImageButton) rootView.findViewById(R.id.nowPlayingCover);
nowPlayingCover.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Intent intent = new Intent(mContext, SongDetailsActivity.class);
intent.putExtra("Title", currentSong.getTitle());
intent.putExtra("Artist", currentSong.getArtistName());
intent.putExtra("Album", currentSong.getAlbumName());
intent.putExtra("Genre", currentSong.getGenre());
intent.putExtra("CoverUrl", currentSong.getCoverArtUrl());
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
});
getSongs();
hideNowPlayingLayout();
}
private void getSongs() {
if (!connectionState.isConnectedToInternet()) {
}
songsAdapter.clear();
String songsUrl = Constants.getAPI_SONGS_URL();
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(songsUrl, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
if (jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject jsonObject = jsonArray.getJSONObject(i);
SongModel song = songsHelper.getSongFromJson(jsonObject);
songsAdapter.add(song);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
});
AppController.getInstance().addToRequestQueue(jsonArrayRequest);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
/**
* Method which updates the SeekBar primary progress by current song playing position
*/
private void primarySeekBarProgressUpdater() {
nowPlayingSeekBar.setProgress((int) (((float) getCurrentPosition() / getDuration()) * 100));
//if (isPlaying()) {
Runnable runnable = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(runnable, 1000);
//}
}
#Override
public void start() {
musicService.start();
}
#Override
public void pause() {
playbackPaused = true;
musicService.pausePlayer();
}
#Override
public int getDuration() {
if (musicService != null && musicBound && musicService.isPlaying()) {
return musicService.getDuration();
}
return 0;
}
#Override
public int getCurrentPosition() {
if (musicService != null && musicBound && musicService.isPlaying()) {
return musicService.getPosition();
}
return 0;
}
public int getCurrentListPosition() {
if (musicService != null && musicBound && musicService.isPlaying()) {
return musicService.getCurrenListPosition();
}
return 0;
}
#Override
public void seekTo(int pos) {
musicService.seekToPosition(pos);
}
#Override
public boolean isPlaying() {
if (musicService != null && musicBound && musicService.isPlaying()) {
return musicService.isPlaying();
}
return false;
}
#Override
public int getBufferPercentage() {
return 0;
}
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return true;
}
#Override
public boolean canSeekForward() {
return true;
}
#Override
public int getAudioSessionId() {
return 0;
}
//connect to the service
private ServiceConnection musicConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.MusicBinder binder = (MusicService.MusicBinder) service;
//get service
musicService = binder.getService();
//pass list
musicService.setList(songsArrayList);
musicBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
}
(The fragment also re-creates itself when navigating through drawer menu items)
I hope somebody can help me achieve this. I dont know how to maintane the state when re-starting the MainActivity (by the way, im using navdrawer to hold fragments)
Include the currently playing song in your notification intent. Update the intent as the song changes. Include the flag to clear top and the flag to update current in the notification intent. :( sorry IDK if I have the flags right for your situation but you'll have a place to do more research.
In your service where you create the notification intent.
// link the notifications to the recorder activity
Intent resultIntent = new Intent(context, KmlReader.class);
resultIntent
.setAction(ServiceLocationRecorder.INTENT_COM_GOSYLVESTER_BESTRIDES_LOCATION_RECORDER);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent resultPendingIntent = PendingIntent
.getActivity(context, 0, resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
return mBuilder.build();
}
Then in main onCreate check the bundle for the name of the currently playing song and display it. Notice how I check for the existence of a bundle key before using it.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String intentaction = intent.getAction();
// First Run checks
if (savedInstanceState == null) {
// first run init
...
} else {
// get the saved_Instance state
// always get the default when key doesn't exist
// default is null for this example
currentCameraPosition = savedInstanceState
.containsKey(SAVED_INSTANCE_CAMERA_POSITION) ? (CameraPosition) savedInstanceState
.getParcelable(SAVED_INSTANCE_CAMERA_POSITION) : null;
...

Back button not working in Media player

I am able to press the back button when music is not played . But when the music plays and I try to press the back button,it doesn't work. Even on pausing the music, back button not working. Please help what could be the issue. Pasting below a snippet of the code:
Inside MainActivity:
public class MainActivity extends Activity implements MediaPlayerControl {
private ArrayList<Song> songList;
private ListView songView;
private MusicService musicSrv;
private Intent playIntent;
private boolean musicBound = false;
private MusicController controller;
private boolean paused = false, playbackPaused = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
songView = (ListView) findViewById(R.id.lv_song_list);
songList = new ArrayList<Song>();
getSongList();
Collections.sort(songList, new Comparator<Song>() {
#Override
public int compare(Song a, Song b) {
return a.getTitle().compareTo(b.getTitle());
}
});
SongAdapter songAdt = new SongAdapter(this, songList);
songView.setAdapter(songAdt);
setController();
}
// connect to the service
private ServiceConnection musicConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicBinder binder = (MusicBinder) service;
// get service
musicSrv = binder.getService();
Log.e("MAIN ACT", "Inside connection");
// pass list
musicSrv.setList(songList);
musicBound = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.e("MAIN ACT", "Inside disconnection");
musicBound = false;
musicSrv = null;
}
};
#Override
protected void onStart() {
super.onStart();
if (playIntent == null) {
playIntent = new Intent(this, MusicService.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
Log.e("MAIN ACT", "Inside onstart" + musicBound);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.e("MAIN ACT", "Inside ondestroy");
musicSrv = null;
}
public void getSongList() {
// retrieve song info
ContentResolver musicResolver = getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null,
null);
if (musicCursor != null && musicCursor.moveToFirst()) {
// get columns
int titleColumn = musicCursor.getColumnIndex(MediaColumns.TITLE);
int idColumn = musicCursor.getColumnIndex(BaseColumns._ID);
int artistColumn = musicCursor.getColumnIndex(AudioColumns.ARTIST);
// add songs to list
do {
long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
songList.add(new Song(thisId, thisTitle, thisArtist));
} while (musicCursor.moveToNext());
}
}
public void songPicked(View view) {
musicSrv.setSong(Integer.parseInt(view.getTag().toString()));
musicSrv.playSong();
if (playbackPaused) {
setController();
playbackPaused = false;
}
controller.show(0);
Log.d(this.getClass().getName(), "Inside song picked");
}
private void setController() {
// set the controller up
controller = new MusicController(this);
controller.setPrevNextListeners(new View.OnClickListener() {
#Override
public void onClick(View v) {
playNext();
}
}, new View.OnClickListener() {
#Override
public void onClick(View v) {
playPrev();
}
});
controller.setMediaPlayer(this);
controller.setAnchorView(findViewById(R.id.lv_song_list));
controller.setEnabled(true);
}
// play next
private void playNext() {
musicSrv.playNext();
if (playbackPaused) {
setController();
playbackPaused = false;
}
controller.show(0);
}
// play previous
private void playPrev() {
musicSrv.playPrev();
if (playbackPaused) {
setController();
playbackPaused = false;
}
controller.show(0);
}
#Override
protected void onPause() {
super.onPause();
paused = true;
musicSrv.pausePlayer();
}
#Override
protected void onResume() {
super.onResume();
if (paused) {
setController();
paused = false;
}
}
#Override
public void onBackPressed() {
if (musicSrv != null){
super.onBackPressed();
Log.e("MAIN ACT", "Inside onbackpress");
}
}
//
// #Override
// public boolean onKeyDown(int keyCode, KeyEvent event)
// {
// Log.e("MAIN ACT", "Inside onkeydown1");
// if ((keyCode == KeyEvent.KEYCODE_BACK))
// { //Back key pressed
// //Things to Do
// Log.e("MAIN ACT", "Inside onkeydown2");
// if(musicSrv!= null)
// {
// musicSrv.pausePlayer();
// musicSrv=null;
// }
// finish();
// return true;
// }
// return super.onKeyDown(keyCode, event);
// }
#Override
protected void onStop() {
Log.e("MAIN ACT", "Inside onstop");
if (playIntent != null) {
Log.e("MAIN ACT", "Inside onstop1");
unbindService(musicConnection);
musicBound = false;
boolean flagservice = stopService(playIntent);
Log.d("MAIN ACT", "Inside onstop1" + flagservice);
}
controller.hide();
super.onStop();
}
#Override
public void start() {
Log.d(this.getClass().getName(), "START");
musicSrv.go();
}
#Override
public void pause() {
playbackPaused = true;
Log.d(this.getClass().getName(), "PAUSE");
musicSrv.pausePlayer();
}
#Override
public int getDuration() {
if (musicSrv != null && musicBound && musicSrv.isPng())
return musicSrv.getDur();
else
return 0;
}
#Override
public int getCurrentPosition() {
if (musicSrv != null && musicBound && musicSrv.isPng())
return musicSrv.getPosn();
else
return 0;
}
#Override
public void seekTo(int pos) {
musicSrv.seek(pos);
}
#Override
public boolean isPlaying() {
if (musicSrv != null && musicBound) {
Log.e("MAIN ACT", "Inside isplaying");
boolean value = musicSrv.isPng();
return value;
} else
return false;
}
#Override
public int getBufferPercentage() {
// TODO Auto-generated method stub
return 0;
}
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return true;
}
#Override
public boolean canSeekForward() {
return true;
}
#Override
public int getAudioSessionId() {
return 0;
}
Service Class:
public class MusicService extends Service implements
MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
MediaPlayer.OnCompletionListener {
// media player
private MediaPlayer player;
// song list
private ArrayList<Song> songs;
// current position
private int songPosn;
private String songTitle = "";
private static final int NOTIFY_ID = 1;
private boolean shuffle = false;
private Random rand;
private final IBinder musicBind = new MusicBinder();
#Override
public IBinder onBind(Intent intent) {
Log.d(this.getClass().getName(), "BIND");
return musicBind;
}
#Override
public boolean onUnbind(Intent intent) {
Log.d(this.getClass().getName(), "UNBIND");
if (player.isPlaying()) {
player.stop();
player.release();
Log.d(this.getClass().getName(), "UNBIND1");
}
return false;
}
#Override
public void onCreate() {
// create the service
// create the service
super.onCreate();
// initialize position
songPosn = 0;
if (player == null) {
// create player
player = new MediaPlayer();
initMusicPlayer();
}
player.reset();
rand = new Random();
}
public void initMusicPlayer() {
// set player properties
player.setWakeMode(getApplicationContext(),
PowerManager.PARTIAL_WAKE_LOCK);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(this);
player.setOnCompletionListener(this);
player.setOnErrorListener(this);
}
public void setList(ArrayList<Song> theSongs) {
this.songs = theSongs;
}
public class MusicBinder extends Binder {
MusicService getService() {
return MusicService.this;
}
}
public void playSong() {
// play a song
player.reset();
// get song
Song playSong = songs.get(songPosn);
songTitle = playSong.getTitle();
// get id
long currSong = playSong.getId();
// set uri
Uri trackUri = ContentUris.withAppendedId(
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
currSong);
try {
player.setDataSource(getApplicationContext(), trackUri);
player.prepareAsync();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
Log.d("MUSIC SERVICE", "Inside playsong");
}
public void setShuffle() {
if (shuffle)
shuffle = false;
else
shuffle = true;
}
#Override
public void onCompletion(MediaPlayer mp) {
if (player.isPlaying()) {
mp.stop();
mp.release();
}
if (player.getCurrentPosition() < 0) {
mp.reset();
playNext();
}
}
public void setSong(int songIndex) {
this.songPosn = songIndex;
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();
Log.e("ERROR", "Inside onError");
return false;
}
#Override
public void onPrepared(MediaPlayer mp) {
if (!player.isPlaying()) {
Log.d(this.getClass().getName(), "ONPREPARE");
try
{
mp.start();
}
catch(IllegalStateException e)
{
e.printStackTrace();
}
}
Intent notIntent = new Intent(this, MainActivity.class);
notIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendInt = PendingIntent.getActivity(this, 0,
notIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(this);
builder.setContentIntent(pendInt)
.setSmallIcon(R.drawable.play)
.setTicker(songTitle)
.setOngoing(true)
.setContentTitle("Playing")
.setContentText(songTitle);
Notification not = builder.build();
Log.e("MUSIC SERVICE", "Inside prepare");
startForeground(NOTIFY_ID, not);
}
public void stop() {
if (!player.isPlaying()) {
player.stop();
Log.d("MUSIC SERVICE", "Inside stop");
}
}
public int getPosn() {
return player.getCurrentPosition();
}
public int getDur() {
return player.getDuration();
}
public boolean isPng() {
return player.isPlaying();
}
public void pausePlayer() {
if (player.isPlaying()) {
player.pause();
}
}
public void seek(int posn) {
player.seekTo(posn);
}
public void go() {
if (!player.isPlaying()) {
Log.d(this.getClass().getName(), "GO");
player.start();
}
}
public void playPrev() {
songPosn--;
if (songPosn < 0)
songPosn = songs.size() - 1;
playSong();
}
// skip to next
public void playNext() {
songPosn++;
if (songPosn >= songs.size())
songPosn = 0;
playSong();
if (shuffle) {
int newSong = songPosn;
while (newSong == songPosn) {
newSong = rand.nextInt(songs.size());
}
songPosn = newSong;
} else {
songPosn++;
if (songPosn <= songs.size())
songPosn = 0;
}
playSong();
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(this.getClass().getName(), "ON DESTROY");
stopForeground(true);
if (player != null) {
if (player.isPlaying()) {
player.stop();
}
player.release();
}
}
}
MediaController class:
public class MusicController extends MediaController {
public MusicController(Context c){
super(c);
}
#Override
public void hide(){
Log.d(this.getClass().getName(),"Hide");
super.show();
}
#Override
public void show(int timeout) {
Log.d(this.getClass().getName(),"Show");
super.show(0);
}
#Override
public boolean dispatchKeyEvent(KeyEvent event)
{
int keyCode = event.getKeyCode();
if(keyCode == KeyEvent.KEYCODE_BACK)
{
Log.d(this.getClass().getName(),"DispACH");
super.hide();
Context c = getContext();
((Activity) c).finish();
return true;
}
return super.dispatchKeyEvent(event);
}
}
Why do you want to handle the Back key in onKeyDown . The Activity will taken care of finishing itself when back key is pressed.
Remove the onKeyDown method from Activity if your aim is to handle BACK Key there.
You can stop and release the MediaPlayer Instance in Activity onDestroy
Also, If you need to do any specific work on back press , do it in onBackPressed method before calling super.onBackPressed.
If media controller is visible when music play, you need to handle the KEYCODE_BACK to finish the Activity
Add this in your MusicController class
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
if(keyCode == KeyEvent.KEYCODE_BACK){
finish();
return true;
}
return super.dispatchKeyEvent(event);
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
//release meadia playes here
super.onBackPressed();
}

How can i exit my app with out this error

I created a Karaoke application. But I can't stop the MediaPlayer with out an error. When I press Back Button to go to home, I get "sorry ,Application has stopped working" The same thing happens if I try to start another activity
public class Main extends Activity implements MediaPlayerControl {
private MediaController mMediaController;
private MediaPlayer mMediaPlayer;
Handler mHandler = new Handler();
public TextView subtitles,subtitles2;
static Context context;
#SuppressLint("HandlerLeak")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.Main);
subtitles = (TextView) findViewById(R.id.subs2);
subtitles2 = (TextView) findViewById(R.id.subs21);
mMediaPlayer = new MediaPlayer();
mMediaController = new MediaController(this)
/*
* {
*
* #Override public void hide() { mMediaController.show(0); } }
*/;
mMediaController.setMediaPlayer(Main.this);
mMediaController.setAnchorView(findViewById(R.id.AudioView));
mMediaController.setPrevNextListeners(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Next button clicked
Intent intent = new Intent(Main.this, Hello.class);
startActivity(intent);
}
}, new View.OnClickListener() {
#Override
public void onClick(View v) {
// Previous button clicked
Intent intent = new Intent(Main.this, Sorry.class);
startActivity(intent);
}
});
// String audioFile = "" ;
try {
mMediaPlayer.setDataSource(this, Uri
.parse("android.resource://com.app.suadmon/raw/buchatri"));
mMediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
final long currentPos = mMediaPlayer.getCurrentPosition();
if (currentPos < 5130) {
subtitles.setText("1111+");
} else if (currentPos > 5130 && currentPos < 10572) {
subtitles.setText("555+");
} else if (currentPos > 10572 && currentPos < 10597) {
subtitles.setText("666+");
} else if (currentPos > 15312 && currentPos < 18478) {
subtitles.setText("777+");
} else if (currentPos > 18478 && currentPos < 24191) {
subtitles.setText("888+");
} else if (currentPos > 24191 && currentPos < 28137) {
subtitles.setText("999+");
} else if (currentPos > 28137 && currentPos < 29500) {
subtitles.setText("Thank you");
subtitles2.setText(".............");
}
mHandler.sendEmptyMessageDelayed(0, 1);
}
};
mHandler.sendEmptyMessage(0);
mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mHandler.post(new Runnable() {
public void run() {
mMediaController.show(0);
// mMediaPlayer.reset();
mMediaPlayer.start();
}
});
}
});
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
Intent stopplay = new Intent(Main.this, Hello.class);
startActivity(stopplay);
}
});
}
protected void onDestroy() {
super.onDestroy();
mMediaPlayer.stop();
mMediaPlayer.release();
}
public void releaseMediaPlayer(){
if(mMediaPlayer != null){
mMediaPlayer.release();
mMediaPlayer = null;
}
}
public boolean canPause() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canSeekForward() {
return true;
}
public int getBufferPercentage() {
int percentage = (mMediaPlayer.getCurrentPosition() * 100)
/ mMediaPlayer.getDuration();
return percentage;
}
public int getCurrentPosition() {
return mMediaPlayer.getCurrentPosition();
}
public int getDuration() {
return mMediaPlayer.getDuration();
}
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
public void seekTo(int pos) {
mMediaPlayer.seekTo(pos);
}
#Override
public void pause() {
// TODO Auto-generated method stub
mMediaPlayer.pause();
}
protected void onPause() {
super.onPause();
mMediaPlayer.getCurrentPosition();
mMediaPlayer.pause();
}
protected void onResume() {
super.onResume();
mMediaPlayer.seekTo(0);
mMediaPlayer.start();
}
// public void onUserLeaveHint(){
// mMediaPlayer.stop();
// super.onUserLeaveHint();
// }
/*
* public void stopPlayback(){ mMediaPlayer.stop(); }
*/
public void start() {
mMediaPlayer.start();
}
public boolean onTouchEvent(MotionEvent event) {
mMediaController.show(0);
return false;
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
finish();
Intent intent = new Intent(Main.this, Show.class);
startActivity(intent);
super.onBackPressed();
}
}
and Log Cat's here.
How can I fix this. I have no idea.
Can anyone help me. Please !!!
You need to stop and release the media player before your activity finishes. Try adding this to your activity:
#Override
protected void onDestroy() {
super.onDestroy();
if(mMediaPlayer != null)
{
mMediaPlayer.stop();
mMediaPlayer.release();
}
}

How can I stop MediaPlayer without error when I press Back or go to another activity

I created a Karaoke application. But I can't stop the MediaPlayer with out an error. When I press Back Button to go to home, I get "sorry ,Application has stopped working" The same thing happens if I try to start another activity.
This my code.
public class Main extends Activity implements MediaPlayerControl, OnClickListener {
private MediaController mMediaController;
private MediaPlayer mMediaPlayer;
public TextView subtitles;
Handler mHandler = new Handler();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
subtitles = (TextView) findViewById(R.id.subs1);
Button btnvol = (Button) findViewById(R.id.volc);
btnvol.setOnClickListener(this);
mMediaPlayer = new MediaPlayer();
mMediaController = new MediaController(this);
mMediaController.setMediaPlayer(Main.this);
mMediaController.setAnchorView(findViewById(R.id.audioView));
try {
mMediaPlayer
.setDataSource(
this,
Uri.parse("android.resource://com.app.audioplayer/raw/buchatri"));
mMediaPlayer.prepare();
} catch (IllegalStateException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mHandler = new Handler(){
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
final long currentPos = mMediaPlayer.getCurrentPosition();
if (currentPos < 5130) {
subtitles.setText("Stupid");
} else if (currentPos > 5130 && currentPos < 10572) {
subtitles.setText("Sorry");
} else if (currentPos > 10572 && currentPos < 10597) {
subtitles.setText("555+");
} else if (currentPos > 15312 && currentPos < 18478) {
subtitles.setText("OMG");
} else if (currentPos > 18478 && currentPos < 24191) {
subtitles.setText("AFK");
} else if (currentPos > 24191 && currentPos < 28137) {
subtitles.setText("Help me !");
} else if (currentPos > 28137 && currentPos < 29500) {
subtitles.setText("Oh no !");
}
mHandler.sendEmptyMessageDelayed(0, 1);
}
};
mHandler.sendEmptyMessage(0);
mMediaPlayer.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mHandler.post(new Runnable() {
public void run() {
mMediaController.show(0);
mMediaPlayer.start();
}
});
}
});
}
protected void onDestroy() {
super.onDestroy();
mMediaPlayer.stop();
mMediaPlayer.release();
}
public boolean canPause() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canSeekForward() {
return true;
}
public int getBufferPercentage() {
int percentage = (mMediaPlayer.getCurrentPosition() * 100)
/ mMediaPlayer.getDuration();
return percentage;
}
public int getCurrentPosition() {
return mMediaPlayer.getCurrentPosition();
}
public int getDuration() {
return mMediaPlayer.getDuration();
}
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
#Override
public void pause() {
// TODO Auto-generated method stub
super.onPause();
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
public void seekTo(int pos) {
mMediaPlayer.seekTo(pos);
}
public void start() {
mMediaPlayer.start();
}
public boolean onTouchEvent(MotionEvent event) {
mMediaController.show(0);
return false;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
I think I have an error with "if else". How can I fix this ?
Try first mMediaPlayer.stop() and then release it by mMediaPlayer.release()
you can try this,
after release you should set mediaplayer null
private void releaseMediaPlayer() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}

Categories

Resources