Skip to content

Commit 4130ef2

Browse files
committed
Use channel to ensure only one location push task is running at a given time
1 parent dd2b07e commit 4130ef2

File tree

2 files changed

+39
-32
lines changed

2 files changed

+39
-32
lines changed

mage/src/main/java/mil/nga/giat/mage/data/repository/location/LocationRepository.kt

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -152,19 +152,17 @@ class LocationRepository @Inject constructor(
152152
try {
153153
val response = locationService.pushLocations(event.remoteId, localLocations)
154154
if (response.isSuccessful) {
155-
val remoteLocations = response.body() ?: emptyList()
155+
val pushedLocations = response.body() ?: emptyList()
156156
// We've sync-ed locations to the server, lets remove the locations we synced from the database
157-
Log.d(LOG_NAME, "Pushed " + remoteLocations.size + " locations.")
157+
Log.d(LOG_NAME, "Pushed " + pushedLocations.size + " locations.")
158158
try {
159159
localLocations.forEachIndexed { index, localLocation ->
160-
val remoteLocation = remoteLocations.getOrNull(index)
161-
if (remoteLocation == null) {
160+
val remoteId = pushedLocations.getOrNull(index)?.remoteId
161+
if (remoteId == null) {
162162
locationLocalDataSource.delete(listOf(localLocation))
163163
} else {
164-
remoteLocation.id = localLocation.id
165-
remoteLocation.user = currentUser
166-
remoteLocation.event = event
167-
locationLocalDataSource.update(remoteLocation)
164+
localLocation.remoteId = remoteId
165+
locationLocalDataSource.update(localLocation)
168166
}
169167
}
170168

mage/src/main/java/mil/nga/giat/mage/location/LocationReportingService.kt

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ package mil.nga.giat.mage.location
33
import android.app.NotificationChannel
44
import android.app.NotificationManager
55
import android.app.PendingIntent
6-
import android.app.Service
76
import android.content.Context
87
import android.content.Intent
98
import android.content.SharedPreferences
109
import android.location.Location
1110
import android.location.LocationManager
12-
import android.os.Build
1311
import android.util.Log
1412
import androidx.core.app.NotificationCompat
1513
import androidx.lifecycle.LifecycleService
1614
import androidx.lifecycle.Observer
1715
import androidx.lifecycle.lifecycleScope
1816
import dagger.hilt.android.AndroidEntryPoint
17+
import kotlinx.coroutines.channels.Channel
18+
import kotlinx.coroutines.flow.receiveAsFlow
1919
import kotlinx.coroutines.launch
2020
import mil.nga.giat.mage.MageApplication
2121
import mil.nga.giat.mage.R
@@ -34,6 +34,7 @@ open class LocationReportingService : LifecycleService(), Observer<Location>, Sh
3434
private var shouldReportLocation: Boolean = false
3535
private var locationPushFrequency: Long = 0
3636
private var oldestLocationTime: Long = 0
37+
private lateinit var locationChannel: Channel<Location>
3738

3839
companion object {
3940
private val LOG_NAME = LocationReportingService::class.java.name
@@ -57,12 +58,10 @@ open class LocationReportingService : LifecycleService(), Observer<Location>, Sh
5758
locationPushFrequency = getLocationPushFrequency()
5859
shouldReportLocation = getShouldReportLocation()
5960

60-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
61-
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
62-
val channel = NotificationChannel(NOTIFICATION_CHANNEL_ID, "MAGE", NotificationManager.IMPORTANCE_MIN)
63-
channel.setShowBadge(true)
64-
notificationManager.createNotificationChannel(channel)
65-
}
61+
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
62+
val notificationChannel = NotificationChannel(NOTIFICATION_CHANNEL_ID, "MAGE", NotificationManager.IMPORTANCE_MIN)
63+
notificationChannel.setShowBadge(true)
64+
notificationManager.createNotificationChannel(notificationChannel)
6665

6766
val intent = Intent(applicationContext, LoginActivity::class.java)
6867
intent.putExtra("LOGOUT", true)
@@ -77,6 +76,13 @@ open class LocationReportingService : LifecycleService(), Observer<Location>, Sh
7776
.addAction(R.drawable.ic_power_settings_new_white_24dp, "Logout", pendingIntent)
7877
.build()
7978

79+
locationChannel = Channel(Channel.CONFLATED)
80+
lifecycleScope.launch {
81+
locationChannel.receiveAsFlow().collect { location ->
82+
pushLocations(location)
83+
}
84+
}
85+
8086
startForeground(NOTIFICATION_ID, notification)
8187
}
8288

@@ -85,34 +91,37 @@ open class LocationReportingService : LifecycleService(), Observer<Location>, Sh
8591

8692
locationProvider.observe(this, this)
8793

88-
return Service.START_STICKY
94+
return START_STICKY
8995
}
9096

9197
override fun onDestroy() {
9298
super.onDestroy()
9399

94100
locationProvider.removeObserver(this)
95-
101+
locationChannel.close()
96102
preferences.unregisterOnSharedPreferenceChangeListener(this)
97103
}
98104

99-
override fun onChanged(location: Location) {
100-
if (shouldReportLocation && location?.provider == LocationManager.GPS_PROVIDER) {
105+
override fun onChanged(value: Location) {
106+
if (shouldReportLocation && value.provider == LocationManager.GPS_PROVIDER) {
101107
Log.v(LOG_NAME, "GPS location changed")
102108

103109
lifecycleScope.launch {
104-
locationRepository.saveLocation(location)
105-
106-
if (oldestLocationTime == 0L) {
107-
oldestLocationTime = location.time
108-
}
109-
110-
if (!locationAccess.isPreciseLocationGranted() || (location.time - oldestLocationTime > locationPushFrequency)) {
111-
val success = locationRepository.pushLocations()
112-
if (success) {
113-
oldestLocationTime = 0
114-
}
115-
}
110+
locationRepository.saveLocation(value)
111+
locationChannel.send(value)
112+
}
113+
}
114+
}
115+
116+
private suspend fun pushLocations(location: Location) {
117+
if (oldestLocationTime == 0L) {
118+
oldestLocationTime = location.time
119+
}
120+
121+
if (!locationAccess.isPreciseLocationGranted() || (location.time - oldestLocationTime > locationPushFrequency)) {
122+
val success = locationRepository.pushLocations()
123+
if (success) {
124+
oldestLocationTime = 0
116125
}
117126
}
118127
}

0 commit comments

Comments
 (0)