I use the following code to stop the music that plays in loop in the app background when the app goes to background, it works on the emulator, not so much on the phone. Even when I exit the app the sound still plays, anyone got a solution for that? I'd be very thankful
#Override
protected void onPause() {
super.onPause();
Context context = getApplicationContext();
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
if (!taskInfo.isEmpty()) {
ComponentName topActivity = taskInfo.get(0).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
MusicManager.getInstance().stopMusic();
Toast.makeText(MainActivity.this, "YOU LEFT YOUR APP", Toast.LENGTH_SHORT).show();
}
}
UPDATE:
MusicManager:
public class MusicManager {
MediaPlayer mp = null;
private static MusicManager refrence = null;
public static MusicManager getInstance(){
if(refrence==null){
refrence = new MusicManager();
}
return refrence;
}
public void initializeMediaPlayer(Context context, int musicID){
mp = MediaPlayer.create(context, R.raw.rock);
mp.setLooping(true);
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void playMusic(){
mp.start();
}
public void stopMusic(){
if (mp != null) {
mp.stop();
mp.release();
}
}
}
Main:
MusicManager.getInstance().initializeMediaPlayer(this, R.raw.rock);
MusicManager.getInstance().playMusic();
Here's the code
Main:
public class MainActivity extends Activity{
ImageView startB;
Bitmap b = null;
int keyCode = 0;
boolean onKeyDown = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getApplication().registerActivityLifecycleCallbacks(new MYLifeCycleHandler(getApplication())); // New error:the constructor MYLifeCycleHandler is undefined
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
/* adapt the image to the size of the display */
Display d = getWindowManager().getDefaultDisplay();
Point p = new Point();
d.getSize(p);
b = Bitmap.createScaledBitmap(
BitmapFactory.decodeResource(getResources(), R.drawable.screen1),//b
p.x, p.y, true);
setContentView(R.layout.activity_main);
RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl1);
rl.setBackgroundDrawable(new BitmapDrawable(getResources(), b));
ImageView startB = (ImageView) findViewById(R.id.startbutton);
MusicManager.getInstance().initializeMediaPlayer(this, R.raw.rock);
MusicManager.getInstance().playMusic();
if(keyCode == KeyEvent.KEYCODE_HOME)
{
onKeyDown = true;
}
startB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent myIntent = new Intent(getApplicationContext(), WorkoutPlace2.class);
startActivity(myIntent);
finish();
}
});
}
#Override
public void onBackPressed(){
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}
public void onHomePressed(){
if (onKeyDown = true){
AudioManager manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
manager.setStreamMute(AudioManager.STREAM_MUSIC, true);
android.os.Process.killProcess(android.os.Process.myPid());
}
}
/*#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_HOME)
{
android.os.Process.killProcess(android.os.Process.myPid());
}
return super.onKeyDown(keyCode, event);
}*/
#Override
protected void onPause() {
super.onPause();
Context context = getApplicationContext();
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> taskInfo = am.getRunningTasks(1);
if (!taskInfo.isEmpty()) {
ComponentName topActivity = taskInfo.get(0).topActivity;
if (!topActivity.getPackageName().equals(context.getPackageName())) {
MusicManager.getInstance().stopMusic();
Toast.makeText(MainActivity.this, "YOU LEFT YOUR APP", Toast.LENGTH_SHORT).show();
AudioManager manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
manager.setStreamMute(AudioManager.STREAM_MUSIC, true);
}
}
if (b != null){
b.recycle();
b = null;
}
}
#Override
protected void onResume(){
super.onResume();
MusicManager.getInstance().playMusic();
}
}
MYLifeCycleHadler:
Exactly as in your updated post
You should use activitylifecyclecallbacks to check whether app is foreground or background. It was added in api level 14.
You may use the following code
#SuppressLint("NewApi")
public class MYLifeCycleHandler implements ActivityLifecycleCallbacks
{
private static int resumed;
private static int paused;
private static int started;
private static int stopped;
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState)
{
}
#Override
public void onActivityDestroyed(Activity activity)
{
}
#Override
public void onActivityResumed(Activity activity)
{
++resumed;
}
#Override
public void onActivityPaused(Activity activity)
{
++paused;
}
#Override
public void onActivityStarted(Activity activity) {
++started;
if(started > stopped)
{
//start music player if not already running
MusicManager.getInstance().playMusic();
}
}
public boolean isApplicationInForeground()
{
return resumed > paused;
}
#Override
public void onActivityStopped(Activity activity) {
++stopped;
//if application in background
if(stopped == started)
{
//stop music player if running
MusicManager.getInstance().stopMusic();
}
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState)
{
}
}
You should register for callbacks as follows
getApplication().registerActivityLifecycleCallbacks(new MPLifeCycleHandler());
Ideally register in the onCreate of your first activity
Related
I recently worked in the project for making screen dimmer app but I stuck with one problem. In my app, there is MaterialAnimatedSwitch it works fine but when the app goes to the backhand, the switch is automatically off but the working of the app is perfectly continued. I want that the switch remains active or on whenever the user come back to the app interface.I use MaterialAnimatedSwitch so how to do this task.
i want the switch to be active or ON whenever the app resumes.
public class MainActivity extends AppCompatActivity {
int b1 = 40;
int b2 = 90;
DiscreteSeekBar bSeekBar;
ChatHeadService binder=null;
boolean isOn = false;
boolean mBounded;
public boolean isRunning=false;
ServiceConnection mConnection = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) {
mBounded = false;
mService = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBounded = true;
LocalBinder mLocalBinder = (LocalBinder) service;
mService = mLocalBinder.getServerInstance();
int brightness = mService.getBrightness();
int brightness2 = mService.getBrightness2();
seekBar.setProgress(brightness);
bSeekBar.setProgress(brightness2);
}
};
ChatHeadService mService;
RadioGroup radioGroup;
DiscreteSeekBar seekBar;
MaterialAnimatedSwitch aSwitch;
SharedPreferences sharedPrefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fabric.with(this, new Kit[]{new Crashlytics()});
setContentView(R.layout.activity_main);
initInstances();
if (isOn && !isMyServiceRunning(ChatHeadService.class)) {
startService(new Intent(this, ChatHeadService.class));
}
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
for (RunningServiceInfo service : ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE)).getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
private void initInstances() {
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
seekBar = (DiscreteSeekBar) findViewById(R.id.seekBar);
bSeekBar = (DiscreteSeekBar) findViewById(R.id.brightnessSeekBar);
int b = sharedPrefs.getInt("b", 40);
int bb = sharedPrefs.getInt("bb", 90);
seekBar.setProgress(b);
bSeekBar.setProgress(bb);
aSwitch=(MaterialAnimatedSwitch)findViewById(R.id.switch1);
aSwitch.setClickable(sharedPrefs.getBoolean("isOn",false));
aSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(boolean b) {
if(b){
sharedPrefs.edit().putBoolean("isOn", true).apply();
isOn = true;
isRunning=aSwitch.isChecked();
startService(new Intent(MainActivity.this, ChatHeadService.class));
bindService();
}
else{
sharedPrefs.edit().putBoolean("isOn", false).apply();
isOn = false;
unBindService();
stopService(new Intent(MainActivity.this, ChatHeadService.class)); }
}
});
seekBar.setOnProgressChangeListener(new OnProgressChangeListener() {
public void onProgressChanged(DiscreteSeekBar seekBar, int value, boolean fromUser) {
b1 = value;
if (mService != null) {
mService.setBrightness(value, b2);
}
sharedPrefs.edit().putInt("b", value).apply();
}
public void onStartTrackingTouch(DiscreteSeekBar seekBar) {
}
public void onStopTrackingTouch(DiscreteSeekBar seekBar) {
}
});
bSeekBar.setOnProgressChangeListener(new OnProgressChangeListener() {
public void onProgressChanged(DiscreteSeekBar seekBar, int value, boolean fromUser) {
b2 = value;
if (mService != null) {
mService.setBrightness(b1, value);
}
sharedPrefs.edit().putInt("bb", value).apply();
}
public void onStartTrackingTouch(DiscreteSeekBar seekBar) {
}
public void onStopTrackingTouch(DiscreteSeekBar seekBar) {
}
});
}
#Override
protected void onStart() {
super.onStart();
if (isOn) {
bindService();
}
}
public void bindService() {
bindService(new Intent(this, ChatHeadService.class), mConnection,Context.BIND_AUTO_CREATE);
}
public void unBindService() {
if (mBounded) {
unbindService(mConnection);
mBounded = false;
}
}
#Override
protected void onPause() {
super.onPause();
isRunning=aSwitch.isPressed();
}
#Override
protected void onResume() {
super.onResume();
if(!isOn == aSwitch.isPressed()){
aSwitch.toggle();
}
}
}
Thanks in advance!
This is the screenshot when app is just open
This is the screenshot when night mode is ON
But When the going to backhand and then open the switch state changed
You are saving switch state in Shared preferences but not using it.
just add the following line above aswitch.setOnCheckedChangeListener
line, it will apply the state you saved in preferences
aSwitch.setChecked(sharedPrefs.getBoolean("isOn", false)); //false default
I suggest store value of your switch in one of your global variable and at time resume set it with the switch again like below:
public boolean isRunning = false;
#Override
protected void onPause() {
super.onPause();
isRunning = switchAler.isChecked();
}
#Override
protected void onResume() {
super.onResume();
binding.switchAler.setChecked(isRunning);
if(!isRunning == switchAler.isChecked()){
switchAler.toggle();
}
}
I am trying to play background music in simple game on Android using Services.
Using the link: Android Life Cycles
But this code doesn't work properly, onResumeActivity, onPauseActivity are called but the music keep running in background even when the onPauseActivity method is called.
The music keeps on playing while the app is in background.
is there any other way to play background music in an Android App/Game??
I think this code will work for you. Add this class (Enclosed in your activity class).
public class BackgroundMusic extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
MediaPlayer backgroundmusic = MediaPlayer.create(YourActivity.this, R.raw.yourbackgroundmusic);
player.setVolume(100,100);
player.setLooping(true);
player.start();
return null;
}
}
And create it
BackgroundMusic bm = new BackgroundMusic();
On onResume method:
public void onResume() {
super.onResume();
bm.execute(null);
}
And onPause method:
public void onPause() {
super.onPause();
bm.cancel(true);
}
Hope this help!
public class SoundGameBaseActivity extends Activity {
public static boolean isSoundPaused = false;
public static MediaPlayer mp;
protected static final String TAG = SoundGameBaseActivity.class.getName();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
playMusic();
}
public static boolean isAppWentToBg = false;
public static boolean isWindowFocused = false;
public static boolean isMenuOpened = false;
public static boolean isBackPressed = false;
#Override
protected void onStart() {
Log.d(TAG, "onStart isAppWentToBg " + isAppWentToBg);
applicationWillEnterForeground();
super.onStart();
}
private void applicationWillEnterForeground() {
if (isAppWentToBg) {
//Google Analytics
MyApp.getInstance().trackScreenView("ApplicationActivated");
isAppWentToBg = false;
// Toast.makeText(getApplicationContext(), "App is in foreground",
// Toast.LENGTH_SHORT).show();
playMusic();
}
}
#Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop ");
applicationdidenterbackground();
}
public void applicationdidenterbackground() {
if (!isWindowFocused) {
isAppWentToBg = true;
Toast.makeText(getApplicationContext(),
"App is Going to Background", Toast.LENGTH_SHORT).show();
stopMusic();
}
}
public void TurnOnMusicAgain() {
}
void playMusic() {
if (mp == null) {
mp = MediaPlayer.create(this, R.raw.background1);
// mp.prepare();
mp.start();
mp.setLooping(true);
} else {
if (mp.isPlaying()) {
} else {
Log.e("", "coming back");
mp.start();
}
}
}
void stopMusic() {
if (mp != null)
mp.pause();
}
#Override
public void onBackPressed() {
if (this instanceof StartScreen) {
} else {
isBackPressed = true;
}
Log.d(TAG,
"onBackPressed " + isBackPressed + ""
+ this.getLocalClassName());
super.onBackPressed();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
isWindowFocused = hasFocus;
Log.e("Is Window Focus", "" + isWindowFocused);
if (isBackPressed && !hasFocus) {
isBackPressed = false;
isWindowFocused = true;
}
super.onWindowFocusChanged(hasFocus);
}
}
I need a background music which is continuously playing through Activities. I want to stop my background music when clicking on the Home Button.
This is my Service Code.
public class BackgroundSoundService extends Service
{
private static final String TAG = null;
MediaPlayer player;
Context context;
private int length = 0;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.haha);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
#Override
public void onStart(Intent intent, int startId) {
player.start();
}
public IBinder onUnBind(Intent arg0) {
return null;
}
public void onStop() {
player.stop();
player.release();
player = null;
}
public void onPause() {
player.pause();
}
public void onHomePressed(){
player.stop();
}
public void pauseMusic()
{
if(player.isPlaying())
{
player.pause();
length=player.getCurrentPosition();
}
}
public void resumeMusic()
{
if(player.isPlaying()==false)
{
player.seekTo(length);
player.start();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if(player != null)
{
try{
player.stop();
player.release();
}finally {
player = null;
}
}
}
#Override
public void onLowMemory() {
}
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(this, "music player failed", Toast.LENGTH_SHORT).show();
if(player != null)
{
try{
player.stop();
player.release();
}finally {
player = null;
}
}
return false;
}
}
This is my 1st Activity Class
public class AdventureTime extends Activity implements OnClickListener {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.story);
Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc);
View story1 = this.findViewById(R.id.button1);
story1.setOnClickListener(this);
View story2 = this.findViewById(R.id.button2);
story2.setOnClickListener(this);
View story3 = this.findViewById(R.id.button3);
story3.setOnClickListener(this);
View back= this.findViewById(R.id.buttonback);
back.setOnClickListener(this);
}
#Override
public void onBackPressed(){
new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle("Exit")
.setMessage("Are you sure you want to exit?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
System.exit(0);
}
}).setNegativeButton("No", null).show();
}
public void onClick(View v) {
switch(v.getId()){
case R.id.button1:
Intent button1 = new Intent(this, Story1.class);
startActivity(button1);
break;
case R.id.button2:
Intent button2 = new Intent(this, Story2.class);
startActivity(button2);
break;
case R.id.button3:
Intent button3 = new Intent(this, Story3.class);
startActivity(button3);
break;
case R.id.buttonback:
Intent buttonback = new Intent(this, MainActivity.class);
startActivity(buttonback);
break;
}
}
}
Add this in the Activity AdventureTime :
...
#Override
public void onPause(){
stopService(svc);
super.onPause();
}
...
if you want to pause music without stopping your service
try this
add this class in your service
public class LocalBinder extends Binder {
BackgroundSoundService getService() {
return BackgroundSoundService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
and add this in your activity
private BackgroundSoundService mBoundService;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mBoundService = ((BackgroundSoundService.LocalBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
}
};
replace
startService(svc)
with
bindService(svc, mConnection, Context.BIND_AUTO_CREATE);
and call the pause method in service whenever u need it
mBoundService.pauseMusic();
Why don't you try to listen to a dispatchKeyEvent instead? You could write:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_HOME) {
stopService(svc)
return true;
}
else
return super.dispatchKeyEvent(event);
}
on each of your activities.
on you mainActivity class add this.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_HOME) {
// pause or stop ung Background music here.
return true;
}
return false;
}
i use surfaceview for my game.
When the game is complete it'll automatically start other activity (score activity) by this intent :
mContext = getContext();
Intent intent = new Intent(mContext, ScoreScreen.class);
mContext.startActivity(intent);
it works fine, but has one problem when i want to close that score activity then back to surfaceview ("Try again" button).
i use this code to finish score activity:
tryagain.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
but it don't want back to surfaceview
Help me..
sorry for my bad english
this my SurfaceviewScreen :
public class SurfaceScreen extends Activity {
OurView v;
int level =1, lives = 3, score=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
v = new OurView(this);
v.setKeepScreenOn(true);
setContentView(v);
}
#Override
protected void onPause() {
super.onPause();
v.pause();
}
#Override
protected void onResume() {
super.onResume();
v.resume();
}
public class OurView extends SurfaceView implements Runnable {
Thread t = null;
SurfaceHolder holder;
boolean isItOK = false;
boolean spriteLoaded = false;
private Context mContext;
Paint paint = new Paint();
public OurView(Context context) {
super(context);
this.mContext = context;
mContext = getContext();
holder = getHolder();
}
#Override
public void run() {
while (isItOK) {
if (!holder.getSurface().isValid()) {
continue;
}
update();
Canvas c = holder.lockCanvas();
onDraw(c);
holder.unlockCanvasAndPost(c);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void pause() {
isItOK = false;
while (true) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
t = null;
}
public void resume() {
isItOK = true;
t = new Thread(this);
t.start();
}
protected void update(){
if(lives<1){
Intent i = new Intent(mContext, gameover.class);
i.putExtra("msg", "LOSE");
mContext.startActivity(i);
}
//updating
}
#Override
protected void onDraw(Canvas canvas) {
//drawing
}
}
}
}
and this is my ScoreScreen code :
public class ScoreScreen extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scorescreen);
TextView txtResult = (TextView)findViewById(R.id.scorescreen_result);
Button tryagain = (Button)findViewById(R.id.scorescreen_tryagain);
Intent i = this.getIntent();
txtResult.setText(i.getStringExtra("msg"));
tryagain.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
}
As far as I can uderstand your question you should try
ScoreActivity.this.finish();
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;
...