Fix tracker backgound location issue
This commit is contained in:
parent
b9f1f69934
commit
9c7bacc3af
7 changed files with 41 additions and 184 deletions
|
@ -19,7 +19,10 @@
|
|||
android:launchMode="singleTask"
|
||||
android:screenOrientation="unspecified"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
android:theme="@style/AppTheme"
|
||||
android:hasFragileUserData="true"
|
||||
android:requestLegacyExternalStorage="true">
|
||||
|
||||
<activity android:name=".ui.TrackerLogcatActivity" />
|
||||
<activity
|
||||
android:name=".ui.MainActivity"
|
||||
|
@ -48,14 +51,13 @@
|
|||
<service
|
||||
android:name=".TelegramService"
|
||||
android:label="@string/process_service"
|
||||
android:foregroundServiceType="location"
|
||||
android:stopWithTask="false">
|
||||
<intent-filter>
|
||||
<action android:name="net.osmand.telegram.TelegramService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<receiver android:name=".OnTelegramServiceAlarmReceiver" />
|
||||
|
||||
<receiver
|
||||
android:name=".InitAppBroadcastReceiver"
|
||||
android:enabled="true"
|
||||
|
|
|
@ -4,8 +4,8 @@ apply plugin: 'kotlin-android'
|
|||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
buildToolsVersion "28.0.3"
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion "29.0.3"
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
|
@ -23,7 +23,7 @@ android {
|
|||
defaultConfig {
|
||||
applicationId "net.osmand.telegram"
|
||||
minSdkVersion 15
|
||||
targetSdkVersion 28
|
||||
targetSdkVersion 29
|
||||
multiDexEnabled true
|
||||
versionCode 1
|
||||
versionCode System.getenv("APK_NUMBER_VERSION") ? System.getenv("APK_NUMBER_VERSION").toInteger() : versionCode
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
package net.osmand.telegram
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.location.LocationManager
|
||||
import net.osmand.telegram.utils.AndroidUtils
|
||||
|
||||
class OnTelegramServiceAlarmReceiver : BroadcastReceiver() {
|
||||
@SuppressLint("MissingPermission")
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val lock = TelegramService.getLock(context)
|
||||
val app = context.applicationContext as TelegramApplication
|
||||
val service = app.telegramService
|
||||
// do not do nothing
|
||||
if (lock.isHeld || service == null) {
|
||||
return
|
||||
}
|
||||
lock.acquire(15 * 60 * 1000L)
|
||||
|
||||
// request location updates
|
||||
val locationManager = service.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
try {
|
||||
if (AndroidUtils.isLocationPermissionAvailable(app)) {
|
||||
locationManager.requestLocationUpdates(service.serviceOffProvider, 0, 0f, service)
|
||||
}
|
||||
val handler = service.handler
|
||||
if (service.serviceOffInterval > service.serviceErrorInterval && handler != null) {
|
||||
handler.postDelayed({
|
||||
// if lock is not anymore held
|
||||
if (lock.isHeld) {
|
||||
lock.release()
|
||||
locationManager.removeUpdates(service)
|
||||
}
|
||||
}, service.serviceErrorInterval)
|
||||
}
|
||||
} catch (e: RuntimeException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,12 +8,13 @@ import android.net.ConnectivityManager
|
|||
import android.net.NetworkInfo
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import androidx.core.content.ContextCompat
|
||||
import net.osmand.PlatformUtil
|
||||
import net.osmand.telegram.ui.TrackerLogcatActivity
|
||||
import net.osmand.telegram.helpers.*
|
||||
import net.osmand.telegram.helpers.OsmandAidlHelper.OsmandHelperListener
|
||||
import net.osmand.telegram.helpers.OsmandAidlHelper.UpdatesListener
|
||||
import net.osmand.telegram.notifications.NotificationHelper
|
||||
import net.osmand.telegram.ui.TrackerLogcatActivity
|
||||
import net.osmand.telegram.utils.AndroidUtils
|
||||
import net.osmand.telegram.utils.UiUtils
|
||||
import java.io.File
|
||||
|
@ -146,35 +147,21 @@ class TelegramApplication : Application() {
|
|||
return internetConnectionAvailable
|
||||
}
|
||||
|
||||
private fun startTelegramService(intent: Int, serviceOffInterval: Long = 0) {
|
||||
private fun startTelegramService(intent: Int) {
|
||||
var i = intent
|
||||
var interval = serviceOffInterval
|
||||
val serviceIntent = Intent(this, TelegramService::class.java)
|
||||
|
||||
val telegramService = telegramService
|
||||
if (telegramService != null) {
|
||||
i = intent or telegramService.usedBy
|
||||
interval = if (TelegramService.isOffIntervalDepended(intent)) {
|
||||
Math.min(telegramService.serviceOffInterval, interval)
|
||||
} else {
|
||||
telegramService.serviceOffInterval
|
||||
}
|
||||
telegramService.stopSelf()
|
||||
}
|
||||
|
||||
serviceIntent.putExtra(TelegramService.USAGE_INTENT, i)
|
||||
serviceIntent.putExtra(TelegramService.USAGE_OFF_INTERVAL, interval)
|
||||
serviceIntent.putExtra(TelegramService.SEND_LOCATION_INTERVAL, settings.sendMyLocInterval)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
startForegroundService(serviceIntent)
|
||||
} else {
|
||||
startService(serviceIntent)
|
||||
}
|
||||
ContextCompat.startForegroundService(this, serviceIntent)
|
||||
}
|
||||
|
||||
fun startMyLocationService() {
|
||||
val interval = settings.sendMyLocInterval
|
||||
startTelegramService(TelegramService.USED_BY_MY_LOCATION, TelegramService.normalizeOffInterval(interval))
|
||||
startTelegramService(TelegramService.USED_BY_MY_LOCATION)
|
||||
}
|
||||
|
||||
fun stopMyLocationService() {
|
||||
|
|
|
@ -166,7 +166,7 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
|
|||
registerOrUnregisterCompassListener(true)
|
||||
}
|
||||
|
||||
fun redownloadAGPS() {
|
||||
private fun redownloadAGPS() {
|
||||
try {
|
||||
val service = app.getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
service.sendExtraCommand(LocationManager.GPS_PROVIDER, "delete_aiding_data", null)
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
package net.osmand.telegram
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ServiceInfo
|
||||
import android.location.Location
|
||||
import android.location.LocationListener
|
||||
import android.location.LocationManager
|
||||
import android.os.*
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import net.osmand.PlatformUtil
|
||||
import net.osmand.telegram.TelegramSettings.ShareChatInfo
|
||||
|
@ -26,7 +24,7 @@ private const val UPDATE_LIVE_MESSAGES_INTERVAL_MS = 10000L // 10 sec
|
|||
private const val UPDATE_LIVE_TRACKS_INTERVAL_MS = 30000L // 30 sec
|
||||
|
||||
class TelegramService : Service(), LocationListener, TelegramIncomingMessagesListener,
|
||||
TelegramOutgoingMessagesListener {
|
||||
TelegramOutgoingMessagesListener {
|
||||
|
||||
private val log = PlatformUtil.getLog(TelegramService::class.java)
|
||||
|
||||
|
@ -43,21 +41,14 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
private var updateWidgetHandler: Handler? = null
|
||||
private var updateWidgetThread = HandlerThread("WidgetUpdateServiceThread")
|
||||
|
||||
var handler: Handler? = null
|
||||
private set
|
||||
var usedBy = 0
|
||||
private set
|
||||
var serviceOffProvider: String = LocationManager.GPS_PROVIDER
|
||||
private set
|
||||
var serviceOffInterval = 0L
|
||||
private set
|
||||
var serviceErrorInterval = 0L
|
||||
private set
|
||||
var sendLocationInterval = 0L
|
||||
private set
|
||||
|
||||
private var lastLocationSentTime = 0L
|
||||
private var pendingIntent: PendingIntent? = null
|
||||
|
||||
class LocationServiceBinder : Binder()
|
||||
|
||||
|
@ -71,7 +62,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
updateWidgetHandler = Handler(updateWidgetThread.looper)
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? {
|
||||
override fun onBind(intent: Intent): IBinder {
|
||||
return binder
|
||||
}
|
||||
|
||||
|
@ -86,13 +77,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
ctx.stopService(serviceIntent)
|
||||
}
|
||||
isUsedByMyLocation(usedBy) -> {
|
||||
val app = app()
|
||||
if (app.settings.sendMyLocInterval >= OFF_INTERVAL_THRESHOLD && serviceOffInterval == 0L) {
|
||||
serviceOffInterval = app.settings.sendMyLocInterval
|
||||
setupServiceErrorInterval()
|
||||
setupAlarm()
|
||||
}
|
||||
app.notificationHelper.refreshNotification(NotificationType.LOCATION)
|
||||
app().notificationHelper.refreshNotification(NotificationType.LOCATION)
|
||||
}
|
||||
isUsedByUsersLocations(usedBy) -> removeLocationUpdates()
|
||||
}
|
||||
|
@ -100,19 +85,21 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
|
||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
val app = app()
|
||||
handler = Handler()
|
||||
val usageIntent = intent.getIntExtra(USAGE_INTENT, 0)
|
||||
usedBy = usageIntent or usedBy
|
||||
|
||||
serviceOffInterval = intent.getLongExtra(USAGE_OFF_INTERVAL, 0)
|
||||
sendLocationInterval = intent.getLongExtra(SEND_LOCATION_INTERVAL, 0)
|
||||
setupServiceErrorInterval()
|
||||
|
||||
app.telegramHelper.addIncomingMessagesListener(this)
|
||||
app.telegramHelper.addOutgoingMessagesListener(this)
|
||||
|
||||
app.telegramService = this
|
||||
|
||||
val locationNotification = app.notificationHelper.locationNotification
|
||||
val notification = app.notificationHelper.buildNotification(locationNotification)
|
||||
startForeground(locationNotification.telegramNotificationId, notification)
|
||||
app.notificationHelper.refreshNotification(locationNotification.type)
|
||||
|
||||
if (isUsedByMyLocation(usedBy)) {
|
||||
initLocationUpdates()
|
||||
startShareInfoUpdates()
|
||||
|
@ -124,21 +111,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
}
|
||||
app.shareLocationHelper.checkAndSendBufferMessages()
|
||||
|
||||
val locationNotification = app.notificationHelper.locationNotification
|
||||
val notification = app.notificationHelper.buildNotification(locationNotification)
|
||||
startForeground(locationNotification.telegramNotificationId, notification)
|
||||
app.notificationHelper.refreshNotification(locationNotification.type)
|
||||
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)
|
||||
return START_REDELIVER_INTENT
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
@ -158,13 +131,6 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
|
||||
removeLocationUpdates()
|
||||
|
||||
if (!isContinuous()) {
|
||||
val lock = getLock(this)
|
||||
if (lock.isHeld) {
|
||||
lock.release()
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldCleanupResources) {
|
||||
app.cleanupResources()
|
||||
}
|
||||
|
@ -176,7 +142,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
fun updateSendLocationInterval(newInterval: Long) {
|
||||
sendLocationInterval = newInterval
|
||||
}
|
||||
|
||||
|
||||
fun forceLocationUpdate() {
|
||||
val location = getFirstTimeRunDefaultLocation()
|
||||
app().shareLocationHelper.updateLocation(location)
|
||||
|
@ -186,21 +152,16 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
val firstLocation = getFirstTimeRunDefaultLocation()
|
||||
app().shareLocationHelper.updateLocation(firstLocation)
|
||||
|
||||
// requesting
|
||||
if (isContinuous()) {
|
||||
// request location updates
|
||||
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
try {
|
||||
locationManager.requestLocationUpdates(serviceOffProvider, 0, 0f, this@TelegramService)
|
||||
} catch (e: SecurityException) {
|
||||
Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show()
|
||||
Log.d(PlatformUtil.TAG, "Location service permission not granted") //$NON-NLS-1$
|
||||
} catch (e: IllegalArgumentException) {
|
||||
Toast.makeText(this, R.string.gps_not_available, Toast.LENGTH_LONG).show()
|
||||
Log.d(PlatformUtil.TAG, "GPS location provider not available") //$NON-NLS-1$
|
||||
}
|
||||
} else {
|
||||
setupAlarm()
|
||||
// request location updates
|
||||
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
try {
|
||||
locationManager.requestLocationUpdates(serviceOffProvider, 0, 0f, this@TelegramService)
|
||||
} catch (e: SecurityException) {
|
||||
Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show()
|
||||
log.debug("Location service permission not granted")
|
||||
} catch (e: IllegalArgumentException) {
|
||||
Toast.makeText(this, R.string.gps_not_available, Toast.LENGTH_LONG).show()
|
||||
log.debug("GPS location provider not available")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +215,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
startWidgetUpdates()
|
||||
}, UPDATE_WIDGET_INTERVAL_MS)
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
private fun getFirstTimeRunDefaultLocation(): net.osmand.Location? {
|
||||
val app = app()
|
||||
|
@ -282,43 +243,19 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
return location
|
||||
}
|
||||
|
||||
private fun setupAlarm() {
|
||||
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
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)
|
||||
}
|
||||
|
||||
private fun removeLocationUpdates() {
|
||||
// remove updates
|
||||
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
try {
|
||||
locationManager.removeUpdates(this)
|
||||
} catch (e: SecurityException) {
|
||||
Log.d(PlatformUtil.TAG, "Location service permission not granted")
|
||||
log.debug("Location service permission not granted")
|
||||
}
|
||||
}
|
||||
|
||||
private fun isContinuous(): Boolean {
|
||||
return serviceOffInterval == 0L
|
||||
}
|
||||
|
||||
override fun onLocationChanged(l: Location?) {
|
||||
val location = convertLocation(l)
|
||||
if (!isContinuous()) {
|
||||
// unregister listener and wait next time
|
||||
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||
try {
|
||||
locationManager.removeUpdates(this)
|
||||
} catch (e: Throwable) {
|
||||
Log.d(PlatformUtil.TAG, "Location service permission not granted") //$NON-NLS-1$
|
||||
}
|
||||
|
||||
val lock = getLock(this)
|
||||
if (lock.isHeld) {
|
||||
lock.release()
|
||||
}
|
||||
app().shareLocationHelper.updateLocation(location)
|
||||
} else if (System.currentTimeMillis() - lastLocationSentTime > sendLocationInterval * 1000) {
|
||||
if (System.currentTimeMillis() - lastLocationSentTime > sendLocationInterval * 1000) {
|
||||
lastLocationSentTime = System.currentTimeMillis()
|
||||
app().shareLocationHelper.updateLocation(location)
|
||||
}
|
||||
|
@ -373,7 +310,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
}
|
||||
|
||||
override fun onSendLiveLocationError(code: Int, message: String, shareInfo: ShareChatInfo, messageType: Int) {
|
||||
Log.d(PlatformUtil.TAG, "Send live location error: $code - $message")
|
||||
log.debug("Send live location error: $code - $message")
|
||||
when (messageType) {
|
||||
TelegramHelper.MESSAGE_TYPE_TEXT -> shareInfo.pendingTdLibText--
|
||||
TelegramHelper.MESSAGE_TYPE_MAP -> {
|
||||
|
@ -388,26 +325,8 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
const val USED_BY_MY_LOCATION: Int = 1
|
||||
const val USED_BY_USERS_LOCATIONS: Int = 2
|
||||
const val USAGE_INTENT = "SERVICE_USED_BY"
|
||||
const val USAGE_OFF_INTERVAL = "SERVICE_OFF_INTERVAL"
|
||||
const val SEND_LOCATION_INTERVAL = "SEND_LOCATION_INTERVAL"
|
||||
|
||||
const val OFF_INTERVAL_THRESHOLD: Long = 30000L
|
||||
|
||||
private var lockStatic: PowerManager.WakeLock? = null
|
||||
|
||||
@Synchronized
|
||||
fun getLock(context: Context): PowerManager.WakeLock {
|
||||
var lockStatic = lockStatic
|
||||
return if (lockStatic == null) {
|
||||
val mgr = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||
lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "OsmandServiceLock")
|
||||
this.lockStatic = lockStatic
|
||||
lockStatic
|
||||
} else {
|
||||
lockStatic
|
||||
}
|
||||
}
|
||||
|
||||
fun isUsedByMyLocation(usedBy: Int): Boolean {
|
||||
return (usedBy and USED_BY_MY_LOCATION) > 0
|
||||
}
|
||||
|
@ -416,14 +335,6 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
return (usedBy and USED_BY_USERS_LOCATIONS) > 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? {
|
||||
if (l == null) {
|
||||
return null
|
||||
|
|
|
@ -21,7 +21,6 @@ import android.widget.*
|
|||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import net.osmand.PlatformUtil
|
||||
import net.osmand.telegram.*
|
||||
|
@ -42,7 +41,7 @@ private const val SUGGESTED = 2
|
|||
private const val SHARE_LOCATION_CHAT = 1
|
||||
private const val DEFAULT_CHAT = 0
|
||||
|
||||
private const val ADAPTER_UPDATE_INTERVAL_MIL = 5 * 1000L // 5 sec
|
||||
private const val ADAPTER_UPDATE_INTERVAL_MS = 5 * 1000L // 5 sec
|
||||
|
||||
class MyLocationTabFragment : Fragment(), TelegramListener {
|
||||
|
||||
|
@ -380,7 +379,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
updateContent()
|
||||
startHandler()
|
||||
}
|
||||
}, ADAPTER_UPDATE_INTERVAL_MIL)
|
||||
}, ADAPTER_UPDATE_INTERVAL_MS)
|
||||
}
|
||||
|
||||
private fun animateStartSharingBtn(show: Boolean) {
|
||||
|
|
Loading…
Reference in a new issue