Telegram - added service for showing locations on map

This commit is contained in:
crimean 2018-06-11 13:41:43 +03:00
parent 2ab3abd502
commit 08c65712a4
10 changed files with 385 additions and 72 deletions

View file

@ -20,8 +20,8 @@
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:configChanges="orientation|screenSize"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
<intent-filter>
@ -33,14 +33,24 @@
</activity>
<service
android:name=".services.MyLocationService"
android:label="@string/process_location_service"
android:name="net.osmand.telegram.LocationService"
android:stopWithTask="true">
android:stopWithTask="false">
<intent-filter>
<action android:name="net.osmand.telegram.LocationService" />
<action android:name="net.osmand.telegram.services.MyLocationService" />
</intent-filter>
</service>
<service
android:name=".services.UserLocationService"
android:label="@string/process_location_service"
android:stopWithTask="false">
<intent-filter>
<action android:name="net.osmand.telegram.services.UserLocationService" />
</intent-filter>
</service>
<receiver android:name=".notifications.NotificationDismissReceiver" />
</application>

View file

@ -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)
}
}
}
}

View file

@ -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)) {

View file

@ -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<AMapPoint>): Boolean {
fun addMapLayer(id: String, name: String, zOrder: Float, points: List<AMapPoint>?): 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<AMapPoint>): Boolean {
fun updateMapLayer(id: String, name: String, zOrder: Float, points: List<AMapPoint>?): 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<String>): Boolean {
typeName: String, color: Int, location: ALatLon, details: List<String>?): 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<String>): Boolean {
typeName: String, color: Int, location: ALatLon, details: List<String>?): Boolean {
if (mIOsmAndAidlInterface != null) {
try {
val point = AMapPoint(pointId, shortName, fullName, typeName, color, location, details)

View file

@ -52,17 +52,20 @@ class ShareLocationHelper(private val app: TelegramApplication) {
}
fun startSharingLocation() {
if (!sharingLocation) {
sharingLocation = true
app.startLocationService()
app.startMyLocationService()
refreshNotification()
}
}
fun stopSharingLocation() {
if (sharingLocation) {
sharingLocation = false
app.stopLocationService()
app.stopMyLocationService()
lastLocation = null
lastTimeInMillis = 0L
distance = 0
@ -70,11 +73,12 @@ class ShareLocationHelper(private val app: TelegramApplication) {
refreshNotification()
}
}
fun pauseSharingLocation() {
sharingLocation = false
app.stopLocationService()
app.stopMyLocationService()
lastLocation = null
lastTimeInMillis = 0L

View file

@ -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()
}
}
}

View file

@ -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<OrderedChat>()
private val chatLiveMessages = ConcurrentHashMap<Long, Long>()
private val usersLiveMessages = ConcurrentHashMap<Long, TdApi.Message>()
private val usersFullInfo = ConcurrentHashMap<Int, TdApi.UserFullInfo>()
private val basicGroupsFullInfo = ConcurrentHashMap<Int, TdApi.BasicGroupFullInfo>()
private val supergroupsFullInfo = ConcurrentHashMap<Int, TdApi.SupergroupFullInfo>()
@ -61,6 +64,7 @@ class TelegramHelper private constructor() {
private val liveLocationMessageUpdatesHandler = LiveLocationMessageUpdatesHandler()
var listener: TelegramListener? = null
var incomingMessagesListener: TelegramIncomingMessagesListener? = null
fun getChatList(): TreeSet<OrderedChat> {
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<TdApi.Message> {
val res = mutableListOf<TdApi.Message>()
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<String>) {
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.
@ -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]

View file

@ -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"
}
}

View file

@ -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()
}
}

View file

@ -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<TdApi.Message, Void, Void?>() {
override fun doInBackground(vararg messages: TdApi.Message): Void? {
for (message in messages) {
app.showLocationHelper.showLocationOnMap(chatTitle, message)
}
return null
}
}
}