diff --git a/OsmAnd-telegram/AndroidManifest.xml b/OsmAnd-telegram/AndroidManifest.xml index d99383f3e6..3b98f7e1e8 100644 --- a/OsmAnd-telegram/AndroidManifest.xml +++ b/OsmAnd-telegram/AndroidManifest.xml @@ -20,8 +20,8 @@ @@ -33,14 +33,24 @@ + android:stopWithTask="false"> - + + + + + + + + diff --git a/OsmAnd-telegram/src/net/osmand/telegram/MainActivity.kt b/OsmAnd-telegram/src/net/osmand/telegram/MainActivity.kt index ede5a2edb5..66e0356a30 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/MainActivity.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/MainActivity.kt @@ -44,6 +44,7 @@ class MainActivity : AppCompatActivity(), TelegramListener { get() = application as TelegramApplication private val telegramHelper get() = app.telegramHelper + private val osmandHelper get() = app.osmandHelper private val settings get() = app.settings override fun onCreate(savedInstanceState: Bundle?) { @@ -92,7 +93,7 @@ class MainActivity : AppCompatActivity(), TelegramListener { if (settings.hasAnyChatToShareLocation() && !AndroidUtils.isLocationPermissionAvailable(this)) { requestLocationPermission() - } else if (settings.hasAnyChatToShowOnMap() && !app.osmandHelper.isOsmandBound()) { + } else if (settings.hasAnyChatToShowOnMap() && osmandHelper.initialized && !osmandHelper.isOsmandBound()) { showOsmandMissingDialog() } } @@ -292,7 +293,7 @@ class MainActivity : AppCompatActivity(), TelegramListener { app.shareLocationHelper.startSharingLocation() } } - if (settings.hasAnyChatToShowOnMap() && app.osmandHelper.isOsmandBound()) { + if (settings.hasAnyChatToShowOnMap() && osmandHelper.initialized && !osmandHelper.isOsmandBound()) { showOsmandMissingDialog() } } @@ -362,18 +363,26 @@ class MainActivity : AppCompatActivity(), TelegramListener { holder.showOnMapSwitch?.setOnCheckedChangeListener(null) holder.showOnMapSwitch?.isChecked = settings.isShowingChatOnMap(chatTitle) - holder.showOnMapSwitch?.setOnCheckedChangeListener { view, isChecked -> + holder.showOnMapSwitch?.setOnCheckedChangeListener { _, isChecked -> settings.showChatOnMap(chatTitle, isChecked) if (settings.hasAnyChatToShowOnMap()) { - if (!app.osmandHelper.isOsmandBound()) { + if (osmandHelper.initialized && !osmandHelper.isOsmandBound()) { if (isChecked) { showOsmandMissingDialog() } } else { - //app.shareLocationHelper.startSharingLocation() + if (isChecked) { + app.showLocationHelper.showChatMessages(chatTitle) + } else { + app.showLocationHelper.hideChatMessages(chatTitle) + } + app.showLocationHelper.startShowingLocation() } } else { - //app.shareLocationHelper.stopSharingLocation() + app.showLocationHelper.stopShowingLocation() + if (!isChecked) { + app.showLocationHelper.hideChatMessages(chatTitle) + } } } } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt b/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt index affb055ff1..3cc75dd9eb 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/TelegramApplication.kt @@ -9,8 +9,11 @@ import android.os.Build import android.os.Handler import net.osmand.telegram.helpers.OsmandAidlHelper import net.osmand.telegram.helpers.ShareLocationHelper +import net.osmand.telegram.helpers.ShowLocationHelper import net.osmand.telegram.helpers.TelegramHelper import net.osmand.telegram.notifications.NotificationHelper +import net.osmand.telegram.services.MyLocationService +import net.osmand.telegram.services.UserLocationService import net.osmand.telegram.utils.AndroidUtils class TelegramApplication : Application() { @@ -18,10 +21,12 @@ class TelegramApplication : Application() { val telegramHelper = TelegramHelper.instance lateinit var settings: TelegramSettings private set lateinit var shareLocationHelper: ShareLocationHelper private set + lateinit var showLocationHelper: ShowLocationHelper private set lateinit var notificationHelper: NotificationHelper private set lateinit var osmandHelper: OsmandAidlHelper private set - var locationService: LocationService? = null + var myLocationService: MyLocationService? = null + var userLocationService: UserLocationService? = null private val uiHandler = Handler() @@ -33,13 +38,17 @@ class TelegramApplication : Application() { telegramHelper.appDir = filesDir.absolutePath settings = TelegramSettings(this) - shareLocationHelper = ShareLocationHelper(this) - notificationHelper = NotificationHelper(this) osmandHelper = OsmandAidlHelper(this) + shareLocationHelper = ShareLocationHelper(this) + showLocationHelper = ShowLocationHelper(this) + notificationHelper = NotificationHelper(this) if (settings.hasAnyChatToShareLocation() && AndroidUtils.isLocationPermissionAvailable(this)) { shareLocationHelper.startSharingLocation() } + if (settings.hasAnyChatToShowOnMap()) { + showLocationHelper.startShowingLocation() + } } override fun onTerminate() { @@ -80,14 +89,14 @@ class TelegramApplication : Application() { return internetConnectionAvailable } - fun startLocationService(restart: Boolean = false) { - val serviceIntent = Intent(this, LocationService::class.java) + fun startMyLocationService(restart: Boolean = false) { + val serviceIntent = Intent(this, MyLocationService::class.java) - val locationService = locationService - if (locationService != null && restart) { - locationService.stopSelf() + val myLocationService = myLocationService + if (myLocationService != null && restart) { + myLocationService.stopSelf() } - if (locationService == null || restart) { + if (myLocationService == null || restart) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(serviceIntent) } else { @@ -96,8 +105,28 @@ class TelegramApplication : Application() { } } - fun stopLocationService() { - locationService?.stopIfNeeded(this) + fun stopMyLocationService() { + myLocationService?.stopIfNeeded(this) + } + + fun startUserLocationService(restart: Boolean = false) { + val serviceIntent = Intent(this, UserLocationService::class.java) + + val userLocationService = userLocationService + if (userLocationService != null && restart) { + userLocationService.stopSelf() + } + if (userLocationService == null || restart) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + startForegroundService(serviceIntent) + } else { + startService(serviceIntent) + } + } + } + + fun stopUserLocationService() { + userLocationService?.stopIfNeeded(this) } fun runInUIThread(action: (() -> Unit)) { diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/OsmandAidlHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/OsmandAidlHelper.kt index ba37d519be..e1c69c6081 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/OsmandAidlHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/OsmandAidlHelper.kt @@ -56,6 +56,18 @@ class OsmandAidlHelper(private val app: Application) { private var mIOsmAndAidlInterface: IOsmAndAidlInterface? = null + var initialized: Boolean = false + private set + + var bound: Boolean = false + private set + + var listener: OsmandHelperListener? = null + + interface OsmandHelperListener { + fun onOsmandConnectionStateChanged(connected: Boolean) + } + /** * Class for interacting with the main interface of the service. */ @@ -68,18 +80,25 @@ class OsmandAidlHelper(private val app: Application) { // service through an IDL interface, so get a client-side // representation of that from the raw service object. mIOsmAndAidlInterface = IOsmAndAidlInterface.Stub.asInterface(service) - Toast.makeText(app, "OsmAnd service connected", Toast.LENGTH_SHORT).show() + initialized = true + Toast.makeText(app, "OsmAnd connected", Toast.LENGTH_SHORT).show() + listener?.onOsmandConnectionStateChanged(true) } override fun onServiceDisconnected(className: ComponentName) { // This is called when the connection with the service has been // unexpectedly disconnected -- that is, its process crashed. mIOsmAndAidlInterface = null - Toast.makeText(app, "OsmAnd service disconnected", Toast.LENGTH_SHORT).show() + Toast.makeText(app, "OsmAnd disconnected", Toast.LENGTH_SHORT).show() + listener?.onOsmandConnectionStateChanged(false) } } fun isOsmandBound(): Boolean { + return bound + } + + fun isOsmandConnected(): Boolean { return mIOsmAndAidlInterface != null } @@ -96,7 +115,7 @@ class OsmandAidlHelper(private val app: Application) { if (mIOsmAndAidlInterface!!.getActiveGpx(res)) { return res } - } catch (e: RemoteException) { + } catch (e: Throwable) { e.printStackTrace() } @@ -106,10 +125,17 @@ class OsmandAidlHelper(private val app: Application) { init { when { - bindService(OSMAND_PLUS_PACKAGE_NAME) -> OSMAND_PACKAGE_NAME = OSMAND_PLUS_PACKAGE_NAME - bindService(OSMAND_FREE_PACKAGE_NAME) -> OSMAND_PACKAGE_NAME = OSMAND_FREE_PACKAGE_NAME + bindService(OSMAND_PLUS_PACKAGE_NAME) -> { + OSMAND_PACKAGE_NAME = OSMAND_PLUS_PACKAGE_NAME + bound = true + } + bindService(OSMAND_FREE_PACKAGE_NAME) -> { + OSMAND_PACKAGE_NAME = OSMAND_FREE_PACKAGE_NAME + bound = true + } else -> { - Toast.makeText(app, "OsmAnd service NOT bind", Toast.LENGTH_SHORT).show() + bound = false + initialized = true } } } @@ -118,13 +144,7 @@ class OsmandAidlHelper(private val app: Application) { return if (mIOsmAndAidlInterface == null) { val intent = Intent("net.osmand.aidl.OsmandAidlService") intent.`package` = packageName - val res = app.bindService(intent, mConnection, Context.BIND_AUTO_CREATE) - if (res) { - Toast.makeText(app, "OsmAnd service bind", Toast.LENGTH_SHORT).show() - true - } else { - false - } + app.bindService(intent, mConnection, Context.BIND_AUTO_CREATE) } else { true } @@ -443,7 +463,7 @@ class OsmandAidlHelper(private val app: Application) { * @param zOrder - z-order position of layer. Default value is 5.5f * @param points - initial list of points. Nullable. */ - fun addMapLayer(id: String, name: String, zOrder: Float, points: List): Boolean { + fun addMapLayer(id: String, name: String, zOrder: Float, points: List?): Boolean { if (mIOsmAndAidlInterface != null) { try { val layer = AMapLayer(id, name, zOrder, points) @@ -464,7 +484,7 @@ class OsmandAidlHelper(private val app: Application) { * @param zOrder - z-order position of layer. Default value is 5.5f * @param points - list of points. Nullable. */ - fun updateMapLayer(id: String, name: String, zOrder: Float, points: List): Boolean { + fun updateMapLayer(id: String, name: String, zOrder: Float, points: List?): Boolean { if (mIOsmAndAidlInterface != null) { try { val layer = AMapLayer(id, name, zOrder, points) @@ -507,7 +527,7 @@ class OsmandAidlHelper(private val app: Application) { * @param details - list of details. Displayed under context menu. */ fun addMapPoint(layerId: String, pointId: String, shortName: String, fullName: String, - typeName: String, color: Int, location: ALatLon, details: List): Boolean { + typeName: String, color: Int, location: ALatLon, details: List?): Boolean { if (mIOsmAndAidlInterface != null) { try { val point = AMapPoint(pointId, shortName, fullName, typeName, color, location, details) @@ -533,7 +553,7 @@ class OsmandAidlHelper(private val app: Application) { * @param details - list of details. Displayed under context menu. */ fun updateMapPoint(layerId: String, pointId: String, shortName: String, fullName: String, - typeName: String, color: Int, location: ALatLon, details: List): Boolean { + typeName: String, color: Int, location: ALatLon, details: List?): Boolean { if (mIOsmAndAidlInterface != null) { try { val point = AMapPoint(pointId, shortName, fullName, typeName, color, location, details) diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt index 74a0676629..f8cbfdc863 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShareLocationHelper.kt @@ -52,29 +52,33 @@ class ShareLocationHelper(private val app: TelegramApplication) { } fun startSharingLocation() { - sharingLocation = true + if (!sharingLocation) { + sharingLocation = true - app.startLocationService() + app.startMyLocationService() - refreshNotification() + refreshNotification() + } } fun stopSharingLocation() { - sharingLocation = false + if (sharingLocation) { + sharingLocation = false - app.stopLocationService() - lastLocation = null - lastTimeInMillis = 0L - distance = 0 - duration = 0 + app.stopMyLocationService() + lastLocation = null + lastTimeInMillis = 0L + distance = 0 + duration = 0 - refreshNotification() + refreshNotification() + } } fun pauseSharingLocation() { sharingLocation = false - app.stopLocationService() + app.stopMyLocationService() lastLocation = null lastTimeInMillis = 0L diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShowLocationHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShowLocationHelper.kt new file mode 100644 index 0000000000..ba6dc98e19 --- /dev/null +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/ShowLocationHelper.kt @@ -0,0 +1,83 @@ +package net.osmand.telegram.helpers + +import android.graphics.Color +import net.osmand.aidl.map.ALatLon +import net.osmand.telegram.TelegramApplication +import org.drinkless.td.libcore.telegram.TdApi + +class ShowLocationHelper(private val app: TelegramApplication) { + + companion object { + private const val MAP_LAYER_ID = "telegram_layer" + } + + private val telegramHelper = app.telegramHelper + private val osmandHelper = app.osmandHelper + + var showingLocation: Boolean = false + private set + + private fun setMapLayer() { + osmandHelper.addMapLayer(MAP_LAYER_ID, "Telegram", 5.5f, null) + } + + fun showLocationOnMap(chatTitle: String, message: TdApi.Message) { + if (osmandHelper.isOsmandConnected()) { + val content = message.content + if (content is TdApi.MessageLocation) { + var userName = "" + val user = telegramHelper.getUser(message.senderUserId) + if (user != null) { + userName = "${user.firstName} ${user.lastName}".trim() + if (userName.isEmpty()) { + userName = user.username + } + if (userName.isEmpty()) { + userName = user.phoneNumber + } + } + if (userName.isEmpty()) { + userName = message.senderUserId.toString() + } + setMapLayer() + osmandHelper.addMapPoint(MAP_LAYER_ID, "${chatTitle}_${message.senderUserId}", userName, userName, + chatTitle, Color.RED, ALatLon(content.location.latitude, content.location.longitude), null) + } + } + } + + fun showChatMessages(chatTitle: String) { + if (osmandHelper.isOsmandConnected()) { + val messages = telegramHelper.getChatMessages(chatTitle) + for (message in messages) { + showLocationOnMap(chatTitle, message) + } + } + } + + fun hideChatMessages(chatTitle: String) { + if (osmandHelper.isOsmandConnected()) { + val messages = telegramHelper.getChatMessages(chatTitle) + for (message in messages) { + val user = telegramHelper.getUser(message.senderUserId) + if (user != null) { + osmandHelper.removeMapPoint(MAP_LAYER_ID, "${chatTitle}_${message.senderUserId}") + } + } + } + } + + fun startShowingLocation() { + if (!showingLocation) { + showingLocation = true + app.startUserLocationService() + } + } + + fun stopShowingLocation() { + if (showingLocation) { + showingLocation = false + app.stopUserLocationService() + } + } +} \ No newline at end of file diff --git a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt index ef3c09fa92..3933f23dff 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/helpers/TelegramHelper.kt @@ -17,6 +17,7 @@ class TelegramHelper private constructor() { companion object { private val log = PlatformUtil.getLog(TelegramHelper::class.java) private const val CHATS_LIMIT = 100 + private const val CHAT_LIVE_USERS_LIMIT = 100 private const val IGNORED_ERROR_CODE = 406 private var helper: TelegramHelper? = null @@ -40,6 +41,8 @@ class TelegramHelper private constructor() { private val chatList = TreeSet() private val chatLiveMessages = ConcurrentHashMap() + private val usersLiveMessages = ConcurrentHashMap() + private val usersFullInfo = ConcurrentHashMap() private val basicGroupsFullInfo = ConcurrentHashMap() private val supergroupsFullInfo = ConcurrentHashMap() @@ -61,6 +64,7 @@ class TelegramHelper private constructor() { private val liveLocationMessageUpdatesHandler = LiveLocationMessageUpdatesHandler() var listener: TelegramListener? = null + var incomingMessagesListener: TelegramIncomingMessagesListener? = null fun getChatList(): TreeSet { synchronized(chatList) { @@ -76,6 +80,21 @@ class TelegramHelper private constructor() { return chats[id] } + fun getUser(id: Int): TdApi.User? { + return users[id] + } + + fun getChatMessages(chatTitle: String): List { + val res = mutableListOf() + for (message in usersLiveMessages.values) { + val title = chats[message.chatId]?.title + if (title == chatTitle) { + res.add(message) + } + } + return res + } + private fun updateChatTitles() { chatTitles.clear() for (chatEntry in chats.entries) { @@ -111,6 +130,10 @@ class TelegramHelper private constructor() { fun onSendLiveLicationError(code: Int, message: String) } + interface TelegramIncomingMessagesListener { + fun onReceiveChatLocationMessages(chatTitle: String, vararg messages: TdApi.Message) + } + interface TelegramAuthorizationRequestListener { fun onRequestTelegramAuthenticationParameter(parameterType: TelegramAuthenticationParameterType) fun onTelegramAuthorizationRequestError(code: Int, message: String) @@ -174,7 +197,7 @@ class TelegramHelper private constructor() { } } - fun requestChats(reload: Boolean = false) { + private fun requestChats(reload: Boolean = false) { synchronized(chatList) { if (reload) { chatList.clear() @@ -214,9 +237,41 @@ class TelegramHelper private constructor() { } } updateChatTitles() + getChatRecentLocationMessages(chatTitles.keys) listener?.onTelegramChatsRead() } + private fun getChatRecentLocationMessages(chatTitles: Set) { + if (haveAuthorization) { + for (chatTitle in chatTitles) { + val chatId = this.chatTitles[chatTitle] + if (chatId != null) { + client?.send(TdApi.SearchChatRecentLocationMessages(chatId, CHAT_LIVE_USERS_LIMIT), { obj -> + when (obj.constructor) { + TdApi.Error.CONSTRUCTOR -> { + val error = obj as TdApi.Error + val code = error.code + if (code != IGNORED_ERROR_CODE && code != 400) { + listener?.onTelegramError(code, error.message) + } + } + TdApi.Messages.CONSTRUCTOR -> { + val messages = (obj as TdApi.Messages).messages + for (message in messages) { + if (!message.isOutgoing) { + usersLiveMessages[message.id] = message + } + } + incomingMessagesListener?.onReceiveChatLocationMessages(chatTitle, *messages) + } + else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj") + } + }) + } + } + } + } + /** * @chatId Id of the chat * @livePeriod Period for which the location can be updated, in seconds; should be between 60 and 86400 for a live location and 0 otherwise. @@ -338,7 +393,7 @@ class TelegramHelper private constructor() { } } - private inner class LiveLocationMessageUpdatesHandler: ResultHandler { + private inner class LiveLocationMessageUpdatesHandler : ResultHandler { override fun onResult(obj: TdApi.Object) { when (obj.constructor) { TdApi.Error.CONSTRUCTOR -> { @@ -564,6 +619,28 @@ class TelegramHelper private constructor() { chat.unreadMentionCount = updateChat.unreadMentionCount } } + TdApi.UpdateMessageContent.CONSTRUCTOR -> { + val updateMessageContent = obj as TdApi.UpdateMessageContent + val message = usersLiveMessages[updateMessageContent.messageId] + if (message != null && !message.isOutgoing) { + message.content = updateMessageContent.newContent + val chatTitle = chats[message.chatId]?.title + if (chatTitle != null) { + incomingMessagesListener?.onReceiveChatLocationMessages(chatTitle, message) + } + } + } + TdApi.UpdateNewMessage.CONSTRUCTOR -> { + val updateNewMessage = obj as TdApi.UpdateNewMessage + val message = updateNewMessage.message + if (!message.isOutgoing && message.content is TdApi.MessageLocation) { + usersLiveMessages[message.id] = message + val chatTitle = chats[message.chatId]?.title + if (chatTitle != null) { + incomingMessagesListener?.onReceiveChatLocationMessages(chatTitle, message) + } + } + } TdApi.UpdateMessageMentionRead.CONSTRUCTOR -> { val updateChat = obj as TdApi.UpdateMessageMentionRead val chat = chats[updateChat.chatId] diff --git a/OsmAnd-telegram/src/net/osmand/telegram/notifications/ShareLocationNotification.kt b/OsmAnd-telegram/src/net/osmand/telegram/notifications/ShareLocationNotification.kt index 8ac3664204..f642076106 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/notifications/ShareLocationNotification.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/notifications/ShareLocationNotification.kt @@ -14,6 +14,14 @@ import net.osmand.util.Algorithms class ShareLocationNotification(app: TelegramApplication) : TelegramNotification(app, GROUP_NAME) { + companion object { + + const val OSMAND_START_LOCATION_SHARING_SERVICE_ACTION = "osmand_start_location_sharing_service_action" + const val OSMAND_PAUSE_LOCATION_SHARING_SERVICE_ACTION = "osmand_pause_location_sharing_service_action" + const val OSMAND_STOP_LOCATION_SHARING_SERVICE_ACTION = "osmand_stop_location_sharing_service_action" + const val GROUP_NAME = "share_location" + } + private var wasNoDataDismissed: Boolean = false private var lastBuiltNoData: Boolean = false @@ -25,7 +33,7 @@ class ShareLocationNotification(app: TelegramApplication) : TelegramNotification override val isActive: Boolean get() { - val service = app.locationService + val service = app.myLocationService return isEnabled && service != null } @@ -141,12 +149,4 @@ class ShareLocationNotification(app: TelegramApplication) : TelegramNotification return notificationBuilder } - - companion object { - - const val OSMAND_START_LOCATION_SHARING_SERVICE_ACTION = "osmand_start_location_sharing_service_action" - const val OSMAND_PAUSE_LOCATION_SHARING_SERVICE_ACTION = "osmand_pause_location_sharing_service_action" - const val OSMAND_STOP_LOCATION_SHARING_SERVICE_ACTION = "osmand_stop_location_sharing_service_action" - const val GROUP_NAME = "share_location" - } } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/LocationService.kt b/OsmAnd-telegram/src/net/osmand/telegram/services/MyLocationService.kt similarity index 89% rename from OsmAnd-telegram/src/net/osmand/telegram/LocationService.kt rename to OsmAnd-telegram/src/net/osmand/telegram/services/MyLocationService.kt index 0a6734763b..8369910450 100644 --- a/OsmAnd-telegram/src/net/osmand/telegram/LocationService.kt +++ b/OsmAnd-telegram/src/net/osmand/telegram/services/MyLocationService.kt @@ -1,4 +1,4 @@ -package net.osmand.telegram +package net.osmand.telegram.services import android.app.Service import android.content.Context @@ -14,10 +14,13 @@ import android.util.Log import android.widget.Toast import net.osmand.telegram.notifications.TelegramNotification import net.osmand.PlatformUtil +import net.osmand.telegram.R +import net.osmand.telegram.TelegramApplication -class LocationService : Service(), LocationListener { +class MyLocationService : Service(), LocationListener { private val binder = LocationServiceBinder() + private fun app() = application as TelegramApplication var handler: Handler? = null @@ -28,7 +31,7 @@ class LocationService : Service(), LocationListener { } fun stopIfNeeded(ctx: Context) { - val serviceIntent = Intent(ctx, LocationService::class.java) + val serviceIntent = Intent(ctx, MyLocationService::class.java) ctx.stopService(serviceIntent) } @@ -36,13 +39,13 @@ class LocationService : Service(), LocationListener { handler = Handler() val app = app() - app.locationService = this + app.myLocationService = this // requesting // request location updates val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager try { - locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, this@LocationService) + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, this@MyLocationService) } catch (e: SecurityException) { Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show() Log.d(PlatformUtil.TAG, "Location service permission not granted") @@ -51,8 +54,6 @@ class LocationService : Service(), LocationListener { Log.d(PlatformUtil.TAG, "GPS location provider not available") } - // registering icon at top level - // Leave icon visible even for navigation for proper display val notification = app.notificationHelper.buildTopNotification() if (notification != null) { startForeground(TelegramNotification.TOP_NOTIFICATION_SERVICE_ID, notification) @@ -62,12 +63,10 @@ class LocationService : Service(), LocationListener { return Service.START_REDELIVER_INTENT } - private fun app() = application as TelegramApplication - override fun onDestroy() { super.onDestroy() val app = app() - app.locationService = null + app.myLocationService = null // remove updates val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager @@ -107,8 +106,9 @@ class LocationService : Service(), LocationListener { override fun onTaskRemoved(rootIntent: Intent) { val app = app() app.notificationHelper.removeNotifications() - if (app.locationService != null) { - this@LocationService.stopSelf() + if (app.myLocationService != null) { + // Do not stop service after UI task was dismissed + //this@MyLocationService.stopSelf() } } diff --git a/OsmAnd-telegram/src/net/osmand/telegram/services/UserLocationService.kt b/OsmAnd-telegram/src/net/osmand/telegram/services/UserLocationService.kt new file mode 100644 index 0000000000..ca205cc9c6 --- /dev/null +++ b/OsmAnd-telegram/src/net/osmand/telegram/services/UserLocationService.kt @@ -0,0 +1,81 @@ +package net.osmand.telegram.services + +import android.app.Service +import android.content.Context +import android.content.Intent +import android.os.AsyncTask +import android.os.Binder +import android.os.Handler +import android.os.IBinder +import net.osmand.telegram.TelegramApplication +import net.osmand.telegram.helpers.TelegramHelper.TelegramIncomingMessagesListener +import net.osmand.telegram.notifications.TelegramNotification +import org.drinkless.td.libcore.telegram.TdApi +import java.util.concurrent.Executors + +class UserLocationService : Service(), TelegramIncomingMessagesListener { + + private val binder = LocationServiceBinder() + private fun app() = application as TelegramApplication + private val executor = Executors.newSingleThreadExecutor() + + var handler: Handler? = null + + class LocationServiceBinder : Binder() + + override fun onBind(intent: Intent): IBinder? { + return binder + } + + override fun onReceiveChatLocationMessages(chatTitle: String, vararg messages: TdApi.Message) { + val app = app() + if (app.settings.isShowingChatOnMap(chatTitle)) { + ShowMessagesTask(app, chatTitle).executeOnExecutor(executor, *messages) + } + } + + fun stopIfNeeded(ctx: Context) { + val serviceIntent = Intent(ctx, UserLocationService::class.java) + ctx.stopService(serviceIntent) + } + + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + handler = Handler() + val app = app() + + app.userLocationService = this + app.telegramHelper.incomingMessagesListener = this + + //val notification = app.notificationHelper.buildTopNotification() + //startForeground(TelegramNotification.TOP_NOTIFICATION_SERVICE_ID, notification) + + return Service.START_REDELIVER_INTENT + } + + override fun onDestroy() { + super.onDestroy() + val app = app() + app.telegramHelper.incomingMessagesListener = null + app.userLocationService = null + + stopForeground(java.lang.Boolean.TRUE) + } + + override fun onTaskRemoved(rootIntent: Intent) { + val app = app() + if (app.userLocationService != null) { + // Do not stop service after UI task was dismissed + //this@MyLocationService.stopSelf() + } + } + + class ShowMessagesTask(private val app: TelegramApplication, private val chatTitle: String) : AsyncTask() { + + override fun doInBackground(vararg messages: TdApi.Message): Void? { + for (message in messages) { + app.showLocationHelper.showLocationOnMap(chatTitle, message) + } + return null + } + } +} \ No newline at end of file