9

I need to turn off Bluetooth when my app "goes to background"/"becomes inactive".

I tried to do it in onPause() of my MainActivity but that doesn't work since now BT goes off (onPause() of the Mainactivity is fired) even when I start a new activity showing an entity detail of chosen item from the Mainactivity.

What I need is some kind of "onPause()" of my App not of a single activity.

I think nothing like this exists so is there any preferable solution?

Petr B
  • 519
  • 2
  • 6
  • 15
  • Dude, I've faced this problem thousand times, but its our unfortunate that no such method or event exists.. You'll have to find a work around for it. – Abhishek Shukla Dec 09 '13 at 11:38
  • Put it in `onDestroy` and `onBackPressed` of the MainActivity so that when user closes the application bluetooth gets turned off. – Abhishek V Dec 09 '13 at 11:41
  • onDestroy() isn't what I'm looking for since it can take time to this method get called – Petr B Dec 10 '13 at 08:44

7 Answers7

16

Pull this dependency in your build.gradle file:

dependencies {
    implementation "android.arch.lifecycle:extensions:1.1.1"
}

Then in your Application class, use this:

public class MyApplication extends Application implements LifecycleObserver {

    @Override
    public void onCreate() {
        super.onCreate();
        ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    private void onAppBackgrounded() {
        Log.d("MyApp", "App in background");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    private void onAppForegrounded() {
        Log.d("MyApp", "App in foreground");
    }
}

Update your AndroidManifest.xml file:

<application
    android:name=".MyApplication"
    ....>
</application>
Sachin Upreti
  • 190
  • 1
  • 8
9

UPDATE: Beware, according to comments this does NOT work in all cases!!!

Solutions listed here on SO seem too complicated to me. I came up using this:

Create static variable accessible from all your Activities to detect count of currently running ones.

public class SharedData {
    static int runningActivities = 0;
}

In every activity override this two methods.

public void onStart() {
    super.onStart();
    if (SharedData.runningActivities == 0) {
        // app enters foreground
    }
    SharedData.runningActivities++;
}

public void onStop() {
    super.onStop();
    SharedData.runningActivities--;
    if (SharedData.runningActivities == 0) {
        // app goes to background
    }
}

You can create MyActivity extending Activity, put this code in it and make all your Activities extend this class.

Miroslav Hrivik
  • 822
  • 13
  • 16
  • 1
    this does NOT work this is also triggered when activity is resumed by backbutton or when activity is entered from another activity – CommonSenseCode Jan 14 '16 at 15:58
  • A pitfall of tracking activity count is rotation. Often times, the activity that is going down finishes completely before the new activity for the new configuration comes up resulting in incorrect background->foreground transition detection. – bduhbya Mar 03 '17 at 01:48
3

To detect that application is going to background, Override following method in Application class of your App :

@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);
    if(level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN)
        //called when app goes to background
}
Tarun Deep Attri
  • 8,174
  • 8
  • 41
  • 56
2

You can refer this question How to detect when an Android app goes to the background and come back to the foreground the guy who answered this solved using onFocuschanged don't know how much effective is this method,anyway keep researching in google

private boolean isApplicationBroughtToBackground() {
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List tasks = am.getRunningTasks(1);
    if (!tasks.isEmpty()) {
        ComponentName topActivity = tasks.get(0).topActivity;
        if (!topActivity.getPackageName().equals(context.getPackageName())) {
            return true;
        }
    }

    return false;
}
Community
  • 1
  • 1
insomniac
  • 11,146
  • 6
  • 44
  • 55
2

For a not single Activity app, I would recomend that every activity implements a time based control of visibility. Launch on every onPause() a timed status checker and also cancel this timer on every onResume() method.

Here an example

    @Override
protected void onPause() {
    TimerTask backgroundCheck = new TimerTask() {

        @Override
        public void run() {
            ActivityManager am = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);
            List<RunningTaskInfo> tasks = am.getRunningTasks(1);
            if (!tasks.isEmpty()) {
                ComponentName topActivity = tasks.get(0).topActivity;
                if (!topActivity.getPackageName().equals(getApplicationContext().getPackageName())) {
                    // APP in background, do something
                }
            }

            // APP in foreground, do something else
        }
    };

    Timer isBackgroundChecker = new Timer();
    isBackgroundChecker.schedule(backgroundCheck, 1000, 1000);

    super.onPause();
}

After implement that, remember to cancel the Timer isBackgroundChecker = new Timer();

iflorit
  • 740
  • 5
  • 10
2

It is not advisable to use RunningTaskInfo because its “method is only intended for debugging and presenting task management user interfaces“. well, if you are developing app for ICS and above I found this link very useful !

http://vardhan-justlikethat.blogspot.in/2013/05/android-solution-to-detect-when-android.html

spaceMonkey
  • 4,475
  • 4
  • 26
  • 34
1

You can implement the onPause() on every activity you have, but I don't think it's needed to turn off bluetooth by yourself, some users may be using bluetooth for some other reason, or they want to turn it of themselves (that's what I do )

TomTsagk
  • 1,474
  • 9
  • 23
  • 1
    this won't work since it would mean BT would go off if I leave Main activity and open anaother Activity which is part of my app – Petr B Dec 10 '13 at 08:41
  • you can maybe try working with fragments ? They can behave like activities and you can include them in a single activity, that turns of bluetooth when onPause() is called. – TomTsagk Dec 10 '13 at 11:03