diff --git a/changelog.d/5595.feature b/changelog.d/5595.feature
new file mode 100644
index 0000000000..8fd4d4b144
--- /dev/null
+++ b/changelog.d/5595.feature
@@ -0,0 +1 @@
+Live Location Sharing - Foreground Service and Notification
\ No newline at end of file
diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml
index 1d99fba91a..d52e95b382 100644
--- a/vector/src/main/AndroidManifest.xml
+++ b/vector/src/main/AndroidManifest.xml
@@ -84,8 +84,8 @@
         android:resizeableActivity="true"
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
-        android:theme="@style/Theme.Vector.Light"
         android:taskAffinity="${applicationId}.${appTaskAffinitySuffix}"
+        android:theme="@style/Theme.Vector.Light"
         tools:replace="android:allowBackup">
 
         <!-- No limit for screen ratio: avoid black strips -->
@@ -369,6 +369,11 @@
             </intent-filter>
         </service>
 
+        <service
+            android:name=".features.location.LocationSharingService"
+            android:exported="false"
+            android:foregroundServiceType="location" />
+
         <!-- Receivers -->
 
         <receiver
diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt
index d7d686ee60..4025fbefa8 100644
--- a/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt
+++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingAction.kt
@@ -23,5 +23,5 @@ sealed class LocationSharingAction : VectorViewModelAction {
     data class PinnedLocationSharing(val locationData: LocationData?) : LocationSharingAction()
     data class LocationTargetChange(val locationData: LocationData) : LocationSharingAction()
     object ZoomToUserLocation : LocationSharingAction()
-    object StartLiveLocationSharing : LocationSharingAction()
+    data class StartLiveLocationSharing(val duration: Long) : LocationSharingAction()
 }
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 d61d53ae51..b779b50c8b 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
@@ -82,9 +84,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)
             }
         }
     }
@@ -176,6 +179,16 @@ class LocationSharingFragment @Inject constructor(
         views.mapView.zoomToLocation(event.userLocation.latitude, event.userLocation.longitude)
     }
 
+    private fun handleStartLiveLocationService(event: LocationSharingViewEvents.StartLiveLocationService) {
+        val args = LocationSharingService.RoomArgs(event.sessionId, event.roomId, event.duration)
+
+        Intent(requireContext(), LocationSharingService::class.java)
+                .putExtra(LocationSharingService.EXTRA_ROOM_ARGS, args)
+                .also {
+                    ContextCompat.startForegroundService(requireContext(), it)
+                }
+    }
+
     private fun initOptionsPicker() {
         // set no option at start
         views.shareLocationOptionsPicker.render()
@@ -221,7 +234,9 @@ class LocationSharingFragment @Inject constructor(
     }
 
     private fun startLiveLocationSharing() {
-        viewModel.handle(LocationSharingAction.StartLiveLocationSharing)
+        // TODO. Get duration from user
+        val duration = 30 * 1000L
+        viewModel.handle(LocationSharingAction.StartLiveLocationSharing(duration))
     }
 
     private fun updateMap(state: LocationSharingViewState) {
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
new file mode 100644
index 0000000000..a2a68e4188
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2022 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.location
+
+import android.content.Intent
+import android.os.IBinder
+import android.os.Parcelable
+import dagger.hilt.android.AndroidEntryPoint
+import im.vector.app.core.services.VectorService
+import im.vector.app.features.notifications.NotificationUtils
+import kotlinx.parcelize.Parcelize
+import timber.log.Timber
+import java.util.Timer
+import java.util.TimerTask
+import javax.inject.Inject
+
+@AndroidEntryPoint
+class LocationSharingService : VectorService(), LocationTracker.Callback {
+
+    @Parcelize
+    data class RoomArgs(
+            val sessionId: String,
+            val roomId: String,
+            val durationMillis: Long
+    ) : Parcelable
+
+    @Inject lateinit var notificationUtils: NotificationUtils
+    @Inject lateinit var locationTracker: LocationTracker
+
+    private var roomArgsList = mutableListOf<RoomArgs>()
+    private var timers = mutableListOf<Timer>()
+
+    override fun onCreate() {
+        super.onCreate()
+        Timber.i("### LocationSharingService.onCreate")
+
+        // Start tracking location
+        locationTracker.addCallback(this)
+        locationTracker.start()
+    }
+
+    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+        val roomArgs = intent?.getParcelableExtra(EXTRA_ROOM_ARGS) as? RoomArgs
+
+        Timber.i("### LocationSharingService.onStartCommand. sessionId - roomId ${roomArgs?.sessionId} - ${roomArgs?.roomId}")
+
+        if (roomArgs != null) {
+            roomArgsList.add(roomArgs)
+
+            // Show a sticky notification
+            val notification = notificationUtils.buildLiveLocationSharingNotification()
+            startForeground(roomArgs.roomId.hashCode(), notification)
+
+            // Schedule a timer to stop sharing
+            scheduleTimer(roomArgs.roomId, roomArgs.durationMillis)
+        }
+
+        return START_STICKY
+    }
+
+    private fun scheduleTimer(roomId: String, durationMillis: Long) {
+        Timer()
+                .apply {
+                    schedule(object : TimerTask() {
+                        override fun run() {
+                            stopSharingLocation(roomId)
+                            timers.remove(this@apply)
+                        }
+                    }, durationMillis)
+                }
+                .also {
+                    timers.add(it)
+                }
+    }
+
+    private fun stopSharingLocation(roomId: String) {
+        Timber.i("### LocationSharingService.stopSharingLocation for $roomId")
+        synchronized(roomArgsList) {
+            roomArgsList.removeAll { it.roomId == roomId }
+            if (roomArgsList.isEmpty()) {
+                Timber.i("### LocationSharingService. Destroying self, time is up for all rooms")
+                destroyMe()
+            }
+        }
+    }
+
+    override fun onLocationUpdate(locationData: LocationData) {
+        Timber.i("### LocationSharingService.onLocationUpdate. Uncertainty: ${locationData.uncertainty}")
+    }
+
+    override fun onLocationProviderIsNotAvailable() {
+        stopForeground(true)
+        stopSelf()
+    }
+
+    private fun destroyMe() {
+        locationTracker.removeCallback(this)
+        timers.forEach { it.cancel() }
+        timers.clear()
+        stopSelf()
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+        Timber.i("### LocationSharingService.onDestroy")
+        destroyMe()
+    }
+
+    override fun onBind(intent: Intent?): IBinder? {
+        return null
+    }
+
+    companion object {
+        const val EXTRA_ROOM_ARGS = "EXTRA_ROOM_ARGS"
+    }
+}
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..b25a4988b0 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, val duration: Long) : 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 1d68247f2c..dfa936dcaa 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
@@ -37,7 +37,6 @@ import kotlinx.coroutines.launch
 import org.matrix.android.sdk.api.extensions.orFalse
 import org.matrix.android.sdk.api.session.Session
 import org.matrix.android.sdk.api.util.toMatrixItem
-import timber.log.Timber
 
 /**
  * Sampling period to compare target location and user location.
@@ -64,7 +63,8 @@ class LocationSharingViewModel @AssistedInject constructor(
     companion object : MavericksViewModelFactory<LocationSharingViewModel, LocationSharingViewState> by hiltMavericksViewModelFactory()
 
     init {
-        locationTracker.start(this)
+        locationTracker.addCallback(this)
+        locationTracker.start()
         setUserItem()
         updatePin()
         compareTargetAndUserLocation()
@@ -111,16 +111,16 @@ class LocationSharingViewModel @AssistedInject constructor(
 
     override fun onCleared() {
         super.onCleared()
-        locationTracker.stop()
+        locationTracker.removeCallback(this)
     }
 
     override fun handle(action: LocationSharingAction) {
         when (action) {
-            LocationSharingAction.CurrentUserLocationSharing -> handleCurrentUserLocationSharingAction()
-            is LocationSharingAction.PinnedLocationSharing   -> handlePinnedLocationSharingAction(action)
-            is LocationSharingAction.LocationTargetChange    -> handleLocationTargetChangeAction(action)
-            LocationSharingAction.ZoomToUserLocation         -> handleZoomToUserLocationAction()
-            LocationSharingAction.StartLiveLocationSharing   -> handleStartLiveLocationSharingAction()
+            LocationSharingAction.CurrentUserLocationSharing  -> handleCurrentUserLocationSharingAction()
+            is LocationSharingAction.PinnedLocationSharing    -> handlePinnedLocationSharingAction(action)
+            is LocationSharingAction.LocationTargetChange     -> handleLocationTargetChangeAction(action)
+            LocationSharingAction.ZoomToUserLocation          -> handleZoomToUserLocationAction()
+            is LocationSharingAction.StartLiveLocationSharing -> handleStartLiveLocationSharingAction(action.duration)
         }
     }
 
@@ -158,9 +158,12 @@ class LocationSharingViewModel @AssistedInject constructor(
         }
     }
 
-    private fun handleStartLiveLocationSharingAction() {
-        // TODO start sharing live location and update view state
-        Timber.d("live location sharing started")
+    private fun handleStartLiveLocationSharingAction(duration: Long) {
+        _viewEvents.post(LocationSharingViewEvents.StartLiveLocationService(
+                sessionId = session.sessionId,
+                roomId = room.roomId,
+                duration = duration
+        ))
     }
 
     override fun onLocationUpdate(locationData: LocationData) {
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 162fbc5959..b7006370a6 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
@@ -26,7 +26,9 @@ import androidx.core.location.LocationListenerCompat
 import im.vector.app.BuildConfig
 import timber.log.Timber
 import javax.inject.Inject
+import javax.inject.Singleton
 
+@Singleton
 class LocationTracker @Inject constructor(
         context: Context
 ) : LocationListenerCompat {
@@ -38,18 +40,17 @@ class LocationTracker @Inject constructor(
         fun onLocationProviderIsNotAvailable()
     }
 
-    private var callback: Callback? = null
+    private var callbacks = mutableListOf<Callback>()
 
     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
         }
@@ -79,7 +80,7 @@ class LocationTracker @Inject constructor(
                     )
                 }
                 ?: run {
-                    callback?.onLocationProviderIsNotAvailable()
+                    callbacks.forEach { it.onLocationProviderIsNotAvailable() }
                     Timber.v("## LocationTracker. There is no location provider available")
                 }
     }
@@ -88,7 +89,20 @@ class LocationTracker @Inject constructor(
     fun stop() {
         Timber.d("## LocationTracker. stop()")
         locationManager?.removeUpdates(this)
-        callback = null
+        callbacks.clear()
+    }
+
+    fun addCallback(callback: Callback) {
+        if (!callbacks.contains(callback)) {
+            callbacks.add(callback)
+        }
+    }
+
+    fun removeCallback(callback: Callback) {
+        callbacks.remove(callback)
+        if (callbacks.size == 0) {
+            stop()
+        }
     }
 
     override fun onLocationChanged(location: Location) {
@@ -113,12 +127,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 d39926f620..161b58d53d 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,20 @@ 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_attachment_location_live_white)
+                .setColor(ThemeUtils.getColor(context, android.R.attr.colorPrimary))
+                .setCategory(NotificationCompat.CATEGORY_LOCATION_SHARING)
+                .setContentIntent(buildOpenHomePendingIntentForSummary())
+                .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 551e5961ec..a276e07b1e 100644
--- a/vector/src/main/res/values/strings.xml
+++ b/vector/src/main/res/values/strings.xml
@@ -2950,6 +2950,8 @@
     <string name="location_timeline_failed_to_load_map">Failed to load map</string>
     <string name="location_share_live_enabled">Live location enabled</string>
     <string name="location_share_live_stop">Stop</string>
+    <string name="live_location_sharing_notification_title">${app_name} Live Location</string>
+    <string name="live_location_sharing_notification_description">Location sharing is in progress</string>
 
     <string name="message_bubbles">Show Message bubbles</string>