0

I want to implement functionality when an app goes in the background the GPS should automatically Off and when an app in the foreground the GPS should automatically On. I've referred https://stackoverflow.com/a/44668999/9635628 for Enable GPS It's working fine but how can I disable when an app goes in the background?

Please, help me to solve it!

I've tried below code

    class ArchLifecycleApp : Application(), LifecycleObserver {

        override fun onCreate() {
            super.onCreate()
            ProcessLifecycleOwner.get().lifecycle.addObserver(this)
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
        fun onAppBackgrounded() {
            Log.d("App", "App in background")
            offGPS() 
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_START)
        fun onAppForegrounded() {
            Log.d("App", "App in foreground")
            enableLoc() 
        }
    }

private fun enableLoc() {

        if (googleApiClient == null) {
            googleApiClient = GoogleApiClient.Builder(this@MainActivity)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(object : GoogleApiClient.ConnectionCallbacks {
                        override fun onConnected(bundle: Bundle?) {

                        }

                        override fun onConnectionSuspended(i: Int) {
                            googleApiClient!!.connect()
                        }
                    })
                    .addOnConnectionFailedListener { connectionResult -> Log.d("Location error", "Location error " + connectionResult.errorCode) }.build()
            googleApiClient!!.connect()

            val locationRequest = LocationRequest.create()
            locationRequest.priority = LocationRequest.PRIORITY_NO_POWER
            locationRequest.interval = (30 * 1000).toLong()
            locationRequest.fastestInterval = (5 * 1000).toLong()
            val builder = LocationSettingsRequest.Builder()
                    .addLocationRequest(locationRequest)

            builder.setAlwaysShow(true)

            val result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build())
            result.setResultCallback(object : ResultCallback<LocationSettingsResult> {
                override fun onResult(result: LocationSettingsResult) {
                    val status = result.status
                    when (status.statusCode) {
                        LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try {
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(this@MainActivity, REQUEST_LOCATION)

//                            finish()
                        } catch (e: IntentSender.SendIntentException) {
                            // Ignore the error.
                        }
                    }
                }
            })
        }
    }
fun offGPS() {
        var provider = Settings.Secure.getString(contentResolver, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)
        if (provider.contains("gps")) { //if gps is enabled
            var poke: Intent = Intent();
            poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
            poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
            poke.setData(Uri.parse("3"));
            sendBroadcast(poke);
        }
    }
Komal
  • 79
  • 1
  • 10
  • 2
    Do you want to turn GPS off for your app or all apps? If just for your app, simply unregister your request. If for all apps- why? That seems user unfriendly. – Gabe Sechan Sep 20 '18 at 06:14
  • Not for all apps, I want just for my app. – Komal Sep 20 '18 at 06:20

3 Answers3

1

Try this solution

private void turnGPSOff() {
    String provider = Settings.Secure.getString(getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);

    if(provider.contains("gps")){ //if gps is enabled
        final Intent poke = new Intent();
        poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
        poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
        poke.setData(Uri.parse("3")); 
        sendBroadcast(poke);
    }
}

Hope this will work for you.

Ircover
  • 2,406
  • 2
  • 22
  • 42
Rashpal Singh
  • 633
  • 3
  • 13
  • When app is going on froground the always onResume will call and when background then onPause will call, So check on these method that gps is on/off. you can also check this link https://stackoverflow.com/questions/4721449/how-can-i-enable-or-disable-the-gps-programmatically-on-android – Rashpal Singh Sep 20 '18 at 06:38
  • I've seen and tried as well but for disabling GPS It's not working. Have you another idea about it? – Komal Sep 20 '18 at 06:45
  • is you have Base Activity? – Rashpal Singh Sep 20 '18 at 06:58
  • No an Application() class which implements LifecycleObserver and I tried in Activity on button click as well but the outcome is same. – Komal Sep 20 '18 at 07:01
  • There is two solution. In first solution in the activity override onResume and call on Gps On method and In onPause method call gps off method. – Rashpal Singh Sep 20 '18 at 07:07
  • I also tried it but the GPS is not disabling. I made a demo which contains two buttons On and Off and doing the same for the testing purpose but not working! btnGPSOn.setOnClickListener { turnGpsOn(this@MainActivity) } btnGPSOff.setOnClickListener { turnGpsOff(this@MainActivity) } – Komal Sep 20 '18 at 07:10
1

Second solution is

/** * Method checks if the app is in background or not */

fun isAppIsInBackground(context : Context) : Boolean{
    var isInBackground = true
    val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH) {
        val runningProcesses = am.runningAppProcesses
        for (processInfo in runningProcesses) {
            if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                for (activeProcess in processInfo.pkgList) {
                    if (activeProcess.equals(context.packageName)) {
                        isInBackground = false
                    }
                }
            }
        }
    } else {
        val taskInfo = am.getRunningTasks(1)
        val componentInfo = taskInfo.get(0).topActivity
        if (componentInfo.packageName.equals(context.packageName)) {
            isInBackground = false
        }
    }

    return isInBackground
}
Rashpal Singh
  • 633
  • 3
  • 13
  • Thanks, @Rashpal Singh but My query was GPS not disabling if I'm checking in Foreground/Background OR on click, the issue is to disable GPS. – Komal Sep 20 '18 at 07:19
1

First, in your Application class you should register a detector like this:

registerActivityLifecycleCallbacks(new Detector());

In the detector, which is an instance of Application.ActivityLifecycleCallbacks you should keep a count of activities resumed and paused like this:

/**Detector class**/

@Override
public void onActivityResumed(Activity activity) {
    mActivitiesResumed++;
    if (mInBackground) {
        mInBackground = false;
        // App is in background
    }
}

@Override
public void onActivityPaused(Activity activity) {
    mActivitiesResumed--;
}

@Override
public void onActivityStopped(Activity activity) {
    if (mActivitiesResumed == 0) {
        mInBackground = true;
        // App is in foreground
    }
}

And that should be it. I've this class working in production flawlessly.

Reinherd
  • 5,476
  • 7
  • 51
  • 88