Sync: fix crash on gplay flavor and reschedule when no network instead of showing a potential notification all the time
This commit is contained in:
parent
5338f93852
commit
3a269be2ef
|
@ -62,6 +62,9 @@ internal class NetworkConnectivityChecker @Inject constructor(private val contex
|
|||
|
||||
override fun onMoveToForeground() {
|
||||
merlin.bind()
|
||||
merlinsBeard.hasInternetAccess {
|
||||
hasInternetAccess = it
|
||||
}
|
||||
merlin.registerDisconnectable {
|
||||
if (hasInternetAccess) {
|
||||
Timber.v("On Disconnect")
|
||||
|
|
|
@ -34,8 +34,9 @@ import java.util.concurrent.atomic.AtomicBoolean
|
|||
* in order to be able to perform a sync even if the app is not running.
|
||||
* The <receiver> and <service> must be declared in the Manifest or the app using the SDK
|
||||
*/
|
||||
open class SyncService : Service() {
|
||||
abstract class SyncService : Service() {
|
||||
|
||||
private var userId: String? = null
|
||||
private var mIsSelfDestroyed: Boolean = false
|
||||
|
||||
private lateinit var syncTask: SyncTask
|
||||
|
@ -50,9 +51,10 @@ open class SyncService : Service() {
|
|||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
Timber.i("onStartCommand $intent")
|
||||
intent?.let {
|
||||
val userId = it.getStringExtra(EXTRA_USER_ID)
|
||||
val sessionComponent = Matrix.getInstance(applicationContext).sessionManager.getSessionComponent(userId)
|
||||
val safeUserId = it.getStringExtra(EXTRA_USER_ID) ?: return@let
|
||||
val sessionComponent = Matrix.getInstance(applicationContext).sessionManager.getSessionComponent(safeUserId)
|
||||
?: return@let
|
||||
userId = safeUserId
|
||||
syncTask = sessionComponent.syncTask()
|
||||
networkConnectivityChecker = sessionComponent.networkConnectivityChecker()
|
||||
taskExecutor = sessionComponent.taskExecutor()
|
||||
|
@ -87,9 +89,11 @@ open class SyncService : Service() {
|
|||
|
||||
private suspend fun doSync() {
|
||||
if (!networkConnectivityChecker.hasInternetAccess()) {
|
||||
Timber.v("No network, try to sync again in 10s")
|
||||
delay(DELAY_NO_NETWORK)
|
||||
doSync()
|
||||
Timber.v("No network reschedule to avoid wasting resources")
|
||||
userId?.also {
|
||||
onRescheduleAsked(it, delay = 10_000L)
|
||||
}
|
||||
stopMe()
|
||||
return
|
||||
}
|
||||
Timber.v("Execute sync request with timeout 0")
|
||||
|
@ -109,6 +113,8 @@ open class SyncService : Service() {
|
|||
}
|
||||
}
|
||||
|
||||
abstract fun onRescheduleAsked(userId: String, delay: Long)
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
return null
|
||||
}
|
||||
|
@ -116,7 +122,6 @@ open class SyncService : Service() {
|
|||
companion object {
|
||||
const val EXTRA_USER_ID = "EXTRA_USER_ID"
|
||||
private const val TIME_OUT = 0L
|
||||
private const val DELAY_NO_NETWORK = 10_000L
|
||||
private const val DELAY_FAILURE = 5_000L
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="im.vector.riotx">
|
||||
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
||||
<application>
|
||||
|
||||
<!-- Firebase components -->
|
||||
|
|
|
@ -15,11 +15,12 @@
|
|||
*/
|
||||
package im.vector.riotx.core.services
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import androidx.core.content.ContextCompat
|
||||
import im.vector.matrix.android.internal.session.sync.job.SyncService
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.vectorComponent
|
||||
|
@ -44,16 +45,6 @@ class VectorSyncService : SyncService() {
|
|||
notificationUtils = vectorComponent().notificationUtils()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
removeForegroundNotif()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
private fun removeForegroundNotif() {
|
||||
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
notificationManager.cancel(NotificationUtils.NOTIFICATION_ID_FOREGROUND_SERVICE)
|
||||
}
|
||||
|
||||
/**
|
||||
* Service is started in fdroid mode when no FCM is available or is used for initialSync
|
||||
*/
|
||||
|
@ -65,4 +56,33 @@ class VectorSyncService : SyncService() {
|
|||
}
|
||||
return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
removeForegroundNotif()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onRescheduleAsked(userId: String, delay: Long) {
|
||||
reschedule(userId, delay)
|
||||
}
|
||||
|
||||
private fun removeForegroundNotif() {
|
||||
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
notificationManager.cancel(NotificationUtils.NOTIFICATION_ID_FOREGROUND_SERVICE)
|
||||
}
|
||||
|
||||
private fun reschedule(userId: String, delay: Long) {
|
||||
val pendingIntent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
PendingIntent.getForegroundService(this, 0, newIntent(this, userId), 0)
|
||||
} else {
|
||||
PendingIntent.getService(this, 0, newIntent(this, userId), 0)
|
||||
}
|
||||
val firstMillis = System.currentTimeMillis() + delay
|
||||
val alarmMgr = getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
alarmMgr.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, firstMillis, pendingIntent)
|
||||
} else {
|
||||
alarmMgr.set(AlarmManager.RTC_WAKEUP, firstMillis, pendingIntent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue