Telegram - added service for showing locations on map
This commit is contained in:
parent
2ab3abd502
commit
08c65712a4
10 changed files with 385 additions and 72 deletions
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:launchMode="singleTask"
|
|
||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
|
android:launchMode="singleTask"
|
||||||
android:windowSoftInputMode="adjustResize">
|
android:windowSoftInputMode="adjustResize">
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
@ -33,14 +33,24 @@
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
|
android:name=".services.MyLocationService"
|
||||||
android:label="@string/process_location_service"
|
android:label="@string/process_location_service"
|
||||||
android:name="net.osmand.telegram.LocationService"
|
android:stopWithTask="false">
|
||||||
android:stopWithTask="true">
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="net.osmand.telegram.LocationService" />
|
<action android:name="net.osmand.telegram.services.MyLocationService" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</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" />
|
<receiver android:name=".notifications.NotificationDismissReceiver" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ class MainActivity : AppCompatActivity(), TelegramListener {
|
||||||
get() = application as TelegramApplication
|
get() = application as TelegramApplication
|
||||||
|
|
||||||
private val telegramHelper get() = app.telegramHelper
|
private val telegramHelper get() = app.telegramHelper
|
||||||
|
private val osmandHelper get() = app.osmandHelper
|
||||||
private val settings get() = app.settings
|
private val settings get() = app.settings
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
@ -92,7 +93,7 @@ class MainActivity : AppCompatActivity(), TelegramListener {
|
||||||
|
|
||||||
if (settings.hasAnyChatToShareLocation() && !AndroidUtils.isLocationPermissionAvailable(this)) {
|
if (settings.hasAnyChatToShareLocation() && !AndroidUtils.isLocationPermissionAvailable(this)) {
|
||||||
requestLocationPermission()
|
requestLocationPermission()
|
||||||
} else if (settings.hasAnyChatToShowOnMap() && !app.osmandHelper.isOsmandBound()) {
|
} else if (settings.hasAnyChatToShowOnMap() && osmandHelper.initialized && !osmandHelper.isOsmandBound()) {
|
||||||
showOsmandMissingDialog()
|
showOsmandMissingDialog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,7 +293,7 @@ class MainActivity : AppCompatActivity(), TelegramListener {
|
||||||
app.shareLocationHelper.startSharingLocation()
|
app.shareLocationHelper.startSharingLocation()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (settings.hasAnyChatToShowOnMap() && app.osmandHelper.isOsmandBound()) {
|
if (settings.hasAnyChatToShowOnMap() && osmandHelper.initialized && !osmandHelper.isOsmandBound()) {
|
||||||
showOsmandMissingDialog()
|
showOsmandMissingDialog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,18 +363,26 @@ class MainActivity : AppCompatActivity(), TelegramListener {
|
||||||
|
|
||||||
holder.showOnMapSwitch?.setOnCheckedChangeListener(null)
|
holder.showOnMapSwitch?.setOnCheckedChangeListener(null)
|
||||||
holder.showOnMapSwitch?.isChecked = settings.isShowingChatOnMap(chatTitle)
|
holder.showOnMapSwitch?.isChecked = settings.isShowingChatOnMap(chatTitle)
|
||||||
holder.showOnMapSwitch?.setOnCheckedChangeListener { view, isChecked ->
|
holder.showOnMapSwitch?.setOnCheckedChangeListener { _, isChecked ->
|
||||||
settings.showChatOnMap(chatTitle, isChecked)
|
settings.showChatOnMap(chatTitle, isChecked)
|
||||||
if (settings.hasAnyChatToShowOnMap()) {
|
if (settings.hasAnyChatToShowOnMap()) {
|
||||||
if (!app.osmandHelper.isOsmandBound()) {
|
if (osmandHelper.initialized && !osmandHelper.isOsmandBound()) {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
showOsmandMissingDialog()
|
showOsmandMissingDialog()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//app.shareLocationHelper.startSharingLocation()
|
if (isChecked) {
|
||||||
|
app.showLocationHelper.showChatMessages(chatTitle)
|
||||||
|
} else {
|
||||||
|
app.showLocationHelper.hideChatMessages(chatTitle)
|
||||||
|
}
|
||||||
|
app.showLocationHelper.startShowingLocation()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//app.shareLocationHelper.stopSharingLocation()
|
app.showLocationHelper.stopShowingLocation()
|
||||||
|
if (!isChecked) {
|
||||||
|
app.showLocationHelper.hideChatMessages(chatTitle)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,11 @@ import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import net.osmand.telegram.helpers.OsmandAidlHelper
|
import net.osmand.telegram.helpers.OsmandAidlHelper
|
||||||
import net.osmand.telegram.helpers.ShareLocationHelper
|
import net.osmand.telegram.helpers.ShareLocationHelper
|
||||||
|
import net.osmand.telegram.helpers.ShowLocationHelper
|
||||||
import net.osmand.telegram.helpers.TelegramHelper
|
import net.osmand.telegram.helpers.TelegramHelper
|
||||||
import net.osmand.telegram.notifications.NotificationHelper
|
import net.osmand.telegram.notifications.NotificationHelper
|
||||||
|
import net.osmand.telegram.services.MyLocationService
|
||||||
|
import net.osmand.telegram.services.UserLocationService
|
||||||
import net.osmand.telegram.utils.AndroidUtils
|
import net.osmand.telegram.utils.AndroidUtils
|
||||||
|
|
||||||
class TelegramApplication : Application() {
|
class TelegramApplication : Application() {
|
||||||
|
@ -18,10 +21,12 @@ class TelegramApplication : Application() {
|
||||||
val telegramHelper = TelegramHelper.instance
|
val telegramHelper = TelegramHelper.instance
|
||||||
lateinit var settings: TelegramSettings private set
|
lateinit var settings: TelegramSettings private set
|
||||||
lateinit var shareLocationHelper: ShareLocationHelper private set
|
lateinit var shareLocationHelper: ShareLocationHelper private set
|
||||||
|
lateinit var showLocationHelper: ShowLocationHelper private set
|
||||||
lateinit var notificationHelper: NotificationHelper private set
|
lateinit var notificationHelper: NotificationHelper private set
|
||||||
lateinit var osmandHelper: OsmandAidlHelper private set
|
lateinit var osmandHelper: OsmandAidlHelper private set
|
||||||
|
|
||||||
var locationService: LocationService? = null
|
var myLocationService: MyLocationService? = null
|
||||||
|
var userLocationService: UserLocationService? = null
|
||||||
|
|
||||||
private val uiHandler = Handler()
|
private val uiHandler = Handler()
|
||||||
|
|
||||||
|
@ -33,13 +38,17 @@ class TelegramApplication : Application() {
|
||||||
telegramHelper.appDir = filesDir.absolutePath
|
telegramHelper.appDir = filesDir.absolutePath
|
||||||
|
|
||||||
settings = TelegramSettings(this)
|
settings = TelegramSettings(this)
|
||||||
shareLocationHelper = ShareLocationHelper(this)
|
|
||||||
notificationHelper = NotificationHelper(this)
|
|
||||||
osmandHelper = OsmandAidlHelper(this)
|
osmandHelper = OsmandAidlHelper(this)
|
||||||
|
shareLocationHelper = ShareLocationHelper(this)
|
||||||
|
showLocationHelper = ShowLocationHelper(this)
|
||||||
|
notificationHelper = NotificationHelper(this)
|
||||||
|
|
||||||
if (settings.hasAnyChatToShareLocation() && AndroidUtils.isLocationPermissionAvailable(this)) {
|
if (settings.hasAnyChatToShareLocation() && AndroidUtils.isLocationPermissionAvailable(this)) {
|
||||||
shareLocationHelper.startSharingLocation()
|
shareLocationHelper.startSharingLocation()
|
||||||
}
|
}
|
||||||
|
if (settings.hasAnyChatToShowOnMap()) {
|
||||||
|
showLocationHelper.startShowingLocation()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTerminate() {
|
override fun onTerminate() {
|
||||||
|
@ -80,14 +89,14 @@ class TelegramApplication : Application() {
|
||||||
return internetConnectionAvailable
|
return internetConnectionAvailable
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startLocationService(restart: Boolean = false) {
|
fun startMyLocationService(restart: Boolean = false) {
|
||||||
val serviceIntent = Intent(this, LocationService::class.java)
|
val serviceIntent = Intent(this, MyLocationService::class.java)
|
||||||
|
|
||||||
val locationService = locationService
|
val myLocationService = myLocationService
|
||||||
if (locationService != null && restart) {
|
if (myLocationService != null && restart) {
|
||||||
locationService.stopSelf()
|
myLocationService.stopSelf()
|
||||||
}
|
}
|
||||||
if (locationService == null || restart) {
|
if (myLocationService == null || restart) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
startForegroundService(serviceIntent)
|
startForegroundService(serviceIntent)
|
||||||
} else {
|
} else {
|
||||||
|
@ -96,8 +105,28 @@ class TelegramApplication : Application() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopLocationService() {
|
fun stopMyLocationService() {
|
||||||
locationService?.stopIfNeeded(this)
|
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)) {
|
fun runInUIThread(action: (() -> Unit)) {
|
||||||
|
|
|
@ -56,6 +56,18 @@ class OsmandAidlHelper(private val app: Application) {
|
||||||
|
|
||||||
private var mIOsmAndAidlInterface: IOsmAndAidlInterface? = null
|
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.
|
* 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
|
// service through an IDL interface, so get a client-side
|
||||||
// representation of that from the raw service object.
|
// representation of that from the raw service object.
|
||||||
mIOsmAndAidlInterface = IOsmAndAidlInterface.Stub.asInterface(service)
|
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) {
|
override fun onServiceDisconnected(className: ComponentName) {
|
||||||
// This is called when the connection with the service has been
|
// This is called when the connection with the service has been
|
||||||
// unexpectedly disconnected -- that is, its process crashed.
|
// unexpectedly disconnected -- that is, its process crashed.
|
||||||
mIOsmAndAidlInterface = null
|
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 {
|
fun isOsmandBound(): Boolean {
|
||||||
|
return bound
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isOsmandConnected(): Boolean {
|
||||||
return mIOsmAndAidlInterface != null
|
return mIOsmAndAidlInterface != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +115,7 @@ class OsmandAidlHelper(private val app: Application) {
|
||||||
if (mIOsmAndAidlInterface!!.getActiveGpx(res)) {
|
if (mIOsmAndAidlInterface!!.getActiveGpx(res)) {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
} catch (e: RemoteException) {
|
} catch (e: Throwable) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,10 +125,17 @@ class OsmandAidlHelper(private val app: Application) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
when {
|
when {
|
||||||
bindService(OSMAND_PLUS_PACKAGE_NAME) -> OSMAND_PACKAGE_NAME = OSMAND_PLUS_PACKAGE_NAME
|
bindService(OSMAND_PLUS_PACKAGE_NAME) -> {
|
||||||
bindService(OSMAND_FREE_PACKAGE_NAME) -> OSMAND_PACKAGE_NAME = OSMAND_FREE_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 -> {
|
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) {
|
return if (mIOsmAndAidlInterface == null) {
|
||||||
val intent = Intent("net.osmand.aidl.OsmandAidlService")
|
val intent = Intent("net.osmand.aidl.OsmandAidlService")
|
||||||
intent.`package` = packageName
|
intent.`package` = packageName
|
||||||
val res = app.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
|
app.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
|
||||||
if (res) {
|
|
||||||
Toast.makeText(app, "OsmAnd service bind", Toast.LENGTH_SHORT).show()
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -443,7 +463,7 @@ class OsmandAidlHelper(private val app: Application) {
|
||||||
* @param zOrder - z-order position of layer. Default value is 5.5f
|
* @param zOrder - z-order position of layer. Default value is 5.5f
|
||||||
* @param points - initial list of points. Nullable.
|
* @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) {
|
if (mIOsmAndAidlInterface != null) {
|
||||||
try {
|
try {
|
||||||
val layer = AMapLayer(id, name, zOrder, points)
|
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 zOrder - z-order position of layer. Default value is 5.5f
|
||||||
* @param points - list of points. Nullable.
|
* @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) {
|
if (mIOsmAndAidlInterface != null) {
|
||||||
try {
|
try {
|
||||||
val layer = AMapLayer(id, name, zOrder, points)
|
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.
|
* @param details - list of details. Displayed under context menu.
|
||||||
*/
|
*/
|
||||||
fun addMapPoint(layerId: String, pointId: String, shortName: String, fullName: String,
|
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) {
|
if (mIOsmAndAidlInterface != null) {
|
||||||
try {
|
try {
|
||||||
val point = AMapPoint(pointId, shortName, fullName, typeName, color, location, details)
|
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.
|
* @param details - list of details. Displayed under context menu.
|
||||||
*/
|
*/
|
||||||
fun updateMapPoint(layerId: String, pointId: String, shortName: String, fullName: String,
|
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) {
|
if (mIOsmAndAidlInterface != null) {
|
||||||
try {
|
try {
|
||||||
val point = AMapPoint(pointId, shortName, fullName, typeName, color, location, details)
|
val point = AMapPoint(pointId, shortName, fullName, typeName, color, location, details)
|
||||||
|
|
|
@ -52,29 +52,33 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun startSharingLocation() {
|
fun startSharingLocation() {
|
||||||
sharingLocation = true
|
if (!sharingLocation) {
|
||||||
|
sharingLocation = true
|
||||||
|
|
||||||
app.startLocationService()
|
app.startMyLocationService()
|
||||||
|
|
||||||
refreshNotification()
|
refreshNotification()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopSharingLocation() {
|
fun stopSharingLocation() {
|
||||||
sharingLocation = false
|
if (sharingLocation) {
|
||||||
|
sharingLocation = false
|
||||||
|
|
||||||
app.stopLocationService()
|
app.stopMyLocationService()
|
||||||
lastLocation = null
|
lastLocation = null
|
||||||
lastTimeInMillis = 0L
|
lastTimeInMillis = 0L
|
||||||
distance = 0
|
distance = 0
|
||||||
duration = 0
|
duration = 0
|
||||||
|
|
||||||
refreshNotification()
|
refreshNotification()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun pauseSharingLocation() {
|
fun pauseSharingLocation() {
|
||||||
sharingLocation = false
|
sharingLocation = false
|
||||||
|
|
||||||
app.stopLocationService()
|
app.stopMyLocationService()
|
||||||
lastLocation = null
|
lastLocation = null
|
||||||
lastTimeInMillis = 0L
|
lastTimeInMillis = 0L
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ class TelegramHelper private constructor() {
|
||||||
companion object {
|
companion object {
|
||||||
private val log = PlatformUtil.getLog(TelegramHelper::class.java)
|
private val log = PlatformUtil.getLog(TelegramHelper::class.java)
|
||||||
private const val CHATS_LIMIT = 100
|
private const val CHATS_LIMIT = 100
|
||||||
|
private const val CHAT_LIVE_USERS_LIMIT = 100
|
||||||
private const val IGNORED_ERROR_CODE = 406
|
private const val IGNORED_ERROR_CODE = 406
|
||||||
|
|
||||||
private var helper: TelegramHelper? = null
|
private var helper: TelegramHelper? = null
|
||||||
|
@ -40,6 +41,8 @@ class TelegramHelper private constructor() {
|
||||||
private val chatList = TreeSet<OrderedChat>()
|
private val chatList = TreeSet<OrderedChat>()
|
||||||
private val chatLiveMessages = ConcurrentHashMap<Long, Long>()
|
private val chatLiveMessages = ConcurrentHashMap<Long, Long>()
|
||||||
|
|
||||||
|
private val usersLiveMessages = ConcurrentHashMap<Long, TdApi.Message>()
|
||||||
|
|
||||||
private val usersFullInfo = ConcurrentHashMap<Int, TdApi.UserFullInfo>()
|
private val usersFullInfo = ConcurrentHashMap<Int, TdApi.UserFullInfo>()
|
||||||
private val basicGroupsFullInfo = ConcurrentHashMap<Int, TdApi.BasicGroupFullInfo>()
|
private val basicGroupsFullInfo = ConcurrentHashMap<Int, TdApi.BasicGroupFullInfo>()
|
||||||
private val supergroupsFullInfo = ConcurrentHashMap<Int, TdApi.SupergroupFullInfo>()
|
private val supergroupsFullInfo = ConcurrentHashMap<Int, TdApi.SupergroupFullInfo>()
|
||||||
|
@ -61,6 +64,7 @@ class TelegramHelper private constructor() {
|
||||||
private val liveLocationMessageUpdatesHandler = LiveLocationMessageUpdatesHandler()
|
private val liveLocationMessageUpdatesHandler = LiveLocationMessageUpdatesHandler()
|
||||||
|
|
||||||
var listener: TelegramListener? = null
|
var listener: TelegramListener? = null
|
||||||
|
var incomingMessagesListener: TelegramIncomingMessagesListener? = null
|
||||||
|
|
||||||
fun getChatList(): TreeSet<OrderedChat> {
|
fun getChatList(): TreeSet<OrderedChat> {
|
||||||
synchronized(chatList) {
|
synchronized(chatList) {
|
||||||
|
@ -76,6 +80,21 @@ class TelegramHelper private constructor() {
|
||||||
return chats[id]
|
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() {
|
private fun updateChatTitles() {
|
||||||
chatTitles.clear()
|
chatTitles.clear()
|
||||||
for (chatEntry in chats.entries) {
|
for (chatEntry in chats.entries) {
|
||||||
|
@ -111,6 +130,10 @@ class TelegramHelper private constructor() {
|
||||||
fun onSendLiveLicationError(code: Int, message: String)
|
fun onSendLiveLicationError(code: Int, message: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface TelegramIncomingMessagesListener {
|
||||||
|
fun onReceiveChatLocationMessages(chatTitle: String, vararg messages: TdApi.Message)
|
||||||
|
}
|
||||||
|
|
||||||
interface TelegramAuthorizationRequestListener {
|
interface TelegramAuthorizationRequestListener {
|
||||||
fun onRequestTelegramAuthenticationParameter(parameterType: TelegramAuthenticationParameterType)
|
fun onRequestTelegramAuthenticationParameter(parameterType: TelegramAuthenticationParameterType)
|
||||||
fun onTelegramAuthorizationRequestError(code: Int, message: String)
|
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) {
|
synchronized(chatList) {
|
||||||
if (reload) {
|
if (reload) {
|
||||||
chatList.clear()
|
chatList.clear()
|
||||||
|
@ -214,9 +237,41 @@ class TelegramHelper private constructor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateChatTitles()
|
updateChatTitles()
|
||||||
|
getChatRecentLocationMessages(chatTitles.keys)
|
||||||
listener?.onTelegramChatsRead()
|
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
|
* @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.
|
* @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) {
|
override fun onResult(obj: TdApi.Object) {
|
||||||
when (obj.constructor) {
|
when (obj.constructor) {
|
||||||
TdApi.Error.CONSTRUCTOR -> {
|
TdApi.Error.CONSTRUCTOR -> {
|
||||||
|
@ -564,6 +619,28 @@ class TelegramHelper private constructor() {
|
||||||
chat.unreadMentionCount = updateChat.unreadMentionCount
|
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 -> {
|
TdApi.UpdateMessageMentionRead.CONSTRUCTOR -> {
|
||||||
val updateChat = obj as TdApi.UpdateMessageMentionRead
|
val updateChat = obj as TdApi.UpdateMessageMentionRead
|
||||||
val chat = chats[updateChat.chatId]
|
val chat = chats[updateChat.chatId]
|
||||||
|
|
|
@ -14,6 +14,14 @@ import net.osmand.util.Algorithms
|
||||||
|
|
||||||
class ShareLocationNotification(app: TelegramApplication) : TelegramNotification(app, GROUP_NAME) {
|
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 wasNoDataDismissed: Boolean = false
|
||||||
private var lastBuiltNoData: Boolean = false
|
private var lastBuiltNoData: Boolean = false
|
||||||
|
|
||||||
|
@ -25,7 +33,7 @@ class ShareLocationNotification(app: TelegramApplication) : TelegramNotification
|
||||||
|
|
||||||
override val isActive: Boolean
|
override val isActive: Boolean
|
||||||
get() {
|
get() {
|
||||||
val service = app.locationService
|
val service = app.myLocationService
|
||||||
return isEnabled && service != null
|
return isEnabled && service != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,12 +149,4 @@ class ShareLocationNotification(app: TelegramApplication) : TelegramNotification
|
||||||
|
|
||||||
return notificationBuilder
|
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"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package net.osmand.telegram
|
package net.osmand.telegram.services
|
||||||
|
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
@ -14,10 +14,13 @@ import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import net.osmand.telegram.notifications.TelegramNotification
|
import net.osmand.telegram.notifications.TelegramNotification
|
||||||
import net.osmand.PlatformUtil
|
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 val binder = LocationServiceBinder()
|
||||||
|
private fun app() = application as TelegramApplication
|
||||||
|
|
||||||
var handler: Handler? = null
|
var handler: Handler? = null
|
||||||
|
|
||||||
|
@ -28,7 +31,7 @@ class LocationService : Service(), LocationListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopIfNeeded(ctx: Context) {
|
fun stopIfNeeded(ctx: Context) {
|
||||||
val serviceIntent = Intent(ctx, LocationService::class.java)
|
val serviceIntent = Intent(ctx, MyLocationService::class.java)
|
||||||
ctx.stopService(serviceIntent)
|
ctx.stopService(serviceIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,13 +39,13 @@ class LocationService : Service(), LocationListener {
|
||||||
handler = Handler()
|
handler = Handler()
|
||||||
val app = app()
|
val app = app()
|
||||||
|
|
||||||
app.locationService = this
|
app.myLocationService = this
|
||||||
|
|
||||||
// requesting
|
// requesting
|
||||||
// request location updates
|
// request location updates
|
||||||
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||||
try {
|
try {
|
||||||
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, this@LocationService)
|
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f, this@MyLocationService)
|
||||||
} catch (e: SecurityException) {
|
} catch (e: SecurityException) {
|
||||||
Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show()
|
Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show()
|
||||||
Log.d(PlatformUtil.TAG, "Location service permission not granted")
|
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")
|
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()
|
val notification = app.notificationHelper.buildTopNotification()
|
||||||
if (notification != null) {
|
if (notification != null) {
|
||||||
startForeground(TelegramNotification.TOP_NOTIFICATION_SERVICE_ID, notification)
|
startForeground(TelegramNotification.TOP_NOTIFICATION_SERVICE_ID, notification)
|
||||||
|
@ -62,12 +63,10 @@ class LocationService : Service(), LocationListener {
|
||||||
return Service.START_REDELIVER_INTENT
|
return Service.START_REDELIVER_INTENT
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun app() = application as TelegramApplication
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
val app = app()
|
val app = app()
|
||||||
app.locationService = null
|
app.myLocationService = null
|
||||||
|
|
||||||
// remove updates
|
// remove updates
|
||||||
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
|
||||||
|
@ -107,8 +106,9 @@ class LocationService : Service(), LocationListener {
|
||||||
override fun onTaskRemoved(rootIntent: Intent) {
|
override fun onTaskRemoved(rootIntent: Intent) {
|
||||||
val app = app()
|
val app = app()
|
||||||
app.notificationHelper.removeNotifications()
|
app.notificationHelper.removeNotifications()
|
||||||
if (app.locationService != null) {
|
if (app.myLocationService != null) {
|
||||||
this@LocationService.stopSelf()
|
// Do not stop service after UI task was dismissed
|
||||||
|
//this@MyLocationService.stopSelf()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue