diff --git a/OsmAnd-telegram/AndroidManifest.xml b/OsmAnd-telegram/AndroidManifest.xml
index 625e51ee8e..d3d2a945a9 100644
--- a/OsmAnd-telegram/AndroidManifest.xml
+++ b/OsmAnd-telegram/AndroidManifest.xml
@@ -8,6 +8,7 @@
+
+
+
+
+
+
+
()
private val compassListeners = ArrayList()
- private var gpsStatusListener: GpsStatus.Listener? = null
private val mRotationM = FloatArray(9)
- private var agpsDataLastTimeDownloaded: Long = 0
private val useMagneticFieldSensorCompass = false
- private val gpsListener = object : LocationListener {
- override fun onLocationChanged(location: Location?) {
- if (location != null) {
- lastTimeGPSLocationFixed = location.time
- }
- setLocation(convertLocation(location))
- }
-
- override fun onProviderDisabled(provider: String) {}
-
- override fun onProviderEnabled(provider: String) {}
-
- override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
- }
- private val networkListeners = LinkedList()
-
val lastKnownLocationLatLon: LatLon?
get() = if (lastKnownLocation != null) {
LatLon(lastKnownLocation!!.latitude, lastKnownLocation!!.longitude)
@@ -87,109 +83,20 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
@SuppressLint("MissingPermission")
fun resumeAllUpdates() {
- val service = app.getSystemService(Context.LOCATION_SERVICE) as LocationManager
- if (app.isInternetConnectionAvailable) {
- if (System.currentTimeMillis() - agpsDataLastTimeDownloaded > AGPS_TO_REDOWNLOAD) {
- //force an updated check for internet connectivity here before destroying A-GPS-data
- if (app.isInternetConnectionAvailable(true)) {
- //redownloadAGPS()
- }
- }
+ if (AndroidUtils.isLocationPermissionAvailable(app) && fusedLocationProviderClient == null) {
+ fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(app)
}
- if (AndroidUtils.isLocationPermissionAvailable(app)) {
- service.addGpsStatusListener(getGpsStatusListener(service))
- try {
- service.requestLocationUpdates(
- LocationManager.GPS_PROVIDER,
- GPS_TIMEOUT_REQUEST.toLong(),
- GPS_DIST_REQUEST.toFloat(),
- gpsListener
- )
- } catch (e: IllegalArgumentException) {
- Log.d(PlatformUtil.TAG, "GPS location provider not available") //$NON-NLS-1$
- }
- // try to always ask for network provide : it is faster way to find location
-
- val providers = service.getProviders(true) ?: return
- for (provider in providers) {
- if (provider == null || provider == LocationManager.GPS_PROVIDER) {
- continue
- }
- try {
- val networkListener = NetworkListener()
- service.requestLocationUpdates(
- provider,
- GPS_TIMEOUT_REQUEST.toLong(),
- GPS_DIST_REQUEST.toFloat(),
- networkListener
- )
- networkListeners.add(networkListener)
- } catch (e: IllegalArgumentException) {
- Log.d(
- PlatformUtil.TAG,
- "$provider location provider not available"
- ) //$NON-NLS-1$
- }
-
- }
+ try {
+ fusedLocationProviderClient?.requestLocationUpdates(
+ locationRequest, locationCallback, Looper.myLooper())
+ } catch (unlikely: SecurityException) {
+ Log.d(PlatformUtil.TAG, "Lost location permissions. Couldn't request updates. $unlikely")
}
registerOrUnregisterCompassListener(true)
}
- private fun redownloadAGPS() {
- try {
- val service = app.getSystemService(Context.LOCATION_SERVICE) as LocationManager
- service.sendExtraCommand(LocationManager.GPS_PROVIDER, "delete_aiding_data", null)
- val bundle = Bundle()
- service.sendExtraCommand("gps", "force_xtra_injection", bundle)
- service.sendExtraCommand("gps", "force_time_injection", bundle)
- agpsDataLastTimeDownloaded = System.currentTimeMillis()
- } catch (e: Exception) {
- agpsDataLastTimeDownloaded = 0L
- e.printStackTrace()
- }
- }
-
- private fun getGpsStatusListener(service: LocationManager): GpsStatus.Listener {
- gpsStatusListener = object : GpsStatus.Listener {
- private var gpsStatus: GpsStatus? = null
-
- @SuppressLint("MissingPermission")
- override fun onGpsStatusChanged(event: Int) {
- try {
- gpsStatus = service.getGpsStatus(gpsStatus)
- } catch (e: Exception) {
- e.printStackTrace()
- }
- updateGPSInfo(gpsStatus)
- updateLocation(lastKnownLocation)
- }
- }
- return gpsStatusListener!!
- }
-
- private fun updateGPSInfo(s: GpsStatus?) {
- var fixed = false
- var n = 0
- var u = 0
- if (s != null) {
- val iterator = s.satellites.iterator()
- while (iterator.hasNext()) {
- val g = iterator.next()
- n++
- if (g.usedInFix()) {
- u++
- fixed = true
- }
- }
- }
- gpsInfo.fixed = fixed
- gpsInfo.foundSatellites = n
- gpsInfo.usedSatellites = u
- }
-
fun updateScreenOrientation(orientation: Int) {
currentScreenOrientation = orientation
}
@@ -217,12 +124,12 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
@Synchronized
fun registerOrUnregisterCompassListener(register: Boolean) {
if (sensorRegistered && !register) {
- Log.d(PlatformUtil.TAG, "Disable sensor") //$NON-NLS-1$
+ Log.d(PlatformUtil.TAG, "Disable sensor")
(app.getSystemService(Context.SENSOR_SERVICE) as SensorManager).unregisterListener(this)
sensorRegistered = false
heading = null
} else if (!sensorRegistered && register) {
- Log.d(PlatformUtil.TAG, "Enable sensor") //$NON-NLS-1$
+ Log.d(PlatformUtil.TAG, "Enable sensor")
val sensorMgr = app.getSystemService(Context.SENSOR_SERVICE) as SensorManager
if (useMagneticFieldSensorCompass) {
var s: Sensor? = sensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
@@ -360,7 +267,7 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
}
private fun getAngle(sinA: Float, cosA: Float) = MapUtils.unifyRotationTo360(
- (Math.atan2(sinA.toDouble(), cosA.toDouble()) * 180 / Math.PI).toFloat()
+ (atan2(sinA.toDouble(), cosA.toDouble()) * 180 / Math.PI).toFloat()
)
private fun updateLocation(loc: net.osmand.Location?) {
@@ -369,31 +276,11 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
}
}
- private fun useOnlyGPS() =
- System.currentTimeMillis() - lastTimeGPSLocationFixed < NOT_SWITCH_TO_NETWORK_WHEN_GPS_LOST_MS
-
- // Working with location checkListeners
- private inner class NetworkListener : LocationListener {
-
- override fun onLocationChanged(location: Location) {
- if (!useOnlyGPS()) {
- setLocation(convertLocation(location))
- }
- }
-
- override fun onProviderDisabled(provider: String) {}
-
- override fun onProviderEnabled(provider: String) {}
-
- override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
- }
-
private fun stopLocationRequests() {
- val service = app.getSystemService(Context.LOCATION_SERVICE) as LocationManager
- service.removeGpsStatusListener(gpsStatusListener)
- service.removeUpdates(gpsListener)
- while (!networkListeners.isEmpty()) {
- service.removeUpdates(networkListeners.poll())
+ try {
+ fusedLocationProviderClient?.removeLocationUpdates(locationCallback)
+ } catch (unlikely: SecurityException) {
+ Log.d(PlatformUtil.TAG, "Lost location permissions. Couldn't remove updates. $unlikely")
}
}
@@ -403,17 +290,7 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
}
private fun setLocation(location: net.osmand.Location?) {
- if (location == null) {
- updateGPSInfo(null)
- }
- if (location != null) {
- if (gpsSignalLost) {
- gpsSignalLost = false
- }
- }
this.lastKnownLocation = location
-
- // Update information
updateLocation(this.lastKnownLocation)
}
@@ -424,21 +301,10 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
}
}
- class GPSInfo {
- var foundSatellites = 0
- var usedSatellites = 0
- var fixed = false
- }
-
companion object {
private const val INTERVAL_TO_CLEAR_SET_LOCATION = 30 * 1000
- private const val GPS_TIMEOUT_REQUEST = 0
- private const val GPS_DIST_REQUEST = 0
- private const val NOT_SWITCH_TO_NETWORK_WHEN_GPS_LOST_MS = 12000
- private const val AGPS_TO_REDOWNLOAD = 16L * 60 * 60 * 1000 // 16 hours
-
fun convertLocation(l: Location?): net.osmand.Location? {
if (l == null) {
return null
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt
index c3dde54e76..2d85e971b0 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramService.kt
@@ -4,30 +4,27 @@ import android.annotation.SuppressLint
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 com.google.android.gms.location.*
import net.osmand.PlatformUtil
import net.osmand.telegram.TelegramSettings.ShareChatInfo
import net.osmand.telegram.helpers.TelegramHelper
-import net.osmand.telegram.helpers.TelegramHelper.*
+import net.osmand.telegram.helpers.TelegramHelper.TelegramIncomingMessagesListener
+import net.osmand.telegram.helpers.TelegramHelper.TelegramOutgoingMessagesListener
import net.osmand.telegram.notifications.TelegramNotification.NotificationType
import net.osmand.telegram.utils.AndroidUtils
import org.drinkless.td.libcore.telegram.TdApi
-import java.util.*
private const val UPDATE_WIDGET_INTERVAL_MS = 1000L // 1 sec
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,
+class TelegramService : Service(), TelegramIncomingMessagesListener,
TelegramOutgoingMessagesListener {
-
- private val log = PlatformUtil.getLog(TelegramService::class.java)
-
+
private fun app() = application as TelegramApplication
private val binder = LocationServiceBinder()
private var shouldCleanupResources: Boolean = false
@@ -41,10 +38,18 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
private var updateWidgetHandler: Handler? = null
private var updateWidgetThread = HandlerThread("WidgetUpdateServiceThread")
+ // FusedLocationProviderClient - Main class for receiving location updates.
+ private lateinit var fusedLocationProviderClient: FusedLocationProviderClient
+
+ // LocationRequest - Requirements for the location updates, i.e., how often you should receive
+ // updates, the priority, etc.
+ private lateinit var locationRequest: LocationRequest
+
+ // LocationCallback - Called when FusedLocationProviderClient has a new Location.
+ private lateinit var locationCallback: LocationCallback
+
var usedBy = 0
private set
- var serviceOffProvider: String = LocationManager.GPS_PROVIDER
- private set
var sendLocationInterval = 0L
private set
@@ -60,6 +65,42 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
updateShareInfoHandler = Handler(mHandlerThread.looper)
updateTracksHandler = Handler(tracksHandlerThread.looper)
updateWidgetHandler = Handler(updateWidgetThread.looper)
+
+ fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
+
+ locationRequest = LocationRequest().apply {
+ // Sets the desired interval for active location updates. This interval is inexact. You
+ // may not receive updates at all if no location sources are available, or you may
+ // receive them less frequently than requested. You may also receive updates more
+ // frequently than requested if other applications are requesting location at a more
+ // frequent interval.
+ //
+ // IMPORTANT NOTE: Apps running on Android 8.0 and higher devices (regardless of
+ // targetSdkVersion) may receive updates less frequently than this interval when the app
+ // is no longer in the foreground.
+ interval = 1000
+
+ // Sets the fastest rate for active location updates. This interval is exact, and your
+ // application will never receive updates more frequently than this value.
+ fastestInterval = 500
+
+ // Sets the maximum time when batched location updates are delivered. Updates may be
+ // delivered sooner than this interval.
+ maxWaitTime = 2000
+
+ priority = LocationRequest.PRIORITY_HIGH_ACCURACY
+ }
+
+ locationCallback = object : LocationCallback() {
+ override fun onLocationResult(locationResult: LocationResult?) {
+ super.onLocationResult(locationResult)
+ val location = convertLocation(locationResult?.lastLocation)
+ if (System.currentTimeMillis() - lastLocationSentTime > sendLocationInterval * 1000) {
+ lastLocationSentTime = System.currentTimeMillis()
+ app().shareLocationHelper.updateLocation(location)
+ }
+ }
+ }
}
override fun onBind(intent: Intent): IBinder {
@@ -144,27 +185,27 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
}
fun forceLocationUpdate() {
- val location = getFirstTimeRunDefaultLocation()
- app().shareLocationHelper.updateLocation(location)
+ getFirstTimeRunDefaultLocation { location ->
+ app().shareLocationHelper.updateLocation(location)
+ }
}
private fun initLocationUpdates() {
- val firstLocation = getFirstTimeRunDefaultLocation()
- app().shareLocationHelper.updateLocation(firstLocation)
+ getFirstTimeRunDefaultLocation { location ->
+ app().shareLocationHelper.updateLocation(location)
+ }
// request location updates
- /*
- val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
try {
- locationManager.requestLocationUpdates(serviceOffProvider, 0, 0f, this@TelegramService)
- } catch (e: SecurityException) {
+ fusedLocationProviderClient.requestLocationUpdates(
+ locationRequest, locationCallback, Looper.myLooper())
+ } catch (unlikely: SecurityException) {
Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show()
- log.debug("Location service permission not granted")
+ Log.d(PlatformUtil.TAG, "Lost location permissions. Couldn't request updates. $unlikely")
} catch (e: IllegalArgumentException) {
Toast.makeText(this, R.string.gps_not_available, Toast.LENGTH_LONG).show()
- log.debug("GPS location provider not available")
+ Log.d(PlatformUtil.TAG, "GPS location provider not available")
}
- */
}
private fun startShareInfoUpdates() {
@@ -219,62 +260,27 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
}
@SuppressLint("MissingPermission")
- private fun getFirstTimeRunDefaultLocation(): net.osmand.Location? {
+ private fun getFirstTimeRunDefaultLocation(locationListener: (net.osmand.Location?) -> Unit) {
val app = app()
if (!AndroidUtils.isLocationPermissionAvailable(app)) {
- return null
+ locationListener(null)
+ return
}
- var location: net.osmand.Location? = null
- /*
- val service = app.getSystemService(Context.LOCATION_SERVICE) as LocationManager
- val ps = service.getProviders(true) ?: return null
- val providers = ArrayList(ps)
- // note, passive provider is from API_LEVEL 8 but it is a constant, we can check for it.
- // constant should not be changed in future
- val passiveFirst = providers.indexOf("passive") // LocationManager.PASSIVE_PROVIDER
- // put passive provider to first place
- if (passiveFirst > -1) {
- providers.add(0, providers.removeAt(passiveFirst))
- }
- // find location
- for (provider in providers) {
- val loc = convertLocation(service.getLastKnownLocation(provider))
- if (loc != null && (location == null || loc.hasAccuracy() && loc.accuracy < location.accuracy)) {
- location = loc
- }
- }
- */
- return location
+ fusedLocationProviderClient.lastLocation
+ .addOnSuccessListener { location : Location? ->
+ locationListener(convertLocation(location))
+ }
}
private fun removeLocationUpdates() {
// remove updates
- /*
- val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
try {
- locationManager.removeUpdates(this)
- } catch (e: SecurityException) {
- log.debug("Location service permission not granted")
- }
- */
- }
-
- override fun onLocationChanged(l: Location?) {
- val location = convertLocation(l)
- if (System.currentTimeMillis() - lastLocationSentTime > sendLocationInterval * 1000) {
- lastLocationSentTime = System.currentTimeMillis()
- app().shareLocationHelper.updateLocation(location)
+ fusedLocationProviderClient.removeLocationUpdates(locationCallback)
+ } catch (unlikely: SecurityException) {
+ Log.d(PlatformUtil.TAG, "Lost location permissions. Couldn't remove updates. $unlikely")
}
}
- override fun onProviderDisabled(provider: String) {
- Toast.makeText(this, getString(R.string.location_service_no_gps_available), Toast.LENGTH_LONG).show()
- }
-
- override fun onProviderEnabled(provider: String) {}
-
- override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
-
override fun onTaskRemoved(rootIntent: Intent) {
val app = app()
if (app.telegramService != null) {
@@ -316,7 +322,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
}
override fun onSendLiveLocationError(code: Int, message: String, shareInfo: ShareChatInfo, messageType: Int) {
- log.debug("Send live location error: $code - $message")
+ Log.d(PlatformUtil.TAG, "Send live location error: $code - $message")
when (messageType) {
TelegramHelper.MESSAGE_TYPE_TEXT -> shareInfo.pendingTdLibText--
TelegramHelper.MESSAGE_TYPE_MAP -> {
diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
index ae6805fae9..8dec6de092 100644
--- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
+++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramSettings.kt
@@ -1,7 +1,6 @@
package net.osmand.telegram
import android.content.Context
-import android.location.LocationManager
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import androidx.annotation.ColorRes