Merge pull request #6108 from osmandapp/TelegramImprovements

Add setting to share location from different devices to url
This commit is contained in:
Alexander Sytnyk 2018-10-03 13:30:32 +03:00 committed by GitHub
commit 2ae3bfe436
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 270 additions and 9 deletions

View file

@ -74,6 +74,56 @@
<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="wrap_content"
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/share_location_as"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/list_item_title_text_size"
app:firstBaselineToTopHeight="25sp"
app:typeface="@string/font_roboto_medium" />
<net.osmand.telegram.ui.views.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard"
android:text="@string/share_location_as_descr"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
app:firstBaselineToTopHeight="20sp"
app:lastBaselineToBottomHeight="16sp"
app:typeface="@string/font_roboto_regular" />
<View
android:layout_width="wrap_content"
android:layout_height="1dp"
android:layout_marginStart="@dimen/content_padding_standard"
android:layout_marginLeft="@dimen/content_padding_standard"
android:layout_marginBottom="@dimen/content_padding_half"
android:background="?attr/card_divider_color" />
<LinearLayout
android:id="@+id/share_as_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"

View file

@ -1,4 +1,10 @@
<resources>
<string name="shared_string_save">Save</string>
<string name="add_device_descr">Enter your device id that you can find at https://live.osmand.net/device/ID</string>
<string name="device_id">Device id</string>
<string name="add_device">Add device</string>
<string name="share_location_as_descr">The option allow you to share this device location, or location of custom added via API devices.</string>
<string name="share_location_as">Share location as</string>
<string name="live_now_description">Contacts and groups who share their location with you.</string>
<string name="logout_from_osmand_telegram_descr">Are you sure you want to log out of OsmAnd Telegram? After that, you will not be able to send your position and see the locations of your contacts on the map in OsmAnd.</string>
<string name="logout_from_osmand_telegram">Logout from OsmAnd Telegram?</string>

View file

@ -37,6 +37,8 @@ private const val SETTINGS_NAME = "osmand_telegram_settings"
private const val SHARE_LOCATION_CHATS_KEY = "share_location_chats"
private const val HIDDEN_ON_MAP_CHATS_KEY = "hidden_on_map_chats"
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"
@ -62,6 +64,9 @@ class TelegramSettings(private val app: TelegramApplication) {
private var shareLocationChats: Set<Long> = emptySet()
private var hiddenOnMapChats: Set<Long> = emptySet()
var shareDevicesIds = mutableMapOf<String, String>()
var currentSharingMode = ""
var metricsConstants = MetricsConstants.KILOMETERS_AND_METERS
var speedConstants = SpeedConstants.KILOMETERS_PER_HOUR
@ -137,6 +142,13 @@ class TelegramSettings(private val app: TelegramApplication) {
this.shareLocationChats = shareLocationChats.toHashSet()
}
fun updateShareDevicesIds(list: List<DeviceBot>) {
shareDevicesIds.clear()
list.forEach {
shareDevicesIds[it.externalId] = it.deviceName
}
}
fun getChatLivePeriod(chatId: Long) = chatLivePeriods[chatId]
fun getChatAddActiveTime(chatId: Long) = chatShareAddActiveTime[chatId] ?: MESSAGE_ADD_ACTIVE_TIME_VALUES_SEC[0]
@ -232,6 +244,8 @@ class TelegramSettings(private val app: TelegramApplication) {
}
edit.putStringSet(HIDDEN_ON_MAP_CHATS_KEY, hiddenChatsSet)
edit.putString(SHARING_MODE_KEY, currentSharingMode)
edit.putString(METRICS_CONSTANTS_KEY, metricsConstants.name)
edit.putString(SPEED_CONSTANTS_KEY, speedConstants.name)
@ -277,6 +291,8 @@ class TelegramSettings(private val app: TelegramApplication) {
val locHistoryDef = LOC_HISTORY_VALUES_SEC[LOC_HISTORY_DEFAULT_INDEX]
locHistoryTime = prefs.getLong(LOC_HISTORY_TIME_KEY, locHistoryDef)
currentSharingMode = prefs.getString(SHARING_MODE_KEY, "")
appToConnectPackage = prefs.getString(APP_TO_CONNECT_PACKAGE_KEY, "")
liveNowSortType = LiveNowSortType.valueOf(
@ -430,4 +446,13 @@ class TelegramSettings(private val app: TelegramApplication) {
fun isSortByGroup() = this == SORT_BY_GROUP
}
class DeviceBot {
var id: Long = -1
var userId: Long = -1
var chatId: Long = -1
var deviceName: String = ""
var externalId: String = ""
var data: String = ""
}
}

View file

@ -3,6 +3,7 @@ package net.osmand.telegram.helpers
import net.osmand.Location
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.notifications.TelegramNotification.NotificationType
import net.osmand.telegram.utils.AndroidNetworkUtils
class ShareLocationHelper(private val app: TelegramApplication) {
@ -40,7 +41,14 @@ class ShareLocationHelper(private val app: TelegramApplication) {
if (location != null && app.isInternetConnectionAvailable) {
val chatLivePeriods = app.settings.getChatLivePeriods()
if (chatLivePeriods.isNotEmpty()) {
val user = app.telegramHelper.getCurrentUser()
val sharingMode = app.settings.currentSharingMode
if (user != null && sharingMode == user.id.toString()) {
app.telegramHelper.sendLiveLocationMessage(chatLivePeriods, location.latitude, location.longitude)
} else if (sharingMode.isNotEmpty()) {
val url = "https://live.osmand.net/device/$sharingMode/send?lat=${location.latitude}&lon=${location.longitude}"
AndroidNetworkUtils.sendRequestAsync(url, null)
}
}
lastLocationMessageSentTime = System.currentTimeMillis()
}

View file

@ -25,9 +25,7 @@ import net.osmand.telegram.helpers.TelegramHelper.*
import net.osmand.telegram.ui.LoginDialogFragment.LoginDialogType
import net.osmand.telegram.ui.MyLocationTabFragment.ActionButtonsListener
import net.osmand.telegram.ui.views.LockableViewPager
import net.osmand.telegram.utils.AndroidUtils
import net.osmand.telegram.utils.GRAYSCALE_PHOTOS_DIR
import net.osmand.telegram.utils.GRAYSCALE_PHOTOS_EXT
import net.osmand.telegram.utils.*
import org.drinkless.td.libcore.telegram.TdApi
import java.lang.ref.WeakReference
@ -216,6 +214,13 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
} else {
AndroidUtils.requestLocationPermission(this)
}
val user = telegramHelper.getCurrentUser()
if (user != null) {
OsmandApiUtils.updateSharingDevices(app, user.id)
if (settings.currentSharingMode.isEmpty()) {
settings.currentSharingMode = user.id.toString()
}
}
}
else -> Unit
}

View file

@ -9,10 +9,7 @@ import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.RadioButton
import android.widget.TextView
import android.widget.*
import net.osmand.telegram.R
import net.osmand.telegram.TelegramSettings
import net.osmand.telegram.TelegramSettings.DurationPref
@ -94,7 +91,15 @@ class SettingsDialogFragment : BaseDialogFragment() {
}
updateSelectedAppConn()
container = mainView.findViewById(R.id.share_as_container)
val user = telegramHelper.getCurrentUser()
if (user != null) {
addItemToContainer(inflater, container, user.id.toString(), TelegramUiHelper.getUserName(user))
}
settings.shareDevicesIds.forEach {
addItemToContainer(inflater, container, it.key, it.value)
}
if (user != null) {
TelegramUiHelper.setupPhoto(
app,
@ -134,6 +139,23 @@ class SettingsDialogFragment : BaseDialogFragment() {
}
}
private fun addItemToContainer(inflater: LayoutInflater, container: ViewGroup, tag: String, title: String) {
inflater.inflate(R.layout.item_with_rb_and_btn, container, false).apply {
findViewById<TextView>(R.id.title).text = title
findViewById<View>(R.id.primary_btn).visibility = View.GONE
findViewById<RadioButton>(R.id.radio_button).apply {
visibility = View.VISIBLE
isChecked = tag == settings.currentSharingMode
}
setOnClickListener {
settings.currentSharingMode = tag
updateSelectedSharingMode()
}
this.tag = tag
container.addView(this)
}
}
private fun showPopupMenu(pref: DurationPref, valueView: TextView) {
val menuList = pref.getMenuItems()
val ctx = valueView.context
@ -164,6 +186,17 @@ class SettingsDialogFragment : BaseDialogFragment() {
}
}
private fun updateSelectedSharingMode() {
view?.findViewById<ViewGroup>(R.id.share_as_container)?.apply {
for (i in 0 until childCount) {
getChildAt(i).apply {
findViewById<RadioButton>(R.id.radio_button).isChecked =
tag == settings.currentSharingMode
}
}
}
}
private fun logoutTelegram() {
val act = activity ?: return
(act as MainActivity).logoutTelegram()

View file

@ -0,0 +1,88 @@
package net.osmand.telegram.utils
import android.os.AsyncTask
import net.osmand.PlatformUtil
import java.io.*
import java.net.*
object AndroidNetworkUtils {
private val log = PlatformUtil.getLog(AndroidNetworkUtils::class.java)
interface OnRequestResultListener {
fun onResult(result: String)
}
fun sendRequestAsync(urlText: String, listener: OnRequestResultListener?) {
SendRequestTask(urlText, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
}
private class SendRequestTask(
private val urlText: String,
private val listener: OnRequestResultListener?
) : AsyncTask<Void, Void, String?>() {
override fun doInBackground(vararg params: Void): String? {
return try {
sendRequest(urlText)
} catch (e: Exception) {
log.error(e.message, e)
null
}
}
override fun onPostExecute(response: String?) {
if (response != null) {
listener?.onResult(response)
}
}
}
fun sendRequest(urlText: String): String? {
try {
log.info("GET : $urlText")
val conn = getHttpURLConnection(urlText)
conn.doInput = true
conn.doOutput = false
conn.requestMethod = "GET"
conn.setRequestProperty("User-Agent", "OsmAnd Sharing")
log.info("Response code and message : " + conn.responseCode + " " + conn.responseMessage)
if (conn.responseCode != 200) {
return conn.responseMessage
}
val inputStream = conn.inputStream
val responseBody = StringBuilder()
responseBody.setLength(0)
if (inputStream != null) {
val bufferedInput = BufferedReader(InputStreamReader(inputStream, "UTF-8"))
var s = bufferedInput.readLine()
var first = true
while (s != null) {
if (first) {
first = false
} else {
responseBody.append("\n")
}
responseBody.append(s)
s = bufferedInput.readLine()
}
inputStream.close()
}
return responseBody.toString()
} catch (e: IOException) {
log.error(e.message, e)
return e.message
}
}
@Throws(MalformedURLException::class, IOException::class)
fun getHttpURLConnection(urlString: String): HttpURLConnection {
return getHttpURLConnection(URL(urlString))
}
@Throws(IOException::class)
fun getHttpURLConnection(url: URL): HttpURLConnection {
return url.openConnection() as HttpURLConnection
}
}

View file

@ -0,0 +1,46 @@
package net.osmand.telegram.utils
import net.osmand.PlatformUtil
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.TelegramSettings
import org.json.JSONException
import org.json.JSONObject
object OsmandApiUtils {
private val log = PlatformUtil.getLog(OsmandApiUtils::class.java)
fun updateSharingDevices(app: TelegramApplication, userId: Int) {
AndroidNetworkUtils.sendRequestAsync(
"https://osmand.net/device/send-devices?uid=$userId",
object : AndroidNetworkUtils.OnRequestResultListener {
override fun onResult(result: String) {
val list = parseJsonContents(result)
app.settings.updateShareDevicesIds(list)
}
}
)
}
fun parseJsonContents(contentsJson: String): List<TelegramSettings.DeviceBot> {
val list = mutableListOf<TelegramSettings.DeviceBot>()
try {
val jArray = JSONObject(contentsJson).getJSONArray("devices")
for (i in 0 until jArray.length()) {
val deviceJSON = jArray.getJSONObject(i)
val deviceBot = TelegramSettings.DeviceBot().apply {
id = deviceJSON.getLong("id")
userId = deviceJSON.getLong("userId")
chatId = deviceJSON.getLong("chatId")
deviceName = deviceJSON.getString("deviceName")
externalId = deviceJSON.getString("externalId")
data = deviceJSON.getString("data")
}
list.add(deviceBot)
}
} catch (e: JSONException) {
log.error(e.message, e)
}
return list
}
}