Add the ability to open somebody`s location on map in OsmAnd
This commit is contained in:
parent
4e2500578c
commit
90cc7dd8f4
7 changed files with 143 additions and 8 deletions
|
@ -16,8 +16,10 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/user_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/list_item_height"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
android:background="?attr/card_bg_color">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/main_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/list_item_height"
|
||||
android:layout_marginBottom="@dimen/list_item_bottom_margin"
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
package net.osmand.telegram.helpers
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.support.v4.app.FragmentActivity
|
||||
import net.osmand.telegram.helpers.TelegramUiHelper.ChatItem
|
||||
import net.osmand.telegram.helpers.TelegramUiHelper.LocationItem
|
||||
import net.osmand.telegram.ui.MainActivity
|
||||
import net.osmand.telegram.utils.AndroidUtils
|
||||
|
||||
object OsmandHelper {
|
||||
|
||||
private const val PREFIX = "osmand.api://"
|
||||
|
||||
private const val API_CMD_SHOW_LOCATION = "show_location"
|
||||
|
||||
private const val PARAM_LAT = "lat"
|
||||
private const val PARAM_LON = "lon"
|
||||
|
||||
private const val PARAM_AMAP_LAYER_ID = "amap_layer_id"
|
||||
private const val PARAM_AMAP_POINT_ID = "amap_point_id"
|
||||
|
||||
fun showUserOnMap(activity: FragmentActivity?, chatItem: ChatItem) {
|
||||
if (chatItem.canBeOpenedOnMap()) {
|
||||
showLocationPointOnMap(
|
||||
activity,
|
||||
chatItem.latLon?.latitude,
|
||||
chatItem.latLon?.longitude,
|
||||
"${chatItem.title}_${chatItem.userId}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun showUserOnMap(activity: FragmentActivity?, locationItem: LocationItem) {
|
||||
if (locationItem.canBeOpenedOnMap()) {
|
||||
val userId = locationItem.senderUserId
|
||||
val id = if (userId != 0) userId.toString() else locationItem.name
|
||||
showLocationPointOnMap(
|
||||
activity,
|
||||
locationItem.latLon?.latitude,
|
||||
locationItem.latLon?.longitude,
|
||||
"${locationItem.chatTitle}_$id"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun showLocationPointOnMap(
|
||||
activity: FragmentActivity?,
|
||||
lat: Double?,
|
||||
lon: Double?,
|
||||
pointId: String
|
||||
) {
|
||||
if (activity == null || lat == null || lon == null) {
|
||||
return
|
||||
}
|
||||
val params = mapOf(
|
||||
PARAM_LAT to lat.toString(),
|
||||
PARAM_LON to lon.toString(),
|
||||
PARAM_AMAP_LAYER_ID to MAP_LAYER_ID,
|
||||
PARAM_AMAP_POINT_ID to pointId
|
||||
)
|
||||
val intent = Intent(Intent.ACTION_VIEW, createUri(API_CMD_SHOW_LOCATION, params))
|
||||
if (AndroidUtils.isIntentSafe(activity, intent)) {
|
||||
activity.startActivity(intent)
|
||||
} else {
|
||||
MainActivity.OsmandMissingDialogFragment().show(activity.supportFragmentManager, null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createUri(command: String, params: Map<String, String>): Uri {
|
||||
val sb = StringBuilder(PREFIX).append(command)
|
||||
if (params.isNotEmpty()) {
|
||||
sb.append("?")
|
||||
params.forEach { (key, value) -> sb.append("$key=$value&") }
|
||||
sb.delete(sb.length - 1, sb.length)
|
||||
}
|
||||
return Uri.parse(sb.toString())
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ import net.osmand.telegram.utils.AndroidUtils
|
|||
import org.drinkless.td.libcore.telegram.TdApi
|
||||
import java.io.File
|
||||
|
||||
private const val MAP_LAYER_ID = "telegram_layer"
|
||||
const val MAP_LAYER_ID = "telegram_layer"
|
||||
|
||||
class ShowLocationHelper(private val app: TelegramApplication) {
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ object TelegramUiHelper {
|
|||
}
|
||||
val chatType = chat.type
|
||||
if (chatType is TdApi.ChatTypePrivate && !helper.isBot(chatType.userId)) {
|
||||
res.userId = chatType.userId
|
||||
val content = messages.firstOrNull()?.content
|
||||
if (content is TdApi.MessageLocation) {
|
||||
res.latLon = LatLon(content.location.latitude, content.location.longitude)
|
||||
|
@ -55,18 +56,26 @@ object TelegramUiHelper {
|
|||
return res
|
||||
}
|
||||
|
||||
fun messageToLocationItem(helper: TelegramHelper, message: TdApi.Message): LocationItem? {
|
||||
fun messageToLocationItem(
|
||||
helper: TelegramHelper,
|
||||
chat: TdApi.Chat,
|
||||
message: TdApi.Message
|
||||
): LocationItem? {
|
||||
val content = message.content
|
||||
return when (content) {
|
||||
is MessageOsmAndBotLocation -> botMessageToLocationItem(content)
|
||||
is TdApi.MessageLocation -> locationMessageToLocationItem(helper, message)
|
||||
is MessageOsmAndBotLocation -> botMessageToLocationItem(chat, content)
|
||||
is TdApi.MessageLocation -> locationMessageToLocationItem(helper, chat, message)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun botMessageToLocationItem(content: MessageOsmAndBotLocation): LocationItem? {
|
||||
private fun botMessageToLocationItem(
|
||||
chat: TdApi.Chat,
|
||||
content: MessageOsmAndBotLocation
|
||||
): LocationItem? {
|
||||
return if (content.isValid()) {
|
||||
LocationItem().apply {
|
||||
chatTitle = chat.title
|
||||
name = content.name
|
||||
latLon = LatLon(content.lat, content.lon)
|
||||
placeholderId = R.drawable.ic_group
|
||||
|
@ -78,11 +87,13 @@ object TelegramUiHelper {
|
|||
|
||||
private fun locationMessageToLocationItem(
|
||||
helper: TelegramHelper,
|
||||
chat: TdApi.Chat,
|
||||
message: TdApi.Message
|
||||
): LocationItem? {
|
||||
val user = helper.getUser(message.senderUserId) ?: return null
|
||||
val content = message.content as TdApi.MessageLocation
|
||||
return LocationItem().apply {
|
||||
chatTitle = chat.title
|
||||
name = "${user.firstName} ${user.lastName}".trim()
|
||||
if (name.isEmpty()) {
|
||||
name = user.username
|
||||
|
@ -93,6 +104,7 @@ object TelegramUiHelper {
|
|||
latLon = LatLon(content.location.latitude, content.location.longitude)
|
||||
photoPath = helper.getUserPhotoPath(user)
|
||||
placeholderId = R.drawable.ic_group
|
||||
senderUserId = message.senderUserId
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,9 +117,15 @@ object TelegramUiHelper {
|
|||
internal set
|
||||
var placeholderId: Int = 0
|
||||
internal set
|
||||
var userId: Int = 0
|
||||
internal set
|
||||
|
||||
fun canBeOpenedOnMap() = latLon != null && userId != 0
|
||||
}
|
||||
|
||||
class LocationItem {
|
||||
var chatTitle: String = ""
|
||||
internal set
|
||||
var name: String = ""
|
||||
internal set
|
||||
var latLon: LatLon? = null
|
||||
|
@ -116,5 +134,9 @@ object TelegramUiHelper {
|
|||
internal set
|
||||
var placeholderId: Int = 0
|
||||
internal set
|
||||
var senderUserId: Int = 0
|
||||
internal set
|
||||
|
||||
fun canBeOpenedOnMap() = latLon != null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import net.osmand.telegram.R
|
|||
import net.osmand.telegram.TelegramApplication
|
||||
import net.osmand.telegram.TelegramLocationProvider.TelegramCompassListener
|
||||
import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener
|
||||
import net.osmand.telegram.helpers.OsmandHelper
|
||||
import net.osmand.telegram.helpers.TelegramHelper.*
|
||||
import net.osmand.telegram.helpers.TelegramUiHelper
|
||||
import net.osmand.telegram.helpers.TelegramUiHelper.ChatItem
|
||||
|
@ -170,7 +171,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
telegramHelper.getChat(id)?.also { chat ->
|
||||
res.add(TelegramUiHelper.chatToChatItem(telegramHelper, chat, messages))
|
||||
if (needLocationItems(chat.type)) {
|
||||
res.addAll(convertToLocationItems(messages))
|
||||
res.addAll(convertToLocationItems(chat, messages))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -186,10 +187,15 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
}
|
||||
}
|
||||
|
||||
private fun convertToLocationItems(messages: List<TdApi.Message>): List<LocationItem> {
|
||||
private fun convertToLocationItems(
|
||||
chat: TdApi.Chat,
|
||||
messages: List<TdApi.Message>
|
||||
): List<LocationItem> {
|
||||
val res = mutableListOf<LocationItem>()
|
||||
messages.forEach { message ->
|
||||
TelegramUiHelper.messageToLocationItem(telegramHelper, message)?.also { res.add(it) }
|
||||
TelegramUiHelper.messageToLocationItem(telegramHelper, chat, message)?.also {
|
||||
res.add(it)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
@ -231,7 +237,16 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
val nextIsLocation = !lastItem && items[position + 1] is LocationItem
|
||||
val chatTitle = item.title
|
||||
val stateTextInd = if (settings.isShowingChatOnMap(chatTitle)) 1 else 0
|
||||
val canBeOpenedOnMap = item.canBeOpenedOnMap()
|
||||
|
||||
holder.userRow?.isEnabled = canBeOpenedOnMap
|
||||
if (canBeOpenedOnMap) {
|
||||
holder.userRow?.setOnClickListener {
|
||||
OsmandHelper.showUserOnMap(activity, item)
|
||||
}
|
||||
} else {
|
||||
holder.userRow?.setOnClickListener(null)
|
||||
}
|
||||
TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, item.placeholderId)
|
||||
holder.title?.text = chatTitle
|
||||
if (location != null && item.latLon != null) {
|
||||
|
@ -253,6 +268,16 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
holder.bottomDivider?.visibility = if (nextIsLocation) View.VISIBLE else View.GONE
|
||||
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
|
||||
} else if (item is LocationItem && holder is ContactViewHolder) {
|
||||
val canBeOpenedOnMap = item.canBeOpenedOnMap()
|
||||
|
||||
holder.mainView?.isEnabled = canBeOpenedOnMap
|
||||
if (canBeOpenedOnMap) {
|
||||
holder.mainView?.setOnClickListener {
|
||||
OsmandHelper.showUserOnMap(activity, item)
|
||||
}
|
||||
} else {
|
||||
holder.mainView?.setOnClickListener(null)
|
||||
}
|
||||
TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, item.placeholderId)
|
||||
holder.title?.text = item.name
|
||||
if (location != null && item.latLon != null) {
|
||||
|
@ -325,6 +350,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
}
|
||||
|
||||
inner class ContactViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||
val mainView: View? = view.findViewById(R.id.main_view)
|
||||
val icon: ImageView? = view.findViewById(R.id.icon)
|
||||
val title: TextView? = view.findViewById(R.id.title)
|
||||
val locationViewContainer: View? = view.findViewById(R.id.location_view_container)
|
||||
|
@ -335,6 +361,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
}
|
||||
|
||||
inner class ChatViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||
val userRow: View? = view.findViewById(R.id.user_row)
|
||||
val icon: ImageView? = view.findViewById(R.id.icon)
|
||||
val title: TextView? = view.findViewById(R.id.title)
|
||||
val locationViewContainer: View? = view.findViewById(R.id.location_view_container)
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.osmand.telegram.utils
|
|||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
|
@ -90,4 +91,7 @@ object AndroidUtils {
|
|||
}
|
||||
return "https://play.google.com/store/apps/details?id=$packageName"
|
||||
}
|
||||
|
||||
fun isIntentSafe(ctx: Context, intent: Intent) =
|
||||
ctx.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).isNotEmpty()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue