Merge pull request #6500 from osmandapp/TelegramDataBase

Telegram improvements
This commit is contained in:
Alexey 2019-02-01 14:38:19 +03:00 committed by GitHub
commit 5daac573a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 300 additions and 131 deletions

View file

@ -277,7 +277,9 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
override fun onReceiveChatLocationMessages(chatId: Long, vararg messages: TdApi.Message) { override fun onReceiveChatLocationMessages(chatId: Long, vararg messages: TdApi.Message) {
app().showLocationHelper.startShowMessagesTask(chatId, *messages) app().showLocationHelper.startShowMessagesTask(chatId, *messages)
messages.forEach { messages.forEach {
app().locationMessages.addNewLocationMessage(it) if (!it.isOutgoing) {
app().locationMessages.addNewLocationMessage(it)
}
} }
} }
@ -294,7 +296,9 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
app().settings.updateShareInfo(it) app().settings.updateShareInfo(it)
app().shareLocationHelper.checkAndSendBufferMessagesToChat(it.chatId) app().shareLocationHelper.checkAndSendBufferMessagesToChat(it.chatId)
if (it.sendingState == null && (it.content is TdApi.MessageLocation || it.content is TdApi.MessageText)) { if (it.sendingState == null && (it.content is TdApi.MessageLocation || it.content is TdApi.MessageText)) {
app().locationMessages.addNewLocationMessage(it) if (!it.isOutgoing) {
app().locationMessages.addNewLocationMessage(it)
}
} }
} }
} }

View file

@ -360,7 +360,7 @@ class TelegramSettings(private val app: TelegramApplication) {
if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) { if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
val loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER) val loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER)
val gpsActive = loc != null && ((statusChangeTime - loc.time) / 1000) < GPS_UPDATE_EXPIRED_TIME val gpsActive = loc != null && ((statusChangeTime - loc.time) / 1000) < GPS_UPDATE_EXPIRED_TIME
val lastSentLocationExpired = ((statusChangeTime - app.shareLocationHelper.lastLocationMessageSentTime) / 1000) > GPS_UPDATE_EXPIRED_TIME val lastSentLocationExpired = ((statusChangeTime - app.shareLocationHelper.lastLocationUpdateTime) / 1000) > GPS_UPDATE_EXPIRED_TIME
(gpsActive || !lastSentLocationExpired) (gpsActive || !lastSentLocationExpired)
} else { } else {
false false
@ -393,7 +393,7 @@ class TelegramSettings(private val app: TelegramApplication) {
} else if (!initializing) { } else if (!initializing) {
when { when {
!gpsEnabled -> { !gpsEnabled -> {
locationTime = app.shareLocationHelper.lastLocationMessageSentTime locationTime = app.shareLocationHelper.lastLocationUpdateTime
if (locationTime <= 0) { if (locationTime <= 0) {
locationTime = getLastSuccessfulSendTime() locationTime = getLastSuccessfulSendTime()
} }

View file

@ -4,19 +4,21 @@ import android.content.Context
import android.database.Cursor import android.database.Cursor
import android.database.sqlite.SQLiteDatabase import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper import android.database.sqlite.SQLiteOpenHelper
import net.osmand.Location
import net.osmand.PlatformUtil import net.osmand.PlatformUtil
import net.osmand.data.LatLon
import net.osmand.telegram.TelegramApplication import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.utils.OsmandLocationUtils import net.osmand.telegram.utils.OsmandLocationUtils
import net.osmand.util.MapUtils
import org.drinkless.td.libcore.telegram.TdApi import org.drinkless.td.libcore.telegram.TdApi
class LocationMessages(val app: TelegramApplication) { class LocationMessages(val app: TelegramApplication) {
private val log = PlatformUtil.getLog(LocationMessages::class.java) private val log = PlatformUtil.getLog(LocationMessages::class.java)
// todo - bufferedMessages is for prepared/pending messages only. On app start we read prepared/pending messages to bufferedMessages. After status changed to sent/error - remove message from buffered.
private var bufferedMessages = emptyList<BufferMessage>() private var bufferedMessages = emptyList<BufferMessage>()
private var lastMessages = emptyList<LocationMessage>() private var lastLocationPoints = mutableMapOf<LocationHistoryPoint, LatLon>()
private val dbHelper: SQLiteHelper private val dbHelper: SQLiteHelper
@ -33,11 +35,14 @@ class LocationMessages(val app: TelegramApplication) {
return bufferedMessages.filter { it.chatId==chatId }.sortedBy { it.time } return bufferedMessages.filter { it.chatId==chatId }.sortedBy { it.time }
} }
// todo - read from db by date (Victor's suggestion - filter by one day only. Need to be changed in UI also.
fun getIngoingMessages(currentUserId: Int, start: Long, end: Long): List<LocationMessage> { fun getIngoingMessages(currentUserId: Int, start: Long, end: Long): List<LocationMessage> {
return dbHelper.getIngoingMessages(currentUserId, start, end) return dbHelper.getIngoingMessages(currentUserId, start, end)
} }
fun getIngoingUserLocations(currentUserId: Int, start: Long, end: Long): List<UserLocations> {
return dbHelper.getIngoingUserLocations(currentUserId, start, end)
}
fun getMessagesForUserInChat(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> { fun getMessagesForUserInChat(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> {
return dbHelper.getMessagesForUserInChat(userId, chatId, start, end) return dbHelper.getMessagesForUserInChat(userId, chatId, start, end)
} }
@ -46,6 +51,10 @@ class LocationMessages(val app: TelegramApplication) {
return dbHelper.getMessagesForUser(userId, start, end) return dbHelper.getMessagesForUser(userId, start, end)
} }
fun getUserLocations(userId: Int, start: Long, end: Long): UserLocations? {
return dbHelper.getUserLocations(userId, start, end)
}
fun addBufferedMessage(message: BufferMessage) { fun addBufferedMessage(message: BufferMessage) {
log.debug("addBufferedMessage $message") log.debug("addBufferedMessage $message")
val messages = mutableListOf(*this.bufferedMessages.toTypedArray()) val messages = mutableListOf(*this.bufferedMessages.toTypedArray())
@ -58,17 +67,28 @@ class LocationMessages(val app: TelegramApplication) {
log.debug("addNewLocationMessage ${message.id}") log.debug("addNewLocationMessage ${message.id}")
val type = OsmandLocationUtils.getMessageType(message, app.telegramHelper) val type = OsmandLocationUtils.getMessageType(message, app.telegramHelper)
val previousMessage = lastMessages.firstOrNull { it.chatId == message.chatId && it.userId == message.senderUserId && it.type == type } val newItem = LocationHistoryPoint(message.senderUserId, message.chatId, type)
val locationMessage = OsmandLocationUtils.parseMessage(message, app.telegramHelper, previousMessage) val previousMessageLatLon = lastLocationPoints[newItem]
val locationMessage = OsmandLocationUtils.parseMessage(message, app.telegramHelper, previousMessageLatLon)
if (locationMessage != null) { if (locationMessage != null) {
dbHelper.addLocationMessage(locationMessage) dbHelper.addLocationMessage(locationMessage)
val messages = mutableListOf(*this.lastMessages.toTypedArray()) lastLocationPoints[newItem] = LatLon(locationMessage.lat, locationMessage.lon)
messages.remove(previousMessage)
messages.add(locationMessage)
this.lastMessages = messages
} }
} }
fun addMyLocationMessage(loc: Location) {
log.debug("addMyLocationMessage")
val currentUserId = app.telegramHelper.getCurrentUserId()
val newItem = LocationHistoryPoint(currentUserId, 0, -1)
val previousMessageLatLon = lastLocationPoints[newItem]
val distance = if (previousMessageLatLon != null) { MapUtils.getDistance(previousMessageLatLon, loc.latitude, loc.longitude) } else 0.0
val message = LocationMessages.LocationMessage(currentUserId, 0, loc.latitude, loc.longitude, loc.altitude,
loc.speed.toDouble(), loc.accuracy.toDouble(), loc.bearing.toDouble(), loc.time, -1, 0, distance)
dbHelper.addLocationMessage(message)
lastLocationPoints[newItem] = LatLon(message.lat, message.lon)
}
fun clearBufferedMessages() { fun clearBufferedMessages() {
log.debug("clearBufferedMessages") log.debug("clearBufferedMessages")
dbHelper.clearBufferedMessages() dbHelper.clearBufferedMessages()
@ -88,7 +108,7 @@ class LocationMessages(val app: TelegramApplication) {
} }
private fun readLastMessages() { private fun readLastMessages() {
this.lastMessages = dbHelper.getLastMessages() this.lastLocationPoints = dbHelper.getLastMessages()
} }
private class SQLiteHelper(context: Context) : private class SQLiteHelper(context: Context) :
@ -121,7 +141,7 @@ class LocationMessages(val app: TelegramApplication) {
internal fun getMessagesForUser(userId: Int, start: Long, end: Long): List<LocationMessage> { internal fun getMessagesForUser(userId: Int, start: Long, end: Long): List<LocationMessage> {
val res = arrayListOf<LocationMessage>() val res = arrayListOf<LocationMessage>()
readableDatabase?.rawQuery( readableDatabase?.rawQuery(
"$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID = ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_TIME ASC ", "$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID = ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_CHAT_ID ASC, $COL_TYPE DESC, $COL_TIME ASC ",
arrayOf(userId.toString()))?.apply { arrayOf(userId.toString()))?.apply {
if (moveToFirst()) { if (moveToFirst()) {
do { do {
@ -133,6 +153,33 @@ class LocationMessages(val app: TelegramApplication) {
return res return res
} }
internal fun getUserLocations(userId: Int, start: Long, end: Long): UserLocations? {
var userLocations: UserLocations? = null
readableDatabase?.rawQuery(
"$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID = ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_CHAT_ID ASC, $COL_TYPE DESC, $COL_TIME ASC ",
arrayOf(userId.toString()))?.apply {
var type = -1
val userLocationsMap: MutableMap<Int, List<LocationMessage>> = mutableMapOf()
userLocations = UserLocations(userId, 0, emptyMap())
var userLocationsListBytetype: MutableList<LocationMessage>? = null
if (moveToFirst()) {
do {
val locationMessage = readLocationMessage(this@apply)
if (type != locationMessage.type) {
type = locationMessage.type
userLocationsListBytetype = mutableListOf()
userLocationsListBytetype.add(locationMessage)
userLocationsMap.set(type, userLocationsListBytetype)
} else {
userLocationsListBytetype?.add(locationMessage)
}
} while (moveToNext())
}
close()
}
return userLocations
}
internal fun getPreviousMessage(userId: Int, chatId: Long): LocationMessage? { internal fun getPreviousMessage(userId: Int, chatId: Long): LocationMessage? {
var res:LocationMessage? = null var res:LocationMessage? = null
readableDatabase?.rawQuery( readableDatabase?.rawQuery(
@ -149,7 +196,7 @@ class LocationMessages(val app: TelegramApplication) {
internal fun getIngoingMessages(currentUserId: Int, start: Long, end: Long): List<LocationMessage> { internal fun getIngoingMessages(currentUserId: Int, start: Long, end: Long): List<LocationMessage> {
val res = arrayListOf<LocationMessage>() val res = arrayListOf<LocationMessage>()
readableDatabase?.rawQuery( readableDatabase?.rawQuery(
"$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID != ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_USER_ID ASC, $COL_CHAT_ID ASC, $COL_TIME ASC ", "$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID != ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_USER_ID, $COL_CHAT_ID, $COL_TYPE DESC, $COL_TIME ",
arrayOf(currentUserId.toString()))?.apply { arrayOf(currentUserId.toString()))?.apply {
if (moveToFirst()) { if (moveToFirst()) {
do { do {
@ -161,10 +208,50 @@ class LocationMessages(val app: TelegramApplication) {
return res return res
} }
internal fun getIngoingUserLocations(currentUserId: Int, start: Long, end: Long): List<UserLocations> {
val res = arrayListOf<UserLocations>()
readableDatabase?.rawQuery(
"$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID != ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_USER_ID, $COL_CHAT_ID, $COL_TYPE DESC, $COL_TIME ",
arrayOf(currentUserId.toString()))?.apply {
var type = -1
var userId = -1
var chatId = -1L
var userLocations: UserLocations? = null
var userLocationsMap: MutableMap<Int, List<LocationMessage>>? = null
var userLocationsListBytetype: MutableList<LocationMessage>? = null
if (moveToFirst()) {
do {
val locationMessage = readLocationMessage(this@apply)
if (userId != locationMessage.userId || chatId != locationMessage.chatId) {
userId = locationMessage.userId
chatId = locationMessage.chatId
type = locationMessage.type
userLocationsMap = mutableMapOf()
userLocationsListBytetype = mutableListOf()
userLocationsListBytetype.add(locationMessage)
userLocationsMap[type] = userLocationsListBytetype
userLocations = UserLocations(userId, chatId, userLocationsMap)
res.add(userLocations)
}
if (type != locationMessage.type) {
type = locationMessage.type
userLocationsListBytetype = mutableListOf()
userLocationsListBytetype.add(locationMessage)
userLocationsMap?.set(type, userLocationsListBytetype)
} else {
userLocationsListBytetype?.add(locationMessage)
}
} while (moveToNext())
}
close()
}
return res
}
internal fun getMessagesForUserInChat(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> { internal fun getMessagesForUserInChat(userId: Int, chatId: Long, start: Long, end: Long): List<LocationMessage> {
val res = arrayListOf<LocationMessage>() val res = arrayListOf<LocationMessage>()
readableDatabase?.rawQuery( readableDatabase?.rawQuery(
"$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID = ? AND $COL_CHAT_ID = ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_TIME ASC ", "$TIMELINE_TABLE_SELECT WHERE $COL_USER_ID = ? AND $COL_CHAT_ID = ? AND $COL_TIME BETWEEN $start AND $end ORDER BY $COL_TYPE DESC, $COL_TIME ",
arrayOf(userId.toString(), chatId.toString()))?.apply { arrayOf(userId.toString(), chatId.toString()))?.apply {
if (moveToFirst()) { if (moveToFirst()) {
do { do {
@ -189,12 +276,12 @@ class LocationMessages(val app: TelegramApplication) {
return res return res
} }
internal fun getLastMessages(): List<LocationMessage> { internal fun getLastMessages(): MutableMap<LocationHistoryPoint, LatLon> {
val res = arrayListOf<LocationMessage>() val res = mutableMapOf<LocationHistoryPoint, LatLon>()
readableDatabase?.rawQuery(TIMELINE_TABLE_SELECT, null)?.apply { readableDatabase?.rawQuery("$TIMELINE_TABLE_SELECT_HISTORY_POINTS ORDER BY $COL_TIME ASC", null)?.apply {
if (moveToFirst()) { if (moveToFirst()) {
do { do {
res.add(readLocationMessage(this@apply)) // res.add(readLocationMessage(this@apply))
} while (moveToNext()) } while (moveToNext())
} }
close() close()
@ -233,6 +320,16 @@ class LocationMessages(val app: TelegramApplication) {
return BufferMessage(chatId, lat, lon, altitude, speed, hdop, bearing, date, type) return BufferMessage(chatId, lat, lon, altitude, speed, hdop, bearing, date, type)
} }
internal fun readLocationHistoryPoint(cursor: Cursor): Pair<LocationHistoryPoint, LatLon> {
val userId = cursor.getInt(0)
val chatId = cursor.getLong(1)
val lat = cursor.getDouble(2)
val lon = cursor.getDouble(3)
val type = cursor.getInt(4)
return Pair(LocationHistoryPoint(userId, chatId, type), LatLon(lat, lon))
}
internal fun clearBufferedMessages() { internal fun clearBufferedMessages() {
writableDatabase?.execSQL(BUFFER_TABLE_CLEAR) writableDatabase?.execSQL(BUFFER_TABLE_CLEAR)
} }
@ -288,6 +385,9 @@ class LocationMessages(val app: TelegramApplication) {
private const val TIMELINE_TABLE_SELECT = private const val TIMELINE_TABLE_SELECT =
"SELECT $COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_TIME, $COL_TYPE, $COL_MESSAGE_ID, $COL_DISTANCE_FROM_PREV FROM $TIMELINE_TABLE_NAME" "SELECT $COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_ALTITUDE, $COL_SPEED, $COL_HDOP, $COL_BEARING, $COL_TIME, $COL_TYPE, $COL_MESSAGE_ID, $COL_DISTANCE_FROM_PREV FROM $TIMELINE_TABLE_NAME"
private const val TIMELINE_TABLE_SELECT_HISTORY_POINTS =
"SELECT $COL_USER_ID, $COL_CHAT_ID, $COL_LAT, $COL_LON, $COL_TIME, $COL_TYPE FROM $TIMELINE_TABLE_NAME"
private const val TIMELINE_TABLE_CLEAR = "DELETE FROM $TIMELINE_TABLE_NAME" private const val TIMELINE_TABLE_CLEAR = "DELETE FROM $TIMELINE_TABLE_NAME"
private const val TIMELINE_TABLE_DELETE = "DROP TABLE IF EXISTS $TIMELINE_TABLE_NAME" private const val TIMELINE_TABLE_DELETE = "DROP TABLE IF EXISTS $TIMELINE_TABLE_NAME"
@ -335,6 +435,40 @@ class LocationMessages(val app: TelegramApplication) {
val time: Long, val time: Long,
val type: Int) val type: Int)
data class UserLocations(
var userId: Int,
var chatId: Long,
var locationsByType: Map<Int, List<LocationMessage>>
)
data class LocationHistoryPoint(
val userId: Int,
val chatId: Long,
val type: Int
) {
override fun equals(other: Any?): Boolean {
if (other == null) {
return false
}
if (other !is LocationHistoryPoint) {
return false
}
val o = other as LocationHistoryPoint?
return this.userId == o!!.userId && this.chatId == o.chatId && this.type == o.type
}
override fun hashCode(): Int {
val prime = 31
var result = 1
result = prime * result + userId.hashCode()
result = prime * result + chatId.hashCode()
result = prime * result + type.hashCode()
return result
}
}
companion object { companion object {
const val TYPE_USER_MAP = 0 const val TYPE_USER_MAP = 0

View file

@ -203,6 +203,15 @@ class OsmandAidlHelper(private val app: TelegramApplication) {
} }
} }
fun execOsmandApi(action: (() -> Unit)) {
if (!isOsmandConnected() && isOsmandBound()) {
connectOsmand()
}
if (isOsmandConnected()) {
action.invoke()
}
}
private fun bindService(packageName: String): Boolean { private fun bindService(packageName: String): Boolean {
return if (mIOsmAndAidlInterface == null) { return if (mIOsmAndAidlInterface == null) {
val intent = Intent("net.osmand.aidl.OsmandAidlService") val intent = Intent("net.osmand.aidl.OsmandAidlService")

View file

@ -13,6 +13,8 @@ import org.json.JSONObject
private const val USER_SET_LIVE_PERIOD_DELAY_MS = 5000 // 5 sec private const val USER_SET_LIVE_PERIOD_DELAY_MS = 5000 // 5 sec
private const val MY_LOCATION_UPDATE_MS = 15000 // 15 sec
class ShareLocationHelper(private val app: TelegramApplication) { class ShareLocationHelper(private val app: TelegramApplication) {
private val log = PlatformUtil.getLog(ShareLocationHelper::class.java) private val log = PlatformUtil.getLog(ShareLocationHelper::class.java)
@ -26,7 +28,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
var distance: Int = 0 var distance: Int = 0
private set private set
var lastLocationMessageSentTime: Long = 0 var lastLocationUpdateTime: Long = 0
var lastLocation: Location? = null var lastLocation: Location? = null
set(value) { set(value) {
@ -52,7 +54,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
if (app.settings.getChatsShareInfo().isNotEmpty()) { if (app.settings.getChatsShareInfo().isNotEmpty()) {
shareLocationMessages(location, app.telegramHelper.getCurrentUserId()) shareLocationMessages(location, app.telegramHelper.getCurrentUserId())
} }
lastLocationMessageSentTime = System.currentTimeMillis() lastLocationUpdateTime = System.currentTimeMillis()
} }
app.settings.updateSharingStatusHistory() app.settings.updateSharingStatusHistory()
refreshNotification() refreshNotification()
@ -188,6 +190,11 @@ class ShareLocationHelper(private val app: TelegramApplication) {
val chatsShareInfo = app.settings.getChatsShareInfo() val chatsShareInfo = app.settings.getChatsShareInfo()
val latitude = location.latitude val latitude = location.latitude
val longitude = location.longitude val longitude = location.longitude
val altitude = location.altitude
val speed = location.speed.toDouble()
val accuracy = location.accuracy.toDouble()
val bearing = location.bearing.toDouble()
val time = location.time
val sharingMode = app.settings.currentSharingMode val sharingMode = app.settings.currentSharingMode
val isBot = sharingMode != userId.toString() val isBot = sharingMode != userId.toString()
var bufferedMessagesFull = false var bufferedMessagesFull = false
@ -206,10 +213,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
if (shareInfo.pendingTdLib >= 10) { if (shareInfo.pendingTdLib >= 10) {
bufferedMessagesFull = true bufferedMessagesFull = true
} }
val message = BufferMessage( val message = BufferMessage(shareInfo.chatId, latitude, longitude, altitude, speed, accuracy, bearing, time, type)
shareInfo.chatId, latitude, longitude, location.altitude, location.speed.toDouble(),
location.accuracy.toDouble(), location.bearing.toDouble(), System.currentTimeMillis(), type
)
if (type == LocationMessages.TYPE_USER_MAP || type == LocationMessages.TYPE_BOT_MAP) { if (type == LocationMessages.TYPE_USER_MAP || type == LocationMessages.TYPE_BOT_MAP) {
prepareMapMessage(shareInfo, message, isBot, sharingMode) prepareMapMessage(shareInfo, message, isBot, sharingMode)
@ -219,6 +223,9 @@ class ShareLocationHelper(private val app: TelegramApplication) {
prepareMapAndTextMessage(shareInfo, message, isBot, sharingMode) prepareMapAndTextMessage(shareInfo, message, isBot, sharingMode)
} }
} }
if (System.currentTimeMillis() - lastLocationUpdateTime > MY_LOCATION_UPDATE_MS) {
app.locationMessages.addMyLocationMessage(location)
}
if (bufferedMessagesFull) { if (bufferedMessagesFull) {
checkNetworkType() checkNetworkType()
} }
@ -226,9 +233,9 @@ class ShareLocationHelper(private val app: TelegramApplication) {
private fun prepareTextMessage(shareInfo: TelegramSettings.ShareChatInfo,message: BufferMessage,isBot:Boolean, sharingMode: String) { private fun prepareTextMessage(shareInfo: TelegramSettings.ShareChatInfo,message: BufferMessage,isBot:Boolean, sharingMode: String) {
log.debug("prepareTextMessage $message") log.debug("prepareTextMessage $message")
shareInfo.collectedMessages++
if (shareInfo.currentTextMessageId == -1L) { if (shareInfo.currentTextMessageId == -1L) {
if (shareInfo.pendingTextMessage) { if (shareInfo.pendingTextMessage) {
shareInfo.collectedMessages++
app.locationMessages.addBufferedMessage(message) app.locationMessages.addBufferedMessage(message)
} else { } else {
if (isBot) { if (isBot) {
@ -244,6 +251,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
if (shareInfo.pendingTdLib < 10) { if (shareInfo.pendingTdLib < 10) {
app.telegramHelper.editTextLocation(shareInfo, message) app.telegramHelper.editTextLocation(shareInfo, message)
} else { } else {
shareInfo.collectedMessages++
app.locationMessages.addBufferedMessage(message) app.locationMessages.addBufferedMessage(message)
} }
} }
@ -252,9 +260,9 @@ class ShareLocationHelper(private val app: TelegramApplication) {
private fun prepareMapMessage(shareInfo: TelegramSettings.ShareChatInfo,message: BufferMessage,isBot:Boolean, sharingMode: String) { private fun prepareMapMessage(shareInfo: TelegramSettings.ShareChatInfo,message: BufferMessage,isBot:Boolean, sharingMode: String) {
log.debug("prepareMapMessage $message") log.debug("prepareMapMessage $message")
shareInfo.collectedMessages++
if (shareInfo.currentMapMessageId == -1L) { if (shareInfo.currentMapMessageId == -1L) {
if (shareInfo.pendingMapMessage) { if (shareInfo.pendingMapMessage) {
shareInfo.collectedMessages++
app.locationMessages.addBufferedMessage(message) app.locationMessages.addBufferedMessage(message)
} else { } else {
if (isBot) { if (isBot) {
@ -279,8 +287,8 @@ class ShareLocationHelper(private val app: TelegramApplication) {
private fun prepareMapAndTextMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot:Boolean, sharingMode: String) { private fun prepareMapAndTextMessage(shareInfo: TelegramSettings.ShareChatInfo, message: BufferMessage, isBot:Boolean, sharingMode: String) {
log.debug("prepareMapAndTextMessage $message") log.debug("prepareMapAndTextMessage $message")
shareInfo.collectedMessages++
if (shareInfo.pendingMapMessage || shareInfo.pendingTextMessage || shareInfo.pendingTdLib >= 10) { if (shareInfo.pendingMapMessage || shareInfo.pendingTextMessage || shareInfo.pendingTdLib >= 10) {
shareInfo.collectedMessages++
app.locationMessages.addBufferedMessage(message) app.locationMessages.addBufferedMessage(message)
} else { } else {
if (isBot) { if (isBot) {

View file

@ -35,7 +35,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
private var forcedStop: Boolean = false private var forcedStop: Boolean = false
fun setupMapLayer() { fun setupMapLayer() {
execOsmandApi { osmandAidlHelper.execOsmandApi {
osmandAidlHelper.addMapLayer(MAP_LAYER_ID, "Telegram", 5.5f, null) osmandAidlHelper.addMapLayer(MAP_LAYER_ID, "Telegram", 5.5f, null)
} }
} }
@ -44,7 +44,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
if (item.latLon == null) { if (item.latLon == null) {
return return
} }
execOsmandApi { osmandAidlHelper.execOsmandApi {
osmandAidlHelper.showMapPoint( osmandAidlHelper.showMapPoint(
MAP_LAYER_ID, MAP_LAYER_ID,
item.getMapPointId(), item.getMapPointId(),
@ -60,7 +60,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
} }
fun updateLocationsOnMap() { fun updateLocationsOnMap() {
execOsmandApi { osmandAidlHelper.execOsmandApi {
val messages = telegramHelper.getMessages() val messages = telegramHelper.getMessages()
for (message in messages) { for (message in messages) {
val date = OsmandLocationUtils.getLastUpdatedTime(message) val date = OsmandLocationUtils.getLastUpdatedTime(message)
@ -75,7 +75,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
} }
fun addOrUpdateLocationOnMap(message: TdApi.Message, update: Boolean = false) { fun addOrUpdateLocationOnMap(message: TdApi.Message, update: Boolean = false) {
execOsmandApi { osmandAidlHelper.execOsmandApi {
val chatId = message.chatId val chatId = message.chatId
val chatTitle = telegramHelper.getChat(message.chatId)?.title val chatTitle = telegramHelper.getChat(message.chatId)?.title
val content = message.content val content = message.content
@ -133,7 +133,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
} }
fun showChatMessages(chatId: Long) { fun showChatMessages(chatId: Long) {
execOsmandApi { osmandAidlHelper.execOsmandApi {
val messages = telegramHelper.getChatMessages(chatId) val messages = telegramHelper.getChatMessages(chatId)
for (message in messages) { for (message in messages) {
addOrUpdateLocationOnMap(message) addOrUpdateLocationOnMap(message)
@ -146,7 +146,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
} }
fun hideMessages(messages: List<TdApi.Message>) { fun hideMessages(messages: List<TdApi.Message>) {
execOsmandApi { osmandAidlHelper.execOsmandApi {
for (message in messages) { for (message in messages) {
val user = telegramHelper.getUser(message.senderUserId) val user = telegramHelper.getUser(message.senderUserId)
if (user != null) { if (user != null) {
@ -257,13 +257,4 @@ class ShowLocationHelper(private val app: TelegramApplication) {
osmandAidlHelper.removeMapPoint(MAP_LAYER_ID, "${chatId}_${content.name}") osmandAidlHelper.removeMapPoint(MAP_LAYER_ID, "${chatId}_${content.name}")
} }
} }
private fun execOsmandApi(action: (() -> Unit)) {
if (!osmandAidlHelper.isOsmandConnected() && osmandAidlHelper.isOsmandBound()) {
osmandAidlHelper.connectOsmand()
}
if (osmandAidlHelper.isOsmandConnected()) {
action.invoke()
}
}
} }

View file

@ -1309,6 +1309,24 @@ class TelegramHelper private constructor() {
} }
} }
} }
TdApi.UpdateMessageEdited.CONSTRUCTOR -> {
val updateMessageEdited = obj as TdApi.UpdateMessageEdited
val message = usersLocationMessages[updateMessageEdited.messageId]
log.debug("UpdateMessageEdited " + updateMessageEdited.messageId)
if (message == null) {
updateMessageEdited.apply {
requestMessage(chatId, messageId, this@TelegramHelper::addNewMessage)
}
} else {
synchronized(message) {
message.editDate = updateMessageEdited.editDate
lastTelegramUpdateTime = Math.max(message.date, message.editDate)
}
incomingMessagesListeners.forEach {
it.updateLocationMessages()
}
}
}
TdApi.UpdateMessageContent.CONSTRUCTOR -> { TdApi.UpdateMessageContent.CONSTRUCTOR -> {
val updateMessageContent = obj as TdApi.UpdateMessageContent val updateMessageContent = obj as TdApi.UpdateMessageContent
val message = usersLocationMessages[updateMessageContent.messageId] val message = usersLocationMessages[updateMessageContent.messageId]
@ -1325,9 +1343,12 @@ class TelegramHelper private constructor() {
val viaBot = isOsmAndBot(message.viaBotUserId) val viaBot = isOsmAndBot(message.viaBotUserId)
message.content = if (newContent is TdApi.MessageText) { message.content = if (newContent is TdApi.MessageText) {
parseTextLocation(newContent.text, (fromBot || viaBot)) parseTextLocation(newContent.text, (fromBot || viaBot))
} else if (newContent is TdApi.MessageLocation && } else if (newContent is TdApi.MessageLocation) {
(isOsmAndBot(message.senderUserId) || isOsmAndBot(message.viaBotUserId))) { if(fromBot||viaBot){
parseOsmAndBotLocationContent(message.content as MessageOsmAndBotLocation, newContent) parseOsmAndBotLocationContent(message.content as MessageOsmAndBotLocation, newContent)
} else {
OsmandLocationUtils.parseUserMapLocation(message)
}
} else { } else {
newContent newContent
} }

View file

@ -131,10 +131,6 @@ object TelegramUiHelper {
} }
} }
fun gpxToChatItem(helper: TelegramHelper, gpx: GPXFile, simpleUserItem: Boolean): GpxChatItem? {
return if (simpleUserItem) gpxToUserGpxChatItem(helper, gpx) else gpxToGpxChatItem(helper, gpx)
}
private fun botMessageToLocationItem( private fun botMessageToLocationItem(
chat: TdApi.Chat, chat: TdApi.Chat,
content: MessageOsmAndBotLocation content: MessageOsmAndBotLocation
@ -256,47 +252,31 @@ object TelegramUiHelper {
} }
} }
fun locationMessagesToChatItem( fun userLocationsToChatItem(helper: TelegramHelper, userLocation: LocationMessages.UserLocations): LocationMessagesChatItem? {
helper: TelegramHelper, val user = helper.getUser(userLocation.userId)
messages: List<LocationMessages.LocationMessage> val chat = helper.getChat(userLocation.chatId)
): LocationMessagesChatItem? {
val message = messages.firstOrNull()
val user = helper.getUser(message?.userId ?: -1) ?: return null
val chat = helper.getChat(message?.chatId ?: -1) ?: return null
return LocationMessagesChatItem().apply { return LocationMessagesChatItem().apply {
chatId = chat.id if (chat != null) {
chatTitle = chat.title chatId = chat.id
locationMessages = messages chatTitle = chat.title
name = TelegramUiHelper.getUserName(user) if (helper.isGroup(chat)) {
if (helper.isGroup(chat)) { photoPath = helper.getUserPhotoPath(user)
photoPath = helper.getUserPhotoPath(user) groupPhotoPath = chat.photo?.small?.local?.path
groupPhotoPath = chat.photo?.small?.local?.path } else {
photoPath = user?.profilePhoto?.small?.local?.path
privateChat = helper.isPrivateChat(chat) || helper.isSecretChat(chat)
}
} else { } else {
photoPath = user.profilePhoto?.small?.local?.path photoPath = user?.profilePhoto?.small?.local?.path
} }
if (user != null) {
name = TelegramUiHelper.getUserName(user)
userId = user.id
}
userLocations = userLocation
grayscalePhotoPath = helper.getUserGreyPhotoPath(user) grayscalePhotoPath = helper.getUserGreyPhotoPath(user)
placeholderId = R.drawable.img_user_picture placeholderId = R.drawable.img_user_picture
userId = user.id
privateChat = helper.isPrivateChat(chat) || helper.isSecretChat(chat)
chatWithBot = helper.isBot(userId) chatWithBot = helper.isBot(userId)
lastUpdated = (messages.maxBy { it.time }?.time ?: -1).toInt()
}
}
private fun gpxToUserGpxChatItem(
helper: TelegramHelper,
gpx: GPXFile
): GpxChatItem? {
val user = helper.getUser(gpx.userId) ?: return null
return GpxChatItem().apply {
gpxFile = gpx
name = TelegramUiHelper.getUserName(user)
photoPath = user.profilePhoto?.small?.local?.path
grayscalePhotoPath = helper.getUserGreyPhotoPath(user)
placeholderId = R.drawable.img_user_picture
userId = user.id
chatWithBot = helper.isBot(userId)
lastUpdated = (gpx.modifiedTime / 1000).toInt()
} }
} }
@ -368,7 +348,7 @@ object TelegramUiHelper {
class LocationMessagesChatItem : ListItem() { class LocationMessagesChatItem : ListItem() {
var locationMessages: List<LocationMessages.LocationMessage> = emptyList() var userLocations: LocationMessages.UserLocations? = null
internal set internal set
var groupPhotoPath: String? = null var groupPhotoPath: String? = null
internal set internal set

View file

@ -19,8 +19,6 @@ import android.widget.*
import net.osmand.PlatformUtil import net.osmand.PlatformUtil
import net.osmand.telegram.R import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.helpers.LocationMessages
import net.osmand.telegram.helpers.LocationMessages.LocationMessage
import net.osmand.telegram.helpers.OsmandAidlHelper import net.osmand.telegram.helpers.OsmandAidlHelper
import net.osmand.telegram.helpers.TelegramHelper import net.osmand.telegram.helpers.TelegramHelper
import net.osmand.telegram.helpers.TelegramHelper.* import net.osmand.telegram.helpers.TelegramHelper.*
@ -294,7 +292,9 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
} }
if (app.telegramService == null) { if (app.telegramService == null) {
messages.forEach { messages.forEach {
if (!it.isOutgoing) {
app.locationMessages.addNewLocationMessage(it) app.locationMessages.addNewLocationMessage(it)
}
} }
} }
} }

View file

@ -718,8 +718,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
} }
holder.gpsPointsCollected?.apply { holder.gpsPointsCollected?.apply {
if (shareInfo != null) { if (shareInfo != null) {
val bufferedMessages = shareInfo.pendingTdLib + app.locationMessages.getBufferedMessagesForChat(shareInfo.chatId).size text = "${shareInfo.pendingTdLib + shareInfo.collectedMessages}"
text = "$bufferedMessages"
} }
} }
holder.gpsPointsSent?.apply { holder.gpsPointsSent?.apply {

View file

@ -159,18 +159,18 @@ class TimelineTabFragment : Fragment() {
val res = mutableListOf<ListItem>() val res = mutableListOf<ListItem>()
val currentUserId = telegramHelper.getCurrentUser()?.id val currentUserId = telegramHelper.getCurrentUser()?.id
if (currentUserId != null) { if (currentUserId != null) {
val outgoingMessages = app.locationMessages.getMessagesForUser(currentUserId, start, end) val currentUserLocations = app.locationMessages.getUserLocations(currentUserId, start, end)
TelegramUiHelper.locationMessagesToChatItem(telegramHelper, outgoingMessages)?.also { chatItem -> if (currentUserLocations != null) {
res.add(chatItem) TelegramUiHelper.userLocationsToChatItem(telegramHelper, currentUserLocations)?.also { chatItem ->
}
val ingoingMessages = app.locationMessages.getIngoingMessages(currentUserId, start, end)
val emm = ingoingMessages.distinctBy { Pair(it.userId, it.chatId) }
emm.forEach { message ->
TelegramUiHelper.locationMessagesToChatItem(telegramHelper,
ingoingMessages.filter { it.chatId == message.chatId && it.userId == message.userId })?.also { chatItem ->
res.add(chatItem) res.add(chatItem)
} }
} }
val ingoingUserLocations = app.locationMessages.getIngoingUserLocations(currentUserId, start, end)
ingoingUserLocations.forEach {
TelegramUiHelper.userLocationsToChatItem(telegramHelper, it)?.also { chatItem ->
res.add(chatItem)
}
}
} }
adapter.items = sortAdapterItems(res) adapter.items = sortAdapterItems(res)
@ -205,17 +205,21 @@ class TimelineTabFragment : Fragment() {
val lastItem = position == itemCount - 1 val lastItem = position == itemCount - 1
val item = items[position] val item = items[position]
val currentUserId = telegramHelper.getCurrentUser()?.id ?: 0 val currentUserId = telegramHelper.getCurrentUser()?.id ?: 0
TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, R.drawable.img_user_picture_active, false) TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, R.drawable.img_user_picture_active, false)
holder.title?.text = item.name holder.title?.text = item.name
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
holder.lastTelegramUpdateTime?.visibility = View.GONE holder.lastTelegramUpdateTime?.visibility = View.GONE
if (item is TelegramUiHelper.LocationMessagesChatItem) { if (item is TelegramUiHelper.LocationMessagesChatItem ) {
val distance = OsmandFormatter.getFormattedDistance(getDistance(item.locationMessages),app) val userLocations = item.userLocations
val name = if ((!item.privateChat || item.chatWithBot) && item.userId != currentUserId) item.getVisibleName() else ""
holder.groupDescrContainer?.visibility = View.VISIBLE if(userLocations!=null){
holder.groupTitle?.text = "$distance (${getString(R.string.points_size, item.locationMessages.size)}) $name" val pair = getDistanceAndCountedPoints(userLocations)
val distance = OsmandFormatter.getFormattedDistance(pair.first,app)
val name = if ((!item.privateChat || item.chatWithBot) && item.userId != currentUserId) item.getVisibleName() else ""
holder.groupDescrContainer?.visibility = View.VISIBLE
holder.groupTitle?.text = "$distance (${getString(R.string.points_size, pair.second)}) $name"
}
TelegramUiHelper.setupPhoto(app, holder.groupImage, item.groupPhotoPath, item.placeholderId, false) TelegramUiHelper.setupPhoto(app, holder.groupImage, item.groupPhotoPath, item.placeholderId, false)
holder.userRow?.setOnClickListener { holder.userRow?.setOnClickListener {
childFragmentManager.also { childFragmentManager.also {
@ -229,12 +233,27 @@ class TimelineTabFragment : Fragment() {
} }
} }
private fun getDistance(messages: List<LocationMessages.LocationMessage>): Float { private fun getDistanceAndCountedPoints(userLocations: LocationMessages.UserLocations): Pair<Float, Int> {
val textUserLoc = userLocations.locationsByType[LocationMessages.TYPE_USER_TEXT]
val textBotLoc = userLocations.locationsByType[LocationMessages.TYPE_BOT_TEXT]
var dist = 0.0 var dist = 0.0
messages.forEach { var countedPoints = 0
dist += it.distanceFromPrev when {
textUserLoc != null -> textUserLoc.forEach {
dist += it.distanceFromPrev
countedPoints++
}
textBotLoc != null -> textBotLoc.forEach {
dist += it.distanceFromPrev
countedPoints++
}
else -> userLocations.locationsByType.values.firstOrNull()?.forEach {
dist += it.distanceFromPrev
countedPoints++
}
} }
return dist.toFloat()
return Pair(dist.toFloat(), countedPoints)
} }
override fun getItemCount() = items.size override fun getItemCount() = items.size

View file

@ -20,12 +20,10 @@ import android.widget.Toast
import net.osmand.PlatformUtil import net.osmand.PlatformUtil
import net.osmand.aidl.gpx.AGpxBitmap import net.osmand.aidl.gpx.AGpxBitmap
import net.osmand.telegram.R import net.osmand.telegram.R
import net.osmand.telegram.helpers.LocationMessages
import net.osmand.telegram.helpers.OsmandAidlHelper import net.osmand.telegram.helpers.OsmandAidlHelper
import net.osmand.telegram.helpers.TelegramUiHelper import net.osmand.telegram.helpers.TelegramUiHelper
import net.osmand.telegram.utils.AndroidUtils import net.osmand.telegram.utils.*
import net.osmand.telegram.utils.GPXUtilities
import net.osmand.telegram.utils.OsmandFormatter
import net.osmand.telegram.utils.OsmandLocationUtils
import net.osmand.util.Algorithms import net.osmand.util.Algorithms
import java.io.File import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
@ -52,6 +50,8 @@ class UserGpxInfoFragment : BaseDialogFragment() {
private var startCalendar = Calendar.getInstance() private var startCalendar = Calendar.getInstance()
private var endCalendar = Calendar.getInstance() private var endCalendar = Calendar.getInstance()
private var locationMessages = emptyList<LocationMessages.LocationMessage>()
private var userId = -1 private var userId = -1
private var chatId = -1L private var chatId = -1L
@ -115,10 +115,10 @@ class UserGpxInfoFragment : BaseDialogFragment() {
setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_speed_average)) setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_speed_average))
} }
mainView.findViewById<ImageView>(R.id.distance_icon).apply { mainView.findViewById<ImageView>(R.id.distance_icon).apply {
setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_altitude_range)) setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_sort_by_distance))
} }
mainView.findViewById<ImageView>(R.id.duration_icon).apply { mainView.findViewById<ImageView>(R.id.duration_icon).apply {
setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_altitude_range)) setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_time_span))
} }
updateGPXStatisticRow() updateGPXStatisticRow()
@ -192,7 +192,8 @@ class UserGpxInfoFragment : BaseDialogFragment() {
private fun saveCurrentGpxToFile(listener: OsmandLocationUtils.SaveGpxListener) { private fun saveCurrentGpxToFile(listener: OsmandLocationUtils.SaveGpxListener) {
if (!gpxFile.isEmpty) { if (!gpxFile.isEmpty) {
OsmandLocationUtils.saveGpx(app, listener, app.getExternalFilesDir(null)!!, gpxFile) val file = File(app.getExternalFilesDir(null), TRACKS_DIR)
OsmandLocationUtils.saveGpx(app, listener, file, gpxFile)
} }
} }
@ -210,10 +211,9 @@ class UserGpxInfoFragment : BaseDialogFragment() {
} }
private fun updateGpxInfo() { private fun updateGpxInfo() {
val emm = app.locationMessages.getMessagesForUserInChat( locationMessages = app.locationMessages.getMessagesForUserInChat(userId, chatId, startCalendar.timeInMillis, endCalendar.timeInMillis)
userId, chatId, startCalendar.timeInMillis, endCalendar.timeInMillis)
gpxFile = OsmandLocationUtils.convertLocationMessagesToGpxFiles(emm).firstOrNull()?:GPXUtilities.GPXFile() gpxFile = OsmandLocationUtils.convertLocationMessagesToGpxFiles(locationMessages).firstOrNull()?:GPXUtilities.GPXFile()
updateGPXStatisticRow() updateGPXStatisticRow()
updateDateAndTimeButtons() updateDateAndTimeButtons()
updateGPXMap() updateGPXMap()
@ -246,7 +246,9 @@ class UserGpxInfoFragment : BaseDialogFragment() {
val widthPixels = dm.widthPixels - (2 * app.resources.getDimensionPixelSize(R.dimen.content_padding_standard)) val widthPixels = dm.widthPixels - (2 * app.resources.getDimensionPixelSize(R.dimen.content_padding_standard))
val heightPixels = AndroidUtils.dpToPx(app, 152f) val heightPixels = AndroidUtils.dpToPx(app, 152f)
val gpxUri = AndroidUtils.getUriForFile(app, File(path)) val gpxUri = AndroidUtils.getUriForFile(app, File(path))
app.osmandAidlHelper.getBitmapForGpx(gpxUri, dm.density , widthPixels, heightPixels, GPX_TRACK_COLOR) app.osmandAidlHelper.execOsmandApi {
app.osmandAidlHelper.getBitmapForGpx(gpxUri, dm.density , widthPixels, heightPixels, GPX_TRACK_COLOR)
}
} }
} }

View file

@ -2,6 +2,7 @@ package net.osmand.telegram.utils
import android.os.AsyncTask import android.os.AsyncTask
import net.osmand.Location import net.osmand.Location
import net.osmand.data.LatLon
import net.osmand.telegram.TelegramApplication import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.helpers.LocationMessages import net.osmand.telegram.helpers.LocationMessages
import net.osmand.telegram.helpers.LocationMessages.BufferMessage import net.osmand.telegram.helpers.LocationMessages.BufferMessage
@ -15,6 +16,7 @@ import java.io.File
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
const val TRACKS_DIR = "tracker/"
object OsmandLocationUtils { object OsmandLocationUtils {
@ -83,10 +85,11 @@ object OsmandLocationUtils {
lat = messageLocation.location.latitude lat = messageLocation.location.latitude
lon = messageLocation.location.longitude lon = messageLocation.location.longitude
lastUpdated = getLastUpdatedTime(message) lastUpdated = getLastUpdatedTime(message)
type = LocationMessages.TYPE_USER_MAP
} }
} }
fun parseMessage(message: TdApi.Message, helper: TelegramHelper, previousMessage: LocationMessage?): LocationMessage? { fun parseMessage(message: TdApi.Message, helper: TelegramHelper, previousMessageLatLon: LatLon?): LocationMessage? {
var locationMessage: LocationMessage? = null var locationMessage: LocationMessage? = null
val oldContent = message.content val oldContent = message.content
val messageType = getMessageType(message,helper) val messageType = getMessageType(message,helper)
@ -114,10 +117,8 @@ object OsmandLocationUtils {
} }
if (parsedMessageContent != null) { if (parsedMessageContent != null) {
val distanceFromPrev = if (previousMessage != null) { val distanceFromPrev = if (previousMessageLatLon != null) {
MapUtils.getDistance(previousMessage.lat, previousMessage.lon, MapUtils.getDistance(previousMessageLatLon, parsedMessageContent.lat, parsedMessageContent.lon) } else 0.0
parsedMessageContent.lat, parsedMessageContent.lon)
} else 0.0
locationMessage = LocationMessage(helper.getSenderMessageId(message), message.chatId, parsedMessageContent.lat, locationMessage = LocationMessage(helper.getSenderMessageId(message), message.chatId, parsedMessageContent.lat,
parsedMessageContent.lon, parsedMessageContent.altitude, parsedMessageContent.speed, parsedMessageContent.hdop, parsedMessageContent.lon, parsedMessageContent.altitude, parsedMessageContent.speed, parsedMessageContent.hdop,
@ -403,11 +404,16 @@ object OsmandLocationUtils {
var segment: GPXUtilities.TrkSegment? = null var segment: GPXUtilities.TrkSegment? = null
var track: GPXUtilities.Track? = null var track: GPXUtilities.Track? = null
var gpx: GPXUtilities.GPXFile? = null var gpx: GPXUtilities.GPXFile? = null
var countedLocations = 0
items.forEach { items.forEach {
val userId = it.userId val userId = it.userId
val chatId = it.chatId val chatId = it.chatId
val time = it.time val time = it.time
if (previousTime >= time) {
return@forEach
}
countedLocations++
if (previousUserId != userId || (newGpxPerChat && previousChatId != chatId)) { if (previousUserId != userId || (newGpxPerChat && previousChatId != chatId)) {
gpx = GPXUtilities.GPXFile() gpx = GPXUtilities.GPXFile()
gpx!!.chatId = chatId gpx!!.chatId = chatId
@ -521,10 +527,6 @@ object OsmandLocationUtils {
userId.toString() + "_" + SimpleDateFormat("yyyy-MM-dd_HH-mm_EEE", Locale.US).format(Date(pt.time)) userId.toString() + "_" + SimpleDateFormat("yyyy-MM-dd_HH-mm_EEE", Locale.US).format(Date(pt.time))
} }
fout = File(dir, "$fileName.gpx") fout = File(dir, "$fileName.gpx")
var ind = 1
while (fout.exists()) {
fout = File(dir, "${fileName}_${++ind}.gpx")
}
} }
val warn = GPXUtilities.writeGpxFile(fout, gpxFile, app) val warn = GPXUtilities.writeGpxFile(fout, gpxFile, app)
if (warn != null) { if (warn != null) {