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() {
|
override fun onMoveToForeground() {
|
||||||
merlin.bind()
|
merlin.bind()
|
||||||
|
merlinsBeard.hasInternetAccess {
|
||||||
|
hasInternetAccess = it
|
||||||
|
}
|
||||||
merlin.registerDisconnectable {
|
merlin.registerDisconnectable {
|
||||||
if (hasInternetAccess) {
|
if (hasInternetAccess) {
|
||||||
Timber.v("On Disconnect")
|
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.
|
* 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
|
* 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 var mIsSelfDestroyed: Boolean = false
|
||||||
|
|
||||||
private lateinit var syncTask: SyncTask
|
private lateinit var syncTask: SyncTask
|
||||||
|
@ -50,9 +51,10 @@ open class SyncService : Service() {
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
Timber.i("onStartCommand $intent")
|
Timber.i("onStartCommand $intent")
|
||||||
intent?.let {
|
intent?.let {
|
||||||
val userId = it.getStringExtra(EXTRA_USER_ID)
|
val safeUserId = it.getStringExtra(EXTRA_USER_ID) ?: return@let
|
||||||
val sessionComponent = Matrix.getInstance(applicationContext).sessionManager.getSessionComponent(userId)
|
val sessionComponent = Matrix.getInstance(applicationContext).sessionManager.getSessionComponent(safeUserId)
|
||||||
?: return@let
|
?: return@let
|
||||||
|
userId = safeUserId
|
||||||
syncTask = sessionComponent.syncTask()
|
syncTask = sessionComponent.syncTask()
|
||||||
networkConnectivityChecker = sessionComponent.networkConnectivityChecker()
|
networkConnectivityChecker = sessionComponent.networkConnectivityChecker()
|
||||||
taskExecutor = sessionComponent.taskExecutor()
|
taskExecutor = sessionComponent.taskExecutor()
|
||||||
|
@ -87,9 +89,11 @@ open class SyncService : Service() {
|
||||||
|
|
||||||
private suspend fun doSync() {
|
private suspend fun doSync() {
|
||||||
if (!networkConnectivityChecker.hasInternetAccess()) {
|
if (!networkConnectivityChecker.hasInternetAccess()) {
|
||||||
Timber.v("No network, try to sync again in 10s")
|
Timber.v("No network reschedule to avoid wasting resources")
|
||||||
delay(DELAY_NO_NETWORK)
|
userId?.also {
|
||||||
doSync()
|
onRescheduleAsked(it, delay = 10_000L)
|
||||||
|
}
|
||||||
|
stopMe()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Timber.v("Execute sync request with timeout 0")
|
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? {
|
override fun onBind(intent: Intent?): IBinder? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -116,7 +122,6 @@ open class SyncService : Service() {
|
||||||
companion object {
|
companion object {
|
||||||
const val EXTRA_USER_ID = "EXTRA_USER_ID"
|
const val EXTRA_USER_ID = "EXTRA_USER_ID"
|
||||||
private const val TIME_OUT = 0L
|
private const val TIME_OUT = 0L
|
||||||
private const val DELAY_NO_NETWORK = 10_000L
|
|
||||||
private const val DELAY_FAILURE = 5_000L
|
private const val DELAY_FAILURE = 5_000L
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="im.vector.riotx">
|
package="im.vector.riotx">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|
||||||
<application>
|
<application>
|
||||||
|
|
||||||
<!-- Firebase components -->
|
<!-- Firebase components -->
|
||||||
|
|
|
@ -15,11 +15,12 @@
|
||||||
*/
|
*/
|
||||||
package im.vector.riotx.core.services
|
package im.vector.riotx.core.services
|
||||||
|
|
||||||
|
import android.app.AlarmManager
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import im.vector.matrix.android.internal.session.sync.job.SyncService
|
import im.vector.matrix.android.internal.session.sync.job.SyncService
|
||||||
import im.vector.riotx.R
|
import im.vector.riotx.R
|
||||||
import im.vector.riotx.core.extensions.vectorComponent
|
import im.vector.riotx.core.extensions.vectorComponent
|
||||||
|
@ -44,16 +45,6 @@ class VectorSyncService : SyncService() {
|
||||||
notificationUtils = vectorComponent().notificationUtils()
|
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
|
* 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)
|
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