Merge pull request #6979 from osmandapp/TrackerBearing

Add bearing to context menu and text messages
This commit is contained in:
Alexey 2019-05-26 14:46:38 +03:00 committed by GitHub
commit 4a4c0a44be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 121 additions and 32 deletions

View file

@ -15,6 +15,7 @@ public class AMapPoint implements Parcelable {
public static final String POINT_SPEED_PARAM = "point_speed_param";
public static final String POINT_TYPE_ICON_NAME_PARAM = "point_type_icon_name_param";
public static final String POINT_STALE_LOC_PARAM = "point_stale_loc_param";
public static final String POINT_BEARING_PARAM = "point_bearing_param";
private String id;
private String shortName;

View file

@ -460,13 +460,18 @@ class TelegramSettings(private val app: TelegramApplication) {
if (shareInfo.lastTextSuccessfulSendTime == -1L && shareInfo.lastMapSuccessfulSendTime == -1L
&& ((statusChangeTime / 1000 - shareInfo.start) < SHARING_INITIALIZATION_TIME)) {
initializing = true
} else if (shareInfo.hasSharingError
|| (shareInfo.lastSendTextMessageTime - shareInfo.lastTextSuccessfulSendTime > WAITING_TDLIB_TIME)
|| (shareInfo.lastSendMapMessageTime - shareInfo.lastMapSuccessfulSendTime > WAITING_TDLIB_TIME)
) {
sendChatsErrors = true
locationTime = Math.max(shareInfo.lastTextSuccessfulSendTime, shareInfo.lastMapSuccessfulSendTime)
chatsIds.add(shareInfo.chatId)
} else {
val textSharingError = shareInfo.lastSendTextMessageTime - shareInfo.lastTextSuccessfulSendTime > WAITING_TDLIB_TIME
val mapSharingError = shareInfo.lastSendMapMessageTime - shareInfo.lastMapSuccessfulSendTime > WAITING_TDLIB_TIME
if (shareInfo.hasSharingError
|| (shareTypeValue == SHARE_TYPE_MAP_AND_TEXT && (textSharingError || mapSharingError))
|| textSharingError && (shareTypeValue == SHARE_TYPE_TEXT)
|| mapSharingError && (shareTypeValue == SHARE_TYPE_MAP)
) {
sendChatsErrors = true
locationTime = Math.max(shareInfo.lastTextSuccessfulSendTime, shareInfo.lastMapSuccessfulSendTime)
chatsIds.add(shareInfo.chatId)
}
}
}
@ -477,7 +482,7 @@ class TelegramSettings(private val app: TelegramApplication) {
} else if (!initializing) {
when {
!gpsEnabled -> {
locationTime = app.shareLocationHelper.lastLocationUpdateTime
locationTime = app.shareLocationHelper.lastLocationUpdateTime / 1000
if (locationTime <= 0) {
locationTime = getLastSuccessfulSendTime()
}

View file

@ -15,6 +15,8 @@ private const val USER_SET_LIVE_PERIOD_DELAY_MS = 5000 // 5 sec
private const val UPDATE_LOCATION_ACCURACY = 150 // 150 meters
private const val SENT_LOCATIONS_INTERVAL_TIME_MS = 4000 // 4 sec
class ShareLocationHelper(private val app: TelegramApplication) {
private val log = PlatformUtil.getLog(ShareLocationHelper::class.java)
@ -30,6 +32,8 @@ class ShareLocationHelper(private val app: TelegramApplication) {
var lastLocationUpdateTime: Long = 0
var lastLocationSentTime: Long = 0
var lastLocation: Location? = null
set(value) {
if (lastTimeInMillis == 0L) {
@ -108,12 +112,16 @@ class ShareLocationHelper(private val app: TelegramApplication) {
}
fun checkAndSendBufferMessagesToChat(chatId: Long) {
val shareInfo = app.settings.getChatsShareInfo()[chatId]
if (shareInfo != null) {
val shareChatsInfo = app.settings.getChatsShareInfo()
val shareInfo = shareChatsInfo[chatId]
val chatsCounts = shareChatsInfo.size
val currentTime = System.currentTimeMillis()
if (shareInfo != null && currentTime - lastLocationSentTime > chatsCounts * SENT_LOCATIONS_INTERVAL_TIME_MS) {
app.locationMessages.getBufferedTextMessagesForChat(chatId).take(MAX_MESSAGES_IN_TDLIB_PER_CHAT).forEach {
if (shareInfo.pendingTdLibText < MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
if (it.deviceName.isEmpty()) {
if (!shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) {
lastLocationSentTime = System.currentTimeMillis()
app.telegramHelper.editTextLocation(shareInfo, it)
app.locationMessages.removeBufferedMessage(it)
}
@ -126,6 +134,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
if (shareInfo.pendingTdLibMap < MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
if (it.deviceName.isEmpty()) {
if (!shareInfo.pendingMapMessage && shareInfo.currentMapMessageId != -1L) {
lastLocationSentTime = System.currentTimeMillis()
app.telegramHelper.editMapLocation(shareInfo, it)
app.locationMessages.removeBufferedMessage(it)
}
@ -188,6 +197,14 @@ class ShareLocationHelper(private val app: TelegramApplication) {
val isBot = app.settings.currentSharingMode != userId.toString()
val deviceName = if (isBot) app.settings.currentSharingMode else ""
var bufferedMessagesFull = false
val chatsCounts = chatsShareInfo.size
val currentTime = System.currentTimeMillis()
app.locationMessages.addMyLocationMessage(location)
if (currentTime - lastLocationSentTime <= chatsCounts * SENT_LOCATIONS_INTERVAL_TIME_MS) {
return
}
chatsShareInfo.values.forEach { shareInfo ->
if (shareInfo.pendingTdLibText >= MAX_MESSAGES_IN_TDLIB_PER_CHAT || shareInfo.pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
@ -209,8 +226,8 @@ class ShareLocationHelper(private val app: TelegramApplication) {
prepareTextMessage(shareInfo, messageText, isBot)
}
}
checkAndSendBufferMessagesToChat(shareInfo.chatId)
}
app.locationMessages.addMyLocationMessage(location)
if (bufferedMessagesFull) {
checkNetworkType()
}
@ -225,6 +242,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
if (isBot) {
sendLocationToBot(message, shareInfo, SHARE_TYPE_TEXT)
} else {
lastLocationSentTime = System.currentTimeMillis()
app.telegramHelper.sendNewTextLocation(shareInfo, message)
}
}
@ -237,6 +255,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
}
} else {
if (shareInfo.pendingTdLibText < MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
lastLocationSentTime = System.currentTimeMillis()
app.telegramHelper.editTextLocation(shareInfo, message)
} else {
app.locationMessages.addBufferedMessage(message)
@ -258,6 +277,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
app.locationMessages.addBufferedMessage(message)
}
} else {
lastLocationSentTime = System.currentTimeMillis()
app.telegramHelper.sendNewMapLocation(shareInfo, message)
}
}
@ -270,6 +290,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
}
} else {
if (shareInfo.pendingTdLibMap < MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
lastLocationSentTime = System.currentTimeMillis()
app.telegramHelper.editMapLocation(shareInfo, message)
} else {
app.locationMessages.addBufferedMessage(message)
@ -298,6 +319,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
} else if (shareType == SHARE_TYPE_MAP) {
shareInfo.lastSendMapMessageTime = (System.currentTimeMillis() / 1000).toInt()
}
lastLocationSentTime = System.currentTimeMillis()
AndroidNetworkUtils.sendRequestAsync(app, url, null, "Send Location", false, false,
object : AndroidNetworkUtils.OnRequestResultListener {
override fun onResult(result: String?) {

View file

@ -90,6 +90,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
if (item.latLon == null) {
return
}
setupMapLayer()
osmandAidlHelper.execOsmandApi {
osmandAidlHelper.showMapPoint(
MAP_LAYER_ID,
@ -100,7 +101,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
Color.WHITE,
ALatLon(item.latLon!!.latitude, item.latLon!!.longitude),
generatePointDetails(item.bearing?.toFloat(), item.altitude?.toFloat(), item.precision?.toFloat()),
generatePointParams(if (stale) item.grayscalePhotoPath else item.photoPath, stale, item.speed?.toFloat())
generatePointParams(if (stale) item.grayscalePhotoPath else item.photoPath, stale, item.speed?.toFloat(), item.bearing?.toFloat())
)
}
}
@ -147,8 +148,13 @@ class ShowLocationHelper(private val app: TelegramApplication) {
}
}
setupMapLayer()
val params = generatePointParams(photoPath, stale, if (content is MessageUserLocation) content.speed.toFloat() else null)
var speed = 0f
var bearing = 0f
if (content is MessageUserLocation) {
speed = content.speed.toFloat()
bearing = content.bearing.toFloat()
}
val params = generatePointParams(photoPath, stale, speed, bearing)
val typeName = if (isGroup) chatTitle else OsmandFormatter.getListItemLiveTimeDescr(app, date, app.getString(R.string.last_response) + ": ")
if (update) {
osmandAidlHelper.updateMapPoint(MAP_LAYER_ID, pointId, name, name, typeName, Color.WHITE, aLatLon, details, params)
@ -158,7 +164,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
points[pointId] = message
} else if (content is MessageOsmAndBotLocation && content.isValid()) {
setupMapLayer()
val params = generatePointParams(null, stale, content.speed.toFloat())
val params = generatePointParams(null, stale, content.speed.toFloat(), content.bearing.toFloat())
if (update) {
osmandAidlHelper.updateMapPoint(MAP_LAYER_ID, pointId, name, name, chatTitle, Color.WHITE, aLatLon, details, params)
} else {
@ -340,7 +346,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
private fun generatePointDetails(bearing: Float?, altitude: Float?, precision: Float?): List<String> {
val details = mutableListOf<String>()
if (bearing != null && bearing != 0.0f) {
details.add(String.format(Locale.US, "${OsmandLocationUtils.BEARING_PREFIX}%.1f \n", bearing))
details.add(String.format(Locale.US, "${OsmandLocationUtils.BEARING_PREFIX}%.1f${OsmandLocationUtils.BEARING_SUFFIX} \n", bearing))
}
if (altitude != null && altitude != 0.0f) {
details.add(String.format(Locale.US, "${OsmandLocationUtils.ALTITUDE_PREFIX}%.1f m\n", altitude))
@ -352,7 +358,7 @@ class ShowLocationHelper(private val app: TelegramApplication) {
return details
}
private fun generatePointParams(photoPath: String?, stale: Boolean, speed: Float?): Map<String, String> {
private fun generatePointParams(photoPath: String?, stale: Boolean, speed: Float?, bearing: Float?): Map<String, String> {
val photoUri = generatePhotoUri(photoPath, stale)
app.grantUriPermission(
app.settings.appToConnectPackage,
@ -366,6 +372,9 @@ class ShowLocationHelper(private val app: TelegramApplication) {
if (speed != 0.0f) {
params[AMapPoint.POINT_SPEED_PARAM] = speed.toString()
}
if (bearing != 0.0f) {
params[AMapPoint.POINT_BEARING_PARAM] = bearing.toString()
}
return params
}

View file

@ -32,6 +32,7 @@ object OsmandLocationUtils {
const val BEARING_PREFIX = "Bearing: "
const val SPEED_PREFIX = "Speed: "
const val HDOP_PREFIX = "Horizontal precision: "
const val BEARING_SUFFIX = "°"
const val NOW = "now"
const val FEW_SECONDS_AGO = "few seconds ago"
@ -241,19 +242,28 @@ object OsmandLocationUtils {
}
}
s.startsWith(SPEED_PREFIX) -> {
val altStr = s.removePrefix(SPEED_PREFIX)
val speedStr = s.removePrefix(SPEED_PREFIX)
try {
val alt = altStr.split(" ").first()
res.speed = alt.toDouble()
val speed = speedStr.split(" ").first()
res.speed = speed.toDouble()
} catch (e: Exception) {
e.printStackTrace()
}
}
s.startsWith(BEARING_PREFIX) -> {
val bearingStr = s.removePrefix(BEARING_PREFIX)
try {
val bearing = bearingStr.removeSuffix(BEARING_SUFFIX)
res.bearing = bearing.toDouble()
} catch (e: Exception) {
e.printStackTrace()
}
}
s.startsWith(HDOP_PREFIX) -> {
val altStr = s.removePrefix(HDOP_PREFIX)
val hdopStr = s.removePrefix(HDOP_PREFIX)
try {
val alt = altStr.split(" ").first()
res.hdop = alt.toDouble()
val hdop = hdopStr.split(" ").first()
res.hdop = hdop.toDouble()
} catch (e: Exception) {
e.printStackTrace()
}
@ -336,6 +346,10 @@ object OsmandLocationUtils {
entities.add(TdApi.TextEntity(builder.lastIndex, SPEED_PREFIX.length, TdApi.TextEntityTypeBold()))
builder.append(String.format(Locale.US, "$SPEED_PREFIX%.1f m/s\n", location.speed))
}
if (location.bearing > 0) {
entities.add(TdApi.TextEntity(builder.lastIndex, BEARING_PREFIX.length, TdApi.TextEntityTypeBold()))
builder.append(String.format(Locale.US, "$BEARING_PREFIX%.1f$BEARING_SUFFIX\n", location.bearing))
}
if (location.hdop != 0.0 && location.speed == 0.0) {
entities.add(TdApi.TextEntity(builder.lastIndex, HDOP_PREFIX.length, TdApi.TextEntityTypeBold()))
builder.append(String.format(Locale.US, "$HDOP_PREFIX%d m\n", location.hdop.toInt()))
@ -375,6 +389,10 @@ object OsmandLocationUtils {
entities.add(TdApi.TextEntity(builder.lastIndex, SPEED_PREFIX.length, TdApi.TextEntityTypeBold()))
builder.append(String.format(Locale.US, "$SPEED_PREFIX%.1f m/s\n", location.speed))
}
if (location.bearing > 0) {
entities.add(TdApi.TextEntity(builder.lastIndex, BEARING_PREFIX.length, TdApi.TextEntityTypeBold()))
builder.append(String.format(Locale.US, "$BEARING_PREFIX%.1f$BEARING_SUFFIX\n", location.bearing))
}
if (location.hdop != 0.0 && location.speed == 0.0) {
entities.add(TdApi.TextEntity(builder.lastIndex, HDOP_PREFIX.length, TdApi.TextEntityTypeBold()))
builder.append(String.format(Locale.US, "$HDOP_PREFIX%d m\n", location.hdop.toInt()))

View file

@ -15,6 +15,7 @@ public class AMapPoint implements Parcelable {
public static final String POINT_SPEED_PARAM = "point_speed_param";
public static final String POINT_TYPE_ICON_NAME_PARAM = "point_type_icon_name_param";
public static final String POINT_STALE_LOC_PARAM = "point_stale_loc_param";
public static final String POINT_BEARING_PARAM = "point_bearing_param";
private String id;
private String shortName;

View file

@ -32,7 +32,7 @@ import java.util.Map;
public class AMapPointMenuController extends MenuController {
private static final float NO_SPEED = -1;
private static final float NO_VALUE = -1;
private static final int NO_ICON = 0;
private AMapPoint point;
@ -136,19 +136,40 @@ public class AMapPointMenuController extends MenuController {
public CharSequence getAdditionalInfoStr() {
MapActivity activity = getMapActivity();
if (activity != null) {
float speed = getPointSpeed();
if (speed != NO_SPEED) {
String formatted = OsmAndFormatter.getFormattedSpeed(speed, activity.getMyApplication());
return activity.getString(R.string.map_widget_speed) + ": " + formatted;
float bearing = getPointBearing();
if (bearing != NO_VALUE) {
return OsmAndFormatter.getFormattedAzimuth(bearing, activity.getMyApplication());
}
}
return super.getAdditionalInfoStr();
}
@NonNull
@Override
public String getSubtypeStr() {
MapActivity activity = getMapActivity();
if (activity != null) {
float speed = getPointSpeed();
if (speed != NO_VALUE) {
return OsmAndFormatter.getFormattedSpeed(speed, activity.getMyApplication());
}
}
return super.getSubtypeStr();
}
@Nullable
@Override
public Drawable getSubtypeIcon() {
if (getPointSpeed() != NO_VALUE) {
return getIcon(R.drawable.ic_action_speed_16);
}
return super.getSubtypeIcon();
}
@Override
public int getAdditionalInfoIconRes() {
if (getPointSpeed() != NO_SPEED) {
return R.drawable.ic_action_speed_16;
if (getPointBearing() != NO_VALUE) {
return R.drawable.ic_action_bearing;
}
return super.getAdditionalInfoIconRes();
}
@ -214,10 +235,22 @@ public class AMapPointMenuController extends MenuController {
try {
return Float.parseFloat(speed);
} catch (NumberFormatException e) {
return NO_SPEED;
return NO_VALUE;
}
}
return NO_SPEED;
return NO_VALUE;
}
private float getPointBearing() {
String bearing = point.getParams().get(AMapPoint.POINT_BEARING_PARAM);
if (!TextUtils.isEmpty(bearing)) {
try {
return Float.parseFloat(bearing);
} catch (NumberFormatException e) {
return NO_VALUE;
}
}
return NO_VALUE;
}
@Nullable