Telegram - fix service

This commit is contained in:
crimean 2018-06-14 15:21:58 +03:00
parent 4ca2e4ace5
commit 3e71d85235
5 changed files with 66 additions and 49 deletions

View file

@ -41,6 +41,7 @@
</intent-filter> </intent-filter>
</service> </service>
<receiver android:name=".OnTelegramServiceAlarmReceiver" />
</application> </application>
</manifest> </manifest>

View file

@ -5,11 +5,9 @@ import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.location.LocationManager import android.location.LocationManager
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.TelegramService
import net.osmand.telegram.utils.AndroidUtils import net.osmand.telegram.utils.AndroidUtils
class OnNavigationServiceAlarmReceiver : BroadcastReceiver() { class OnTelegramServiceAlarmReceiver : BroadcastReceiver() {
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
val lock = TelegramService.getLock(context) val lock = TelegramService.getLock(context)
@ -19,23 +17,23 @@ class OnNavigationServiceAlarmReceiver : BroadcastReceiver() {
if (lock.isHeld || service == null) { if (lock.isHeld || service == null) {
return return
} }
lock.acquire(10 * 60 * 1000L /*10 minutes*/) lock.acquire(15 * 60 * 1000L)
// request location updates // request location updates
val locationManager = service.getSystemService(Context.LOCATION_SERVICE) as LocationManager val locationManager = service.getSystemService(Context.LOCATION_SERVICE) as LocationManager
try { try {
if (AndroidUtils.isLocationPermissionAvailable(app)) { if (AndroidUtils.isLocationPermissionAvailable(app)) {
locationManager.requestLocationUpdates(service.serviceOffProvider, 0, 0f, service) locationManager.requestLocationUpdates(service.serviceOffProvider, 0, 0f, service)
val handler = service.handler }
if (service.serviceOffInterval > service.serviceError && handler != null) { val handler = service.handler
handler.postDelayed({ if (service.serviceOffInterval > service.serviceErrorInterval && handler != null) {
// if lock is not anymore held handler.postDelayed({
if (lock.isHeld) { // if lock is not anymore held
lock.release() if (lock.isHeld) {
locationManager.removeUpdates(service) lock.release()
} locationManager.removeUpdates(service)
}, service.serviceError) }
} }, service.serviceErrorInterval)
} }
} catch (e: RuntimeException) { } catch (e: RuntimeException) {
e.printStackTrace() e.printStackTrace()

View file

@ -92,17 +92,24 @@ class TelegramApplication : Application(), OsmandHelperListener {
showLocationHelper.setupMapLayer() showLocationHelper.setupMapLayer()
} }
private fun startTelegramService(intent: Int) { private fun startTelegramService(intent: Int, serviceOffInterval: Long = 0) {
var i = intent var i = intent
var interval = serviceOffInterval
val serviceIntent = Intent(this, TelegramService::class.java) val serviceIntent = Intent(this, TelegramService::class.java)
val telegramService = telegramService val telegramService = telegramService
if (telegramService != null) { if (telegramService != null) {
i = intent or telegramService.usedBy i = intent or telegramService.usedBy
interval = if (TelegramService.isOffIntervalDepended(intent)) {
Math.min(telegramService.serviceOffInterval, interval)
} else {
telegramService.serviceOffInterval
}
telegramService.stopSelf() telegramService.stopSelf()
} }
serviceIntent.putExtra(TelegramService.USAGE_INTENT, i) serviceIntent.putExtra(TelegramService.USAGE_INTENT, i)
serviceIntent.putExtra(TelegramService.USAGE_OFF_INTERVAL, interval)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(serviceIntent) startForegroundService(serviceIntent)
} else { } else {
@ -111,7 +118,8 @@ class TelegramApplication : Application(), OsmandHelperListener {
} }
fun startMyLocationService() { fun startMyLocationService() {
startTelegramService(TelegramService.USED_BY_MY_LOCATION) val interval = settings.sendMyLocationInterval
startTelegramService(TelegramService.USED_BY_MY_LOCATION, TelegramService.normalizeOffInterval(interval))
} }
fun stopMyLocationService() { fun stopMyLocationService() {

View file

@ -32,7 +32,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
private set private set
var serviceOffInterval = 0L var serviceOffInterval = 0L
private set private set
var serviceError = 0L var serviceErrorInterval = 0L
private set private set
private var pendingIntent: PendingIntent? = null private var pendingIntent: PendingIntent? = null
@ -51,19 +51,14 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
shouldCleanupResources = false shouldCleanupResources = false
val serviceIntent = Intent(ctx, TelegramService::class.java) val serviceIntent = Intent(ctx, TelegramService::class.java)
ctx.stopService(serviceIntent) ctx.stopService(serviceIntent)
} else if (!needLocation()) { } else if (isUsedByMyLocation(usedBy)) {
// Issue #3604
val app = app() val app = app()
if (usedBy == 2 && app.settings.sendMyLocationInterval >= 30000 && serviceOffInterval == 0L) { if (app.settings.sendMyLocationInterval >= OFF_INTERVAL_THRESHOLD && serviceOffInterval == 0L) {
serviceOffInterval = app.settings.sendMyLocationInterval serviceOffInterval = app.settings.sendMyLocationInterval
// From onStartCommand: setupServiceErrorInterval()
serviceError = serviceOffInterval / 5
serviceError = Math.min(serviceError, 12 * 60 * 1000)
serviceError = Math.max(serviceError, 30 * 1000)
serviceError = Math.min(serviceError, serviceOffInterval)
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
pendingIntent = PendingIntent.getBroadcast(this, 0, Intent(this, OnNavigationServiceAlarmReceiver::class.java), PendingIntent.FLAG_UPDATE_CURRENT) pendingIntent = PendingIntent.getBroadcast(this, 0, Intent(this, OnTelegramServiceAlarmReceiver::class.java), PendingIntent.FLAG_UPDATE_CURRENT)
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 500, serviceOffInterval, pendingIntent) alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 500, serviceOffInterval, pendingIntent)
} }
app.notificationHelper.refreshNotification(NotificationType.LOCATION) app.notificationHelper.refreshNotification(NotificationType.LOCATION)
@ -76,20 +71,12 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
usedBy = intent.getIntExtra(USAGE_INTENT, 0) usedBy = intent.getIntExtra(USAGE_INTENT, 0)
serviceOffInterval = intent.getLongExtra(USAGE_OFF_INTERVAL, 0) serviceOffInterval = intent.getLongExtra(USAGE_OFF_INTERVAL, 0)
// use only gps provider setupServiceErrorInterval()
serviceOffProvider = LocationManager.GPS_PROVIDER
serviceError = serviceOffInterval / 5
// 1. not more than 12 mins
serviceError = Math.min(serviceError, 12 * 60 * 1000)
// 2. not less than 30 seconds
serviceError = Math.max(serviceError, 30 * 1000)
// 3. not more than serviceOffInterval
serviceError = Math.min(serviceError, serviceOffInterval)
app.telegramService = this app.telegramService = this
app.telegramHelper.incomingMessagesListener = this app.telegramHelper.incomingMessagesListener = this
if (needLocation()) { if (isUsedByMyLocation(usedBy)) {
initLocationUpdates() initLocationUpdates()
} }
@ -100,6 +87,16 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
return Service.START_REDELIVER_INTENT return Service.START_REDELIVER_INTENT
} }
private fun setupServiceErrorInterval() {
serviceErrorInterval = serviceOffInterval / 5
// 1. not more than 12 mins
serviceErrorInterval = Math.min(serviceErrorInterval, 12 * 60 * 1000)
// 2. not less than 30 seconds
serviceErrorInterval = Math.max(serviceErrorInterval, 30 * 1000)
// 3. not more than serviceOffInterval
serviceErrorInterval = Math.min(serviceErrorInterval, serviceOffInterval)
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
val app = app() val app = app()
@ -141,7 +138,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
} }
} else { } else {
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
pendingIntent = PendingIntent.getBroadcast(this, 0, Intent(this, OnNavigationServiceAlarmReceiver::class.java), PendingIntent.FLAG_UPDATE_CURRENT) pendingIntent = PendingIntent.getBroadcast(this, 0, Intent(this, OnTelegramServiceAlarmReceiver::class.java), PendingIntent.FLAG_UPDATE_CURRENT)
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 500, serviceOffInterval, pendingIntent) alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 500, serviceOffInterval, pendingIntent)
} }
} }
@ -156,10 +153,6 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
} }
} }
private fun needLocation(): Boolean {
return (usedBy and USED_BY_MY_LOCATION) > 0
}
private fun isContinuous(): Boolean { private fun isContinuous(): Boolean {
return serviceOffInterval == 0L return serviceOffInterval == 0L
} }
@ -228,6 +221,8 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
const val USAGE_INTENT = "SERVICE_USED_BY" const val USAGE_INTENT = "SERVICE_USED_BY"
const val USAGE_OFF_INTERVAL = "SERVICE_OFF_INTERVAL" const val USAGE_OFF_INTERVAL = "SERVICE_OFF_INTERVAL"
const val OFF_INTERVAL_THRESHOLD: Long = 30000L
private var lockStatic: PowerManager.WakeLock? = null private var lockStatic: PowerManager.WakeLock? = null
@Synchronized @Synchronized
@ -243,6 +238,18 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
} }
} }
fun isUsedByMyLocation(usedBy: Int): Boolean {
return (usedBy and USED_BY_MY_LOCATION) > 0
}
fun isOffIntervalDepended(usedBy: Int): Boolean {
return isUsedByMyLocation(usedBy)
}
fun normalizeOffInterval(interval: Long): Long {
return if (interval < OFF_INTERVAL_THRESHOLD) 0 else interval
}
fun convertLocation(l: Location?): net.osmand.Location? { fun convertLocation(l: Location?): net.osmand.Location? {
if (l == null) { if (l == null) {
return null return null

View file

@ -230,7 +230,7 @@ class TelegramHelper private constructor() {
offsetOrder = last.order offsetOrder = last.order
offsetChatId = last.chatId offsetChatId = last.chatId
} }
client?.send(TdApi.GetChats(offsetOrder, offsetChatId, CHATS_LIMIT - chatList.size), { obj -> client?.send(TdApi.GetChats(offsetOrder, offsetChatId, CHATS_LIMIT - chatList.size)) { obj ->
when (obj.constructor) { when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> { TdApi.Error.CONSTRUCTOR -> {
val error = obj as TdApi.Error val error = obj as TdApi.Error
@ -250,7 +250,7 @@ class TelegramHelper private constructor() {
} }
else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj") else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
} }
}) }
return return
} }
} }
@ -264,7 +264,7 @@ class TelegramHelper private constructor() {
for (chatTitle in chatTitles) { for (chatTitle in chatTitles) {
val chatId = this.chatTitles[chatTitle] val chatId = this.chatTitles[chatTitle]
if (chatId != null) { if (chatId != null) {
client?.send(TdApi.SearchChatRecentLocationMessages(chatId, CHAT_LIVE_USERS_LIMIT), { obj -> client?.send(TdApi.SearchChatRecentLocationMessages(chatId, CHAT_LIVE_USERS_LIMIT)) { obj ->
when (obj.constructor) { when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> { TdApi.Error.CONSTRUCTOR -> {
val error = obj as TdApi.Error val error = obj as TdApi.Error
@ -284,7 +284,7 @@ class TelegramHelper private constructor() {
} }
else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj") else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
} }
}) }
} }
} }
} }
@ -313,7 +313,7 @@ class TelegramHelper private constructor() {
private fun getActiveLiveLocationMessages(onComplete: (() -> Unit)?) { private fun getActiveLiveLocationMessages(onComplete: (() -> Unit)?) {
requestingActiveLiveLocationMessages = true requestingActiveLiveLocationMessages = true
client?.send(TdApi.GetActiveLiveLocationMessages(), { obj -> client?.send(TdApi.GetActiveLiveLocationMessages()) { obj ->
when (obj.constructor) { when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> { TdApi.Error.CONSTRUCTOR -> {
val error = obj as TdApi.Error val error = obj as TdApi.Error
@ -336,7 +336,7 @@ class TelegramHelper private constructor() {
else -> listener?.onSendLiveLicationError(-1, "Receive wrong response from TDLib: $obj") else -> listener?.onSendLiveLicationError(-1, "Receive wrong response from TDLib: $obj")
} }
requestingActiveLiveLocationMessages = false requestingActiveLiveLocationMessages = false
}) }
} }
private fun sendLiveLocationImpl(chatTitles: List<String>, livePeriod: Int = 61, latitude: Double, longitude: Double) { private fun sendLiveLocationImpl(chatTitles: List<String>, livePeriod: Int = 61, latitude: Double, longitude: Double) {
@ -575,7 +575,7 @@ class TelegramHelper private constructor() {
val remotePhoto = chat.photo?.small?.remote val remotePhoto = chat.photo?.small?.remote
if (remotePhoto != null && remotePhoto.id.isNotEmpty()) { if (remotePhoto != null && remotePhoto.id.isNotEmpty()) {
downloadChatFilesMap[remotePhoto.id] = chat downloadChatFilesMap[remotePhoto.id] = chat
client!!.send(TdApi.GetRemoteFile(remotePhoto.id, null), { obj -> client!!.send(TdApi.GetRemoteFile(remotePhoto.id, null)) { obj ->
when (obj.constructor) { when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> { TdApi.Error.CONSTRUCTOR -> {
val error = obj as TdApi.Error val error = obj as TdApi.Error
@ -590,7 +590,7 @@ class TelegramHelper private constructor() {
} }
else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj") else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
} }
}) }
} }
} }
val order = chat.order val order = chat.order
@ -630,6 +630,7 @@ class TelegramHelper private constructor() {
chat.lastMessage = updateChat.lastMessage chat.lastMessage = updateChat.lastMessage
setChatOrder(chat, updateChat.order) setChatOrder(chat, updateChat.order)
} }
//listener?.onTelegramChatsChanged()
} }
} }
TdApi.UpdateChatOrder.CONSTRUCTOR -> { TdApi.UpdateChatOrder.CONSTRUCTOR -> {
@ -650,6 +651,7 @@ class TelegramHelper private constructor() {
chat.isPinned = updateChat.isPinned chat.isPinned = updateChat.isPinned
setChatOrder(chat, updateChat.order) setChatOrder(chat, updateChat.order)
} }
//listener?.onTelegramChatsChanged()
} }
} }
TdApi.UpdateChatReadInbox.CONSTRUCTOR -> { TdApi.UpdateChatReadInbox.CONSTRUCTOR -> {
@ -751,6 +753,7 @@ class TelegramHelper private constructor() {
chat.draftMessage = updateChat.draftMessage chat.draftMessage = updateChat.draftMessage
setChatOrder(chat, updateChat.order) setChatOrder(chat, updateChat.order)
} }
//listener?.onTelegramChatsChanged()
} }
} }
TdApi.UpdateNotificationSettings.CONSTRUCTOR -> { TdApi.UpdateNotificationSettings.CONSTRUCTOR -> {