MediaBrowserServiceCompat stopped playing music when app goes background - android

Mediabrowsercompat not playing the music when app goes background. If I don't disconnect the mediabrowsercompat instance in activity onStop method then it is working. But that is not the solution as according to documentation we have to disconnect the service once app goes background.
This is my mediabroweserservicecomat class (I am using Exoplayer to play music):
private static final String PLAYBACK_CHANNEL_ID = "100";
private static final int PLAYBACK_NOTIFICATION_ID =101 ;
private MediaSessionCompat mediaSessionCompat;
private PlaybackStateCompat.Builder stateBuilder;
private SimpleExoPlayer exoPlayer;
private Uri oldUri;
private AudioAttributes audioAttributes;
private PlayerNotificationManager playerNotificationManager;
#Override
public void onCreate() {
super.onCreate();
Log.i("Test","Hi");
initPlayer();
initAttributes();
ComponentName mediaButtonReceiver = new ComponentName(getApplicationContext(), MediaButtonReceiver.class);
mediaSessionCompat = new MediaSessionCompat(getApplicationContext(), "Tag", mediaButtonReceiver, null);
mediaSessionCompat.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS|
MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
stateBuilder = new PlaybackStateCompat.Builder();
stateBuilder.setActions(PlaybackStateCompat.ACTION_PLAY|PlaybackStateCompat.ACTION_PLAY_PAUSE);
mediaSessionCompat.setPlaybackState(stateBuilder.build());
mediaSessionCompat.setCallback(mediaSessionCompatCallback);
setSessionToken(mediaSessionCompat.getSessionToken());
mediaSessionCompat.setActive(true);
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
mediaButtonIntent.setClass(this, MediaButtonReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, mediaButtonIntent, 0);
mediaSessionCompat.setMediaButtonReceiver(pendingIntent);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
MediaButtonReceiver.handleIntent(mediaSessionCompat,intent);
return super.onStartCommand(intent, flags, startId);
}
private MediaSessionCompat.Callback mediaSessionCompatCallback = new MediaSessionCompat.Callback() {
#Override
public void onPlayFromUri(Uri uri, Bundle extras) {
super.onPlayFromUri(uri, extras);
if (uri!=null){
MediaItem mediaSource = MediaItem.fromUri(uri);
if (uri!=oldUri){
play(mediaSource);
onPlay();
}else {
oldUri = uri;
}
}
}
#Override
public void onPlay() {
super.onPlay();
Log.i("onPlay","onPlay");
//startService(new Intent(MusicService.this,MusicForegroundService.class));
playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(MusicService.this,
PLAYBACK_CHANNEL_ID, R.string.channel_name, PLAYBACK_NOTIFICATION_ID,
new PlayerNotificationManager.MediaDescriptionAdapter() {
#Override
public CharSequence getCurrentContentTitle(Player player) {
return "title";
}
#Nullable
#Override
public PendingIntent createCurrentContentIntent(Player player) {
Intent intent = new Intent(getBaseContext(), PlayerFullViewActivity.class);
return PendingIntent.getActivity(getBaseContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
#Nullable
#Override
public CharSequence getCurrentContentText(Player player) {
return "content";
}
#Nullable
#Override
public Bitmap getCurrentLargeIcon(Player player, PlayerNotificationManager.BitmapCallback callback) {
return null;
}
},
new PlayerNotificationManager.NotificationListener() {
#Override
public void onNotificationPosted(int notificationId, Notification notification, boolean ongoing) {
startForeground(notificationId,notification);
}
#Override
public void onNotificationCancelled(int notificationId, boolean dismissedByUser) {
stopSelf();
}
});
playerNotificationManager.setPlayer(exoPlayer);
}
#Override
public void onPause() {
super.onPause();
pause();
}
#Override
public void onStop() {
playerNotificationManager.setPlayer(null);
super.onStop();
stop();
}
};
#Override
public void onDestroy() {
super.onDestroy();
stop();
}
private void stop() {
exoPlayer.setPlayWhenReady(false);
exoPlayer.release();
exoPlayer =null;
updatePlayBackState(PlaybackStateCompat.STATE_NONE);
mediaSessionCompat.setActive(false);
mediaSessionCompat.release();
}
#SuppressLint("WrongConstant")
private void pause() {
if (exoPlayer!=null){
exoPlayer.setPlayWhenReady(false);
if (exoPlayer.getPlaybackState()==PlaybackStateCompat.STATE_PLAYING){
updatePlayBackState(PlaybackStateCompat.STATE_PAUSED);
}
}
}
private void play(MediaItem mediaSource){
if (exoPlayer==null) {
initPlayer();
}
if (audioAttributes==null) {
initAttributes();
}
exoPlayer.setAudioAttributes(audioAttributes,true);
exoPlayer.setMediaItem(mediaSource);
exoPlayer.prepare();
play();
}
private void initAttributes() {
audioAttributes = new AudioAttributes.Builder().setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MUSIC)
.build();
}
private void initPlayer() {
exoPlayer = new SimpleExoPlayer.Builder(this, new DefaultRenderersFactory(getBaseContext()),
new DefaultExtractorsFactory()).build();
}
private void play() {
exoPlayer.setPlayWhenReady(true);
updatePlayBackState(PlaybackStateCompat.STATE_PLAYING);
mediaSessionCompat.setActive(true);
}
private void updatePlayBackState(int statePlaying) {
mediaSessionCompat.setPlaybackState(new PlaybackStateCompat.Builder().
setState(statePlaying,0L,0).build());
}
#Nullable
#Override
public BrowserRoot onGetRoot(#NonNull String clientPackageName, int clientUid, #Nullable Bundle rootHints) {
return new BrowserRoot("",null);
}
#Override
public void onLoadChildren(#NonNull String parentId, #NonNull Result<List<MediaBrowserCompat.MediaItem>> result) {
result.sendResult(null);
}
This is my activity class:
ActivityPlayerFullViewBinding activityPlayerFullViewBinding;
private MediaBrowserCompat mediaBrowserCompat;
private MediaBrowserCompat.ConnectionCallback connectionCallback = new MediaBrowserCompat.ConnectionCallback(){
#Override
public void onConnected() {
super.onConnected();
MediaSessionCompat.Token sessionToken = mediaBrowserCompat.getSessionToken();
if (sessionToken!=null){
try {
MediaControllerCompat mediaControllerCompat = new
MediaControllerCompat(PlayerFullViewActivity.this, sessionToken);
MediaControllerCompat.setMediaController(PlayerFullViewActivity.this,mediaControllerCompat);
playPauseBuild();
Log.d("onConnected","ConnectionSuccess");
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
#Override
public void onConnectionFailed() {
super.onConnectionFailed();
Log.d("onConnectionFaild","ConnectionFailed");
}
};
MediaControllerCompat.Callback controllerCallback =
new MediaControllerCompat.Callback() {
#Override
public void onMetadataChanged(MediaMetadataCompat metadata) {}
#Override
public void onPlaybackStateChanged(PlaybackStateCompat state) {}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityPlayerFullViewBinding = DataBindingUtil.setContentView(this,R.layout.activity_player_full_view);
ComponentName componentName = new ComponentName(this,MusicService.class);
mediaBrowserCompat = new MediaBrowserCompat(this,componentName,connectionCallback,null);
}
private void playPauseBuild() {
MediaControllerCompat mediaController = MediaControllerCompat.getMediaController(PlayerFullViewActivity.this);
activityPlayerFullViewBinding.playPauseBtn
.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int state = mediaController.getPlaybackState().getState();
if (state== PlaybackStateCompat.STATE_PAUSED||state==PlaybackStateCompat.STATE_STOPPED||
state==PlaybackStateCompat.STATE_NONE){
mediaController.getTransportControls().playFromUri(
Uri.parse("https://www.mboxdrive.com/Eminem-Sing-For-The-Moment9jamo.com_.mp3"),null);
activityPlayerFullViewBinding.playPauseBtn.setText("Pause");
}else if (state == PlaybackStateCompat.STATE_PLAYING ||
state == PlaybackStateCompat.STATE_BUFFERING ||
state == PlaybackStateCompat.STATE_CONNECTING){
mediaController.getTransportControls().pause();
activityPlayerFullViewBinding.playPauseBtn.setText("Play");
}
}
});
mediaController.registerCallback(controllerCallback);
}
#Override
protected void onStart() {
super.onStart();
mediaBrowserCompat.connect();
}
#Override
public void onResume() {
super.onResume();
setVolumeControlStream(AudioManager.STREAM_MUSIC);
}
#Override
protected void onStop() {
super.onStop();
Log.i("onStop","onStop");
MediaControllerCompat mediaController = MediaControllerCompat.getMediaController(this);
if (mediaController != null) {
mediaController.unregisterCallback(controllerCallback);
}
mediaBrowserCompat.disconnect();
}

After wasting 2 sleepless nights. I found a workaround. I don't know whether it's a correct way to handle this. But if you have ever faced this problem. You can try it:
#Override
protected void onStart() {
super.onStart();
if (!mediaBrowserCompat.isConnected())
mediaBrowserCompat.connect();
}
#Override
protected void onStop() {
super.onStop();
Log.i("onStop","onStop");
MediaControllerCompat mediaController = MediaControllerCompat.getMediaController(this);
if (mediaController != null) {
mediaController.unregisterCallback(controllerCallback);
}
// mediaBrowserCompat.disconnect();
}
#Override
protected void onDestroy() {
super.onDestroy();
mediaBrowserCompat.disconnect();
}

Related

Exoplayer changing track when new track is selected

I am using a service to play music so when I first start the service from an activity and exit it plays properly in the background but when I start another music and exit the background playback stops any idea why this is happening?
public class AudioPlayerService extends Service implements Player.EventListener {
private final IBinder mBinder = new LocalBinder();
private SimpleExoPlayer player;
private Item item;
private PlayerNotificationManager playerNotificationManager;
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onDestroy() {
releasePlayer();
super.onDestroy();
}
private void releasePlayer() {
if (player != null) {
playerNotificationManager.setPlayer(null);
player.release();
player = null;
stopSelf();
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public SimpleExoPlayer getPlayerInstance() {
if (item != null && player == null && !TextUtils.isEmpty(item.getUrl())) {
startPlayer();
}
return player;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
releasePlayer();
Bundle b = intent.getBundleExtra(AppConstants.BUNDLE_KEY);
if (b != null) {
item = b.getParcelable(AppConstants.ITEM_KEY);
}
if (item != null && player == null && !TextUtils.isEmpty(item.getUrl())) {
startPlayer();
}
String action = intent.getAction();
if (player != null) {
if (!TextUtils.isEmpty(action) && action.equalsIgnoreCase(ACTION_PLAY)) {
player.setPlayWhenReady(true);
}
if (!TextUtils.isEmpty(action) && action.equalsIgnoreCase(ACTION_PAUSE)) {
player.setPlayWhenReady(false);
}
}
return START_STICKY;
}
private void startPlayer() {
final Context context = this;
Uri uri = Uri.parse(item.getUrl());
player = ExoPlayerFactory.newSimpleInstance(context, new DefaultTrackSelector());
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(context,
Util.getUserAgent(context, getString(R.string.app_name)));
CacheDataSourceFactory cacheDataSourceFactory = new CacheDataSourceFactory(
CommonUtils.getCache(context),
dataSourceFactory,
CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
MediaSource mediaSource = new ExtractorMediaSource.Factory(cacheDataSourceFactory)
.createMediaSource(uri);
player.prepare(mediaSource);
player.addListener(this);
player.setPlayWhenReady(true);
playerNotificationManager = PlayerNotificationManager.createWithNotificationChannel(context, AppConstants.PLAYBACK_CHANNEL_ID,
R.string.playback_channel_name,
AppConstants.PLAYBACK_NOTIFICATION_ID,
new PlayerNotificationManager.MediaDescriptionAdapter() {
#Override
public String getCurrentContentTitle(Player player) {
return item.getTitle();
}
#Nullable
#Override
public PendingIntent createCurrentContentIntent(Player player) {
Intent intent = new Intent(context, PlayerActivity.class);
Bundle serviceBundle = new Bundle();
serviceBundle.putParcelable(AppConstants.ITEM_KEY, item);
intent.putExtra(AppConstants.BUNDLE_KEY, serviceBundle);
return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
#Nullable
#Override
public String getCurrentContentText(Player player) {
return item.getSummary();
}
#Nullable
#Override
public Bitmap getCurrentLargeIcon(Player player, PlayerNotificationManager.BitmapCallback callback) {
return null;
}
}
);
playerNotificationManager.setNotificationListener(new PlayerNotificationManager.NotificationListener() {
#Override
public void onNotificationStarted(int notificationId, Notification notification) {
startForeground(notificationId, notification);
}
#Override
public void onNotificationCancelled(int notificationId) {
stopSelf();
}
});
playerNotificationManager.setPlayer(player);
}
private void updateWidget(boolean playWhenReady) {
Intent intent = new Intent(this, PlayerWidget.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
int[] ids = AppWidgetManager.getInstance(getApplication())
.getAppWidgetIds(new ComponentName(getApplication(), PlayerWidget.class));
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
Bundle serviceBundle = new Bundle();
serviceBundle.putParcelable(AppConstants.ITEM_KEY, item);
intent.putExtra(AppConstants.BUNDLE_KEY, serviceBundle);
intent.putExtra(PlayerWidget.WIDGET_PLAYING_EXTRA, playWhenReady);
sendBroadcast(intent);
}
#Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
updateWidget(playWhenReady);
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
public class LocalBinder extends Binder {
public AudioPlayerService getService() {
return AudioPlayerService.this;
}
}
}
This is my playerActivity
public class PlayerActivity extends BaseActivity {
#BindView(R.id.video_view)
PlayerView mPlayerView;
#BindView(R.id.tvTitle)
TextView mTvTitle;
#BindView(R.id.tvSummary)
TextView mTvSummary;
#BindView(R.id.ivThumbnail)
ImageView mIvThumb;
#BindView(R.id.adView)
AdView mAdView;
private String mTitle;
private String mSummary;
private String mImage;
private AudioPlayerService mService;
private Intent intent;
private String shareableLink;
private boolean mBound = false;
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
AudioPlayerService.LocalBinder binder = (AudioPlayerService.LocalBinder) iBinder;
mService = binder.getService();
mBound = true;
initializePlayer();
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mBound = false;
}
};
#SuppressLint("MissingSuperCall")
#Override
protected void onCreate(Bundle savedInstanceState) {
onCreate(savedInstanceState, R.layout.activity_player);
Bundle b = getIntent().getBundleExtra(AppConstants.BUNDLE_KEY);
if (b != null) {
Item item = b.getParcelable(AppConstants.ITEM_KEY);
shareableLink = b.getString(AppConstants.SHARE_KEY);
String mUrl = item.getUrl();
mImage = item.getImage();
mTitle = item.getTitle();
mSummary = item.getSummary();
intent = new Intent(this, AudioPlayerService.class);
Bundle serviceBundle = new Bundle();
serviceBundle.putParcelable(AppConstants.ITEM_KEY, item);
intent.putExtra(AppConstants.BUNDLE_KEY, serviceBundle);
Util.startForegroundService(this, intent);
mPlayerView.setUseController(true);
mPlayerView.showController();
mPlayerView.setControllerAutoShow(true);
mPlayerView.setControllerHideOnTouch(false);
}
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
}
private void initializePlayer() {
if (mBound) {
SimpleExoPlayer mPlayer = mService.getPlayerInstance();
mPlayerView.setPlayer(mPlayer);
}
}
#Override
public void onStart() {
super.onStart();
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
initializePlayer();
setUI();
}
private void setUI() {
mTvTitle.setText(mTitle);
mTvSummary.setText(Html.fromHtml(mSummary));
GlideApp.with(this)
.load(mImage)
.placeholder(R.drawable.about_background)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(mIvThumb);
}
#Override
protected void onStop() {
unbindService(mConnection);
mBound = false;
super.onStop();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.player_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.share_podcast:
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_SUBJECT, mTitle);
shareIntent.putExtra(Intent.EXTRA_TEXT, mTitle + "\n\n" + shareableLink);
shareIntent.setType("text/plain");
startActivity(Intent.createChooser(shareIntent, getString(R.string.share_text)));
return true;
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onToolBarSetUp(Toolbar toolbar, ActionBar actionBar) {
TextView tvHeader = toolbar.findViewById(R.id.tvClassName);
tvHeader.setText(R.string.app_name);
}
}
The music should be playing even if I exit the activity which happens properly when I select the music for the first time but when I re-select another track while one is already playing background it changes the track but as soon as I exit the activity the service stops.

ExoPlayer recreates after screen rotation in fragment

In my App, I have fragment in which I, alongside with other, play video in ExoPlayer. I set it up as simple as possible and the player itself works flawlessly, even with media session.
But the problem is that on device rotation, the video loads again in background (there seems to be two layers - one standard, functioning normally, loading video and playing it; and second layer in background. I can hear the sound of the video shortly after the activity recreates.
I am stopping and releasing the player and media session, but it didn't help.
MediaFragment.java
public class StepViewFragment extends Fragment implements Player.EventListener{
//vars
public StepViewFragment() {
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
//attach callbacks for buttons
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_step_view, container, false);
//Bind view ButterKnife
ButterKnife.bind(this, rootView);
//get Step from Bundle
Bundle bundle = this.getArguments();
if (bundle != null) {
step = bundle.getParcelable(AppConstants.STEP_BUNDLE_KEY);
recipe = bundle.getParcelable(AppConstants.RECIPE_BUNDLE_KEY);
}
mainHandler = new Handler();
//...
//setup ui
//...
if (step.videoURL.equals("")) {
mediaCard.setVisibility(View.GONE);
} else {
playVideo();
initMediaSession();
}
return rootView;
}
public void initMediaSession (){
mExoPlayer.addListener(this);
mMediaSession = new MediaSessionCompat(getContext(), TAG);
mMediaSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS);
mMediaSession.setMediaButtonReceiver(null);
mStateBuilder = new PlaybackStateCompat.Builder()
.setActions(
PlaybackStateCompat.ACTION_PLAY | PlaybackStateCompat.ACTION_PAUSE | PlaybackStateCompat.ACTION_PLAY_PAUSE
);
mMediaSession.setPlaybackState(mStateBuilder.build());
mMediaSession.setCallback(new MySessionCallback());
mMediaSession.setActive(true);
}
public void playVideo() {
if (mExoPlayer == null) {
DefaultTrackSelector trackSelector = new DefaultTrackSelector();
LoadControl loadControl = new DefaultLoadControl();
RenderersFactory renderersFactory = new DefaultRenderersFactory(getContext());
mExoPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector, loadControl);
mPlayerView.setPlayer(mExoPlayer);
String videoUrl = step.videoURL;
Uri mp4VideoUri = Uri.parse(videoUrl);
String userAgent = Util.getUserAgent(getContext(), "BakingApp");
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getContext(), userAgent);
ExtractorMediaSource.Factory mediaSource = new ExtractorMediaSource.Factory(dataSourceFactory);
mExoPlayer.prepare(mediaSource.createMediaSource(mp4VideoUri));
mPlayerView.hideController();
mExoPlayer.setPlayWhenReady(true);
}
}
public void releasePlayer() {
mExoPlayer.stop();
mExoPlayer.release();
mExoPlayer = null;
mMediaSession.release();
mPlayerView = null;
}
#Override
public void onStop() {
if (mExoPlayer != null) {
releasePlayer();
}
super.onStop();
}
#Override
public void onDestroyView() {
super.onDestroyView();
if (mExoPlayer != null) {
releasePlayer();
}
}
#Override
public void onPause() {
super.onPause();
if (mExoPlayer != null) {
releasePlayer();
}
}
#Override
public void onDetach() {
super.onDetach();
if (mExoPlayer != null) {
releasePlayer();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (mExoPlayer != null){
releasePlayer();
}
}
#Override
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if ((playbackState == Player.STATE_READY) && playWhenReady) {
mStateBuilder.setState(PlaybackStateCompat.STATE_PLAYING, mExoPlayer.getCurrentPosition(), 1f);
} else if ((playbackState == Player.STATE_READY)){
mStateBuilder.setState(PlaybackStateCompat.STATE_PAUSED, mExoPlayer.getCurrentPosition(), 1f);
}
mMediaSession.setPlaybackState(mStateBuilder.build());
Log.d("HOVNOOOO", "Playback State Changed");
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
private class MySessionCallback extends MediaSessionCompat.Callback {
#Override
public void onPlay() {
mExoPlayer.setPlayWhenReady(true);
}
#Override
public void onPause() {
mExoPlayer.setPlayWhenReady(false);
}
}
Solved...
I was using add() to create the Fragment, so on rotation it added new one.
Using replace instead solved the problem.

onReadyForSpeech calling multiple times while continuous Speech Recognition

I am creating an application in that i need continuous speech recognition. But onReadyForSpeech calling two times.
I am also attaching my code. Please help me to find out the problem.
Thanks in advance.
private SpeechRecognizer mSpeechRecognizer = null;
public static VoiceRecognizeService sVoiceRecognizeService;
private ITelephony mListener;
private boolean isListening;
private Intent mSaverController;
public VoiceRecognizeService() {
super();
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
sVoiceRecognizeService = this;
startListening();
return START_NOT_STICKY;
}
public void setTelephonyListener(ITelephony mListener) {
this.mListener = mListener;
}
public static VoiceRecognizeService getInstance() {
return sVoiceRecognizeService;
}
// starts the service
public void startListening() {
if (!isListening) {
mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(this);
Intent mRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "en_IN");
mRecognizerIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 2000);
mRecognizerIntent.putExtra("android.speech.extra.DICTATION_MODE", true);
mRecognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, false);
mRecognizerIntent.putExtra("android.speech.extra.PREFER_OFFLINE", true);
mRecognizerIntent.putExtra("calling_package", this.getPackageName());
mSpeechRecognizer.startListening(mRecognizerIntent);
isListening = true;
}
}
public void processVoiceCommands(final ArrayList<String> partialData) {
}
public void restartListeningService() {
cancelSpeechRecognition();
startListening();
}
public void cancelSpeechRecognition() {
if (mSpeechRecognizer != null) {
mSpeechRecognizer.stopListening();
mSpeechRecognizer.cancel();
mSpeechRecognizer.destroy();
mSpeechRecognizer = null;
isListening = false;
}
}
#Override
public void onReadyForSpeech(Bundle bundle) {
Log.e("VoiceError", "speechReady");
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onRmsChanged(float scale) {
if (mListener != null) {
mListener.onRmsChanged(scale);
}
}
#Override
public void onBufferReceived(byte[] bytes) {
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onError(int i) {
if (i == SpeechRecognizer.ERROR_RECOGNIZER_BUSY) {
} else {
restartListeningService();
}
}
#Override
public void onResults(Bundle bundle) {
final ArrayList<String> data = bundle.getStringArrayList(
SpeechRecognizer.RESULTS_RECOGNITION);
if (data != null) {
processVoiceCommands(data);
}
restartListeningService();
}
#Override
public void onPartialResults(Bundle bundle) {
final ArrayList<String> data = bundle.getStringArrayList(
SpeechRecognizer.RESULTS_RECOGNITION);
Log.e("VoiceError", "partialResults " + data);
}
#Override
public void onEvent(int i, Bundle bundle) {
}
#Override
public void onDestroy() {
if (mSpeechRecognizer != null) {
mSpeechRecognizer.setRecognitionListener(null);
cancelSpeechRecognition();
}
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}

Android Service stops automatically without calling stopService()

I have made an android Service to play music, when i close my application then it keeps on playing song for few minutes and then automatically stops without even calling destroy method. I am not able to understand why is it happening.
Below is the code of my Service class.
public class MusicService extends Service implements MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener,
MediaPlayer.OnInfoListener, MediaPlayer.OnErrorListener, MediaPlayer.OnBufferingUpdateListener {
private MediaPlayer player;
private int songPosition;
private IBinder iBinder = new LocalBinder();
private PhoneStateListener phoneStateListener;
private TelephonyManager telephonyManager;
private boolean isPaused = false;
private ArrayList<Song> songsList;
private boolean isRepeat = false;
private boolean isShuffle = false;
private Intent broadcastIntent;
public static final String BROADCAST_INTENT = "music.akumar.com.musicplayer.seekbarintent";
private Handler handler = new Handler();
public class LocalBinder extends Binder {
public MusicService getService() {
return MusicService.this;
}
}
#Override
public void onCreate() {
broadcastIntent = new Intent(BROADCAST_INTENT);
player = new MediaPlayer();
player.setOnBufferingUpdateListener(this);
player.setOnCompletionListener(this);
player.setOnSeekCompleteListener(this);
player.setOnPreparedListener(this);
player.setOnInfoListener(this);
player.setOnErrorListener(this);
player.setLooping(true);
player.reset();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
telephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch(state) {
case TelephonyManager.CALL_STATE_OFFHOOK:
case TelephonyManager.CALL_STATE_RINGING:
if (player.isPlaying()) {
pauseMedia();
isPaused = true;
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if (player != null) {
if (isPaused) {
playMedia();
isPaused = false;
}
}
break;
}
}
};
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
return START_STICKY;
}
public void playMedia() {
if (player != null && !player.isPlaying()) {
player.start();
}
}
public void pauseMedia() {
if (player != null && player.isPlaying()) {
player.pause();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (player.isPlaying()) {
player.stop();
}
player.release();
}
#Override
public IBinder onBind(Intent intent) {
return iBinder;
}
public void playSong(Song song) {
player.reset();
try {
player.setDataSource(getApplicationContext(), Uri.parse(song.getPath()));
player.prepare();
playMedia();
setHandler();
} catch (IOException e) {
e.printStackTrace();
}
}
private void setHandler() {
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 500);
}
private Runnable sendUpdatesToUI = new Runnable() {
#Override
public void run() {
logMediaPosition();
handler.postDelayed(this, 500);
}
};
private void logMediaPosition() {
}
public void playNext() {
}
public void playPrev() {
}
public boolean isPlaying() {
return player.isPlaying();
}
public int getSongPosition() {
return songPosition;
}
public void setSongPosition(int songPosition) {
this.songPosition = songPosition;
}
public ArrayList<Song> getSongsList() {
return songsList;
}
public void setSongsList(ArrayList<Song> songsList) {
this.songsList = songsList;
}
public boolean isRepeat() {
return isRepeat;
}
public void setRepeat(boolean isRepeat) {
this.isRepeat = isRepeat;
}
public boolean isShuffle() {
return isShuffle;
}
public void setShuffle(boolean isShuffle) {
this.isShuffle = isShuffle;
}
public void addSongToList(Song song) {
songsList.add(song);
}
public Song getCurrentSong() {
return songsList.get(songPosition);
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
}
#Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i2) {
return false;
}
#Override
public boolean onInfo(MediaPlayer mediaPlayer, int i, int i2) {
return false;
}
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
}
#Override
public void onSeekComplete(MediaPlayer mediaPlayer) {
}
}
And below the code of my activity class.
public class MusicPlayer extends FragmentActivity implements View.OnClickListener, SeekBar.OnSeekBarChangeListener {
private boolean mBound = false;
private MusicService musicService;
private ArrayList<Song> songsList = new ArrayList<Song>();
private boolean isRepeat = false;
private boolean isShuffle = false;
private int position;
private ImageButton btnPlay;
private ImageButton btnPlayNext;
private ImageButton btnPlayPrev;
private ImageButton btnRepeat;
private ImageButton btnShuffle;
private ImageButton btnFavorite;
private TextView currentSongView;
private SeekBar seekBar;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
private ViewPager viewPager;
private BroadcastReceiver broadcastReceiver;
private boolean mBroadcastIsRegistered;
ServiceConnection serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mBound = true;
MusicService.LocalBinder localBinder = (MusicService.LocalBinder)iBinder;
musicService = localBinder.getService();
musicService.setSongsList(songsList);
musicService.setSongPosition(0);
musicService.playSong(0);
btnPlay.setImageResource(R.drawable.btn_pause);
registerReceiver(broadcastReceiver, new IntentFilter(MusicService.BROADCAST_INTENT));
mBroadcastIsRegistered = true;
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mBound = false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_player);
songsList = prepareListOfSongsAndAlbumMap();
currentSongView = (TextView)findViewById(R.id.currentSongView);
btnPlay = (ImageButton)findViewById(R.id.btnPlay);
btnPlayNext = (ImageButton)findViewById(R.id.btnNext);
btnPlayPrev = (ImageButton)findViewById(R.id.btnPrevious);
btnRepeat = (ImageButton)findViewById(R.id.btnRepeat);
btnShuffle = (ImageButton)findViewById(R.id.btnShuffle);
btnFavorite = (ImageButton)findViewById(R.id.btnFavourite);
seekBar = (SeekBar)findViewById(R.id.SeekBar01);
songCurrentDurationLabel = (TextView)findViewById(R.id.songCurrentDurationLabel);
songTotalDurationLabel = (TextView)findViewById(R.id.songTotalDurationLabel);
viewPager = (ViewPager)findViewById(R.id.viewPagerMusicPlayer);
position = 0;
btnPlay.setOnClickListener(this);
btnPlayNext.setOnClickListener(this);
btnPlayPrev.setOnClickListener(this);
btnRepeat.setOnClickListener(this);
btnShuffle.setOnClickListener(this);
btnFavorite.setOnClickListener(this);
seekBar.setOnSeekBarChangeListener(this);
DataTransferBetweenActivity data = new DataTransferBetweenActivity(songsList, position);
MusicPlayerTabAdapter musicPlayerTabAdapter = new MusicPlayerTabAdapter(getSupportFragmentManager(), data);
viewPager.setAdapter(musicPlayerTabAdapter);
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateUI(intent);
}
};
}
private void updateUI(Intent serviceIntent) {
}
private ArrayList<Song> prepareListOfSongsAndAlbumMap() {
Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] projection;
projection = null;
String sortOrder = null;
String selectionMimeType = MediaStore.Audio.Media.IS_MUSIC + " !=0";
Cursor musicCursor = getContentResolver().query(musicUri, projection, selectionMimeType, null, sortOrder);
int count = musicCursor.getCount();
if (musicCursor.moveToFirst()) {
do {
String path = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA));
String title = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
String album = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
String artist = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
int artistId = musicCursor.getInt(musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST_ID));
int albumId = musicCursor.getInt(musicCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
int trackId = musicCursor.getInt(musicCursor.getColumnIndex(MediaStore.Audio.Media.TRACK));
long duration = musicCursor.getInt(musicCursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
Uri sArtworkUri = Uri
.parse("content://media/external/audio/albumart");
Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, albumId);
Song song = new Song(path, title, album, artist, albumId, trackId, duration, albumArtUri.toString(), artistId);
songsList.add(song);
} while (musicCursor.moveToNext());
Collections.sort(songsList, new Comparator<Song>() {
#Override
public int compare(Song song, Song song2) {
return song.getTitle().toUpperCase().compareTo(song2.getTitle().toUpperCase());
}
});
musicCursor.close();
}
return songsList;
}
#Override
protected void onStart() {
super.onStart();
Intent serviceIntent = new Intent(this, MusicService.class);
startService(serviceIntent);
bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mBound) {
unbindService(serviceConnection);
mBound = false;
}
}
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btnPlay:
break;
case R.id.btnNext:
break;
case R.id.btnPrevious:
break;
case R.id.btnRepeat:
break;
case R.id.btnShuffle:
break;
}
}
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
protected void onPause() {
if (mBroadcastIsRegistered) {
unregisterReceiver(broadcastReceiver);
mBroadcastIsRegistered = false;
}
super.onPause();
}
#Override
protected void onResume() {
if (!mBroadcastIsRegistered) {
registerReceiver(broadcastReceiver, new IntentFilter(MusicService.BROADCAST_INTENT));
mBroadcastIsRegistered = true;
}
super.onResume();
}
public void playSong(int position) {
musicService.playSong(position);
musicService.setSongPosition(position);
}
}
I am starting my service with startService() method and i am not calling stopService() or stopSelf() anywhere, but i am not able to figure out why it stops playing after sometime.
I think you should call startForeground() from your service.
Here is a sample project of a music player. I might be helpful
FakePlayer

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;
...

Categories

Resources