Start the foreground service when users start live location sharing.

This commit is contained in:
Onuray Sahin 2022-03-21 14:27:15 +03:00
parent a1d27940cd
commit c63fc3d6c2
6 changed files with 71 additions and 7 deletions

View File

@ -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()

View File

@ -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"
}
}

View File

@ -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()
}

View File

@ -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) {

View File

@ -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))

View File

@ -2946,6 +2946,8 @@
<string name="settings_enable_location_sharing_summary">Once enabled you will be able to send your location to any room</string>
<string name="labs_render_locations_in_timeline">Render user locations in the timeline</string>
<string name="location_timeline_failed_to_load_map">Failed to load map</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>