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
|
||||
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>
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
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.
|
||||
|
@ -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]
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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