Merge branch 'master' of ssh://github.com/osmandapp/Osmand into Manage_profile_settings
BIN
OsmAnd-telegram/res/drawable-hdpi/ic_action_ruler_unit.png
Executable file
After Width: | Height: | Size: 336 B |
BIN
OsmAnd-telegram/res/drawable-hdpi/ic_action_speed.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
OsmAnd-telegram/res/drawable-hdpi/ic_world_globe_dark.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
OsmAnd-telegram/res/drawable-mdpi/ic_action_ruler_unit.png
Executable file
After Width: | Height: | Size: 186 B |
BIN
OsmAnd-telegram/res/drawable-mdpi/ic_action_speed.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
OsmAnd-telegram/res/drawable-mdpi/ic_world_globe_dark.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
OsmAnd-telegram/res/drawable-xhdpi/ic_action_ruler_unit.png
Executable file
After Width: | Height: | Size: 294 B |
BIN
OsmAnd-telegram/res/drawable-xhdpi/ic_action_speed.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
OsmAnd-telegram/res/drawable-xhdpi/ic_world_globe_dark.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
OsmAnd-telegram/res/drawable-xxhdpi/ic_action_ruler_unit.png
Executable file
After Width: | Height: | Size: 417 B |
BIN
OsmAnd-telegram/res/drawable-xxhdpi/ic_action_speed.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
OsmAnd-telegram/res/drawable-xxhdpi/ic_world_globe_dark.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
OsmAnd-telegram/res/drawable-xxxhdpi/ic_action_ruler_unit.png
Executable file
After Width: | Height: | Size: 681 B |
|
@ -75,6 +75,35 @@
|
|||
|
||||
<include layout="@layout/list_item_divider"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/card_bg_color"
|
||||
android:orientation="vertical">
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/list_header_height"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/content_padding_standard"
|
||||
android:text="@string/units_and_formats"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/list_item_title_text_size"
|
||||
app:typeface="@string/font_roboto_medium"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/units_and_formats_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/list_item_divider"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="time_zone_descr">Select time zone to show in your location messages.</string>
|
||||
<string name="time_zone">Time zone</string>
|
||||
<string name="units_and_formats">Units & formats</string>
|
||||
<string name="unit_of_length_descr">Change what distance is measured in.</string>
|
||||
<string name="unit_of_length">Units of length</string>
|
||||
<string name="unit_of_speed_system_descr">Define unit of speed.</string>
|
||||
<string name="unit_of_speed_system">Unit of speed</string>
|
||||
<string name="saved_messages">Saved messages</string>
|
||||
<string name="shared_string_end">End</string>
|
||||
<string name="shared_string_start">Start</string>
|
||||
|
|
|
@ -11,9 +11,7 @@ import net.osmand.PlatformUtil
|
|||
import net.osmand.telegram.helpers.OsmandAidlHelper
|
||||
import net.osmand.telegram.helpers.ShowLocationHelper
|
||||
import net.osmand.telegram.helpers.TelegramHelper
|
||||
import net.osmand.telegram.utils.AndroidUtils
|
||||
import net.osmand.telegram.utils.OsmandApiUtils
|
||||
import net.osmand.telegram.utils.OsmandFormatter
|
||||
import net.osmand.telegram.utils.*
|
||||
import net.osmand.telegram.utils.OsmandFormatter.MetricsConstants
|
||||
import net.osmand.telegram.utils.OsmandFormatter.SpeedConstants
|
||||
import net.osmand.telegram.utils.OsmandLocationUtils
|
||||
|
@ -72,6 +70,7 @@ private const val SHARING_MODE_KEY = "current_sharing_mode"
|
|||
|
||||
private const val METRICS_CONSTANTS_KEY = "metrics_constants"
|
||||
private const val SPEED_CONSTANTS_KEY = "speed_constants"
|
||||
private const val UTC_OFFSET_CONSTANTS_KEY = "utc_offset_constants"
|
||||
|
||||
private const val SEND_MY_LOC_INTERVAL_KEY = "send_my_loc_interval"
|
||||
private const val STALE_LOC_TIME_KEY = "stale_loc_time"
|
||||
|
@ -125,6 +124,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
|
||||
var metricsConstants = MetricsConstants.KILOMETERS_AND_METERS
|
||||
var speedConstants = SpeedConstants.KILOMETERS_PER_HOUR
|
||||
var utcOffset = DataConstants.UTC_FORMAT
|
||||
|
||||
var sendMyLocInterval = SEND_MY_LOC_VALUES_SEC[SEND_MY_LOC_DEFAULT_INDEX]
|
||||
var staleLocTime = STALE_LOC_VALUES_SEC[STALE_LOC_DEFAULT_INDEX]
|
||||
|
@ -142,6 +142,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
|
||||
val gpsAndLocPrefs = listOf(SendMyLocPref(), StaleLocPref(), LocHistoryPref(), ShareTypePref())
|
||||
val gpxLoggingPrefs = listOf(MinLocationDistance(), MinLocationAccuracy(), MinLocationSpeed())
|
||||
val unitsAndFormatsPrefs = listOf(UnitsOfSpeed(), UnitsOfLength(), UtcOffset())
|
||||
|
||||
var batteryOptimisationAsked = false
|
||||
|
||||
|
@ -606,6 +607,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
|
||||
edit.putString(METRICS_CONSTANTS_KEY, metricsConstants.name)
|
||||
edit.putString(SPEED_CONSTANTS_KEY, speedConstants.name)
|
||||
edit.putString(UTC_OFFSET_CONSTANTS_KEY, utcOffset)
|
||||
|
||||
edit.putLong(SEND_MY_LOC_INTERVAL_KEY, sendMyLocInterval)
|
||||
edit.putLong(STALE_LOC_TIME_KEY, staleLocTime)
|
||||
|
@ -668,6 +670,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
speedConstants = SpeedConstants.valueOf(
|
||||
prefs.getString(SPEED_CONSTANTS_KEY, SpeedConstants.KILOMETERS_PER_HOUR.name)
|
||||
)
|
||||
utcOffset = prefs.getString(UTC_OFFSET_CONSTANTS_KEY, DataConstants.UTC_FORMAT)
|
||||
|
||||
try {
|
||||
parseShareChatsInfo(JSONArray(prefs.getString(SHARE_CHATS_INFO_KEY, "")))
|
||||
|
@ -895,68 +898,64 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
inner class SendMyLocPref : NumericPref(
|
||||
inner class SendMyLocPref : ListPreference(
|
||||
R.drawable.ic_action_share_location,
|
||||
R.string.send_my_location,
|
||||
R.string.send_my_location_desc,
|
||||
SEND_MY_LOC_VALUES_SEC
|
||||
R.string.send_my_location_desc
|
||||
) {
|
||||
|
||||
override fun getCurrentValue() =
|
||||
OsmandFormatter.getFormattedDuration(app, sendMyLocInterval)
|
||||
|
||||
override fun setCurrentValue(index: Int) {
|
||||
sendMyLocInterval = values[index].toLong()
|
||||
sendMyLocInterval = SEND_MY_LOC_VALUES_SEC[index]
|
||||
app.updateSendLocationInterval()
|
||||
}
|
||||
|
||||
override fun getMenuItems() =
|
||||
values.map { OsmandFormatter.getFormattedDuration(app, it.toLong()) }
|
||||
SEND_MY_LOC_VALUES_SEC.map { OsmandFormatter.getFormattedDuration(app, it) }
|
||||
}
|
||||
|
||||
inner class StaleLocPref : NumericPref(
|
||||
inner class StaleLocPref : ListPreference(
|
||||
R.drawable.ic_action_time_span,
|
||||
R.string.stale_location,
|
||||
R.string.stale_location_desc,
|
||||
STALE_LOC_VALUES_SEC
|
||||
R.string.stale_location_desc
|
||||
) {
|
||||
|
||||
override fun getCurrentValue() =
|
||||
OsmandFormatter.getFormattedDuration(app, staleLocTime)
|
||||
|
||||
override fun setCurrentValue(index: Int) {
|
||||
staleLocTime = values[index].toLong()
|
||||
staleLocTime = STALE_LOC_VALUES_SEC[index]
|
||||
}
|
||||
|
||||
override fun getMenuItems() =
|
||||
values.map { OsmandFormatter.getFormattedDuration(app, it.toLong()) }
|
||||
STALE_LOC_VALUES_SEC.map { OsmandFormatter.getFormattedDuration(app, it) }
|
||||
}
|
||||
|
||||
inner class LocHistoryPref : NumericPref(
|
||||
inner class LocHistoryPref : ListPreference(
|
||||
R.drawable.ic_action_location_history,
|
||||
R.string.location_history,
|
||||
R.string.location_history_desc,
|
||||
LOC_HISTORY_VALUES_SEC
|
||||
R.string.location_history_desc
|
||||
) {
|
||||
|
||||
override fun getCurrentValue() =
|
||||
OsmandFormatter.getFormattedDuration(app, locHistoryTime)
|
||||
|
||||
override fun setCurrentValue(index: Int) {
|
||||
val value = values[index]
|
||||
locHistoryTime = value.toLong()
|
||||
app.telegramHelper.messageActiveTimeSec = value.toLong()
|
||||
val value = LOC_HISTORY_VALUES_SEC[index]
|
||||
locHistoryTime = value
|
||||
app.telegramHelper.messageActiveTimeSec = value
|
||||
}
|
||||
|
||||
override fun getMenuItems() =
|
||||
values.map { OsmandFormatter.getFormattedDuration(app, it.toLong()) }
|
||||
LOC_HISTORY_VALUES_SEC.map { OsmandFormatter.getFormattedDuration(app, it) }
|
||||
}
|
||||
|
||||
inner class ShareTypePref : NumericPref(
|
||||
inner class ShareTypePref : ListPreference(
|
||||
R.drawable.ic_action_location_history,
|
||||
R.string.send_location_as,
|
||||
R.string.send_location_as_descr,
|
||||
emptyList()
|
||||
R.string.send_location_as_descr
|
||||
) {
|
||||
|
||||
override fun getCurrentValue(): String {
|
||||
|
@ -988,20 +987,16 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
inner class MinLocationDistance : NumericPref(
|
||||
0, R.string.min_logging_distance,
|
||||
R.string.min_logging_distance_descr,
|
||||
MIN_LOCATION_DISTANCE
|
||||
) {
|
||||
inner class MinLocationDistance :
|
||||
ListPreference(0, R.string.min_logging_distance, R.string.min_logging_distance_descr) {
|
||||
|
||||
override fun getCurrentValue() = getFormattedValue(minLocationDistance)
|
||||
|
||||
override fun setCurrentValue(index: Int) {
|
||||
val value = values[index]
|
||||
minLocationDistance = value.toFloat()
|
||||
minLocationDistance = MIN_LOCATION_DISTANCE[index]
|
||||
}
|
||||
|
||||
override fun getMenuItems() = values.map { getFormattedValue(it.toFloat()) }
|
||||
override fun getMenuItems() = MIN_LOCATION_DISTANCE.map { getFormattedValue(it) }
|
||||
|
||||
private fun getFormattedValue(value: Float): String {
|
||||
return if (value == 0f) app.getString(R.string.shared_string_select)
|
||||
|
@ -1009,20 +1004,16 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
inner class MinLocationAccuracy : NumericPref(
|
||||
0, R.string.min_logging_accuracy,
|
||||
R.string.min_logging_accuracy_descr,
|
||||
MIN_LOCATION_ACCURACY
|
||||
) {
|
||||
inner class MinLocationAccuracy :
|
||||
ListPreference(0, R.string.min_logging_accuracy, R.string.min_logging_accuracy_descr) {
|
||||
|
||||
override fun getCurrentValue() = getFormattedValue(minLocationAccuracy)
|
||||
|
||||
override fun setCurrentValue(index: Int) {
|
||||
val value = values[index]
|
||||
minLocationAccuracy = value.toFloat()
|
||||
minLocationAccuracy = MIN_LOCATION_ACCURACY[index]
|
||||
}
|
||||
|
||||
override fun getMenuItems() = values.map { getFormattedValue(it.toFloat()) }
|
||||
override fun getMenuItems() = MIN_LOCATION_ACCURACY.map { getFormattedValue(it) }
|
||||
|
||||
private fun getFormattedValue(value: Float): String {
|
||||
return if (value == 0f) app.getString(R.string.shared_string_select)
|
||||
|
@ -1030,20 +1021,16 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
inner class MinLocationSpeed : NumericPref(
|
||||
0, R.string.min_logging_speed,
|
||||
R.string.min_logging_speed_descr,
|
||||
MIN_LOCATION_SPEED
|
||||
) {
|
||||
inner class MinLocationSpeed :
|
||||
ListPreference(0, R.string.min_logging_speed, R.string.min_logging_speed_descr) {
|
||||
|
||||
override fun getCurrentValue() = getFormattedValue(minLocationSpeed)
|
||||
|
||||
override fun setCurrentValue(index: Int) {
|
||||
val value = values[index]
|
||||
minLocationSpeed = value.toFloat()
|
||||
minLocationSpeed = MIN_LOCATION_SPEED[index]
|
||||
}
|
||||
|
||||
override fun getMenuItems() = values.map { getFormattedValue(it.toFloat()) }
|
||||
override fun getMenuItems() = MIN_LOCATION_SPEED.map { getFormattedValue(it) }
|
||||
|
||||
private fun getFormattedValue(value: Float): String {
|
||||
return when (value) {
|
||||
|
@ -1054,11 +1041,54 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
abstract inner class NumericPref(
|
||||
inner class UnitsOfSpeed : ListPreference(
|
||||
R.drawable.ic_action_speed,
|
||||
R.string.unit_of_speed_system,
|
||||
R.string.unit_of_speed_system_descr
|
||||
) {
|
||||
|
||||
override fun getCurrentValue() = speedConstants.toShortString(app)
|
||||
|
||||
override fun setCurrentValue(index: Int) {
|
||||
speedConstants = SpeedConstants.values()[index]
|
||||
}
|
||||
|
||||
override fun getMenuItems() = SpeedConstants.values().map { it.toShortString(app) }
|
||||
}
|
||||
|
||||
inner class UnitsOfLength : ListPreference(
|
||||
R.drawable.ic_action_ruler_unit, R.string.unit_of_length,
|
||||
R.string.unit_of_length_descr
|
||||
) {
|
||||
|
||||
override fun getCurrentValue() = metricsConstants.toHumanString(app)
|
||||
|
||||
override fun setCurrentValue(index: Int) {
|
||||
metricsConstants = MetricsConstants.values()[index]
|
||||
}
|
||||
|
||||
override fun getMenuItems() = MetricsConstants.values().map { it.toHumanString(app) }
|
||||
}
|
||||
|
||||
inner class UtcOffset : ListPreference(
|
||||
R.drawable.ic_world_globe_dark, R.string.time_zone,
|
||||
R.string.time_zone_descr
|
||||
) {
|
||||
private val formattedUtcOffsets = DataConstants.utcOffsets.keys.toList()
|
||||
|
||||
override fun getCurrentValue() = utcOffset
|
||||
|
||||
override fun setCurrentValue(index: Int) {
|
||||
utcOffset = formattedUtcOffsets[index]
|
||||
}
|
||||
|
||||
override fun getMenuItems() = formattedUtcOffsets
|
||||
}
|
||||
|
||||
abstract inner class ListPreference(
|
||||
@DrawableRes val iconId: Int,
|
||||
@StringRes val titleId: Int,
|
||||
@StringRes val descriptionId: Int,
|
||||
val values: List<Number>
|
||||
@StringRes val descriptionId: Int
|
||||
) {
|
||||
|
||||
abstract fun getCurrentValue(): String
|
||||
|
|
|
@ -7,6 +7,7 @@ import net.osmand.telegram.helpers.LocationMessages.BufferMessage
|
|||
import net.osmand.telegram.notifications.TelegramNotification.NotificationType
|
||||
import net.osmand.telegram.utils.AndroidNetworkUtils
|
||||
import net.osmand.telegram.utils.BASE_URL
|
||||
import net.osmand.telegram.utils.OsmandLocationUtils
|
||||
import net.osmand.util.MapUtils
|
||||
import org.drinkless.td.libcore.telegram.TdApi
|
||||
import org.json.JSONException
|
||||
|
@ -14,8 +15,6 @@ import org.json.JSONObject
|
|||
|
||||
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) {
|
||||
|
@ -142,7 +141,8 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
if (it.deviceName.isEmpty()) {
|
||||
if (!shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) {
|
||||
lastLocationSentTime = System.currentTimeMillis()
|
||||
app.telegramHelper.editTextLocation(shareInfo, it)
|
||||
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, it, app)
|
||||
app.telegramHelper.editTextLocation(shareInfo, content)
|
||||
app.locationMessages.removeBufferedMessage(it)
|
||||
}
|
||||
} else {
|
||||
|
@ -263,7 +263,8 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
sendLocationToBot(message, shareInfo, SHARE_TYPE_TEXT)
|
||||
} else {
|
||||
lastLocationSentTime = System.currentTimeMillis()
|
||||
app.telegramHelper.sendNewTextLocation(shareInfo, message)
|
||||
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, message, app)
|
||||
app.telegramHelper.sendNewTextLocation(shareInfo, content)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -276,7 +277,8 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
} else {
|
||||
if (shareInfo.pendingTdLibText < MAX_MESSAGES_IN_TDLIB_PER_CHAT) {
|
||||
lastLocationSentTime = System.currentTimeMillis()
|
||||
app.telegramHelper.editTextLocation(shareInfo, message)
|
||||
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, message, app)
|
||||
app.telegramHelper.editTextLocation(shareInfo, content)
|
||||
} else {
|
||||
app.locationMessages.addBufferedMessage(message)
|
||||
}
|
||||
|
|
|
@ -926,9 +926,8 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
fun sendNewTextLocation(shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.BufferMessage) {
|
||||
fun sendNewTextLocation(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageText) {
|
||||
shareInfo.updateTextMessageId = 1
|
||||
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, location)
|
||||
if (!shareInfo.pendingTextMessage) {
|
||||
shareInfo.pendingTextMessage = true
|
||||
shareInfo.pendingTdLibText++
|
||||
|
@ -940,8 +939,7 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
|
||||
fun editTextLocation(shareInfo: TelegramSettings.ShareChatInfo, location: LocationMessages.BufferMessage) {
|
||||
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, location)
|
||||
fun editTextLocation(shareInfo: TelegramSettings.ShareChatInfo, content: TdApi.InputMessageText) {
|
||||
if (shareInfo.currentTextMessageId!=-1L) {
|
||||
shareInfo.pendingTdLibText++
|
||||
shareInfo.lastSendTextMessageTime = (System.currentTimeMillis() / 1000).toInt()
|
||||
|
|
|
@ -17,7 +17,7 @@ import android.view.ViewGroup
|
|||
import android.widget.*
|
||||
import net.osmand.telegram.R
|
||||
import net.osmand.telegram.TelegramSettings
|
||||
import net.osmand.telegram.TelegramSettings.NumericPref
|
||||
import net.osmand.telegram.TelegramSettings.ListPreference
|
||||
import net.osmand.telegram.helpers.TelegramHelper.Companion.OSMAND_BOT_USERNAME
|
||||
import net.osmand.telegram.helpers.TelegramUiHelper
|
||||
import net.osmand.telegram.utils.AndroidUtils
|
||||
|
@ -50,7 +50,7 @@ class SettingsDialogFragment : BaseDialogFragment() {
|
|||
}
|
||||
var container = mainView.findViewById<ViewGroup>(R.id.gps_and_loc_container)
|
||||
settings.gpsAndLocPrefs.forEach {
|
||||
createNumericPref(inflater, container, it)
|
||||
createListPref(inflater, container, it)
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 26) {
|
||||
|
@ -66,6 +66,11 @@ class SettingsDialogFragment : BaseDialogFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
container = mainView.findViewById<ViewGroup>(R.id.units_and_formats_container)
|
||||
settings.unitsAndFormatsPrefs.forEach {
|
||||
createListPref(inflater, container, it)
|
||||
}
|
||||
|
||||
container = mainView.findViewById<ViewGroup>(R.id.gps_points_container)
|
||||
inflater.inflate(R.layout.item_with_descr_and_right_switch, container, false).apply {
|
||||
findViewById<ImageView>(R.id.icon).setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_connect))
|
||||
|
@ -139,7 +144,7 @@ class SettingsDialogFragment : BaseDialogFragment() {
|
|||
|
||||
container = mainView.findViewById<ViewGroup>(R.id.gpx_settings_container)
|
||||
settings.gpxLoggingPrefs.forEach {
|
||||
createNumericPref(inflater, container, it)
|
||||
createListPref(inflater, container, it)
|
||||
}
|
||||
|
||||
container = mainView.findViewById(R.id.osmand_connect_container)
|
||||
|
@ -243,7 +248,7 @@ class SettingsDialogFragment : BaseDialogFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun createNumericPref(inflater: LayoutInflater, container: ViewGroup, pref: NumericPref) {
|
||||
private fun createListPref(inflater: LayoutInflater, container: ViewGroup, pref: ListPreference) {
|
||||
inflater.inflate(R.layout.item_with_desc_and_right_value, container, false).apply {
|
||||
findViewById<ImageView>(R.id.icon).apply {
|
||||
if (pref.iconId != 0) {
|
||||
|
@ -284,14 +289,14 @@ class SettingsDialogFragment : BaseDialogFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun showPopupMenu(pref: NumericPref, valueView: TextView) {
|
||||
private fun showPopupMenu(pref: ListPreference, valueView: TextView) {
|
||||
val menuList = pref.getMenuItems()
|
||||
val ctx = valueView.context
|
||||
ListPopupWindow(ctx).apply {
|
||||
isModal = true
|
||||
anchorView = valueView
|
||||
setContentWidth(AndroidUtils.getPopupMenuWidth(ctx, menuList))
|
||||
height = if (menuList.size < 6) {
|
||||
height = if (menuList.size <= 6) {
|
||||
ListPopupWindow.WRAP_CONTENT
|
||||
} else {
|
||||
AndroidUtils.getPopupMenuHeight(ctx)
|
||||
|
|
|
@ -2,6 +2,8 @@ package net.osmand.telegram.utils
|
|||
|
||||
object DataConstants {
|
||||
|
||||
const val UTC_FORMAT = "UTC"
|
||||
|
||||
val countryPhoneCodes = mapOf("AB" to "+7840,+7940,+99544", "AF" to "+93", "AX" to "+35818",
|
||||
"AL" to "+355","DZ" to "+213", "AS" to "+1684", "AD" to "+376", "AO" to "+244","AI" to "+1264",
|
||||
"AG" to "+1268", "AR" to "+54", "AM" to "+374","AW" to "+297", "SH" to "+247", "AU" to "+61",
|
||||
|
@ -44,4 +46,46 @@ object DataConstants {
|
|||
"TM" to "+993", "TC" to "+1649", "TV" to "+688", "UG" to "+256","UA" to "+380", "AE" to "+971",
|
||||
"UK" to "+44", "US" to "+1","UY" to "+598", "VI" to "+1340", "UZ" to "+998", "VU" to "+678", "VE" to "+58",
|
||||
"VA" to "+3906698,+379", "VN" to "+84", "WF" to "+681","YE" to "+967", "ZM" to "+260", "ZW" to "+263")
|
||||
|
||||
val utcOffsets = mapOf(
|
||||
"$UTC_FORMAT-12" to -12f,
|
||||
"$UTC_FORMAT-11" to -11f,
|
||||
"$UTC_FORMAT-10" to -10f,
|
||||
"$UTC_FORMAT-09:30" to -9.5f,
|
||||
"$UTC_FORMAT-9" to -9f,
|
||||
"$UTC_FORMAT-8" to -8f,
|
||||
"$UTC_FORMAT-7" to -7f,
|
||||
"$UTC_FORMAT-6" to -6f,
|
||||
"$UTC_FORMAT-5" to -5f,
|
||||
"$UTC_FORMAT-4" to -4f,
|
||||
"$UTC_FORMAT-03:30" to -3.5f,
|
||||
"$UTC_FORMAT-3" to -3f,
|
||||
"$UTC_FORMAT-2" to -2f,
|
||||
"$UTC_FORMAT-1" to -1f,
|
||||
UTC_FORMAT to 0f,
|
||||
"$UTC_FORMAT+1" to 1f,
|
||||
"$UTC_FORMAT+2" to 2f,
|
||||
"$UTC_FORMAT+3" to 3f,
|
||||
"$UTC_FORMAT+03:30" to 3.5f,
|
||||
"$UTC_FORMAT+4" to 4f,
|
||||
"$UTC_FORMAT+04:30" to 4.5f,
|
||||
"$UTC_FORMAT+5" to 5f,
|
||||
"$UTC_FORMAT+05:30" to 5.5f,
|
||||
"$UTC_FORMAT+05:45" to 5.75f,
|
||||
"$UTC_FORMAT+6" to 6f,
|
||||
"$UTC_FORMAT+06:30" to 6.5f,
|
||||
"$UTC_FORMAT+7" to 7f,
|
||||
"$UTC_FORMAT+8" to 8f,
|
||||
"$UTC_FORMAT+08:45" to 8.75f,
|
||||
"$UTC_FORMAT+9" to 9f,
|
||||
"$UTC_FORMAT+09:30" to 9.5f,
|
||||
"$UTC_FORMAT+10" to 10f,
|
||||
"$UTC_FORMAT+10:30" to 10.5f,
|
||||
"$UTC_FORMAT+11" to 11f,
|
||||
"$UTC_FORMAT+12" to 12f,
|
||||
"$UTC_FORMAT+12:45" to 12.75f,
|
||||
"$UTC_FORMAT+13" to 13f,
|
||||
"$UTC_FORMAT+13:45" to 13.75f,
|
||||
"$UTC_FORMAT+14" to 14f
|
||||
)
|
||||
}
|
|
@ -17,6 +17,14 @@ object OsmandFormatter {
|
|||
|
||||
val YARDS_IN_ONE_METER = 1.0936f
|
||||
val FEET_IN_ONE_METER = YARDS_IN_ONE_METER * 3f
|
||||
|
||||
val FORMAT_METERS_KEY = "m"
|
||||
val FORMAT_FEET_KEY = "ft"
|
||||
val FORMAT_YARDS_KEY = "yd"
|
||||
val FORMAT_KILOMETERS_KEY = "km"
|
||||
val FORMAT_NAUTICALMILES_KEY = "nmi"
|
||||
val FORMAT_MILES_KEY = "mi"
|
||||
|
||||
private val fixed2 = DecimalFormat("0.00")
|
||||
private val fixed1 = DecimalFormat("0.0")
|
||||
|
||||
|
@ -166,118 +174,94 @@ object OsmandFormatter {
|
|||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun getFormattedDistance(meters: Float, ctx: TelegramApplication, forceTrailingZeros: Boolean = true): String {
|
||||
fun getFormattedDistance(meters: Float, ctx: TelegramApplication, forceTrailingZeros: Boolean = true, useLocalizedString: Boolean = true): String {
|
||||
val format1 = if (forceTrailingZeros) "{0,number,0.0} " else "{0,number,0.#} "
|
||||
val format2 = if (forceTrailingZeros) "{0,number,0.00} " else "{0,number,0.##} "
|
||||
|
||||
val mc = ctx.settings.metricsConstants
|
||||
val mainUnitStr: Int
|
||||
val mainUnitStr: String
|
||||
val mainUnitInMeters: Float
|
||||
if (mc == MetricsConstants.KILOMETERS_AND_METERS) {
|
||||
mainUnitStr = R.string.km
|
||||
mainUnitInMeters = METERS_IN_KILOMETER
|
||||
} else if (mc == MetricsConstants.NAUTICAL_MILES) {
|
||||
mainUnitStr = R.string.nm
|
||||
mainUnitInMeters = METERS_IN_ONE_NAUTICALMILE
|
||||
} else {
|
||||
mainUnitStr = R.string.mile
|
||||
mainUnitInMeters = METERS_IN_ONE_MILE
|
||||
when (mc) {
|
||||
MetricsConstants.KILOMETERS_AND_METERS -> {
|
||||
mainUnitStr = if (useLocalizedString) ctx.getString(R.string.km) else FORMAT_KILOMETERS_KEY
|
||||
mainUnitInMeters = METERS_IN_KILOMETER
|
||||
}
|
||||
MetricsConstants.NAUTICAL_MILES -> {
|
||||
mainUnitStr = if (useLocalizedString) ctx.getString(R.string.nm) else FORMAT_NAUTICALMILES_KEY
|
||||
mainUnitInMeters = METERS_IN_ONE_NAUTICALMILE
|
||||
}
|
||||
else -> {
|
||||
mainUnitStr = if (useLocalizedString) ctx.getString(R.string.mile) else FORMAT_MILES_KEY
|
||||
mainUnitInMeters = METERS_IN_ONE_MILE
|
||||
}
|
||||
}
|
||||
|
||||
if (meters >= 100 * mainUnitInMeters) {
|
||||
return (meters / mainUnitInMeters + 0.5).toInt().toString() + " " + ctx.getString(mainUnitStr) //$NON-NLS-1$
|
||||
return (meters / mainUnitInMeters + 0.5).toInt().toString() + " " + mainUnitStr //$NON-NLS-1$
|
||||
} else if (meters > 9.99f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format1 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
return MessageFormat.format(format1 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
} else if (meters > 0.999f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format2 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
return MessageFormat.format(format2 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.MILES_AND_FEET && meters > 0.249f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format2 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
return MessageFormat.format(format2 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.MILES_AND_METERS && meters > 0.249f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format2 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
return MessageFormat.format(format2 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.MILES_AND_YARDS && meters > 0.249f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format2 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
return MessageFormat.format(format2 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.NAUTICAL_MILES && meters > 0.99f * mainUnitInMeters) {
|
||||
return MessageFormat.format(format2 + ctx.getString(mainUnitStr), meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
return MessageFormat.format(format2 + mainUnitStr, meters / mainUnitInMeters).replace('\n', ' ') //$NON-NLS-1$
|
||||
} else {
|
||||
if (mc == MetricsConstants.KILOMETERS_AND_METERS || mc == MetricsConstants.MILES_AND_METERS) {
|
||||
return (meters + 0.5).toInt().toString() + " " + ctx.getString(R.string.m) //$NON-NLS-1$
|
||||
return (meters + 0.5).toInt().toString() + if (useLocalizedString) " " + ctx.getString(R.string.m) else " $FORMAT_METERS_KEY" //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.MILES_AND_FEET) {
|
||||
val feet = (meters * FEET_IN_ONE_METER + 0.5).toInt()
|
||||
return feet.toString() + " " + ctx.getString(R.string.foot) //$NON-NLS-1$
|
||||
return feet.toString() + if (useLocalizedString) " " + ctx.getString(R.string.foot) else " $FORMAT_FEET_KEY" //$NON-NLS-1$
|
||||
} else if (mc == MetricsConstants.MILES_AND_YARDS) {
|
||||
val yards = (meters * YARDS_IN_ONE_METER + 0.5).toInt()
|
||||
return yards.toString() + " " + ctx.getString(R.string.yard) //$NON-NLS-1$
|
||||
return yards.toString() + if (useLocalizedString) " " + ctx.getString(R.string.yard) else " $FORMAT_YARDS_KEY" //$NON-NLS-1$
|
||||
}
|
||||
return (meters + 0.5).toInt().toString() + " " + ctx.getString(R.string.m) //$NON-NLS-1$
|
||||
return (meters + 0.5).toInt().toString() + if (useLocalizedString) " " + ctx.getString(R.string.m) else " $FORMAT_METERS_KEY" //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
fun getFormattedAlt(alt: Double, ctx: TelegramApplication): String {
|
||||
fun getFormattedAlt(alt: Double, ctx: TelegramApplication, useLocalizedString: Boolean = true): String {
|
||||
val mc = ctx.settings.metricsConstants
|
||||
return if (mc == MetricsConstants.KILOMETERS_AND_METERS) {
|
||||
(alt + 0.5).toInt().toString() + " " + ctx.getString(R.string.m)
|
||||
val useFeet = mc == MetricsConstants.MILES_AND_FEET || mc == MetricsConstants.MILES_AND_YARDS
|
||||
return if (!useFeet) {
|
||||
(alt + 0.5).toInt().toString() + if (useLocalizedString) " " + ctx.getString(R.string.m) else " $FORMAT_METERS_KEY"
|
||||
} else {
|
||||
(alt * FEET_IN_ONE_METER + 0.5).toInt().toString() + " " + ctx.getString(R.string.foot)
|
||||
(alt * FEET_IN_ONE_METER + 0.5).toInt().toString() + if (useLocalizedString) " " + ctx.getString(R.string.foot) else " $FORMAT_FEET_KEY"
|
||||
}
|
||||
}
|
||||
|
||||
fun getFormattedSpeed(metersperseconds: Float, ctx: TelegramApplication): String {
|
||||
fun getFormattedSpeed(metersPerSeconds: Float, ctx: TelegramApplication, useLocalizedString: Boolean = true): String {
|
||||
val mc = ctx.settings.speedConstants
|
||||
val kmh = metersperseconds * 3.6f
|
||||
if (mc == SpeedConstants.KILOMETERS_PER_HOUR) {
|
||||
val kmh = metersPerSeconds * 3.6f
|
||||
val convertedSpeed: Float = when (mc) {
|
||||
SpeedConstants.KILOMETERS_PER_HOUR -> kmh
|
||||
SpeedConstants.MILES_PER_HOUR -> kmh * METERS_IN_KILOMETER / METERS_IN_ONE_MILE
|
||||
SpeedConstants.NAUTICALMILES_PER_HOUR -> kmh * METERS_IN_KILOMETER / METERS_IN_ONE_NAUTICALMILE
|
||||
SpeedConstants.MINUTES_PER_KILOMETER -> {
|
||||
if (metersPerSeconds < 0.111111111) {
|
||||
return "-" + if (useLocalizedString) mc.toShortString(ctx) else mc.getDefaultString()
|
||||
}
|
||||
METERS_IN_KILOMETER / (metersPerSeconds * 60)
|
||||
}
|
||||
SpeedConstants.MINUTES_PER_MILE -> {
|
||||
if (metersPerSeconds < 0.111111111) {
|
||||
return "-" + if (useLocalizedString) mc.toShortString(ctx) else mc.getDefaultString()
|
||||
}
|
||||
METERS_IN_ONE_MILE / (metersPerSeconds * 60)
|
||||
}
|
||||
else -> metersPerSeconds /*if (mc == SpeedConstants.METERS_PER_SECOND) */
|
||||
}
|
||||
|
||||
return if (convertedSpeed >= mc.speedThreshold) {
|
||||
// e.g. car case and for high-speeds: Display rounded to 1 km/h (5% precision at 20 km/h)
|
||||
if (kmh >= 20) {
|
||||
return Math.round(kmh).toString() + " " + mc.toShortString(ctx)
|
||||
}
|
||||
"${Math.round(convertedSpeed)} " + if (useLocalizedString) mc.toShortString(ctx) else mc.getDefaultString()
|
||||
} else {
|
||||
// for smaller values display 1 decimal digit x.y km/h, (0.5% precision at 20 km/h)
|
||||
val kmh10 = Math.round(kmh * 10f)
|
||||
return (kmh10 / 10f).toString() + " " + mc.toShortString(ctx)
|
||||
} else if (mc == SpeedConstants.MILES_PER_HOUR) {
|
||||
val mph = kmh * METERS_IN_KILOMETER / METERS_IN_ONE_MILE
|
||||
if (mph >= 20) {
|
||||
return Math.round(mph).toString() + " " + mc.toShortString(ctx)
|
||||
} else {
|
||||
val mph10 = Math.round(mph * 10f)
|
||||
return (mph10 / 10f).toString() + " " + mc.toShortString(ctx)
|
||||
}
|
||||
} else if (mc == SpeedConstants.NAUTICALMILES_PER_HOUR) {
|
||||
val mph = kmh * METERS_IN_KILOMETER / METERS_IN_ONE_NAUTICALMILE
|
||||
if (mph >= 20) {
|
||||
return Math.round(mph).toString() + " " + mc.toShortString(ctx)
|
||||
} else {
|
||||
val mph10 = Math.round(mph * 10f)
|
||||
return (mph10 / 10f).toString() + " " + mc.toShortString(ctx)
|
||||
}
|
||||
} else if (mc == SpeedConstants.MINUTES_PER_KILOMETER) {
|
||||
if (metersperseconds < 0.111111111) {
|
||||
return "-" + mc.toShortString(ctx)
|
||||
}
|
||||
val minperkm = METERS_IN_KILOMETER / (metersperseconds * 60)
|
||||
if (minperkm >= 10) {
|
||||
return Math.round(minperkm).toString() + " " + mc.toShortString(ctx)
|
||||
} else {
|
||||
val mph10 = Math.round(minperkm * 10f)
|
||||
return (mph10 / 10f).toString() + " " + mc.toShortString(ctx)
|
||||
}
|
||||
} else if (mc == SpeedConstants.MINUTES_PER_MILE) {
|
||||
if (metersperseconds < 0.111111111) {
|
||||
return "-" + mc.toShortString(ctx)
|
||||
}
|
||||
val minperm = METERS_IN_ONE_MILE / (metersperseconds * 60)
|
||||
if (minperm >= 10) {
|
||||
return Math.round(minperm).toString() + " " + mc.toShortString(ctx)
|
||||
} else {
|
||||
val mph10 = Math.round(minperm * 10f)
|
||||
return (mph10 / 10f).toString() + " " + mc.toShortString(ctx)
|
||||
}
|
||||
} else
|
||||
/*if (mc == SpeedConstants.METERS_PER_SECOND) */ {
|
||||
if (metersperseconds >= 10) {
|
||||
return Math.round(metersperseconds).toString() + " " + SpeedConstants.METERS_PER_SECOND.toShortString(ctx)
|
||||
}
|
||||
// for smaller values display 1 decimal digit x.y km/h, (0.5% precision at 20 km/h)
|
||||
val kmh10 = Math.round(metersperseconds * 10f)
|
||||
return (kmh10 / 10f).toString() + " " + SpeedConstants.METERS_PER_SECOND.toShortString(ctx)
|
||||
"${Math.round(convertedSpeed * 10f) / 10f} " + if (useLocalizedString) mc.toShortString(ctx) else mc.getDefaultString()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,20 +295,27 @@ object OsmandFormatter {
|
|||
}
|
||||
}
|
||||
|
||||
enum class SpeedConstants private constructor(private val key: Int, private val descr: Int) {
|
||||
KILOMETERS_PER_HOUR(R.string.km_h, R.string.si_kmh),
|
||||
MILES_PER_HOUR(R.string.mile_per_hour, R.string.si_mph),
|
||||
METERS_PER_SECOND(R.string.m_s, R.string.si_m_s),
|
||||
MINUTES_PER_MILE(R.string.min_mile, R.string.si_min_m),
|
||||
MINUTES_PER_KILOMETER(R.string.min_km, R.string.si_min_km),
|
||||
NAUTICALMILES_PER_HOUR(R.string.nm_h, R.string.si_nm_h);
|
||||
enum class SpeedConstants private constructor(
|
||||
private val key: String,
|
||||
private val title: Int,
|
||||
private val descr: Int,
|
||||
val speedThreshold: Int
|
||||
) {
|
||||
KILOMETERS_PER_HOUR("km/h", R.string.km_h, R.string.si_kmh, 20),
|
||||
MILES_PER_HOUR("mph", R.string.mile_per_hour, R.string.si_mph, 20),
|
||||
METERS_PER_SECOND("m/s", R.string.m_s, R.string.si_m_s, 10),
|
||||
MINUTES_PER_MILE("min/m", R.string.min_mile, R.string.si_min_m, 10),
|
||||
MINUTES_PER_KILOMETER("min/km", R.string.min_km, R.string.si_min_km, 10),
|
||||
NAUTICALMILES_PER_HOUR("nmi/h", R.string.nm_h, R.string.si_nm_h, 20);
|
||||
|
||||
fun toHumanString(ctx: Context): String {
|
||||
return ctx.getString(descr)
|
||||
}
|
||||
|
||||
fun toShortString(ctx: Context): String {
|
||||
return ctx.getString(key)
|
||||
return ctx.getString(title)
|
||||
}
|
||||
|
||||
fun getDefaultString() = key
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,9 @@ object OsmandLocationUtils {
|
|||
const val SECONDS_AGO_SUFFIX = " seconds ago"
|
||||
const val MINUTES_AGO_SUFFIX = " minutes ago"
|
||||
const val HOURS_AGO_SUFFIX = " hours ago"
|
||||
const val UTC_FORMAT_SUFFIX = " UTC"
|
||||
const val UTC_FORMAT_PATTERN = "yyyy-MM-dd HH:mm:ss"
|
||||
|
||||
const val ONE_HOUR_TIME_MS = 60 * 60 * 1000 // 1 hour
|
||||
|
||||
val UTC_DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd", Locale.US).apply {
|
||||
timeZone = TimeZone.getTimeZone("UTC")
|
||||
|
@ -163,9 +165,17 @@ object OsmandLocationUtils {
|
|||
return String.format(Locale.US, "%.5f, %.5f", sig.lat, sig.lon)
|
||||
}
|
||||
|
||||
fun formatFullTime(ti: Long): String {
|
||||
fun formatFullTime(ti: Long, app: TelegramApplication): String {
|
||||
val dt = Date(ti)
|
||||
return UTC_DATE_FORMAT.format(dt) + " " + UTC_TIME_FORMAT.format(dt) + " UTC"
|
||||
val offsetKey = app.settings.utcOffset
|
||||
val utcOffset = DataConstants.utcOffsets[offsetKey] ?: 0f
|
||||
val simpleDateFormat = SimpleDateFormat(UTC_FORMAT_PATTERN, Locale.US)
|
||||
|
||||
simpleDateFormat.timeZone = TimeZone.getTimeZone(DataConstants.UTC_FORMAT).apply {
|
||||
rawOffset = (utcOffset * ONE_HOUR_TIME_MS).toInt()
|
||||
}
|
||||
|
||||
return "${simpleDateFormat.format(dt)} $offsetKey"
|
||||
}
|
||||
|
||||
fun parseOsmAndBotLocationContent(oldContent: MessageOsmAndBotLocation, content: TdApi.MessageContent): MessageOsmAndBotLocation {
|
||||
|
@ -242,21 +252,11 @@ object OsmandLocationUtils {
|
|||
}
|
||||
s.startsWith(ALTITUDE_PREFIX) -> {
|
||||
val altStr = s.removePrefix(ALTITUDE_PREFIX)
|
||||
try {
|
||||
val alt = altStr.split(" ").first()
|
||||
res.altitude = alt.toDouble()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
res.altitude = parseDistance(altStr)
|
||||
}
|
||||
s.startsWith(SPEED_PREFIX) -> {
|
||||
val speedStr = s.removePrefix(SPEED_PREFIX)
|
||||
try {
|
||||
val speed = speedStr.split(" ").first()
|
||||
res.speed = speed.toDouble()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
res.speed = parseSpeed(speedStr)
|
||||
}
|
||||
s.startsWith(BEARING_PREFIX) -> {
|
||||
val bearingStr = s.removePrefix(BEARING_PREFIX)
|
||||
|
@ -269,12 +269,7 @@ object OsmandLocationUtils {
|
|||
}
|
||||
s.startsWith(HDOP_PREFIX) -> {
|
||||
val hdopStr = s.removePrefix(HDOP_PREFIX)
|
||||
try {
|
||||
val hdop = hdopStr.split(" ").first()
|
||||
res.hdop = hdop.toDouble()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
res.hdop = parseDistance(hdopStr)
|
||||
}
|
||||
s.startsWith(UPDATED_PREFIX) -> {
|
||||
if (res.lastUpdated == 0) {
|
||||
|
@ -314,13 +309,19 @@ object OsmandLocationUtils {
|
|||
val hours = locStr.toLong()
|
||||
return (System.currentTimeMillis() - hours * 60 * 60 * 1000)
|
||||
}
|
||||
timeS.endsWith(UTC_FORMAT_SUFFIX) -> {
|
||||
val locStr = timeS.removeSuffix(UTC_FORMAT_SUFFIX)
|
||||
val (latS, lonS) = locStr.split(" ")
|
||||
val date = UTC_DATE_FORMAT.parse(latS)
|
||||
val time = UTC_TIME_FORMAT.parse(lonS)
|
||||
val res = date.time + time.time
|
||||
return res
|
||||
timeS.contains(DataConstants.UTC_FORMAT) -> {
|
||||
val utcIndex = timeS.indexOf(DataConstants.UTC_FORMAT)
|
||||
if (utcIndex != -1) {
|
||||
val locStr = timeS.substring(0, utcIndex)
|
||||
val utcOffset = timeS.substring(utcIndex)
|
||||
val utcTimeOffset = DataConstants.utcOffsets[utcOffset] ?: 0f
|
||||
val simpleDateFormat = SimpleDateFormat(UTC_FORMAT_PATTERN, Locale.US)
|
||||
simpleDateFormat.timeZone = TimeZone.getTimeZone(DataConstants.UTC_FORMAT).apply {
|
||||
rawOffset = (utcTimeOffset * ONE_HOUR_TIME_MS).toInt()
|
||||
}
|
||||
val res = simpleDateFormat.parse(locStr)
|
||||
return res.time
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -329,50 +330,48 @@ object OsmandLocationUtils {
|
|||
return 0
|
||||
}
|
||||
|
||||
fun getTextMessageContent(updateId: Int, location: LocationMessage): TdApi.InputMessageText {
|
||||
val entities = mutableListOf<TdApi.TextEntity>()
|
||||
val builder = StringBuilder()
|
||||
val locationMessage = formatLocation(location)
|
||||
|
||||
val firstSpace = USER_TEXT_LOCATION_TITLE.indexOf(' ')
|
||||
val secondSpace = USER_TEXT_LOCATION_TITLE.indexOf(' ', firstSpace + 1)
|
||||
entities.add(TdApi.TextEntity(builder.length + firstSpace + 1, secondSpace - firstSpace, TdApi.TextEntityTypeTextUrl(SHARING_LINK)))
|
||||
builder.append("$USER_TEXT_LOCATION_TITLE\n")
|
||||
|
||||
entities.add(TdApi.TextEntity(builder.lastIndex, LOCATION_PREFIX.length, TdApi.TextEntityTypeBold()))
|
||||
builder.append(LOCATION_PREFIX)
|
||||
|
||||
entities.add(TdApi.TextEntity(builder.length, locationMessage.length,
|
||||
TdApi.TextEntityTypeTextUrl("$BASE_SHARING_URL?lat=${location.lat}&lon=${location.lon}")))
|
||||
builder.append("$locationMessage\n")
|
||||
|
||||
if (location.altitude != 0.0) {
|
||||
entities.add(TdApi.TextEntity(builder.lastIndex, ALTITUDE_PREFIX.length, TdApi.TextEntityTypeBold()))
|
||||
builder.append(String.format(Locale.US, "$ALTITUDE_PREFIX%.1f m\n", location.altitude))
|
||||
fun parseSpeed(speedS: String): Double {
|
||||
try {
|
||||
if (!speedS.contains(" ")) {
|
||||
return 0.0
|
||||
}
|
||||
val speedSplit = speedS.split(" ")
|
||||
val speedVal = speedSplit.first().toDouble()
|
||||
val speedFormat = OsmandFormatter.SpeedConstants.values().firstOrNull { it.getDefaultString() == speedSplit.last() }
|
||||
return when (speedFormat) {
|
||||
OsmandFormatter.SpeedConstants.KILOMETERS_PER_HOUR -> speedVal / 3.6f
|
||||
OsmandFormatter.SpeedConstants.MILES_PER_HOUR -> (speedVal / 3.6f) / (OsmandFormatter.METERS_IN_KILOMETER / OsmandFormatter.METERS_IN_ONE_MILE)
|
||||
OsmandFormatter.SpeedConstants.NAUTICALMILES_PER_HOUR -> (speedVal / 3.6f) / (OsmandFormatter.METERS_IN_KILOMETER / OsmandFormatter.METERS_IN_ONE_NAUTICALMILE)
|
||||
OsmandFormatter.SpeedConstants.MINUTES_PER_KILOMETER -> (OsmandFormatter.METERS_IN_KILOMETER / speedVal) / 60
|
||||
OsmandFormatter.SpeedConstants.MINUTES_PER_MILE -> (OsmandFormatter.METERS_IN_ONE_MILE / speedVal) / 60
|
||||
else -> speedVal
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
if (location.speed > 0) {
|
||||
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()))
|
||||
}
|
||||
if (updateId == 0) {
|
||||
builder.append(String.format("$UPDATED_PREFIX%s\n", formatFullTime(location.time)))
|
||||
} else {
|
||||
builder.append(String.format("$UPDATED_PREFIX%s (%d)\n", formatFullTime(location.time), updateId))
|
||||
}
|
||||
val textMessage = builder.toString().trim()
|
||||
|
||||
return TdApi.InputMessageText(TdApi.FormattedText(textMessage, entities.toTypedArray()), true, true)
|
||||
return 0.0
|
||||
}
|
||||
|
||||
fun getTextMessageContent(updateId: Int, location: BufferMessage): TdApi.InputMessageText {
|
||||
fun parseDistance(distanceS: String): Double {
|
||||
try {
|
||||
val distanceSplit = distanceS.split(" ")
|
||||
val distanceVal = distanceSplit.first().toDouble()
|
||||
return when (distanceSplit.last()) {
|
||||
OsmandFormatter.FORMAT_METERS_KEY -> return distanceVal
|
||||
OsmandFormatter.FORMAT_FEET_KEY -> return distanceVal / OsmandFormatter.FEET_IN_ONE_METER
|
||||
OsmandFormatter.FORMAT_YARDS_KEY -> return distanceVal / OsmandFormatter.YARDS_IN_ONE_METER
|
||||
OsmandFormatter.FORMAT_KILOMETERS_KEY -> return distanceVal * OsmandFormatter.METERS_IN_KILOMETER
|
||||
OsmandFormatter.FORMAT_NAUTICALMILES_KEY -> return distanceVal * OsmandFormatter.METERS_IN_ONE_NAUTICALMILE
|
||||
OsmandFormatter.FORMAT_MILES_KEY -> return distanceVal * OsmandFormatter.METERS_IN_ONE_MILE
|
||||
else -> distanceVal
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
fun getTextMessageContent(updateId: Int, location: BufferMessage, app: TelegramApplication): TdApi.InputMessageText {
|
||||
val entities = mutableListOf<TdApi.TextEntity>()
|
||||
val builder = StringBuilder()
|
||||
val locationMessage = formatLocation(location)
|
||||
|
@ -391,11 +390,13 @@ object OsmandLocationUtils {
|
|||
|
||||
if (location.altitude != 0.0) {
|
||||
entities.add(TdApi.TextEntity(builder.lastIndex, ALTITUDE_PREFIX.length, TdApi.TextEntityTypeBold()))
|
||||
builder.append(String.format(Locale.US, "$ALTITUDE_PREFIX%.1f m\n", location.altitude))
|
||||
val formattedAltitude = OsmandFormatter.getFormattedAlt(location.altitude, app, false)
|
||||
builder.append(String.format(Locale.US, "$ALTITUDE_PREFIX%s\n", formattedAltitude))
|
||||
}
|
||||
if (location.speed > 0) {
|
||||
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))
|
||||
val formattedSpeed = OsmandFormatter.getFormattedSpeed(location.speed.toFloat(), app, false)
|
||||
builder.append(String.format(Locale.US, "$SPEED_PREFIX%s\n", formattedSpeed))
|
||||
}
|
||||
if (location.bearing > 0) {
|
||||
entities.add(TdApi.TextEntity(builder.lastIndex, BEARING_PREFIX.length, TdApi.TextEntityTypeBold()))
|
||||
|
@ -403,12 +404,13 @@ object OsmandLocationUtils {
|
|||
}
|
||||
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()))
|
||||
val formattedHdop = OsmandFormatter.getFormattedDistance(location.hdop.toFloat(), app, false, false)
|
||||
builder.append(String.format(Locale.US, "$HDOP_PREFIX%s\n", formattedHdop))
|
||||
}
|
||||
if (updateId == 0) {
|
||||
builder.append(String.format("$UPDATED_PREFIX%s\n", formatFullTime(location.time)))
|
||||
builder.append(String.format("$UPDATED_PREFIX%s\n", formatFullTime(location.time, app)))
|
||||
} else {
|
||||
builder.append(String.format("$UPDATED_PREFIX%s (%d)\n", formatFullTime(location.time), updateId))
|
||||
builder.append(String.format("$UPDATED_PREFIX%s (%d)\n", formatFullTime(location.time, app), updateId))
|
||||
}
|
||||
val textMessage = builder.toString().trim()
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
Thx - Hardy
|
||||
|
||||
-->
|
||||
<string name="shared_string_downloading_formatted">Downloading %s</string>
|
||||
<string name="edit_profiles">Edit profiles</string>
|
||||
<string name="select_nav_profile_dialog_message">Navigation type affects the rules for route calculations.</string>
|
||||
<string name="distance_and_address">%1$s • %2$s</string>
|
||||
|
|
|
@ -123,7 +123,7 @@ public class DownloadTilesDialog {
|
|||
}
|
||||
final ProgressDialog progressDlg = new ProgressDialog(ctx);
|
||||
progressDlg.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
||||
progressDlg.setMessage(ctx.getString(R.string.shared_string_downloading) + ctx.getString(R.string.shared_string_ellipsis));
|
||||
progressDlg.setMessage(ctx.getString(R.string.shared_string_downloading));
|
||||
progressDlg.setCancelable(true);
|
||||
progressDlg.setMax(numberTiles);
|
||||
progressDlg.setOnCancelListener(new DialogInterface.OnCancelListener(){
|
||||
|
|
|
@ -263,13 +263,12 @@ public class DownloadFileHelper {
|
|||
mb = 1;
|
||||
}
|
||||
StringBuilder taskName = new StringBuilder();
|
||||
taskName.append(ctx.getString(R.string.shared_string_downloading)).append(": ");
|
||||
//+ de.baseName /*+ " " + mb + " MB"*/;
|
||||
taskName.append(FileNameTranslationHelper.getFileName(ctx, ctx.getRegions(), de.baseName));
|
||||
if (de.type != null) {
|
||||
taskName.append(" ").append(de.type.getString(ctx));
|
||||
}
|
||||
progress.startTask(taskName.toString(), len / 1024);
|
||||
progress.startTask(String.format(ctx.getString(R.string.shared_string_downloading_formatted), taskName.toString()), len / 1024);
|
||||
if (!de.zipStream) {
|
||||
copyFile(de, progress, fin, len, fin, de.fileToDownload);
|
||||
} else if(de.urlToDownload.contains(".gz")) {
|
||||
|
|
|
@ -447,7 +447,7 @@ public class DownloadIndexesThread {
|
|||
mainView.setKeepScreenOn(true);
|
||||
}
|
||||
}
|
||||
startTask(ctx.getString(R.string.shared_string_downloading) + ctx.getString(R.string.shared_string_ellipsis), -1);
|
||||
startTask(ctx.getString(R.string.shared_string_downloading), -1);
|
||||
downloadHasStarted();
|
||||
}
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ public class TravelDownloadUpdateCard extends BaseTravelCard {
|
|||
@NonNull
|
||||
private String getTitle(boolean loading) {
|
||||
if (loading) {
|
||||
return app.getString(R.string.shared_string_downloading) + "...";
|
||||
return app.getString(R.string.shared_string_downloading);
|
||||
}
|
||||
return app.getString(download ? R.string.download_file : R.string.update_is_available);
|
||||
}
|
||||
|
|