Merge remote-tracking branch 'origin/master' into share_address_poi_type

# Conflicts:
#	OsmAnd/src/net/osmand/plus/mapcontextmenu/builders/AmenityMenuBuilder.java
This commit is contained in:
Skalii 2021-01-12 10:30:55 +02:00
commit 35ff73e1db
10 changed files with 137 additions and 216 deletions

View file

@ -19,7 +19,10 @@
android:launchMode="singleTask"
android:screenOrientation="unspecified"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
android:hasFragileUserData="true"
android:requestLegacyExternalStorage="true">
<activity android:name=".ui.TrackerLogcatActivity" />
<activity
android:name=".ui.MainActivity"
@ -48,14 +51,13 @@
<service
android:name=".TelegramService"
android:label="@string/process_service"
android:foregroundServiceType="location"
android:stopWithTask="false">
<intent-filter>
<action android:name="net.osmand.telegram.TelegramService" />
</intent-filter>
</service>
<receiver android:name=".OnTelegramServiceAlarmReceiver" />
<receiver
android:name=".InitAppBroadcastReceiver"
android:enabled="true"

View file

@ -4,8 +4,8 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
compileSdkVersion 29
buildToolsVersion "29.0.3"
sourceSets {
main {
@ -23,7 +23,7 @@ android {
defaultConfig {
applicationId "net.osmand.telegram"
minSdkVersion 15
targetSdkVersion 28
targetSdkVersion 29
multiDexEnabled true
versionCode 1
versionCode System.getenv("APK_NUMBER_VERSION") ? System.getenv("APK_NUMBER_VERSION").toInteger() : versionCode

View file

@ -1,42 +0,0 @@
package net.osmand.telegram
import android.annotation.SuppressLint
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.location.LocationManager
import net.osmand.telegram.utils.AndroidUtils
class OnTelegramServiceAlarmReceiver : BroadcastReceiver() {
@SuppressLint("MissingPermission")
override fun onReceive(context: Context, intent: Intent) {
val lock = TelegramService.getLock(context)
val app = context.applicationContext as TelegramApplication
val service = app.telegramService
// do not do nothing
if (lock.isHeld || service == null) {
return
}
lock.acquire(15 * 60 * 1000L)
// request location updates
val locationManager = service.getSystemService(Context.LOCATION_SERVICE) as LocationManager
try {
if (AndroidUtils.isLocationPermissionAvailable(app)) {
locationManager.requestLocationUpdates(service.serviceOffProvider, 0, 0f, service)
}
val handler = service.handler
if (service.serviceOffInterval > service.serviceErrorInterval && handler != null) {
handler.postDelayed({
// if lock is not anymore held
if (lock.isHeld) {
lock.release()
locationManager.removeUpdates(service)
}
}, service.serviceErrorInterval)
}
} catch (e: RuntimeException) {
e.printStackTrace()
}
}
}

View file

@ -8,12 +8,13 @@ import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.os.Build
import android.os.Handler
import androidx.core.content.ContextCompat
import net.osmand.PlatformUtil
import net.osmand.telegram.ui.TrackerLogcatActivity
import net.osmand.telegram.helpers.*
import net.osmand.telegram.helpers.OsmandAidlHelper.OsmandHelperListener
import net.osmand.telegram.helpers.OsmandAidlHelper.UpdatesListener
import net.osmand.telegram.notifications.NotificationHelper
import net.osmand.telegram.ui.TrackerLogcatActivity
import net.osmand.telegram.utils.AndroidUtils
import net.osmand.telegram.utils.UiUtils
import java.io.File
@ -146,35 +147,21 @@ class TelegramApplication : Application() {
return internetConnectionAvailable
}
private fun startTelegramService(intent: Int, serviceOffInterval: Long = 0) {
private fun startTelegramService(intent: Int) {
var i = intent
var interval = serviceOffInterval
val serviceIntent = Intent(this, TelegramService::class.java)
val telegramService = telegramService
if (telegramService != null) {
i = intent or telegramService.usedBy
interval = if (TelegramService.isOffIntervalDepended(intent)) {
Math.min(telegramService.serviceOffInterval, interval)
} else {
telegramService.serviceOffInterval
}
telegramService.stopSelf()
}
serviceIntent.putExtra(TelegramService.USAGE_INTENT, i)
serviceIntent.putExtra(TelegramService.USAGE_OFF_INTERVAL, interval)
serviceIntent.putExtra(TelegramService.SEND_LOCATION_INTERVAL, settings.sendMyLocInterval)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(serviceIntent)
} else {
startService(serviceIntent)
}
ContextCompat.startForegroundService(this, serviceIntent)
}
fun startMyLocationService() {
val interval = settings.sendMyLocInterval
startTelegramService(TelegramService.USED_BY_MY_LOCATION, TelegramService.normalizeOffInterval(interval))
startTelegramService(TelegramService.USED_BY_MY_LOCATION)
}
fun stopMyLocationService() {

View file

@ -166,7 +166,7 @@ class TelegramLocationProvider(private val app: TelegramApplication) : SensorEve
registerOrUnregisterCompassListener(true)
}
fun redownloadAGPS() {
private fun redownloadAGPS() {
try {
val service = app.getSystemService(Context.LOCATION_SERVICE) as LocationManager
service.sendExtraCommand(LocationManager.GPS_PROVIDER, "delete_aiding_data", null)

View file

@ -1,16 +1,14 @@
package net.osmand.telegram
import android.annotation.SuppressLint
import android.app.AlarmManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.ServiceInfo
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.*
import android.util.Log
import android.widget.Toast
import net.osmand.PlatformUtil
import net.osmand.telegram.TelegramSettings.ShareChatInfo
@ -43,21 +41,14 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
private var updateWidgetHandler: Handler? = null
private var updateWidgetThread = HandlerThread("WidgetUpdateServiceThread")
var handler: Handler? = null
private set
var usedBy = 0
private set
var serviceOffProvider: String = LocationManager.GPS_PROVIDER
private set
var serviceOffInterval = 0L
private set
var serviceErrorInterval = 0L
private set
var sendLocationInterval = 0L
private set
private var lastLocationSentTime = 0L
private var pendingIntent: PendingIntent? = null
class LocationServiceBinder : Binder()
@ -71,7 +62,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
updateWidgetHandler = Handler(updateWidgetThread.looper)
}
override fun onBind(intent: Intent): IBinder? {
override fun onBind(intent: Intent): IBinder {
return binder
}
@ -86,13 +77,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
ctx.stopService(serviceIntent)
}
isUsedByMyLocation(usedBy) -> {
val app = app()
if (app.settings.sendMyLocInterval >= OFF_INTERVAL_THRESHOLD && serviceOffInterval == 0L) {
serviceOffInterval = app.settings.sendMyLocInterval
setupServiceErrorInterval()
setupAlarm()
}
app.notificationHelper.refreshNotification(NotificationType.LOCATION)
app().notificationHelper.refreshNotification(NotificationType.LOCATION)
}
isUsedByUsersLocations(usedBy) -> removeLocationUpdates()
}
@ -100,19 +85,21 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
val app = app()
handler = Handler()
val usageIntent = intent.getIntExtra(USAGE_INTENT, 0)
usedBy = usageIntent or usedBy
serviceOffInterval = intent.getLongExtra(USAGE_OFF_INTERVAL, 0)
sendLocationInterval = intent.getLongExtra(SEND_LOCATION_INTERVAL, 0)
setupServiceErrorInterval()
app.telegramHelper.addIncomingMessagesListener(this)
app.telegramHelper.addOutgoingMessagesListener(this)
app.telegramService = this
val locationNotification = app.notificationHelper.locationNotification
val notification = app.notificationHelper.buildNotification(locationNotification)
startForeground(locationNotification.telegramNotificationId, notification)
app.notificationHelper.refreshNotification(locationNotification.type)
if (isUsedByMyLocation(usedBy)) {
initLocationUpdates()
startShareInfoUpdates()
@ -124,21 +111,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
}
app.shareLocationHelper.checkAndSendBufferMessages()
val locationNotification = app.notificationHelper.locationNotification
val notification = app.notificationHelper.buildNotification(locationNotification)
startForeground(locationNotification.telegramNotificationId, notification)
app.notificationHelper.refreshNotification(locationNotification.type)
return Service.START_REDELIVER_INTENT
}
private fun setupServiceErrorInterval() {
serviceErrorInterval = serviceOffInterval / 5
// 1. not more than 12 mins
serviceErrorInterval = Math.min(serviceErrorInterval, 12 * 60 * 1000)
// 2. not less than 30 seconds
serviceErrorInterval = Math.max(serviceErrorInterval, 30 * 1000)
// 3. not more than serviceOffInterval
serviceErrorInterval = Math.min(serviceErrorInterval, serviceOffInterval)
return START_REDELIVER_INTENT
}
override fun onDestroy() {
@ -158,13 +131,6 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
removeLocationUpdates()
if (!isContinuous()) {
val lock = getLock(this)
if (lock.isHeld) {
lock.release()
}
}
if (shouldCleanupResources) {
app.cleanupResources()
}
@ -186,21 +152,16 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
val firstLocation = getFirstTimeRunDefaultLocation()
app().shareLocationHelper.updateLocation(firstLocation)
// requesting
if (isContinuous()) {
// request location updates
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
try {
locationManager.requestLocationUpdates(serviceOffProvider, 0, 0f, this@TelegramService)
} catch (e: SecurityException) {
Toast.makeText(this, R.string.no_location_permission, Toast.LENGTH_LONG).show()
Log.d(PlatformUtil.TAG, "Location service permission not granted") //$NON-NLS-1$
log.debug("Location service permission not granted")
} catch (e: IllegalArgumentException) {
Toast.makeText(this, R.string.gps_not_available, Toast.LENGTH_LONG).show()
Log.d(PlatformUtil.TAG, "GPS location provider not available") //$NON-NLS-1$
}
} else {
setupAlarm()
log.debug("GPS location provider not available")
}
}
@ -282,43 +243,19 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
return location
}
private fun setupAlarm() {
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
pendingIntent = PendingIntent.getBroadcast(this, 0, Intent(this, OnTelegramServiceAlarmReceiver::class.java), PendingIntent.FLAG_UPDATE_CURRENT)
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 500, serviceOffInterval, pendingIntent)
}
private fun removeLocationUpdates() {
// remove updates
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
try {
locationManager.removeUpdates(this)
} catch (e: SecurityException) {
Log.d(PlatformUtil.TAG, "Location service permission not granted")
log.debug("Location service permission not granted")
}
}
private fun isContinuous(): Boolean {
return serviceOffInterval == 0L
}
override fun onLocationChanged(l: Location?) {
val location = convertLocation(l)
if (!isContinuous()) {
// unregister listener and wait next time
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
try {
locationManager.removeUpdates(this)
} catch (e: Throwable) {
Log.d(PlatformUtil.TAG, "Location service permission not granted") //$NON-NLS-1$
}
val lock = getLock(this)
if (lock.isHeld) {
lock.release()
}
app().shareLocationHelper.updateLocation(location)
} else if (System.currentTimeMillis() - lastLocationSentTime > sendLocationInterval * 1000) {
if (System.currentTimeMillis() - lastLocationSentTime > sendLocationInterval * 1000) {
lastLocationSentTime = System.currentTimeMillis()
app().shareLocationHelper.updateLocation(location)
}
@ -373,7 +310,7 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
}
override fun onSendLiveLocationError(code: Int, message: String, shareInfo: ShareChatInfo, messageType: Int) {
Log.d(PlatformUtil.TAG, "Send live location error: $code - $message")
log.debug("Send live location error: $code - $message")
when (messageType) {
TelegramHelper.MESSAGE_TYPE_TEXT -> shareInfo.pendingTdLibText--
TelegramHelper.MESSAGE_TYPE_MAP -> {
@ -388,26 +325,8 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
const val USED_BY_MY_LOCATION: Int = 1
const val USED_BY_USERS_LOCATIONS: Int = 2
const val USAGE_INTENT = "SERVICE_USED_BY"
const val USAGE_OFF_INTERVAL = "SERVICE_OFF_INTERVAL"
const val SEND_LOCATION_INTERVAL = "SEND_LOCATION_INTERVAL"
const val OFF_INTERVAL_THRESHOLD: Long = 30000L
private var lockStatic: PowerManager.WakeLock? = null
@Synchronized
fun getLock(context: Context): PowerManager.WakeLock {
var lockStatic = lockStatic
return if (lockStatic == null) {
val mgr = context.getSystemService(Context.POWER_SERVICE) as PowerManager
lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "OsmandServiceLock")
this.lockStatic = lockStatic
lockStatic
} else {
lockStatic
}
}
fun isUsedByMyLocation(usedBy: Int): Boolean {
return (usedBy and USED_BY_MY_LOCATION) > 0
}
@ -416,14 +335,6 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
return (usedBy and USED_BY_USERS_LOCATIONS) > 0
}
fun isOffIntervalDepended(usedBy: Int): Boolean {
return isUsedByMyLocation(usedBy)
}
fun normalizeOffInterval(interval: Long): Long {
return if (interval < OFF_INTERVAL_THRESHOLD) 0 else interval
}
fun convertLocation(l: Location?): net.osmand.Location? {
if (l == null) {
return null

View file

@ -21,7 +21,6 @@ import android.widget.*
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.appbar.AppBarLayout
import net.osmand.PlatformUtil
import net.osmand.telegram.*
@ -42,7 +41,7 @@ private const val SUGGESTED = 2
private const val SHARE_LOCATION_CHAT = 1
private const val DEFAULT_CHAT = 0
private const val ADAPTER_UPDATE_INTERVAL_MIL = 5 * 1000L // 5 sec
private const val ADAPTER_UPDATE_INTERVAL_MS = 5 * 1000L // 5 sec
class MyLocationTabFragment : Fragment(), TelegramListener {
@ -380,7 +379,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
updateContent()
startHandler()
}
}, ADAPTER_UPDATE_INTERVAL_MIL)
}, ADAPTER_UPDATE_INTERVAL_MS)
}
private fun animateStartSharingBtn(show: Boolean) {

View file

@ -4049,6 +4049,6 @@
<string name="routing_engine_vehicle_type_car">Automóvil</string>
<string name="message_error_recheck_parameters">Error, vuelve a comprobar los parámetros</string>
<string name="copy_address">Copiar dirección</string>
<string name="online_routing_engine">Motor de ruta en línea</string>
<string name="online_routing_engine">Motor de navegación en línea</string>
<string name="online_routing_engines">Motores de navegación en línea</string>
</resources>

View file

@ -4005,4 +4005,14 @@
<string name="shared_string_last_used">Последний раз использовалось</string>
<string name="routing_attr_allow_intermittent_description">Разрешить прерывистые водные пути</string>
<string name="routing_attr_allow_intermittent_name">Разрешить прерывистые водные пути</string>
<string name="release_3_9">• Добавлена возможность экспорта и импорта всех данных, включая настройки, ресурсы, мои места.
\n
\n• Планирование маршрута: графики для сегментов трека с маршрутом, добавлена возможность создавать и редактировать несколько сегментов трека.
\n
\n• Добавлен OAuth метод аутентификации для OpenStreetMap, улучшен интерфейс диалоговых OSM.
\n
\n • Поддержка пользовательских цветов для избранного и путевых точек трека.
\n
\n</string>
<string name="copy_address">Скопировать адрес</string>
</resources>

View file

@ -93,18 +93,20 @@ public class AmenityMenuBuilder extends MenuBuilder {
protected void buildNearestPoiRow(View view) {
}
private void buildRow(View view, int iconId, String text, String textPrefix,
private void buildRow(View view, int iconId, String text, String textPrefix, String socialMediaUrl,
boolean collapsable, final CollapsableView collapsableView,
int textColor, boolean isWiki, boolean isText, boolean needLinks,
boolean isPhoneNumber, boolean isUrl, boolean matchWidthDivider, int textLinesLimit) {
buildRow(view, iconId == 0 ? null : getRowIcon(iconId), text, textPrefix, collapsable, collapsableView, textColor,
buildRow(view, iconId == 0 ? null : getRowIcon(iconId), text, textPrefix, socialMediaUrl,
collapsable, collapsableView, textColor,
isWiki, isText, needLinks, isPhoneNumber, isUrl, matchWidthDivider, textLinesLimit);
}
protected void buildRow(final View view, Drawable icon, final String text, final String textPrefix,
boolean collapsable, final CollapsableView collapsableView,
int textColor, boolean isWiki, boolean isText, boolean needLinks,
boolean isPhoneNumber, boolean isUrl, boolean matchWidthDivider, int textLinesLimit) {
final String socialMediaUrl, boolean collapsable,
final CollapsableView collapsableView, int textColor, boolean isWiki,
boolean isText, boolean needLinks, boolean isPhoneNumber, boolean isUrl,
boolean matchWidthDivider, int textLinesLimit) {
if (!isFirstRow()) {
buildRowDivider(view);
@ -312,8 +314,9 @@ public class AmenityMenuBuilder extends MenuBuilder {
WikipediaArticleWikiLinkFragment.showInstance(mapActivity.getSupportFragmentManager(), text);
}
} else {
String uri = socialMediaUrl == null ? text : socialMediaUrl;
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(text));
intent.setData(Uri.parse(uri));
v.getContext().startActivity(intent);
}
}
@ -366,6 +369,7 @@ public class AmenityMenuBuilder extends MenuBuilder {
continue;
}
String socialMediaUrl = null;
String textPrefix = "";
CollapsableView collapsableView = null;
boolean collapsable = false;
@ -397,6 +401,11 @@ public class AmenityMenuBuilder extends MenuBuilder {
if (vl.startsWith("http://") || vl.startsWith("https://") || vl.startsWith("HTTP://") || vl.startsWith("HTTPS://")) {
isUrl = true;
} else {
socialMediaUrl = getSocialMediaUrl(key, vl);
if (socialMediaUrl != null) {
isUrl = true;
}
}
if (pType != null && !pType.isText()) {
@ -557,16 +566,16 @@ public class AmenityMenuBuilder extends MenuBuilder {
AmenityInfoRow row;
if (isDescription) {
row = new AmenityInfoRow(key, R.drawable.ic_action_note_dark, textPrefix,
vl, collapsable, collapsableView, 0, false, true,
true, 0, "", false, false, matchWidthDivider, 0);
vl, null, collapsable, collapsableView, 0, false,
true, true, 0, "", false, false, matchWidthDivider, 0);
} else if (icon != null) {
row = new AmenityInfoRow(key, icon, textPrefix, vl, collapsable, collapsableView,
textColor, isWiki, isText, needLinks, poiTypeOrder, poiTypeKeyName,
isPhoneNumber, isUrl, matchWidthDivider, 0);
row = new AmenityInfoRow(key, icon, textPrefix, vl, socialMediaUrl, collapsable,
collapsableView, textColor, isWiki, isText, needLinks, poiTypeOrder,
poiTypeKeyName, isPhoneNumber, isUrl, matchWidthDivider, 0);
} else {
row = new AmenityInfoRow(key, iconId, textPrefix, vl, collapsable, collapsableView,
textColor, isWiki, isText, needLinks, poiTypeOrder, poiTypeKeyName,
isPhoneNumber, isUrl, matchWidthDivider, 0);
row = new AmenityInfoRow(key, iconId, textPrefix, vl, socialMediaUrl, collapsable,
collapsableView, textColor, isWiki, isText, needLinks, poiTypeOrder,
poiTypeKeyName, isPhoneNumber, isUrl, matchWidthDivider, 0);
}
if (isDescription) {
descriptions.add(row);
@ -613,8 +622,11 @@ public class AmenityMenuBuilder extends MenuBuilder {
}
boolean cuisineOrDish = categoryName.equals(Amenity.CUISINE) || categoryName.equals(Amenity.DISH);
CollapsableView collapsableView = getPoiTypeCollapsableView(view.getContext(), true, categoryTypes, true, cuisineOrDish ? cuisineRow : null);
infoRows.add(new AmenityInfoRow(poiAdditionalCategoryName, icon, pType.getPoiAdditionalCategoryTranslation(), sb.toString(), true, collapsableView,
0, false, false, false, pType.getOrder(), pType.getKeyName(), false, false, false, 1));
infoRows.add(new AmenityInfoRow(poiAdditionalCategoryName, icon,
pType.getPoiAdditionalCategoryTranslation(), sb.toString(), null,
true, collapsableView, 0, false, false,
false, pType.getOrder(), pType.getKeyName(), false,
false, false, 1));
}
}
@ -629,8 +641,10 @@ public class AmenityMenuBuilder extends MenuBuilder {
}
sb.append(pt.getTranslation());
}
infoRows.add(new AmenityInfoRow(poiCategory.getKeyName(), icon, poiCategory.getTranslation(), sb.toString(), true, collapsableView,
0, false, false, false, 40, poiCategory.getKeyName(), false, false, false, 1));
infoRows.add(new AmenityInfoRow(poiCategory.getKeyName(), icon,
poiCategory.getTranslation(), sb.toString(), null, true,
collapsableView, 0, false, false, false, 40,
poiCategory.getKeyName(), false, false, false, 1));
}
Collections.sort(infoRows, new Comparator<AmenityInfoRow>() {
@ -670,7 +684,8 @@ public class AmenityMenuBuilder extends MenuBuilder {
if (processNearestWiki() && nearestWiki.size() > 0) {
AmenityInfoRow wikiInfo = new AmenityInfoRow(
"nearest_wiki", R.drawable.ic_plugin_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", true,
"nearest_wiki", R.drawable.ic_plugin_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")",
null, true,
getCollapsableView(view.getContext(), true, nearestWiki),
0, false, false, false, 1000, null, false, false, false, 0);
buildAmenityRow(view, wikiInfo);
@ -678,8 +693,8 @@ public class AmenityMenuBuilder extends MenuBuilder {
if (processNearestPoi() && nearestPoi.size() > 0) {
AmenityInfoRow poiInfo = new AmenityInfoRow(
"nearest_poi", AmenityMenuController.getRightIconId(amenity), null,
app.getString(R.string.speak_poi) + " \"" + AmenityMenuController.getTypeStr(amenity) + "\" (" + nearestPoi.size() + ")", true,
"nearest_poi", AmenityMenuController.getRightIconId(amenity), null, app.getString(R.string.speak_poi) + " (" + nearestPoi.size() + ")",
null, true,
getCollapsableView(view.getContext(), true, nearestPoi),
0, false, false, false, 1000, null, false, false, false, 0);
buildAmenityRow(view, poiInfo);
@ -784,12 +799,14 @@ public class AmenityMenuBuilder extends MenuBuilder {
public void buildAmenityRow(View view, AmenityInfoRow info) {
if (info.icon != null) {
buildRow(view, info.icon, info.text, info.textPrefix, info.collapsable, info.collapsableView,
info.textColor, info.isWiki, info.isText, info.needLinks, info.isPhoneNumber,
buildRow(view, info.icon, info.text, info.textPrefix, info.socialMediaUrl,
info.collapsable, info.collapsableView, info.textColor, info.isWiki, info.isText,
info.needLinks, info.isPhoneNumber,
info.isUrl, info.matchWidthDivider, info.textLinesLimit);
} else {
buildRow(view, info.iconId, info.text, info.textPrefix, info.collapsable, info.collapsableView,
info.textColor, info.isWiki, info.isText, info.needLinks, info.isPhoneNumber,
buildRow(view, info.iconId, info.text, info.textPrefix, info.socialMediaUrl,
info.collapsable, info.collapsableView, info.textColor, info.isWiki, info.isText,
info.needLinks, info.isPhoneNumber,
info.isUrl, info.matchWidthDivider, info.textLinesLimit);
}
}
@ -893,12 +910,45 @@ public class AmenityMenuBuilder extends MenuBuilder {
return new CollapsableView(view, this, collapsed);
}
private String getSocialMediaUrl(String key, String value) {
// Remove leading and closing slashes
StringBuilder sb = new StringBuilder(value.trim());
if (sb.charAt(0) == '/') {
sb.deleteCharAt(0);
}
int lastIdx = sb.length() - 1;
if (sb.charAt(lastIdx) == '/') {
sb.deleteCharAt(lastIdx);
}
// It cannot be username
if (sb.indexOf("/") != -1) {
return "https://" + value;
}
Map<String, String> urls = new HashMap<>(7);
urls.put("facebook", "https://facebook.com/%s");
urls.put("vk", "https://vk.com/%s");
urls.put("instagram", "https://instagram.com/%s");
urls.put("twitter", "https://twitter.com/%s");
urls.put("ok", "https://ok.ru/%s");
urls.put("telegram", "https://t.me/%s");
urls.put("flickr", "https://flickr.com/%s");
if (urls.containsKey(key)) {
return String.format(urls.get(key), value);
} else {
return null;
}
}
private static class AmenityInfoRow {
private String key;
private Drawable icon;
private int iconId;
private String textPrefix;
private String text;
private String socialMediaUrl;
private CollapsableView collapsableView;
private boolean collapsable;
private int textColor;
@ -913,14 +963,16 @@ public class AmenityMenuBuilder extends MenuBuilder {
private int textLinesLimit;
public AmenityInfoRow(String key, Drawable icon, String textPrefix, String text,
boolean collapsable, CollapsableView collapsableView,
int textColor, boolean isWiki, boolean isText, boolean needLinks,
int order, String name, boolean isPhoneNumber, boolean isUrl,
String socialMediaUrl, boolean collapsable,
CollapsableView collapsableView, int textColor, boolean isWiki,
boolean isText, boolean needLinks, int order, String name,
boolean isPhoneNumber, boolean isUrl,
boolean matchWidthDivider, int textLinesLimit) {
this.key = key;
this.icon = icon;
this.textPrefix = textPrefix;
this.text = text;
this.socialMediaUrl = socialMediaUrl;
this.collapsable = collapsable;
this.collapsableView = collapsableView;
this.textColor = textColor;
@ -936,14 +988,16 @@ public class AmenityMenuBuilder extends MenuBuilder {
}
public AmenityInfoRow(String key, int iconId, String textPrefix, String text,
boolean collapsable, CollapsableView collapsableView,
int textColor, boolean isWiki, boolean isText, boolean needLinks,
int order, String name, boolean isPhoneNumber, boolean isUrl,
String socialMediaUrl, boolean collapsable,
CollapsableView collapsableView, int textColor, boolean isWiki,
boolean isText, boolean needLinks, int order, String name,
boolean isPhoneNumber, boolean isUrl,
boolean matchWidthDivider, int textLinesLimit) {
this.key = key;
this.iconId = iconId;
this.textPrefix = textPrefix;
this.text = text;
this.socialMediaUrl = socialMediaUrl;
this.collapsable = collapsable;
this.collapsableView = collapsableView;
this.textColor = textColor;