Skip to content
Snippets Groups Projects
Unverified Commit fc2f4483 authored by Oliver Zimmerman's avatar Oliver Zimmerman Committed by GitHub
Browse files

Implemented a location state within connectivity helper (EXPOSUREAPP-1618) (#853)


* Implemented state check for location

* formatting

* removed duplicate manifest item

* Update ConnectivityHelper.kt

* Update ConnectivityHelper.kt

Co-authored-by: default avatarPhilipp Woessner <64482866+pwoessner@users.noreply.github.com>
parent 707c8fa3
No related branches found
No related tags found
No related merge requests found
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
android:required="true" /> android:required="true" />
<uses-feature android:name="android.hardware.bluetooth" /> <uses-feature android:name="android.hardware.bluetooth" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission <uses-permission
android:name="android.permission.BLUETOOTH" android:name="android.permission.BLUETOOTH"
android:required="true" /> android:required="true" />
......
...@@ -25,6 +25,7 @@ object SettingsRepository { ...@@ -25,6 +25,7 @@ object SettingsRepository {
val isManualKeyRetrievalEnabled = MutableLiveData(true) val isManualKeyRetrievalEnabled = MutableLiveData(true)
val isConnectionEnabled = MutableLiveData(true) val isConnectionEnabled = MutableLiveData(true)
val isBluetoothEnabled = MutableLiveData(true) val isBluetoothEnabled = MutableLiveData(true)
val isLocationEnabled = MutableLiveData(true)
val isBackgroundJobEnabled = MutableLiveData(true) val isBackgroundJobEnabled = MutableLiveData(true)
val isBackgroundPriorityEnabled = MutableLiveData(false) val isBackgroundPriorityEnabled = MutableLiveData(false)
val manualKeyRetrievalTime = MutableLiveData<Long>() val manualKeyRetrievalTime = MutableLiveData<Long>()
...@@ -95,6 +96,15 @@ object SettingsRepository { ...@@ -95,6 +96,15 @@ object SettingsRepository {
isBluetoothEnabled.postValue(value) isBluetoothEnabled.postValue(value)
} }
/**
* Refresh global location state to point out that tracing isn't working
*
* @see ConnectivityHelper
*/
fun updateLocationEnabled(value: Boolean) {
isLocationEnabled.postValue(value)
}
/** /**
* Refresh global bluetooth state to point out that tracing isn't working * Refresh global bluetooth state to point out that tracing isn't working
* *
......
...@@ -60,6 +60,19 @@ class MainActivity : AppCompatActivity() { ...@@ -60,6 +60,19 @@ class MainActivity : AppCompatActivity() {
} }
} }
/**
* Register location callback.
*/
private val callbackLocation = object : ConnectivityHelper.LocationCallback() {
override fun onLocationAvailable() {
settingsViewModel.updateLocationEnabled(true)
}
override fun onLocationUnavailable() {
settingsViewModel.updateLocationEnabled(false)
}
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main) setContentView(R.layout.activity_main)
...@@ -73,6 +86,7 @@ class MainActivity : AppCompatActivity() { ...@@ -73,6 +86,7 @@ class MainActivity : AppCompatActivity() {
super.onResume() super.onResume()
ConnectivityHelper.registerNetworkStatusCallback(this, callbackNetwork) ConnectivityHelper.registerNetworkStatusCallback(this, callbackNetwork)
ConnectivityHelper.registerBluetoothStatusCallback(this, callbackBluetooth) ConnectivityHelper.registerBluetoothStatusCallback(this, callbackBluetooth)
ConnectivityHelper.registerLocationStatusCallback(this, callbackLocation)
settingsViewModel.updateBackgroundJobEnabled(ConnectivityHelper.isBackgroundJobEnabled(this)) settingsViewModel.updateBackgroundJobEnabled(ConnectivityHelper.isBackgroundJobEnabled(this))
scheduleWork() scheduleWork()
} }
...@@ -84,6 +98,7 @@ class MainActivity : AppCompatActivity() { ...@@ -84,6 +98,7 @@ class MainActivity : AppCompatActivity() {
super.onPause() super.onPause()
ConnectivityHelper.unregisterNetworkStatusCallback(this, callbackNetwork) ConnectivityHelper.unregisterNetworkStatusCallback(this, callbackNetwork)
ConnectivityHelper.unregisterBluetoothStatusCallback(this, callbackBluetooth) ConnectivityHelper.unregisterBluetoothStatusCallback(this, callbackBluetooth)
ConnectivityHelper.unregisterLocationStatusCallback(this, callbackLocation)
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
......
...@@ -21,6 +21,8 @@ class SettingsViewModel : ViewModel() { ...@@ -21,6 +21,8 @@ class SettingsViewModel : ViewModel() {
SettingsRepository.isConnectionEnabled SettingsRepository.isConnectionEnabled
val isBluetoothEnabled: LiveData<Boolean> = val isBluetoothEnabled: LiveData<Boolean> =
SettingsRepository.isBluetoothEnabled SettingsRepository.isBluetoothEnabled
val isLocationEnabled: LiveData<Boolean> =
SettingsRepository.isLocationEnabled
// Will impact UI if background activity is not permitted, persistent storing is not necessary // Will impact UI if background activity is not permitted, persistent storing is not necessary
val isBackgroundJobEnabled: LiveData<Boolean> = SettingsRepository.isBackgroundJobEnabled val isBackgroundJobEnabled: LiveData<Boolean> = SettingsRepository.isBackgroundJobEnabled
...@@ -100,6 +102,15 @@ class SettingsViewModel : ViewModel() { ...@@ -100,6 +102,15 @@ class SettingsViewModel : ViewModel() {
SettingsRepository.updateBluetoothEnabled(value) SettingsRepository.updateBluetoothEnabled(value)
} }
/**
* Update location enabled
*
* @param value
*/
fun updateLocationEnabled(value: Boolean) {
SettingsRepository.updateLocationEnabled(value)
}
/** /**
* Update background job enabled * Update background job enabled
* *
......
...@@ -6,11 +6,13 @@ import android.content.BroadcastReceiver ...@@ -6,11 +6,13 @@ import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.location.LocationManager
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.Network import android.net.Network
import android.net.NetworkCapabilities import android.net.NetworkCapabilities
import android.net.NetworkRequest import android.net.NetworkRequest
import android.os.Build import android.os.Build
import androidx.core.location.LocationManagerCompat
import de.rki.coronawarnapp.exception.ExceptionCategory import de.rki.coronawarnapp.exception.ExceptionCategory
import de.rki.coronawarnapp.exception.reporting.report import de.rki.coronawarnapp.exception.reporting.report
import timber.log.Timber import timber.log.Timber
...@@ -71,6 +73,63 @@ object ConnectivityHelper { ...@@ -71,6 +73,63 @@ object ConnectivityHelper {
callback.recevier = null callback.recevier = null
} }
/**
* Register location state change listener.
*
* @param context the context
* @param callback the location state callback
*
*/
fun registerLocationStatusCallback(context: Context, callback: LocationCallback) {
val receiver = object : BroadcastReceiver() {
var isGpsEnabled: Boolean = false
var isNetworkEnabled: Boolean = false
override fun onReceive(context: Context, intent: Intent) {
intent.action?.let { act ->
if (act.matches("android.location.PROVIDERS_CHANGED".toRegex())) {
val locationManager =
context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
isGpsEnabled =
locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
isNetworkEnabled =
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
if (isGpsEnabled || isNetworkEnabled) {
callback.onLocationAvailable()
Timber.d("Location enabled")
} else {
callback.onLocationUnavailable()
Timber.d("Location disabled")
}
}
}
}
}
callback.recevier = receiver
context.registerReceiver(
callback.recevier,
IntentFilter("android.location.PROVIDERS_CHANGED")
)
// location state doesn't change when you register
if (isLocationEnabled(context))
callback.onLocationAvailable()
else
callback.onLocationUnavailable()
}
/**
* Unregister location state change listener.
*
* @param context the context
* @param callback the location state callback
*
*/
fun unregisterLocationStatusCallback(context: Context, callback: LocationCallback) {
context.unregisterReceiver(callback.recevier)
callback.recevier = null
}
/** /**
* Unregister network state change callback. * Unregister network state change callback.
* *
...@@ -158,6 +217,17 @@ object ConnectivityHelper { ...@@ -158,6 +217,17 @@ object ConnectivityHelper {
return bAdapter.isEnabled return bAdapter.isEnabled
} }
/**
* Get location enabled status.
*
* @return current location status
*
*/
fun isLocationEnabled(context: Context): Boolean {
val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
return LocationManagerCompat.isLocationEnabled(locationManager)
}
/** /**
* Get network enabled status. * Get network enabled status.
* *
...@@ -190,6 +260,24 @@ object ConnectivityHelper { ...@@ -190,6 +260,24 @@ object ConnectivityHelper {
abstract fun onBluetoothUnavailable() abstract fun onBluetoothUnavailable()
} }
/**
* Abstract location state change callback.
*
* @see BroadcastReceiver
*/
abstract class LocationCallback {
var recevier: BroadcastReceiver? = null
/**
* Called when location is turned on.
*/
abstract fun onLocationAvailable()
/**
* Called when location is turned off.
*/
abstract fun onLocationUnavailable()
}
/** /**
* Abstract network state change callback. * Abstract network state change callback.
* *
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment