AndroidAPS/app/src/main/java/info/nightscout/androidaps/services/LocationService.kt

148 lines
6 KiB
Kotlin
Raw Normal View History

2020-01-02 23:25:29 +01:00
package info.nightscout.androidaps.services
import android.Manifest
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationManager
import android.os.Bundle
import android.os.IBinder
import androidx.core.app.ActivityCompat
import com.google.android.gms.location.LocationServices
import dagger.android.DaggerService
2020-01-03 14:30:39 +01:00
import info.nightscout.androidaps.MainApp
2020-01-02 23:25:29 +01:00
import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.events.EventLocationChange
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import javax.inject.Inject
2020-01-05 12:02:32 +01:00
class LocationService @Inject constructor(): DaggerService() {
2020-01-02 23:25:29 +01:00
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var sp: SP
2020-01-03 14:30:39 +01:00
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var mainApp: MainApp
2020-01-02 23:25:29 +01:00
private val disposable = CompositeDisposable()
private var locationManager: LocationManager? = null
private var locationListener: LocationListener? = null
private val LOCATION_INTERVAL_ACTIVE = T.mins(5).msecs()
private val LOCATION_INTERVAL_PASSIVE = T.mins(1).msecs() // this doesn't cost more power
2020-01-05 12:02:32 +01:00
var lastLocation: Location? = null
2020-01-02 23:25:29 +01:00
companion object {
private const val LOCATION_DISTANCE = 10f
}
inner class LocationListener internal constructor(val provider: String) : android.location.LocationListener {
init {
aapsLogger.debug(LTag.LOCATION, "LocationListener $provider")
}
override fun onLocationChanged(location: Location) {
aapsLogger.debug(LTag.LOCATION, "onLocationChanged: $location")
lastLocation = location
rxBus.send(EventLocationChange(location))
}
override fun onProviderDisabled(provider: String) {
aapsLogger.debug(LTag.LOCATION, "onProviderDisabled: $provider")
}
override fun onProviderEnabled(provider: String) {
aapsLogger.debug(LTag.LOCATION, "onProviderEnabled: $provider")
}
override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {
aapsLogger.debug(LTag.LOCATION, "onStatusChanged: $provider")
}
}
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
super.onStartCommand(intent, flags, startId)
2020-01-03 14:30:39 +01:00
startForeground(mainApp.notificationId(), mainApp.getNotification())
2020-01-02 23:25:29 +01:00
return Service.START_STICKY
}
override fun onCreate() {
super.onCreate()
2020-01-03 14:30:39 +01:00
startForeground(mainApp.notificationId(), mainApp.getNotification())
2020-01-02 23:25:29 +01:00
// Get last location once until we get regular update
LocationServices.getFusedLocationProviderClient(this).lastLocation.addOnSuccessListener {
lastLocation = it
}
initializeLocationManager()
try {
if (sp.getString(R.string.key_location, "NONE") == "NETWORK") locationManager?.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
LOCATION_INTERVAL_ACTIVE,
LOCATION_DISTANCE,
LocationListener(LocationManager.NETWORK_PROVIDER).also { locationListener = it }
)
if (sp.getString(R.string.key_location, "NONE") == "GPS") locationManager?.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
LOCATION_INTERVAL_ACTIVE,
LOCATION_DISTANCE,
LocationListener(LocationManager.GPS_PROVIDER).also { locationListener = it }
)
if (sp.getString(R.string.key_location, "NONE") == "PASSIVE") locationManager?.requestLocationUpdates(
LocationManager.PASSIVE_PROVIDER,
LOCATION_INTERVAL_PASSIVE,
LOCATION_DISTANCE,
LocationListener(LocationManager.PASSIVE_PROVIDER).also { locationListener = it }
)
} catch (ex: SecurityException) {
aapsLogger.error(LTag.LOCATION, "fail to request location update, ignore", ex)
} catch (ex: IllegalArgumentException) {
aapsLogger.error(LTag.LOCATION, "network provider does not exist", ex)
}
disposable.add(rxBus
.toObservable(EventAppExit::class.java)
.observeOn(Schedulers.io())
.subscribe({
aapsLogger.debug(LTag.LOCATION, "EventAppExit received")
stopSelf()
2020-01-03 14:30:39 +01:00
}) { fabricPrivacy.logException(it) }
2020-01-02 23:25:29 +01:00
)
}
override fun onDestroy() {
super.onDestroy()
if (locationManager != null) {
try {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return
}
locationManager!!.removeUpdates(locationListener)
} catch (ex: Exception) {
aapsLogger.error(LTag.LOCATION, "fail to remove location listener, ignore", ex)
}
}
disposable.clear()
}
override fun onBind(intent: Intent?): IBinder? = null
private fun initializeLocationManager() {
aapsLogger.debug(LTag.LOCATION, "initializeLocationManager - Provider: " + sp.getString(R.string.key_location, "NONE"))
if (locationManager == null) {
locationManager = applicationContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager
}
}
}