0

I have a BaseActivity that gets extended by every other activity. The thing is, I have the music muted whenever the user leaves (onPause) the activity. I also stop listening for telephone calls. The problem is, onPause is getting called whenever the user switches between activities, meaning the app is unnecessarily muting and stopping telephonymanager, even though it should only be muting and stopping telephonymanager if the user were to leave the app.:

@Override
    protected void onPause() {

        Log.v(TAG, "IN onPause!");
        // unregister phone listener to telephony manager
        tManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);

        mute();

        super.onPause();
    }

Now say I switch between public class myClass extends BaseActivity and switch to public class myOtherClass extends BaseActivity. This switch is unnecessarily executing onPause, even though I only want onPause to be called when the user leaves the app. What should I do?

Thanks for the expert advice,

Rich

Ruchir Baronia
  • 7,406
  • 5
  • 48
  • 83
  • Write the code for muting music player inside your MusicplayActiviti instead of writing in BaseActivity – droidev Nov 11 '15 at 18:16
  • Sounds like it's working as intended. The `onPause` method of an `Activity` gets called when another `Activity` comes into the foreground: https://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle – Cory Charlton Nov 11 '15 at 18:38
  • @CoryCharlton So what do you suggest I use. My intention is to mute and stop the `telephoney manager` when the user exits the app. Since I can't use `onPause`, what should I use? – Ruchir Baronia Nov 11 '15 at 18:39
  • @Rich see my answer below – Cory Charlton Nov 11 '15 at 18:56

2 Answers2

1

From my understanding you are muting your music playing in onPause of BaseActivity, instead of that write it inside your Music play activity

Ex :

 public class BaseActivity extends AppCompatActivity{

     @Override
     public void onPause(){
      //do things that common for all activities
     }
    }


public void MusicPlayActivity extends AppCompatActivity{

 @Override
 public void onPause(){
 music.mute()
 }
}

This will work

UPDATE

There are few ways to detect whether your application is running in the background, but only one of them is completely reliable: Track visibility of your application by yourself using Activity.onPause, Activity.onResume methods. Store "visibility" status in some other class.

Example : Implement custom Application class (note the isActivityVisible() static method):

public class MyApplication extends Application {

  public static boolean isActivityVisible() {
    return activityVisible;
  }  

  public static void activityResumed() {
    activityVisible = true;
  }

  public static void activityPaused() {
    activityVisible = false;
  }

  private static boolean activityVisible;
}

Register your application class in AndroidManifest.xml:

<application
    android:name="your.app.package.MyApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name" >

Add onPause and onResume to every Activity in the project (you may create a common ancestor for your Activities if you'd like to, but if your activity is already extended from MapActivity/ListActivity etc. you still need to write the following by hand):

@Override
protected void onResume() {
  super.onResume();
  MyApplication.activityResumed();
}

@Override
protected void onPause() {
  super.onPause();
  MyApplication.activityPaused();
}

ActivityLifecycleCallbacks were added in API level 14 (Android 4.0). You can use them to track whether an activity of your application is currently visible to the user. Check Cornstalks' answer below for the details.

droidev
  • 7,352
  • 11
  • 62
  • 94
0

From your comments you only want to stop the music when the last Activity of your application is exiting. Overriding the finish() method of your BaseActivity like this should accomplish what you want:

@Override
public void finish() {
    super.finish();

    if (isTaskRoot()) {
        // This is the last Activity in the stack so mute your music here...
    }
}

Actually you probably want onDestroy() or onStop() as I'm not sure finish() executes unless you call it but the idea is the same:

@Override
protected void onDestroy() {
    super.onDestroy();

    if (isTaskRoot()) {
        // This is the last Activity in the stack so mute your music here...
    }
}

Here's info on isTaskRoot():

Return whether this activity is the root of a task. The root is the first activity in a task.

Returns

True if this is the root activity, else false.

Cory Charlton
  • 8,868
  • 4
  • 48
  • 68
  • Okay, so if I am on Activity A and I exit out, will `finish()` get called? And `finish()` shouldn't be called if I just switch from Activity A to Activity B. Thanks – Ruchir Baronia Nov 11 '15 at 18:58
  • `isTaskRoot` will only see if it's the last activity in the activityStack. But that's not what I want, instead I want the app to do the mute code when the user exits out. It doesn't matter when or where the user exits out, but when he/she does, I want to mute it – Ruchir Baronia Nov 11 '15 at 19:03
  • @Rich `finish()` will get called when the user presses the back button. See this post for the home button: https://stackoverflow.com/questions/4783960/call-method-when-home-button-pressed-on-android from your last comment though you now need to handle the cases where the user launches a new app from the notification, etc. – Cory Charlton Nov 11 '15 at 19:09
  • Okay, so I tried `finish()`, but the same issue is there. It gets called every activity also...What should I try next? I will mark you best answer and like your post once I get this. Thanks! – Ruchir Baronia Nov 11 '15 at 19:36
  • So I think these only get called when the **activity** is finished, rather than the app. How can I detect whether the **app** is finished? – Ruchir Baronia Nov 11 '15 at 19:50
  • @Rich, yes these are all `Activity` lifecycle methods. The `Application` doesn't have lifecycle methods like this. There are hacks such as this: https://stackoverflow.com/questions/8489993/check-android-application-is-in-foreground-or-not but I wouldn't recommend them. They also don't directly solve your problem because the `Application` can run without any activities (ie: if a `Service` is running). – Cory Charlton Nov 11 '15 at 20:44
  • So what do you suggest I do? – Ruchir Baronia Nov 11 '15 at 20:47
  • Is it impossible to properly check if an app has been exited out of? Because I see games with multiple activities do it all the time? When there is music playing, and I press the home button, the app silents itself – Ruchir Baronia Nov 11 '15 at 20:48
  • How does that work? And can I use the same kind of code? – Ruchir Baronia Nov 11 '15 at 20:48
  • @Rich They probably do like I noted in an earlier comment and also watch for the user pressing the home button as outlined here: https://stackoverflow.com/questions/4783960/call-method-when-home-button-pressed-on-android I'm not sure there's going to be a single, one size fits all, solution for what you want to achieve and will need to cover all aspects (ie: user presses back button on last activity [finish solution in my answer should cover this], user presses home button, user launches another application from a notification, etc.) – Cory Charlton Nov 11 '15 at 20:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/94855/discussion-between-rich-and-cory-charlton). – Ruchir Baronia Nov 11 '15 at 21:00