diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt
index c4dccc1b73..15f91d1f47 100644
--- a/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingFragment.kt
@@ -16,11 +16,13 @@
package im.vector.app.features.location
+import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.core.content.ContextCompat
import androidx.core.view.isGone
import androidx.lifecycle.lifecycleScope
import com.airbnb.mvrx.fragmentViewModel
@@ -83,9 +85,10 @@ class LocationSharingFragment @Inject constructor(
viewModel.observeViewEvents {
when (it) {
- LocationSharingViewEvents.Close -> locationSharingNavigator.quit()
- LocationSharingViewEvents.LocationNotAvailableError -> handleLocationNotAvailableError()
- is LocationSharingViewEvents.ZoomToUserLocation -> handleZoomToUserLocationEvent(it)
+ LocationSharingViewEvents.Close -> locationSharingNavigator.quit()
+ LocationSharingViewEvents.LocationNotAvailableError -> handleLocationNotAvailableError()
+ is LocationSharingViewEvents.ZoomToUserLocation -> handleZoomToUserLocationEvent(it)
+ is LocationSharingViewEvents.StartLiveLocationService -> handleStartLiveLocationService(it)
}.exhaustive
}
}
@@ -177,6 +180,17 @@ class LocationSharingFragment @Inject constructor(
views.mapView.zoomToLocation(event.userLocation.latitude, event.userLocation.longitude)
}
+ private fun handleStartLiveLocationService(event: LocationSharingViewEvents.StartLiveLocationService) {
+ Intent(requireContext(), LocationSharingService::class.java)
+ .apply {
+ putExtra(LocationSharingService.EXTRA_SESSION_ID, event.sessionId)
+ putExtra(LocationSharingService.EXTRA_ROOM_ID, event.roomId)
+ }
+ .also {
+ ContextCompat.startForegroundService(requireContext(), it)
+ }
+ }
+
private fun initOptionsPicker() {
// set no option at start
views.shareLocationOptionsPicker.render()
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 4c565ac2bb..e0faebe528 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
@@ -16,12 +16,45 @@
package im.vector.app.features.location
-import android.app.Service
import android.content.Intent
import android.os.IBinder
+import dagger.hilt.android.AndroidEntryPoint
+import im.vector.app.core.services.VectorService
+import im.vector.app.features.notifications.NotificationUtils
+import timber.log.Timber
+import javax.inject.Inject
+
+@AndroidEntryPoint
+class LocationSharingService : VectorService() {
+
+ @Inject lateinit var notificationUtils: NotificationUtils
+
+ private var sessionId: String? = null
+ private var roomId: String? = null
+
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ 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()
+ }
+
+ val notification = notificationUtils.buildLiveLocationSharingNotification()
+ startForeground(roomId!!.hashCode(), notification)
+
+ return START_STICKY
+ }
-class LocationSharingService : Service() {
override fun onBind(intent: Intent?): IBinder? {
return null
}
+
+ companion object {
+ const val EXTRA_SESSION_ID = "EXTRA_SESSION_ID"
+ const val EXTRA_ROOM_ID = "EXTRA_ROOM_ID"
+ }
}
diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt
index 8d31db1119..a7204f02c1 100644
--- a/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt
+++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingViewEvents.kt
@@ -22,4 +22,5 @@ sealed class LocationSharingViewEvents : VectorViewEvents {
object Close : LocationSharingViewEvents()
object LocationNotAvailableError : LocationSharingViewEvents()
data class ZoomToUserLocation(val userLocation: LocationData) : LocationSharingViewEvents()
+ data class StartLiveLocationService(val sessionId: String, val roomId: String) : LocationSharingViewEvents()
}
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 639666e63f..893eee6f70 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
@@ -160,8 +160,10 @@ class LocationSharingViewModel @AssistedInject constructor(
}
private fun handleStartLiveLocationSharingAction() {
- // TODO start sharing live location and update view state
- Timber.d("live location sharing started")
+ _viewEvents.post(LocationSharingViewEvents.StartLiveLocationService(
+ sessionId = session.sessionId,
+ roomId = room.roomId
+ ))
}
override fun onLocationUpdate(locationData: 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 d39926f620..0366b160ee 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
@@ -521,6 +521,18 @@ class NotificationUtils @Inject constructor(private val context: Context,
return builder.build()
}
+ /**
+ * Creates a notification that indicates the application is retrieving location even if it is in background or killed.
+ */
+ fun buildLiveLocationSharingNotification(): Notification {
+ 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)
+ .setCategory(NotificationCompat.CATEGORY_LOCATION_SHARING)
+ .build()
+ }
+
fun buildDownloadFileNotification(uri: Uri, fileName: String, mimeType: String): Notification {
return NotificationCompat.Builder(context, SILENT_NOTIFICATION_CHANNEL_ID)
.setGroup(stringProvider.getString(R.string.app_name))
diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml
index 428be3209f..9a30e89948 100644
--- a/vector/src/main/res/values/strings.xml
+++ b/vector/src/main/res/values/strings.xml
@@ -2946,6 +2946,8 @@
Once enabled you will be able to send your location to any room
Render user locations in the timeline
Failed to load map
+ ${app_name} Live Location
+ Location sharing is in progress
Show Message bubbles