Add setting to share location from different devices to url

This commit is contained in:
Chumva 2018-09-28 16:44:47 +03:00
parent 58001a40a7
commit 5540b2e31b
9 changed files with 443 additions and 15 deletions

View file

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:layout_gravity="bottom">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/scroll_view_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v4.widget.NestedScrollView
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:behavior_hideable="true"
app:behavior_peekHeight="@dimen/bottom_sheet_peek_height"
app:layout_behavior="@string/bottom_sheet_behavior">
<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:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard"
android:text="@string/logout_from_osmand_telegram"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/list_item_title_text_size"
app:firstBaselineToTopHeight="28sp"
app:typeface="@string/font_roboto_medium" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/description"
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/add_device_descr"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
app:firstBaselineToTopHeight="28sp"
app:lastBaselineToBottomHeight="16sp"
app:typeface="@string/font_roboto_regular" />
<LinearLayout
android:id="@+id/enter_device_id_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:visibility="visible"
tools:visibility="visible">
<studio.carbonylgroup.textfieldboxes.TextFieldBoxes
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hasClearButton="true">
<studio.carbonylgroup.textfieldboxes.ExtendedEditText
android:id="@+id/device_id_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/device_id"
android:inputType="text" />
</studio.carbonylgroup.textfieldboxes.TextFieldBoxes>
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/buttons_bottom_bar_height"
android:background="?attr/card_bg_color"
android:gravity="center_vertical"
android:paddingLeft="@dimen/content_padding_half"
android:paddingRight="@dimen/content_padding_half">
<include
layout="@layout/secondary_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<View
android:layout_width="@dimen/content_padding_half"
android:layout_height="match_parent" />
<include
layout="@layout/primary_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>

View file

@ -74,6 +74,71 @@
<include layout="@layout/list_item_divider"/> <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" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/add_device"
android:layout_width="match_parent"
android:layout_height="@dimen/list_header_height"
android:layout_gravity="center_vertical"
android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:paddingLeft="@dimen/dialog_padding_horizontal"
android:paddingRight="@dimen/dialog_padding_horizontal"
android:text="@string/add_device"
android:textColor="?attr/ctrl_active_color"
app:typeface="@string/font_roboto_medium" />
</LinearLayout>
<include layout="@layout/list_item_divider" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -1,4 +1,10 @@
<resources> <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="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_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> <string name="logout_from_osmand_telegram">Logout from OsmAnd Telegram?</string>

View file

@ -36,6 +36,9 @@ private const val SETTINGS_NAME = "osmand_telegram_settings"
private const val SHARE_LOCATION_CHATS_KEY = "share_location_chats" 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 HIDDEN_ON_MAP_CHATS_KEY = "hidden_on_map_chats"
private const val ADDED_DEVICES_IDS_KEY = "added_devices_ids"
private const val SHARING_MODE_KEY = "current_sharing_mode"
private const val METRICS_CONSTANTS_KEY = "metrics_constants" private const val METRICS_CONSTANTS_KEY = "metrics_constants"
private const val SPEED_CONSTANTS_KEY = "speed_constants" private const val SPEED_CONSTANTS_KEY = "speed_constants"
@ -59,6 +62,9 @@ class TelegramSettings(private val app: TelegramApplication) {
private var shareLocationChats: Set<Long> = emptySet() private var shareLocationChats: Set<Long> = emptySet()
private var hiddenOnMapChats: Set<Long> = emptySet() private var hiddenOnMapChats: Set<Long> = emptySet()
var shareDevicesIds: Set<String> = emptySet()
var currentSharingMode = ""
var metricsConstants = MetricsConstants.KILOMETERS_AND_METERS var metricsConstants = MetricsConstants.KILOMETERS_AND_METERS
var speedConstants = SpeedConstants.KILOMETERS_PER_HOUR var speedConstants = SpeedConstants.KILOMETERS_PER_HOUR
@ -167,6 +173,12 @@ class TelegramSettings(private val app: TelegramApplication) {
hiddenOnMapChats = hiddenChats.toHashSet() hiddenOnMapChats = hiddenChats.toHashSet()
} }
fun addSharingDevice(deviceId: String) {
val shareDevices = shareDevicesIds.toMutableList()
shareDevices.add(deviceId)
shareDevicesIds = shareDevices.toHashSet()
}
fun getShareLocationChats() = ArrayList(shareLocationChats) fun getShareLocationChats() = ArrayList(shareLocationChats)
fun getShowOnMapChats() = getLiveNowChats().minus(hiddenOnMapChats) fun getShowOnMapChats() = getLiveNowChats().minus(hiddenOnMapChats)
@ -202,6 +214,14 @@ class TelegramSettings(private val app: TelegramApplication) {
} }
edit.putStringSet(HIDDEN_ON_MAP_CHATS_KEY, hiddenChatsSet) edit.putStringSet(HIDDEN_ON_MAP_CHATS_KEY, hiddenChatsSet)
val shareDevicesSet = mutableSetOf<String>()
val shareDevices = ArrayList(shareDevicesIds)
for (device in shareDevices) {
shareDevicesSet.add(device)
}
edit.putStringSet(ADDED_DEVICES_IDS_KEY, shareDevicesSet)
edit.putString(SHARING_MODE_KEY, currentSharingMode)
edit.putString(METRICS_CONSTANTS_KEY, metricsConstants.name) edit.putString(METRICS_CONSTANTS_KEY, metricsConstants.name)
edit.putString(SPEED_CONSTANTS_KEY, speedConstants.name) edit.putString(SPEED_CONSTANTS_KEY, speedConstants.name)
@ -233,6 +253,13 @@ class TelegramSettings(private val app: TelegramApplication) {
} }
hiddenOnMapChats = hiddenChats hiddenOnMapChats = hiddenChats
val shareDevices = mutableSetOf<String>()
val shareDevicesSet = prefs.getStringSet(ADDED_DEVICES_IDS_KEY, mutableSetOf())
for (deviceId in shareDevicesSet) {
shareDevices.add(deviceId.toString())
}
shareDevicesIds = shareDevices
metricsConstants = MetricsConstants.valueOf( metricsConstants = MetricsConstants.valueOf(
prefs.getString(METRICS_CONSTANTS_KEY, MetricsConstants.KILOMETERS_AND_METERS.name) prefs.getString(METRICS_CONSTANTS_KEY, MetricsConstants.KILOMETERS_AND_METERS.name)
) )
@ -247,6 +274,8 @@ class TelegramSettings(private val app: TelegramApplication) {
val locHistoryDef = LOC_HISTORY_VALUES_SEC[LOC_HISTORY_DEFAULT_INDEX] val locHistoryDef = LOC_HISTORY_VALUES_SEC[LOC_HISTORY_DEFAULT_INDEX]
locHistoryTime = prefs.getLong(LOC_HISTORY_TIME_KEY, locHistoryDef) locHistoryTime = prefs.getLong(LOC_HISTORY_TIME_KEY, locHistoryDef)
currentSharingMode = prefs.getString(SHARING_MODE_KEY, "")
appToConnectPackage = prefs.getString(APP_TO_CONNECT_PACKAGE_KEY, "") appToConnectPackage = prefs.getString(APP_TO_CONNECT_PACKAGE_KEY, "")
liveNowSortType = LiveNowSortType.valueOf( liveNowSortType = LiveNowSortType.valueOf(

View file

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

View file

@ -1203,15 +1203,15 @@ class TelegramHelper private constructor() {
//listener?.onTelegramChatsChanged() //listener?.onTelegramChatsChanged()
} }
} }
TdApi.UpdateChatNotificationSettings.CONSTRUCTOR -> { // TdApi.UpdateChatNotificationSettings.CONSTRUCTOR -> {
val update = obj as TdApi.UpdateChatNotificationSettings // val update = obj as TdApi.UpdateChatNotificationSettings
val chat = chats[update.chatId] // val chat = chats[update.chatId]
if (chat != null) { // if (chat != null) {
synchronized(chat) { // synchronized(chat) {
chat.notificationSettings = update.notificationSettings // chat.notificationSettings = update.notificationSettings
} // }
} // }
} // }
TdApi.UpdateFile.CONSTRUCTOR -> { TdApi.UpdateFile.CONSTRUCTOR -> {
val updateFile = obj as TdApi.UpdateFile val updateFile = obj as TdApi.UpdateFile

View file

@ -0,0 +1,91 @@
package net.osmand.telegram.ui
import android.content.Intent
import android.os.Bundle
import android.support.design.widget.BottomSheetBehavior
import android.support.v4.app.DialogFragment
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.TextView
import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.ui.views.BottomSheetDialog
class AddDeviceBottomSheet : DialogFragment() {
private lateinit var editText: EditText
override fun onCreateDialog(savedInstanceState: Bundle?) = BottomSheetDialog(context!!)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val mainView = inflater.inflate(R.layout.bottom_sheet_add_device, container, false)
mainView.findViewById<View>(R.id.scroll_view_container).setOnClickListener { dismiss() }
BottomSheetBehavior.from(mainView.findViewById<View>(R.id.scroll_view))
.setBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
override fun onStateChanged(bottomSheet: View, newState: Int) {
if (newState == BottomSheetBehavior.STATE_HIDDEN) {
dismiss()
}
}
override fun onSlide(bottomSheet: View, slideOffset: Float) {}
})
editText = mainView.findViewById<EditText>(R.id.device_id_edit_text)
mainView.findViewById<TextView>(R.id.secondary_btn).apply {
setText(R.string.shared_string_cancel)
setOnClickListener { dismiss() }
}
mainView.findViewById<TextView>(R.id.primary_btn).apply {
setText(R.string.shared_string_save)
setOnClickListener {
val app = activity?.application as TelegramApplication
val settings = app.settings
val newDeviceId = editText.text.toString()
settings.addSharingDevice(newDeviceId)
targetFragment?.also { target ->
val intent = Intent()
intent.putExtra(NEW_DEVICE_ID, newDeviceId)
target.onActivityResult(targetRequestCode, ADD_DEVICE_REQUEST_CODE, intent)
}
dismiss()
}
}
return mainView
}
companion object {
const val ADD_DEVICE_REQUEST_CODE = 5
const val NEW_DEVICE_ID = "NEW_DEVICE_ID"
private const val TAG = "AddDeviceBottomSheet"
fun showInstance(fm: FragmentManager, target: Fragment): Boolean {
return try {
AddDeviceBottomSheet().apply {
setTargetFragment(target, ADD_DEVICE_REQUEST_CODE)
show(fm, TAG)
}
true
} catch (e: RuntimeException) {
false
}
}
}
}

View file

@ -9,10 +9,7 @@ import android.view.Gravity
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ArrayAdapter import android.widget.*
import android.widget.ImageView
import android.widget.RadioButton
import android.widget.TextView
import net.osmand.telegram.R import net.osmand.telegram.R
import net.osmand.telegram.TelegramSettings import net.osmand.telegram.TelegramSettings
import net.osmand.telegram.TelegramSettings.DurationPref import net.osmand.telegram.TelegramSettings.DurationPref
@ -22,13 +19,14 @@ import net.osmand.telegram.utils.AndroidUtils
class SettingsDialogFragment : BaseDialogFragment() { class SettingsDialogFragment : BaseDialogFragment() {
private val uiUtils get() = app.uiUtils private val uiUtils get() = app.uiUtils
private lateinit var mainView: View
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
parent: ViewGroup?, parent: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
val mainView = inflater.inflate(R.layout.fragement_settings_dialog, parent) mainView = inflater.inflate(R.layout.fragement_settings_dialog, parent)
val appBarLayout = mainView.findViewById<View>(R.id.app_bar_layout) val appBarLayout = mainView.findViewById<View>(R.id.app_bar_layout)
AndroidUtils.addStatusBarPadding19v(context!!, appBarLayout) AndroidUtils.addStatusBarPadding19v(context!!, appBarLayout)
@ -94,6 +92,39 @@ class SettingsDialogFragment : BaseDialogFragment() {
} }
updateSelectedAppConn() updateSelectedAppConn()
container = mainView.findViewById(R.id.share_as_container)
if (settings.shareDevicesIds.isEmpty()) {
val user = telegramHelper.getCurrentUser()
if (user != null) {
settings.addSharingDevice(TelegramUiHelper.getUserName(user))
settings.currentSharingMode = TelegramUiHelper.getUserName(user)
}
}
settings.shareDevicesIds.forEach {
val title = it
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 = it == settings.currentSharingMode
}
setOnClickListener {
settings.currentSharingMode = title
updateSelectedSharingMode()
}
tag = it
container.addView(this)
}
}
mainView.findViewById<TextView>(R.id.add_device).setOnClickListener {
val fm = fragmentManager
if (fm != null) {
AddDeviceBottomSheet.showInstance(fm, this)
}
}
val user = telegramHelper.getCurrentUser() val user = telegramHelper.getCurrentUser()
if (user != null) { if (user != null) {
TelegramUiHelper.setupPhoto( TelegramUiHelper.setupPhoto(
@ -131,6 +162,11 @@ class SettingsDialogFragment : BaseDialogFragment() {
logoutTelegram() logoutTelegram()
dismiss() dismiss()
} }
AddDeviceBottomSheet.ADD_DEVICE_REQUEST_CODE -> {
if (data != null && data.hasExtra(AddDeviceBottomSheet.NEW_DEVICE_ID)) {
addNewSharingDevice(data.getStringExtra(AddDeviceBottomSheet.NEW_DEVICE_ID))
}
}
} }
} }
@ -164,6 +200,36 @@ 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 addNewSharingDevice(title: String) {
val inflater = LayoutInflater.from(context)
val container = mainView.findViewById<ViewGroup>(R.id.share_as_container)
inflater.inflate(R.layout.item_with_rb_and_btn, null, 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 = title == settings.currentSharingMode
}
setOnClickListener {
settings.currentSharingMode = title
updateSelectedSharingMode()
}
tag = title
container.addView(this)
}
}
private fun logoutTelegram() { private fun logoutTelegram() {
val act = activity ?: return val act = activity ?: return
(act as MainActivity).logoutTelegram() (act as MainActivity).logoutTelegram()

View file

@ -0,0 +1,51 @@
package net.osmand.telegram.utils
import android.os.AsyncTask
import android.widget.Toast
import net.osmand.PlatformUtil
import net.osmand.osm.io.NetworkUtils
import net.osmand.telegram.TelegramApplication
import java.net.HttpURLConnection
object AndroidNetworkUtils {
private const val CONNECTION_TIMEOUT = 15000
private val log = PlatformUtil.getLog(AndroidNetworkUtils::class.java)
fun sendRequestAsync(ctx: TelegramApplication, url: String) {
object : AsyncTask<Void, Void, String>() {
override fun doInBackground(vararg params: Void): String? {
try {
return sendRequest(ctx, url)
} catch (e: Exception) {
return null
}
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null as Void?)
}
fun sendRequest(ctx: TelegramApplication, url: String): String? {
var connection: HttpURLConnection? = null
try {
connection = NetworkUtils.getHttpURLConnection(url)
if (connection != null) {
connection.setRequestProperty("Accept-Charset", "UTF-8")
connection.setRequestProperty("User-Agent", ctx.packageName)
connection.connectTimeout = CONNECTION_TIMEOUT
connection.requestMethod = "GET"
connection.connect()
if (connection.responseCode != HttpURLConnection.HTTP_OK) {
Toast.makeText(ctx, connection.responseMessage, Toast.LENGTH_LONG).show()
}
}
} catch (e: Exception) {
log.error(e)
} finally {
connection?.disconnect()
}
return null
}
}