From 334368083e2fc2189c22ce9476f79f00f27b9e88 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 21 Mar 2022 16:46:40 +0300 Subject: [PATCH] Track location in foreground service. --- .../location/LocationSharingService.kt | 24 ++++++++++++-- .../location/LocationSharingViewModel.kt | 5 +-- .../app/features/location/LocationTracker.kt | 32 ++++++++++++++----- .../notifications/NotificationUtils.kt | 2 +- 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt index e0faebe528..1253891421 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt @@ -25,9 +25,10 @@ import timber.log.Timber import javax.inject.Inject @AndroidEntryPoint -class LocationSharingService : VectorService() { +class LocationSharingService : VectorService(), LocationTracker.Callback { @Inject lateinit var notificationUtils: NotificationUtils + @Inject lateinit var locationTracker: LocationTracker private var sessionId: String? = null private var roomId: String? = null @@ -36,19 +37,27 @@ class LocationSharingService : VectorService() { sessionId = intent?.getStringExtra(EXTRA_SESSION_ID) roomId = intent?.getStringExtra(EXTRA_ROOM_ID) - Timber.d("LocationSharingService $sessionId - $roomId") - if (sessionId == null || roomId == null) { stopForeground(true) stopSelf() } + // Show a sticky notification val notification = notificationUtils.buildLiveLocationSharingNotification() startForeground(roomId!!.hashCode(), notification) + // Start tracking location + locationTracker.addCallback(this) + locationTracker.start() + return START_STICKY } + override fun onDestroy() { + super.onDestroy() + locationTracker.removeCallback(this) + } + override fun onBind(intent: Intent?): IBinder? { return null } @@ -57,4 +66,13 @@ class LocationSharingService : VectorService() { const val EXTRA_SESSION_ID = "EXTRA_SESSION_ID" const val EXTRA_ROOM_ID = "EXTRA_ROOM_ID" } + + override fun onLocationUpdate(locationData: LocationData) { + Timber.d("### LocationSharingService.onLocationUpdate: ${locationData.latitude} - ${locationData.longitude}") + } + + override fun onLocationProviderIsNotAvailable() { + stopForeground(true) + stopSelf() + } } diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt index 893eee6f70..b2bf6d1762 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewModel.kt @@ -65,7 +65,8 @@ class LocationSharingViewModel @AssistedInject constructor( companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() init { - locationTracker.start(this) + locationTracker.addCallback(this) + locationTracker.start() setUserItem() updatePin() compareTargetAndUserLocation() @@ -112,7 +113,7 @@ class LocationSharingViewModel @AssistedInject constructor( override fun onCleared() { super.onCleared() - locationTracker.stop() + locationTracker.removeCallback(this) } override fun handle(action: LocationSharingAction) { diff --git a/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt b/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt index 0ee6395871..d5e298a14b 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationTracker.kt @@ -40,18 +40,17 @@ class LocationTracker @Inject constructor( fun onLocationProviderIsNotAvailable() } - private var callback: Callback? = null + private var callbacks = mutableListOf() private var hasGpsProviderLiveLocation = false @RequiresPermission(anyOf = [Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION]) - fun start(callback: Callback?) { + fun start() { Timber.d("## LocationTracker. start()") hasGpsProviderLiveLocation = false - this.callback = callback if (locationManager == null) { - callback?.onLocationProviderIsNotAvailable() + callbacks.forEach { it.onLocationProviderIsNotAvailable() } Timber.v("## LocationTracker. LocationManager is not available") return } @@ -81,7 +80,7 @@ class LocationTracker @Inject constructor( ) } ?: run { - callback?.onLocationProviderIsNotAvailable() + callbacks.forEach { it.onLocationProviderIsNotAvailable() } Timber.v("## LocationTracker. There is no location provider available") } } @@ -90,7 +89,24 @@ class LocationTracker @Inject constructor( fun stop() { Timber.d("## LocationTracker. stop()") locationManager?.removeUpdates(this) - callback = null + callbacks.clear() + } + + fun addCallback(callback: Callback) { + synchronized(callbacks) { + if (!callbacks.contains(callback)) { + callbacks.add(callback) + } + } + } + + fun removeCallback(callback: Callback) { + synchronized(callbacks) { + callbacks.remove(callback) + if (callbacks.size == 0) { + stop() + } + } } override fun onLocationChanged(location: Location) { @@ -115,12 +131,12 @@ class LocationTracker @Inject constructor( } } } - callback?.onLocationUpdate(location.toLocationData()) + callbacks.forEach { it.onLocationUpdate(location.toLocationData()) } } override fun onProviderDisabled(provider: String) { Timber.d("## LocationTracker. onProviderDisabled: $provider") - callback?.onLocationProviderIsNotAvailable() + callbacks.forEach { it.onLocationProviderIsNotAvailable() } } private fun Location.toLocationData(): LocationData { diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt index 0366b160ee..9fa094075a 100755 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt @@ -528,7 +528,7 @@ class NotificationUtils @Inject constructor(private val context: Context, return NotificationCompat.Builder(context, SILENT_NOTIFICATION_CHANNEL_ID) .setContentTitle(stringProvider.getString(R.string.live_location_sharing_notification_title)) .setContentText(stringProvider.getString(R.string.live_location_sharing_notification_description)) - .setSmallIcon(R.drawable.ic_location_pin) + .setSmallIcon(R.drawable.ic_attachment_location_live_white) .setCategory(NotificationCompat.CATEGORY_LOCATION_SHARING) .build() }