I want to detect if the user turned off the location at runtime. I can check if he turns it on or if the location was turned off by user before the app was started but I can't check if he turned it off after.
Code Sample:
MapEntity
extends LocationListener
class MapViewer(a: MainActivity, parentView: ViewGroup) : MapEntity(a, parentView) {
override fun onProviderEnabled(provider: String?) {
activity.hideGpsSnackbar()
}
override fun onProviderDisabled(provider: String?) {
activity.showGpsSnackbar()
}
}
For realtime GPS location checking, I'm using GnssStatus.Callback()
UPDATE:
I've created BroadcastReceiver
according to the answer below.
abstract class GPSReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
try {
val locationManager = context.getSystemService(LOCATION_SERVICE) as LocationManager
if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
onGpsChanged(true)
} else {
onGpsChanged(false)
}
} catch (ex: Exception) {
App.log("IsGPSEnabled: $ex")
}
}
abstract fun onGpsChanged(isEnabled: Boolean)
}
Code inside one of my Activities:
private val gpsStatusReceiver = object : GPSReceiver() {
override fun onGpsChanged(isEnabled: Boolean) {
if (isEnabled){
hideGpsSnackbar()
} else {
showGpsSnackbar()
}
}
}
override fun onStart() {
super.onStart()
registerReceiver(gpsStatusReceiver, IntentFilter())
}
override fun onStop() {
super.onStop()
unregisterReceiver(gpsStatusReceiver)
}
UPDATE
If you want to support Android 6.0, you cannot use abstract class. Because it will try to create object out of this class defined in AndroidManifest. Android 8.0+ will not check receiver inside AndroidManifest so you can instantiate object out of Abstract Class. So instead of it create interface.
I'm actually doing it with a BroadcastReceiver
.
I can share my code; it's java but I think you can easily convert it into kotlin.
Broadcastreceiver
Example:
public class GPSBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
try {
LocationManager locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
//isGPSEnabled = true;
} else {
//isGPSEnabled = false;
}
}catch (Exception ex){
}
}
}
BroadcastReceiver
to the manifest
Example:
<receiver android:name=".others.GPSBroadcastReceiver">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Then (for my case) I manage it in my ApplicationContext
as follows:
private GPSBroadcastReceiver gpsBroadcastReceiver = new GPSBroadcastReceiver();
@Override
public void onCreate() {
....
registerReceiver(gpsBroadcastReceiver, new IntentFilter());
}
@Override
public void onTerminate() {
...
unregisterReceiver(gpsBroadcastReceiver);
}
That's just an example, there might be other ways for it but actually I'm fine with that one; good luck!
Edit:
try adding this permission in your manifest
<uses-permission android:name="android.permission.ACCESS_GPS" />
Edit:
For Android 8.0+ register your BroadcastReceiver
like this:
registerReceiver(gpsBroadcastReceiver,IntentFilter("android.location.PROVIDERS_CHANGED"))
Adding action inside AndroidManifest
will not work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With