Custom Filter -> Edit Categories Bug
Merge branch 'master' of github.com:osmandapp/Osmand into kolomiets_branch
This commit is contained in:
commit
67ef319294
25 changed files with 3907 additions and 179 deletions
17
AUTHORS
17
AUTHORS
|
@ -1,17 +0,0 @@
|
|||
Copyright © OsmAnd 2010–2014
|
||||
### Credits to all major contributors/developers:
|
||||
* Victor Shcherb – all parts of the project, originator
|
||||
* Pavol Zibrita – first contributor and developer of some utilities
|
||||
* Dusan Kazik – one of the first contributors
|
||||
* Andre Van Atten – project supporter, active forum participant, one of the first users.
|
||||
* Dr. Hardy Mueller – map appearance concept and base renderers, international consistency and testing, usability, app scoping, concepts, documentation, wiki, market research.
|
||||
* Yvecai – main contributor to Contour Lines and Hillshade maps
|
||||
* Alexey Pelykh – C++ developer, created native library and made application much snappier.
|
||||
* Max (Zahnstocher) – Java contributor, active forum participant.
|
||||
* Harry van der Wolf – contributor to country boundaries, configuration files, address files, and much else; active forum participant.
|
||||
* Robin ‘ypid’ Schneider – opening hours contributor
|
||||
|
||||
### Other Pull requests
|
||||
Copyright © All authors of translations and pull requests could be found in commits history:
|
||||
- Translations are under special “contributor” name ‘weblate’
|
||||
- Pull requests have two committers, first is original contributor and second is project maintainer
|
7
AUTHORS.md
Normal file
7
AUTHORS.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
### Credits to all major contributors/developers:
|
||||
Major contributors /developers listed here https://github.com/osmandapp/osmandapp.github.io/blob/master/website/help/about.html#L8
|
||||
|
||||
### Other Pull requests
|
||||
Copyright © All authors of translations and pull requests could be found in commits history:
|
||||
- Translations are under special “contributor” name ‘weblate’
|
||||
- Pull requests have two committers, first is original contributor and second is project maintainer
|
|
@ -5,17 +5,20 @@ import gnu.trove.map.hash.TIntObjectHashMap;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||
import net.osmand.binary.OsmandOdb.TransportRouteSchedule;
|
||||
import net.osmand.data.TransportSchedule;
|
||||
import net.osmand.data.TransportStop;
|
||||
import net.osmand.data.TransportStopExit;
|
||||
import net.osmand.osm.edit.Node;
|
||||
import net.osmand.osm.edit.Way;
|
||||
import net.osmand.util.MapUtils;
|
||||
import net.sf.junidecode.Junidecode;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.CodedInputStream;
|
||||
import com.google.protobuf.WireFormat;
|
||||
|
||||
|
@ -238,6 +241,11 @@ public class BinaryMapTransportReaderAdapter {
|
|||
stringTable.putIfAbsent(i, "");
|
||||
return ((char) i)+"";
|
||||
}
|
||||
|
||||
private String regStr(TIntObjectHashMap<String> stringTable, int i) throws IOException{
|
||||
stringTable.putIfAbsent(i, "");
|
||||
return ((char) i)+"";
|
||||
}
|
||||
|
||||
public net.osmand.data.TransportRoute getTransportRoute(int filePointer, TIntObjectHashMap<String> stringTable,
|
||||
boolean onlyDescription) throws IOException {
|
||||
|
@ -446,12 +454,26 @@ public class BinaryMapTransportReaderAdapter {
|
|||
}
|
||||
|
||||
protected void initializeNames(TIntObjectHashMap<String> stringTable, TransportStop s) {
|
||||
for (TransportStopExit exit : s.getExits()) {
|
||||
if (exit.getRef().length() > 0) {
|
||||
exit.setRef(stringTable.get(exit.getRef().charAt(0)));
|
||||
}
|
||||
}
|
||||
if (s.getName().length() > 0) {
|
||||
s.setName(stringTable.get(s.getName().charAt(0)));
|
||||
}
|
||||
if (s.getEnName(false).length() > 0) {
|
||||
s.setEnName(stringTable.get(s.getEnName(false).charAt(0)));
|
||||
}
|
||||
Map<String, String> namesMap = new HashMap<>(s.getNamesMap(false));
|
||||
if (!s.getNamesMap(false).isEmpty()) {
|
||||
s.getNamesMap(false).clear();
|
||||
}
|
||||
Iterator<Map.Entry<String, String>> it = namesMap.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
Map.Entry<String, String> e = it.next();
|
||||
s.setName(stringTable.get(e.getKey().charAt(0)),stringTable.get(e.getValue().charAt(0)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -517,6 +539,7 @@ public class BinaryMapTransportReaderAdapter {
|
|||
TransportStop dataObject = new TransportStop();
|
||||
dataObject.setLocation(BinaryMapIndexReader.TRANSPORT_STOP_ZOOM, x, y);
|
||||
dataObject.setFileOffset(shift);
|
||||
List<String> names = null;
|
||||
while(true){
|
||||
int t = codedIS.readTag();
|
||||
tag = WireFormat.getTagFieldNumber(t);
|
||||
|
@ -543,16 +566,76 @@ public class BinaryMapTransportReaderAdapter {
|
|||
} else {
|
||||
skipUnknownField(t);
|
||||
}
|
||||
|
||||
break;
|
||||
case OsmandOdb.TransportStop.ADDITIONALNAMEPAIRS_FIELD_NUMBER :
|
||||
if (req.stringTable != null) {
|
||||
int sizeL = codedIS.readRawVarint32();
|
||||
int oldRef = codedIS.pushLimit(sizeL);
|
||||
while (codedIS.getBytesUntilLimit() > 0) {
|
||||
dataObject.setName(regStr(req.stringTable,codedIS.readRawVarint32()),
|
||||
regStr(req.stringTable,codedIS.readRawVarint32()));
|
||||
}
|
||||
codedIS.popLimit(oldRef);
|
||||
} else {
|
||||
skipUnknownField(t);
|
||||
}
|
||||
break;
|
||||
case OsmandOdb.TransportStop.ID_FIELD_NUMBER :
|
||||
dataObject.setId(codedIS.readSInt64());
|
||||
break;
|
||||
case OsmandOdb.TransportStop.EXITS_FIELD_NUMBER :
|
||||
int length = codedIS.readRawVarint32();
|
||||
int oldLimit = codedIS.pushLimit(length);
|
||||
|
||||
TransportStopExit transportStopExit = readTransportStopExit(cleft, ctop, req);
|
||||
dataObject.addExit(transportStopExit);
|
||||
codedIS.popLimit(oldLimit);
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private TransportStopExit readTransportStopExit(int cleft, int ctop, SearchRequest<TransportStop> req) throws IOException {
|
||||
|
||||
TransportStopExit dataObject = new TransportStopExit();
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
while (true) {
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
|
||||
switch (tag) {
|
||||
case 0:
|
||||
if (dataObject.getName("en").length() == 0) {
|
||||
dataObject.setEnName(Junidecode.unidecode(dataObject.getName()));
|
||||
}
|
||||
if (x != 0 || y != 0) {
|
||||
dataObject.setLocation(BinaryMapIndexReader.TRANSPORT_STOP_ZOOM, x, y);
|
||||
}
|
||||
return dataObject;
|
||||
case OsmandOdb.TransportStopExit.REF_FIELD_NUMBER:
|
||||
if (req.stringTable != null) {
|
||||
dataObject.setRef(regStr(req.stringTable));
|
||||
} else {
|
||||
skipUnknownField(t);
|
||||
}
|
||||
break;
|
||||
case OsmandOdb.TransportStopExit.DX_FIELD_NUMBER:
|
||||
x = codedIS.readSInt32() + cleft;
|
||||
break;
|
||||
case OsmandOdb.TransportStopExit.DY_FIELD_NUMBER:
|
||||
y = codedIS.readSInt32() + ctop;
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -77,6 +77,15 @@ public abstract class MapObject implements Comparable<MapObject> {
|
|||
}
|
||||
}
|
||||
|
||||
public void setNames(Map<String, String> name) {
|
||||
if (name != null) {
|
||||
if (names == null) {
|
||||
names = new HashMap<String, String>();
|
||||
}
|
||||
names.putAll(name);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getNamesMap(boolean includeEn) {
|
||||
if (!includeEn || Algorithms.isEmpty(enName)) {
|
||||
if (names == null) {
|
||||
|
|
|
@ -2,13 +2,20 @@ package net.osmand.data;
|
|||
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TransportStop extends MapObject {
|
||||
private int[] referencesToRoutes = null;
|
||||
private Amenity amenity;
|
||||
public int distance;
|
||||
public int x31;
|
||||
public int y31;
|
||||
|
||||
private List<TransportStopExit> exits;
|
||||
private HashMap<String,String> names;
|
||||
|
||||
public TransportStop(){
|
||||
}
|
||||
|
@ -39,4 +46,35 @@ public class TransportStop extends MapObject {
|
|||
y31 = dy << (31 - zoom);
|
||||
setLocation(MapUtils.getLatitudeFromTile(zoom, dy), MapUtils.getLongitudeFromTile(zoom, dx));
|
||||
}
|
||||
|
||||
public void addExit(TransportStopExit transportStopExit) {
|
||||
if (exits == null) {
|
||||
exits = new ArrayList<>();
|
||||
}
|
||||
exits.add(transportStopExit);
|
||||
}
|
||||
|
||||
public List<TransportStopExit> getExits () {
|
||||
if (exits == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return this.exits;
|
||||
}
|
||||
|
||||
public String getExitsString () {
|
||||
String exitsString = "";
|
||||
String refString = "";
|
||||
if (this.exits != null) {
|
||||
int i = 1;
|
||||
exitsString = exitsString + " Exits: [";
|
||||
for (TransportStopExit e : this.exits ) {
|
||||
if (e.getRef() != null) {
|
||||
refString = " [ref:" + e.getRef() + "] ";
|
||||
}
|
||||
exitsString = exitsString + " " + i + ")" + refString + e.getName() + " " + e.getLocation() + " ]";
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return exitsString;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package net.osmand.data;
|
||||
|
||||
import net.osmand.util.MapUtils;
|
||||
|
||||
public class TransportStopExit extends MapObject {
|
||||
public int x31;
|
||||
public int y31;
|
||||
public String ref = null;
|
||||
@Override
|
||||
public void setLocation(double latitude, double longitude) {
|
||||
super.setLocation(latitude, longitude);
|
||||
}
|
||||
public void setLocation(int zoom, int dx, int dy) {
|
||||
x31 = dx << (31 - zoom);
|
||||
y31 = dy << (31 - zoom);
|
||||
setLocation(MapUtils.getLatitudeFromTile(zoom, dy), MapUtils.getLongitudeFromTile(zoom, dx));
|
||||
}
|
||||
public void setRef (String ref) {
|
||||
this.ref = ref;
|
||||
}
|
||||
public String getRef() {
|
||||
if (ref != null) {
|
||||
return ref;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ public class OSMSettings {
|
|||
BOUNDARY("boundary"), //$NON-NLS-1$
|
||||
POSTAL_CODE("postal_code"), //$NON-NLS-1$
|
||||
RAILWAY("railway"), //$NON-NLS-1$
|
||||
STATION("subway"), //$NON-NLS-1$
|
||||
ONEWAY("oneway"), //$NON-NLS-1$
|
||||
LAYER("layer"), //$NON-NLS-1$
|
||||
BRIDGE("bridge"), //$NON-NLS-1$
|
||||
|
|
|
@ -28,7 +28,7 @@ public class TransportRoutePlanner {
|
|||
|
||||
|
||||
|
||||
public List<TransportRouteResult> buildRoute(TransportRoutingContext ctx, LatLon start, LatLon end) throws IOException {
|
||||
public List<TransportRouteResult> buildRoute(TransportRoutingContext ctx, LatLon start, LatLon end) throws IOException, InterruptedException {
|
||||
ctx.startCalcTime = System.currentTimeMillis();
|
||||
List<TransportRouteSegment> startStops = ctx.getTransportStops(start);
|
||||
List<TransportRouteSegment> endStops = ctx.getTransportStops(end);
|
||||
|
@ -45,7 +45,7 @@ public class TransportRoutePlanner {
|
|||
}
|
||||
double finishTime = ctx.cfg.maxRouteTime;
|
||||
List<TransportRouteSegment> results = new ArrayList<TransportRouteSegment>();
|
||||
|
||||
initProgressBar(ctx, start, end);
|
||||
while (!queue.isEmpty()) {
|
||||
TransportRouteSegment segment = queue.poll();
|
||||
TransportRouteSegment ex = ctx.visitedSegments.get(segment.getId());
|
||||
|
@ -56,7 +56,6 @@ public class TransportRoutePlanner {
|
|||
continue;
|
||||
}
|
||||
ctx.visitedRoutesCount++;
|
||||
System.out.println(segment);
|
||||
ctx.visitedSegments.put(segment.getId(), segment);
|
||||
if (segment.getDepth() > ctx.cfg.maxNumberOfChanges) {
|
||||
continue;
|
||||
|
@ -137,10 +136,36 @@ public class TransportRoutePlanner {
|
|||
results.add(finish);
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx.calculationProgress != null && ctx.calculationProgress.isCancelled) {
|
||||
throw new InterruptedException("Route calculation interrupted");
|
||||
}
|
||||
updateCalculationProgress(ctx, queue);
|
||||
|
||||
}
|
||||
|
||||
return prepareResults(ctx, results);
|
||||
}
|
||||
|
||||
private void initProgressBar(TransportRoutingContext ctx, LatLon start, LatLon end) {
|
||||
ctx.calculationProgress.distanceFromEnd = 0;
|
||||
ctx.calculationProgress.reverseSegmentQueueSize = 0;
|
||||
ctx.calculationProgress.directSegmentQueueSize = 0;
|
||||
float speed = (float) ctx.cfg.travelSpeed + 1; // assume
|
||||
ctx.calculationProgress.totalEstimatedDistance = (float) (MapUtils.getDistance(start, end)/ speed);
|
||||
}
|
||||
|
||||
private void updateCalculationProgress(TransportRoutingContext ctx, PriorityQueue<TransportRouteSegment> queue) {
|
||||
if (ctx.calculationProgress != null) {
|
||||
ctx.calculationProgress.directSegmentQueueSize = queue.size();
|
||||
if (queue.size() > 0) {
|
||||
TransportRouteSegment peek = queue.peek();
|
||||
ctx.calculationProgress.distanceFromBegin = (float) Math.max(peek.distFromStart,
|
||||
ctx.calculationProgress.distanceFromBegin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List<TransportRouteResult> prepareResults(TransportRoutingContext ctx, List<TransportRouteSegment> results) {
|
||||
Collections.sort(results, new SegmentsComparator(ctx));
|
||||
|
|
|
@ -146,4 +146,6 @@ dependencies {
|
|||
implementation("com.github.HITGIF:TextFieldBoxes:1.4.4") {
|
||||
exclude group: 'com.android.support'
|
||||
}
|
||||
|
||||
implementation 'net.sf.kxml:kxml2:2.1.8'
|
||||
}
|
||||
|
|
2
OsmAnd-telegram/res/values-zh-rTW/strings.xml
Normal file
2
OsmAnd-telegram/res/values-zh-rTW/strings.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources></resources>
|
|
@ -1,6 +1,9 @@
|
|||
package net.osmand;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
public class PlatformUtil {
|
||||
|
||||
|
@ -143,4 +146,11 @@ public class PlatformUtil {
|
|||
return getLog(cl.getName());
|
||||
}
|
||||
|
||||
public static XmlPullParser newXMLPullParser() throws XmlPullParserException {
|
||||
return new org.kxml2.io.KXmlParser();
|
||||
}
|
||||
|
||||
public static XmlSerializer newSerializer() {
|
||||
return new org.kxml2.io.KXmlSerializer();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ class TelegramApplication : Application(), OsmandHelperListener {
|
|||
lateinit var osmandAidlHelper: OsmandAidlHelper private set
|
||||
lateinit var locationProvider: TelegramLocationProvider private set
|
||||
lateinit var messagesDbHelper: MessagesDbHelper private set
|
||||
lateinit var savingTracksDbHelper: SavingTracksDbHelper private set
|
||||
|
||||
var telegramService: TelegramService? = null
|
||||
|
||||
|
@ -68,6 +69,7 @@ class TelegramApplication : Application(), OsmandHelperListener {
|
|||
notificationHelper = NotificationHelper(this)
|
||||
locationProvider = TelegramLocationProvider(this)
|
||||
messagesDbHelper = MessagesDbHelper(this)
|
||||
savingTracksDbHelper = SavingTracksDbHelper(this)
|
||||
|
||||
if (settings.hasAnyChatToShareLocation() && AndroidUtils.isLocationPermissionAvailable(this)) {
|
||||
shareLocationHelper.startSharingLocation()
|
||||
|
|
|
@ -105,7 +105,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
var appToConnectPackage = ""
|
||||
private set
|
||||
|
||||
var liveNowSortType = LiveNowSortType.SORT_BY_GROUP
|
||||
var liveNowSortType = LiveNowSortType.SORT_BY_DISTANCE
|
||||
|
||||
val gpsAndLocPrefs = listOf(SendMyLocPref(), StaleLocPref(), LocHistoryPref(), ShareTypePref())
|
||||
|
||||
|
@ -487,7 +487,7 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
appToConnectPackage = prefs.getString(APP_TO_CONNECT_PACKAGE_KEY, "")
|
||||
|
||||
liveNowSortType = LiveNowSortType.valueOf(
|
||||
prefs.getString(LIVE_NOW_SORT_TYPE_KEY, LiveNowSortType.SORT_BY_GROUP.name)
|
||||
prefs.getString(LIVE_NOW_SORT_TYPE_KEY, LiveNowSortType.SORT_BY_DISTANCE.name)
|
||||
)
|
||||
|
||||
batteryOptimisationAsked = prefs.getBoolean(BATTERY_OPTIMISATION_ASKED,false)
|
||||
|
|
|
@ -0,0 +1,311 @@
|
|||
package net.osmand.telegram.helpers;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.os.AsyncTask;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.telegram.TelegramApplication;
|
||||
import net.osmand.telegram.ui.LiveNowTabFragment;
|
||||
import net.osmand.telegram.utils.GPXUtilities;
|
||||
import net.osmand.telegram.utils.GPXUtilities.GPXFile;
|
||||
import net.osmand.telegram.utils.GPXUtilities.Track;
|
||||
import net.osmand.telegram.utils.GPXUtilities.TrkSegment;
|
||||
import net.osmand.telegram.utils.GPXUtilities.WptPt;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.drinkless.td.libcore.telegram.TdApi;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class SavingTracksDbHelper extends SQLiteOpenHelper {
|
||||
|
||||
private final static String DATABASE_NAME = "tracks";
|
||||
private final static int DATABASE_VERSION = 3;
|
||||
|
||||
private final static String TRACK_NAME = "track"; //$NON-NLS-1$
|
||||
private final static String TRACK_COL_USER_ID = "user_id"; //$NON-NLS-1$
|
||||
private final static String TRACK_COL_CHAT_ID = "chat_id"; //$NON-NLS-1$
|
||||
private final static String TRACK_COL_DATE = "date"; //$NON-NLS-1$
|
||||
private final static String TRACK_COL_LAT = "lat"; //$NON-NLS-1$
|
||||
private final static String TRACK_COL_LON = "lon"; //$NON-NLS-1$
|
||||
private final static String TRACK_COL_ALTITUDE = "altitude"; //$NON-NLS-1$
|
||||
private final static String TRACK_COL_SPEED = "speed"; //$NON-NLS-1$
|
||||
private final static String TRACK_COL_HDOP = "hdop"; //$NON-NLS-1$
|
||||
private final static String TRACK_COL_TEXT_INFO = "text_info"; // 1 = true, 0 = false //$NON-NLS-1$
|
||||
|
||||
private final static String INSERT_SCRIPT = "INSERT INTO " + TRACK_NAME + " (" + TRACK_COL_USER_ID + ", " + TRACK_COL_CHAT_ID + ", " + TRACK_COL_LAT + ", " + TRACK_COL_LON + ", "
|
||||
+ TRACK_COL_ALTITUDE + ", " + TRACK_COL_SPEED + ", " + TRACK_COL_HDOP + ", " + TRACK_COL_DATE + ", " + TRACK_COL_TEXT_INFO + ")"
|
||||
+ " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
private final static String CREATE_SCRIPT = "CREATE TABLE " + TRACK_NAME + " (" + TRACK_COL_USER_ID + " long," + TRACK_COL_CHAT_ID + " long," + TRACK_COL_LAT + " double, " + TRACK_COL_LON + " double, " //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$//$NON-NLS-5$
|
||||
+ TRACK_COL_ALTITUDE + " double, " + TRACK_COL_SPEED + " double, " //$NON-NLS-1$ //$NON-NLS-2$
|
||||
+ TRACK_COL_HDOP + " double, " + TRACK_COL_DATE + " long, " + TRACK_COL_TEXT_INFO + " int )";
|
||||
|
||||
public final static Log log = PlatformUtil.getLog(SavingTracksDbHelper.class);
|
||||
|
||||
private final TelegramApplication app;
|
||||
|
||||
public SavingTracksDbHelper(TelegramApplication app) {
|
||||
super(app, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
this.app = app;
|
||||
|
||||
app.getTelegramHelper().addIncomingMessagesListener(new TelegramHelper.TelegramIncomingMessagesListener() {
|
||||
|
||||
@Override
|
||||
public void onReceiveChatLocationMessages(long chatId, @NotNull TdApi.Message... messages) {
|
||||
for (TdApi.Message message : messages) {
|
||||
updateLocationMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleteChatLocationMessages(long chatId, @NotNull List<? extends TdApi.Message> messages) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLocationMessages() {
|
||||
|
||||
}
|
||||
});
|
||||
app.getTelegramHelper().addOutgoingMessagesListener(new TelegramHelper.TelegramOutgoingMessagesListener() {
|
||||
|
||||
@Override
|
||||
public void onUpdateMessages(@NotNull List<? extends TdApi.Message> messages) {
|
||||
for (TdApi.Message message : messages) {
|
||||
updateLocationMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleteMessages(long chatId, @NotNull List<Long> messages) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSendLiveLocationError(int code, @NotNull String message) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(CREATE_SCRIPT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if (oldVersion < 3) {
|
||||
db.execSQL("ALTER TABLE " + TRACK_NAME + " ADD " + TRACK_COL_TEXT_INFO + " int");
|
||||
}
|
||||
}
|
||||
|
||||
public void saveAsyncUserDataToGpx(LiveNowTabFragment fragment, File dir, int userId, long interval) {
|
||||
GPXFile gpxFile = app.getSavingTracksDbHelper().collectRecordedDataForUser(userId, interval);
|
||||
if (gpxFile != null && !gpxFile.isEmpty()) {
|
||||
LiveUpdatesPurchaseTask task = new LiveUpdatesPurchaseTask(fragment, gpxFile, dir, userId);
|
||||
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLocationMessage(TdApi.Message message) {
|
||||
TdApi.MessageContent content = message.content;
|
||||
if (content instanceof TdApi.MessageLocation) {
|
||||
long lastTextMessageUpdate = getLastTextTrackPointTimeForUser(message.senderUserId);
|
||||
long currentTime = System.currentTimeMillis();
|
||||
if (lastTextMessageUpdate == 0 || currentTime - lastTextMessageUpdate < 10 * 1000) {
|
||||
log.debug("Add map message" + message.senderUserId);
|
||||
TdApi.MessageLocation messageLocation = (TdApi.MessageLocation) content;
|
||||
insertData(message.senderUserId, message.chatId, messageLocation.location.latitude,
|
||||
messageLocation.location.longitude, 0.0, 0.0, 0.0,
|
||||
Math.max(message.date, message.editDate), 0);
|
||||
} else {
|
||||
log.debug("Skip map message");
|
||||
}
|
||||
} else if (content instanceof TelegramHelper.MessageLocation) {
|
||||
log.debug("Add text message " + message.senderUserId);
|
||||
TelegramHelper.MessageLocation messageLocation = (TelegramHelper.MessageLocation) content;
|
||||
insertData(message.senderUserId, message.chatId, messageLocation.getLat(), messageLocation.getLon(),
|
||||
messageLocation.getAltitude(), messageLocation.getSpeed(), messageLocation.getHdop(),
|
||||
messageLocation.getLastUpdated() * 1000L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void insertData(int userId, long chatId, double lat, double lon, double alt, double speed, double hdop, long time, int textMessage) {
|
||||
execWithClose(INSERT_SCRIPT, new Object[]{userId, chatId, lat, lon, alt, speed, hdop, time, textMessage});
|
||||
}
|
||||
|
||||
private synchronized void execWithClose(String script, Object[] objects) {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
try {
|
||||
if (db != null) {
|
||||
db.execSQL(script, objects);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
if (db != null) {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long getLastTextTrackPointTimeForUser(int userId) {
|
||||
long res = 0;
|
||||
try {
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
if (db != null) {
|
||||
try {
|
||||
Cursor query = db.rawQuery("SELECT " + TRACK_COL_DATE + " FROM " + TRACK_NAME + " WHERE " + TRACK_COL_USER_ID + " = ? AND "
|
||||
+ TRACK_COL_TEXT_INFO + " = ?" + " ORDER BY " + TRACK_COL_DATE + " ASC ", new String[]{String.valueOf(userId), String.valueOf(1)});
|
||||
if (query.moveToFirst()) {
|
||||
res = query.getLong(0);
|
||||
}
|
||||
query.close();
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private GPXFile collectRecordedDataForUser(int userId, long interval) {
|
||||
GPXFile gpxFile = null;
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
if (db != null && db.isOpen()) {
|
||||
try {
|
||||
gpxFile = collectDBTracksForUser(db, userId, interval);
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
}
|
||||
return gpxFile;
|
||||
}
|
||||
|
||||
private GPXFile collectDBTracksForUser(SQLiteDatabase db, int userId, long interval) {
|
||||
Cursor query = db.rawQuery("SELECT " + TRACK_COL_USER_ID + "," + TRACK_COL_CHAT_ID + "," + TRACK_COL_LAT + "," + TRACK_COL_LON + "," + TRACK_COL_ALTITUDE + "," //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
|
||||
+ TRACK_COL_SPEED + "," + TRACK_COL_HDOP + "," + TRACK_COL_DATE + " FROM " + TRACK_NAME +
|
||||
" WHERE " + TRACK_COL_USER_ID + " = ? ORDER BY " + TRACK_COL_DATE + " ASC ", new String[]{String.valueOf(userId)}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
GPXFile gpxFile = new GPXFile();
|
||||
long previousTime = 0;
|
||||
TrkSegment segment = null;
|
||||
Track track = null;
|
||||
if (query.moveToFirst()) {
|
||||
do {
|
||||
long time = query.getLong(7);
|
||||
long curTime = System.currentTimeMillis();
|
||||
if (curTime - time > interval) {
|
||||
continue;
|
||||
}
|
||||
WptPt pt = new WptPt();
|
||||
pt.userId = query.getInt(0);
|
||||
pt.chatId = query.getLong(1);
|
||||
pt.lat = query.getDouble(2);
|
||||
pt.lon = query.getDouble(3);
|
||||
pt.ele = query.getDouble(4);
|
||||
pt.speed = query.getDouble(5);
|
||||
pt.hdop = query.getDouble(6);
|
||||
pt.time = time;
|
||||
long currentInterval = Math.abs(time - previousTime);
|
||||
|
||||
if (track != null) {
|
||||
if (currentInterval < 30 * 60 * 1000) {
|
||||
// 30 minute - same segment
|
||||
segment.points.add(pt);
|
||||
} else {
|
||||
segment = new TrkSegment();
|
||||
segment.points.add(pt);
|
||||
track.segments.add(segment);
|
||||
}
|
||||
} else {
|
||||
track = new Track();
|
||||
segment = new TrkSegment();
|
||||
track.segments.add(segment);
|
||||
segment.points.add(pt);
|
||||
|
||||
gpxFile.tracks.add(track);
|
||||
}
|
||||
previousTime = time;
|
||||
} while (query.moveToNext());
|
||||
}
|
||||
query.close();
|
||||
return gpxFile;
|
||||
}
|
||||
|
||||
private static class LiveUpdatesPurchaseTask extends AsyncTask<Void, Void, List<String>> {
|
||||
|
||||
private TelegramApplication app;
|
||||
private WeakReference<LiveNowTabFragment> fragmentRef;
|
||||
|
||||
private final GPXFile gpxFile;
|
||||
private File dir;
|
||||
private int userId;
|
||||
|
||||
LiveUpdatesPurchaseTask(LiveNowTabFragment fragment, GPXFile gpxFile, File dir, int userId) {
|
||||
this.gpxFile = gpxFile;
|
||||
this.fragmentRef = new WeakReference<>(fragment);
|
||||
this.app = (TelegramApplication) fragment.getActivity().getApplication();
|
||||
this.dir = dir;
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> doInBackground(Void... params) {
|
||||
List<String> warnings = new ArrayList<String>();
|
||||
dir.mkdirs();
|
||||
if (dir.getParentFile().canWrite()) {
|
||||
if (dir.exists()) {
|
||||
|
||||
// save file
|
||||
File fout = new File(dir, userId + ".gpx"); //$NON-NLS-1$
|
||||
if (!gpxFile.isEmpty()) {
|
||||
WptPt pt = gpxFile.findPointToShow();
|
||||
|
||||
TdApi.User user = app.getTelegramHelper().getUser(pt.userId);
|
||||
String fileName;
|
||||
if (user != null) {
|
||||
fileName = TelegramUiHelper.INSTANCE.getUserName(user)
|
||||
+ "_" + new SimpleDateFormat("yyyy-MM-dd_HH-mm_EEE", Locale.US).format(new Date(pt.time)); //$NON-NLS-1$
|
||||
} else {
|
||||
fileName = userId + "_" + new SimpleDateFormat("yyyy-MM-dd_HH-mm_EEE", Locale.US).format(new Date(pt.time)); //$NON-NLS-1$
|
||||
}
|
||||
fout = new File(dir, fileName + ".gpx"); //$NON-NLS-1$
|
||||
int ind = 1;
|
||||
while (fout.exists()) {
|
||||
fout = new File(dir, fileName + "_" + (++ind) + ".gpx"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
String warn = GPXUtilities.writeGpxFile(fout, gpxFile, app);
|
||||
if (warn != null) {
|
||||
warnings.add(warn);
|
||||
return warnings;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return warnings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(List<String> warnings) {
|
||||
if (warnings != null && warnings.isEmpty()) {
|
||||
LiveNowTabFragment fragment = fragmentRef.get();
|
||||
if (fragment != null && fragment.isResumed()) {
|
||||
fragment.shareGpx(gpxFile.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -221,10 +221,10 @@ class TelegramHelper private constructor() {
|
|||
is MessageUserTextLocation -> content.lastUpdated
|
||||
else -> Math.max(message.editDate, message.date)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun isPrivateChat(chat: TdApi.Chat): Boolean = chat.type is TdApi.ChatTypePrivate
|
||||
|
||||
|
||||
fun isSecretChat(chat: TdApi.Chat): Boolean = chat.type is TdApi.ChatTypeSecret
|
||||
|
||||
private fun isChannel(chat: TdApi.Chat): Boolean {
|
||||
|
@ -384,7 +384,7 @@ class TelegramHelper private constructor() {
|
|||
is TdApi.ChatTypeSecret -> type.userId
|
||||
else -> 0
|
||||
}
|
||||
|
||||
|
||||
fun isOsmAndBot(userId: Int) = users[userId]?.username == OSMAND_BOT_USERNAME
|
||||
|
||||
fun isBot(userId: Int) = users[userId]?.type is TdApi.UserTypeBot
|
||||
|
@ -685,10 +685,16 @@ class TelegramHelper private constructor() {
|
|||
} else if (oldContent is TdApi.MessageLocation && (fromBot || viaBot)) {
|
||||
message.content = parseOsmAndBotLocation(message)
|
||||
}
|
||||
removeOldMessages(message, fromBot, viaBot)
|
||||
usersLocationMessages[message.id] = message
|
||||
incomingMessagesListeners.forEach {
|
||||
it.onReceiveChatLocationMessages(message.chatId, message)
|
||||
if (message.isOutgoing) {
|
||||
outgoingMessagesListeners.forEach {
|
||||
it.onUpdateMessages(listOf(message))
|
||||
}
|
||||
} else {
|
||||
removeOldMessages(message, fromBot, viaBot)
|
||||
usersLocationMessages[message.id] = message
|
||||
incomingMessagesListeners.forEach {
|
||||
it.onReceiveChatLocationMessages(message.chatId, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -753,7 +759,7 @@ class TelegramHelper private constructor() {
|
|||
stopSendingLiveLocationToChat(chatInfo)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun getActiveLiveLocationMessages(onComplete: (() -> Unit)?) {
|
||||
requestingActiveLiveLocationMessages = true
|
||||
client?.send(TdApi.GetActiveLiveLocationMessages()) { obj ->
|
||||
|
@ -1145,19 +1151,20 @@ class TelegramHelper private constructor() {
|
|||
if (isChannelPost) {
|
||||
return false
|
||||
}
|
||||
val content = content
|
||||
val isUserTextLocation = (content is TdApi.MessageText) && content.text.text.startsWith(USER_TEXT_LOCATION_TITLE)
|
||||
val isOsmAndBot = isOsmAndBot(senderUserId) || isOsmAndBot(viaBotUserId)
|
||||
if (isOutgoing && !isOsmAndBot) {
|
||||
if (!(isUserTextLocation || content is TdApi.MessageLocation || isOsmAndBot)) {
|
||||
return false
|
||||
}
|
||||
val lastEdited = Math.max(date, editDate)
|
||||
if (TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) - lastEdited > messageActiveTimeSec) {
|
||||
return false
|
||||
}
|
||||
val content = content
|
||||
val isUserTextLocation = (content is TdApi.MessageText) && content.text.text.startsWith(USER_TEXT_LOCATION_TITLE)
|
||||
|
||||
return when (content) {
|
||||
is TdApi.MessageLocation -> true
|
||||
is TdApi.MessageText -> (isOsmAndBot) && content.text.text.startsWith(DEVICE_PREFIX) || (isUserTextLocation && senderUserId != currentUser?.id)
|
||||
is TdApi.MessageText -> (isOsmAndBot) && content.text.text.startsWith(DEVICE_PREFIX) || isUserTextLocation
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
@ -1234,6 +1241,33 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
}
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
s.startsWith(SPEED_PREFIX) -> {
|
||||
val altStr = s.removePrefix(SPEED_PREFIX)
|
||||
try {
|
||||
val alt = altStr.split(" ").first()
|
||||
res.speed = alt.toDouble()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
s.startsWith(HDOP_PREFIX) -> {
|
||||
val altStr = s.removePrefix(HDOP_PREFIX)
|
||||
try {
|
||||
val alt = altStr.split(" ").first()
|
||||
res.hdop = alt.toDouble()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
s.startsWith(UPDATED_PREFIX) -> {
|
||||
if (res.lastUpdated == 0) {
|
||||
val updatedStr = s.removePrefix(UPDATED_PREFIX)
|
||||
|
@ -1291,6 +1325,12 @@ class TelegramHelper private constructor() {
|
|||
internal set
|
||||
var lastUpdated: Int = 0
|
||||
internal set
|
||||
var speed: Double = 0.0
|
||||
internal set
|
||||
var altitude: Double = 0.0
|
||||
internal set
|
||||
var hdop: Double = 0.0
|
||||
internal set
|
||||
|
||||
override fun getConstructor() = -1
|
||||
|
||||
|
@ -1510,7 +1550,7 @@ class TelegramHelper private constructor() {
|
|||
lastTelegramUpdateTime = Math.max(message.date, message.editDate)
|
||||
}
|
||||
incomingMessagesListeners.forEach {
|
||||
it.onReceiveChatLocationMessages(message.chatId, message)
|
||||
it.updateLocationMessages()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1536,6 +1576,7 @@ class TelegramHelper private constructor() {
|
|||
newContent
|
||||
}
|
||||
}
|
||||
log.debug("UpdateMessageContent " + message.senderUserId)
|
||||
incomingMessagesListeners.forEach {
|
||||
it.onReceiveChatLocationMessages(message.chatId, message)
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import net.osmand.telegram.utils.OsmandFormatter
|
|||
import net.osmand.telegram.utils.UiUtils.UpdateLocationViewCache
|
||||
import net.osmand.util.MapUtils
|
||||
import org.drinkless.td.libcore.telegram.TdApi
|
||||
import java.io.File
|
||||
|
||||
private const val CHAT_VIEW_TYPE = 0
|
||||
private const val LOCATION_ITEM_VIEW_TYPE = 1
|
||||
|
@ -232,6 +233,15 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
stopLocationUpdate()
|
||||
}
|
||||
|
||||
fun shareGpx(path: String) {
|
||||
val fileUri = AndroidUtils.getUriForFile(app, File(path))
|
||||
val sendIntent = Intent(Intent.ACTION_SEND)
|
||||
sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri)
|
||||
sendIntent.type = "application/gpx+xml"
|
||||
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
startActivity(sendIntent)
|
||||
}
|
||||
|
||||
private fun chooseOsmAnd() {
|
||||
val ctx = context ?: return
|
||||
val installedApps = TelegramSettings.AppConnect.getInstalledApps(ctx)
|
||||
|
@ -446,6 +456,15 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
app.showLocationHelper.showLocationOnMap(item, staleLocation)
|
||||
}
|
||||
}
|
||||
openOnMapView?.setOnLongClickListener {
|
||||
app.savingTracksDbHelper.saveAsyncUserDataToGpx(
|
||||
this@LiveNowTabFragment,
|
||||
app.getExternalFilesDir(null),
|
||||
item.userId,
|
||||
60 * 60 * 6 * 1000
|
||||
)
|
||||
true
|
||||
}
|
||||
} else {
|
||||
openOnMapView?.setOnClickListener(null)
|
||||
}
|
||||
|
@ -466,6 +485,17 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
if (lastItem) {
|
||||
holder.lastTelegramUpdateTime?.visibility = View.VISIBLE
|
||||
holder.lastTelegramUpdateTime?.text = OsmandFormatter.getListItemLiveTimeDescr(app, telegramHelper.lastTelegramUpdateTime, lastTelegramUpdateStr)
|
||||
holder.lastTelegramUpdateTime?.setOnClickListener {
|
||||
val currentUserId = telegramHelper.getCurrentUser()?.id
|
||||
if (currentUserId != null) {
|
||||
app.savingTracksDbHelper.saveAsyncUserDataToGpx(
|
||||
this@LiveNowTabFragment,
|
||||
app.getExternalFilesDir(null),
|
||||
currentUserId,
|
||||
60 * 60 * 6 * 1000
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
holder.lastTelegramUpdateTime?.visibility = View.GONE
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
private var actionButtonsListener: ActionButtonsListener? = null
|
||||
|
||||
private var sharingMode = false
|
||||
|
||||
|
||||
private var updateEnable: Boolean = false
|
||||
|
||||
override fun onCreateView(
|
||||
|
@ -96,7 +96,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
searchBoxSidesMargin = resources.getDimensionPixelSize(R.dimen.content_padding_half)
|
||||
|
||||
sharingMode = settings.hasAnyChatToShareLocation()
|
||||
|
||||
|
||||
savedInstanceState?.apply {
|
||||
val chatsArray = getLongArray(SELECTED_CHATS_KEY)
|
||||
val usersArray = getLongArray(SELECTED_CHATS_KEY)
|
||||
|
@ -137,7 +137,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
setupOptionsBtn(optionsBtn)
|
||||
setupOptionsBtn(mainView.findViewById<ImageView>(R.id.options_title))
|
||||
}
|
||||
|
||||
|
||||
imageContainer = mainView.findViewById<FrameLayout>(R.id.image_container)
|
||||
titleContainer = mainView.findViewById<LinearLayout>(R.id.title_container).apply {
|
||||
AndroidUtils.addStatusBarPadding19v(context, this)
|
||||
|
@ -146,8 +146,10 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
mainView.findViewById<TextView>(R.id.status_title).apply {
|
||||
val sharingStatus = getString(R.string.sharing_enabled)
|
||||
val spannable = SpannableString(sharingStatus)
|
||||
spannable.setSpan(ForegroundColorSpan(app.uiUtils.getActiveColor()),
|
||||
sharingStatus.indexOf(" "), sharingStatus.length, 0)
|
||||
spannable.setSpan(
|
||||
ForegroundColorSpan(app.uiUtils.getActiveColor()),
|
||||
sharingStatus.indexOf(" "), sharingStatus.length, 0
|
||||
)
|
||||
text = spannable
|
||||
}
|
||||
|
||||
|
@ -222,7 +224,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
updateContent()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return mainView
|
||||
}
|
||||
|
||||
|
@ -239,7 +241,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
super.onPause()
|
||||
updateEnable = false
|
||||
}
|
||||
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState.putLongArray(SELECTED_CHATS_KEY, selectedChats.toLongArray())
|
||||
|
@ -349,7 +351,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
}, ADAPTER_UPDATE_INTERVAL_MIL)
|
||||
}
|
||||
|
||||
|
||||
private fun animateStartSharingBtn(show: Boolean) {
|
||||
if (startSharingBtn.visibility == View.VISIBLE) {
|
||||
val scale = if (show) 1f else 0f
|
||||
|
@ -361,7 +363,7 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
.start()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun clearSelection() {
|
||||
selectedChats.clear()
|
||||
selectedUsers.clear()
|
||||
|
@ -450,7 +452,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
textContainer.visibility = if (sharingMode) View.GONE else View.VISIBLE
|
||||
titleContainer.visibility = if (sharingMode) View.VISIBLE else View.GONE
|
||||
startSharingBtn.visibility = if (sharingMode) View.VISIBLE else View.GONE
|
||||
headerParams.scrollFlags = if (sharingMode) 0 else AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
|
||||
headerParams.scrollFlags =
|
||||
if (sharingMode) 0 else AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL
|
||||
stopSharingSwitcher.isChecked = true
|
||||
appBarScrollRange = -1
|
||||
}
|
||||
|
@ -460,7 +463,12 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
settings.updateSharingStatusHistory()
|
||||
val sharingStatus = settings.sharingStatusChanges.last()
|
||||
sharingStatusTitle.text = sharingStatus.getTitle(app)
|
||||
sharingStatusIcon.setImageDrawable(app.uiUtils.getIcon(sharingStatus.statusType.iconId, sharingStatus.statusType.iconColorRes))
|
||||
sharingStatusIcon.setImageDrawable(
|
||||
app.uiUtils.getIcon(
|
||||
sharingStatus.statusType.iconId,
|
||||
sharingStatus.statusType.iconColorRes
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -490,7 +498,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
items.addAll(chats)
|
||||
if (!sharingMode) {
|
||||
for (user in contacts.values) {
|
||||
val containsInChats = chats.any { telegramHelper.getUserIdFromChatType(it.type) == user.id }
|
||||
val containsInChats =
|
||||
chats.any { telegramHelper.getUserIdFromChatType(it.type) == user.id }
|
||||
if ((!sharingMode && settings.isSharingLocationToUser(user.id)) || user.id == currentUser?.id || containsInChats) {
|
||||
continue
|
||||
}
|
||||
|
@ -520,8 +529,9 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
})
|
||||
return list
|
||||
}
|
||||
|
||||
inner class MyLocationListAdapter : RecyclerView.Adapter<MyLocationListAdapter.BaseViewHolder>() {
|
||||
|
||||
inner class MyLocationListAdapter :
|
||||
RecyclerView.Adapter<MyLocationListAdapter.BaseViewHolder>() {
|
||||
var items = mutableListOf<TdApi.Object>()
|
||||
set(value) {
|
||||
field = value
|
||||
|
@ -569,7 +579,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
|
||||
val lastItem = position == itemCount - 1
|
||||
val placeholderId = if (isChat && telegramHelper.isGroup(item as TdApi.Chat)) R.drawable.img_group_picture else R.drawable.img_user_picture
|
||||
val placeholderId =
|
||||
if (isChat && telegramHelper.isGroup(item as TdApi.Chat)) R.drawable.img_group_picture else R.drawable.img_user_picture
|
||||
val live = (isChat && settings.isSharingLocationToChat(itemId))
|
||||
val shareInfo = if (isChat) settings.getChatsShareInfo()[itemId] else null
|
||||
|
||||
|
@ -588,7 +599,12 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
|
||||
holder.title?.text = title
|
||||
|
||||
holder.icon?.setOnClickListener {
|
||||
app.forceUpdateMyLocation()
|
||||
val curUser = telegramHelper.getCurrentUser()
|
||||
val text = "${curUser?.id} ${curUser?.firstName} ${curUser?.lastName}"
|
||||
Toast.makeText(app, text, Toast.LENGTH_LONG).show()
|
||||
}
|
||||
if (holder is ChatViewHolder) {
|
||||
holder.description?.visibility = View.GONE
|
||||
if (live) {
|
||||
|
@ -648,7 +664,8 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
|
||||
val duration = shareInfo?.userSetLivePeriod
|
||||
if (duration != null && duration > 0) {
|
||||
holder.descriptionDuration?.text = OsmandFormatter.getFormattedDuration(context!!, duration)
|
||||
holder.descriptionDuration?.text =
|
||||
OsmandFormatter.getFormattedDuration(context!!, duration)
|
||||
holder.description?.apply {
|
||||
visibility = View.VISIBLE
|
||||
text = "${getText(R.string.sharing_time)}:"
|
||||
|
@ -656,19 +673,31 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
}
|
||||
|
||||
val expiresIn = shareInfo?.getChatLiveMessageExpireTime() ?: 0
|
||||
|
||||
|
||||
holder.textInArea?.apply {
|
||||
val time = shareInfo?.additionalActiveTime ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
||||
val time =
|
||||
shareInfo?.additionalActiveTime ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0]
|
||||
visibility = View.VISIBLE
|
||||
text = "+ ${OsmandFormatter.getFormattedDuration(context!!, time)}"
|
||||
setOnClickListener {
|
||||
val expireTime = shareInfo?.getChatLiveMessageExpireTime() ?: 0
|
||||
val newLivePeriod = expireTime + (shareInfo?.additionalActiveTime ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0])
|
||||
val nextAdditionalActiveTime = shareInfo?.getNextAdditionalActiveTime() ?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[1]
|
||||
val newLivePeriod = expireTime + (shareInfo?.additionalActiveTime
|
||||
?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[0])
|
||||
val nextAdditionalActiveTime = shareInfo?.getNextAdditionalActiveTime()
|
||||
?: ADDITIONAL_ACTIVE_TIME_VALUES_SEC[1]
|
||||
if (isChat) {
|
||||
settings.shareLocationToChat(itemId, true, newLivePeriod, nextAdditionalActiveTime)
|
||||
settings.shareLocationToChat(
|
||||
itemId,
|
||||
true,
|
||||
newLivePeriod,
|
||||
nextAdditionalActiveTime
|
||||
)
|
||||
} else {
|
||||
settings.shareLocationToUser(itemId.toInt(), newLivePeriod, nextAdditionalActiveTime)
|
||||
settings.shareLocationToUser(
|
||||
itemId.toInt(),
|
||||
newLivePeriod,
|
||||
nextAdditionalActiveTime
|
||||
)
|
||||
}
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
|
@ -686,13 +715,16 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
|
|||
|
||||
holder.stopSharingSecondPart?.apply {
|
||||
visibility = getStopSharingVisibility(expiresIn)
|
||||
text = "(${getString(R.string.in_time,
|
||||
OsmandFormatter.getFormattedDuration(context!!, expiresIn, true))})"
|
||||
text = "(${getString(
|
||||
R.string.in_time,
|
||||
OsmandFormatter.getFormattedDuration(context!!, expiresIn, true)
|
||||
)})"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getStopSharingVisibility(expiresIn: Long) = if (expiresIn > 0) View.VISIBLE else View.INVISIBLE
|
||||
private fun getStopSharingVisibility(expiresIn: Long) =
|
||||
if (expiresIn > 0) View.VISIBLE else View.INVISIBLE
|
||||
|
||||
private fun removeItem(chat: TdApi.Object) {
|
||||
items.remove(chat)
|
||||
|
|
1754
OsmAnd-telegram/src/net/osmand/telegram/utils/GPXUtilities.java
Normal file
1754
OsmAnd-telegram/src/net/osmand/telegram/utils/GPXUtilities.java
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,24 @@
|
|||
package net.osmand.telegram.utils;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
*/
|
||||
public interface LocationPoint {
|
||||
|
||||
public double getLatitude();
|
||||
|
||||
public double getLongitude();
|
||||
|
||||
public int getColor();
|
||||
|
||||
public boolean isVisible();
|
||||
|
||||
// public PointDescription getPointDescription(Context ctx);
|
||||
|
||||
// public String getSpeakableName();
|
||||
|
||||
//public void prepareCommandPlayer(CommandBuilder cmd, String names);
|
||||
|
||||
}
|
|
@ -3850,24 +3850,24 @@
|
|||
|
||||
<string name="poi_service_car">Servicio automotriz</string>
|
||||
|
||||
<string name="poi_service_vehicle_car_repair_yes">Taller mecánico</string>
|
||||
<string name="poi_service_vehicle_car_repair_yes">Taller para automóviles</string>
|
||||
<string name="poi_service_vehicle_oil_change_yes">Cambio de aceite</string>
|
||||
<string name="poi_service_vehicle_used_car_sales_yes">Venta de autos usados</string>
|
||||
<string name="poi_service_vehicle_brakes_yes">Frenos</string>
|
||||
<string name="poi_service_vehicle_new_car_sales_yes">Venta de autos nuevos</string>
|
||||
<string name="poi_service_vehicle_diagnostics_yes">Diagnóstico</string>
|
||||
<string name="poi_service_vehicle_diagnostics_yes">Diagnósticos</string>
|
||||
<string name="poi_service_vehicle_car_parts_yes">Autopartes</string>
|
||||
<string name="poi_service_vehicle_batteries_yes">Baterías</string>
|
||||
<string name="poi_service_vehicle_air_conditioning_yes">Aire acondicionado</string>
|
||||
<string name="poi_service_vehicle_body_repair_yes">Reparación de carrocería</string>
|
||||
<string name="poi_service_vehicle_body_repair_yes">Reparación de carrocerías</string>
|
||||
<string name="poi_service_vehicle_electrical_yes">Eléctrico</string>
|
||||
<string name="poi_service_vehicle_wheels_yes">Ruedas</string>
|
||||
<string name="poi_service_vehicle_glass_yes">Vidrio</string>
|
||||
<string name="poi_service_vehicle_truck_repair_yes">Taller mecánico para camiones</string>
|
||||
<string name="poi_service_vehicle_glass_yes">Vidrios</string>
|
||||
<string name="poi_service_vehicle_truck_repair_yes">Taller para camiones</string>
|
||||
<string name="poi_service_vehicle_muffler_yes">Silenciador</string>
|
||||
<string name="poi_service_vehicle_alignment_yes">Alineación</string>
|
||||
<string name="poi_service_vehicle_transmission_repair_yes">Reparación de la transmisión</string>
|
||||
<string name="poi_service_vehicle_motor_yes">Motor</string>
|
||||
<string name="poi_service_vehicle_motor_yes">Motores</string>
|
||||
<string name="poi_service_vehicle_insurance_yes">Aseguradora</string>
|
||||
<string name="poi_service_vehicle_tyres_yes">Neumáticos</string>
|
||||
|
||||
|
|
|
@ -2370,7 +2370,7 @@
|
|||
<string name="marker_moved_to_active">Kartmarkør flyttet til aktive</string>
|
||||
<string name="shared_string_list">Liste</string>
|
||||
<string name="passed">Sist brukt: %1$s</string>
|
||||
<string name="mapillary_menu_filter_description">Filtrer bilder etter innsender eller etter dato. Kun aktiv på høyere zoomnivåer.</string>
|
||||
<string name="mapillary_menu_filter_description">Filtrer bilder etter innsender, dato eller type. Kun aktivt på nærgående forstørrelsesnivå.</string>
|
||||
<string name="improve_coverage_install_mapillary_desc">Installer Mapillary for å legge til et eller flere bilder til denne kartposisjonen.</string>
|
||||
<string name="plugin_mapillary_descr">Foto på gatenivå for alle. Oppdag plasser, samarbeid, fang inn verden.</string>
|
||||
<string name="quick_action_showhide_osmbugs_title">Vis/skjul OSM-notater</string>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources><string name="poi_shoes">Skoaffär</string>
|
||||
<string name="poi_computer">Datorbutik</string>
|
||||
<string name="poi_shop">Butik</string>
|
||||
|
@ -3105,4 +3105,199 @@
|
|||
|
||||
<string name="poi_payment_troika_yes">Troika</string>
|
||||
<string name="poi_support_ceiling">Stöd: tak</string>
|
||||
</resources>
|
||||
<string name="poi_bulk_purchase">Massköp</string>
|
||||
<string name="poi_substation_type">Typ</string>
|
||||
<string name="poi_books_type">Bok</string>
|
||||
<string name="poi_car_pooling">Bilpoolplats</string>
|
||||
<string name="poi_atm">Bankomat</string>
|
||||
<string name="poi_pump_type_beam_pump">Pumptyp: domkraftspump</string>
|
||||
<string name="poi_pump_type_india_mk_2_3">Pumptyp: India Mk II eller III></string>
|
||||
<string name="poi_payment_troika_no">Troika-kort accepteras ej</string>
|
||||
<string name="poi_support_billboard">Stöd: billboard</string>
|
||||
<string name="poi_support_suspended">Stöd: upphängd</string>
|
||||
<string name="poi_support_roof">Stöd: tak</string>
|
||||
<string name="poi_support_tower">Stöd: torn</string>
|
||||
<string name="poi_passenger_information_display_yes">Skärm för passagerarinformation: ja</string>
|
||||
<string name="poi_passenger_information_display_no">Skärm för passagerarinformation: nej</string>
|
||||
<string name="poi_aquaculture">Vattenbruk</string>
|
||||
<string name="poi_aquaculture_shrimp">Vattenbruk: räkor</string>
|
||||
<string name="poi_aquaculture_fish">Vattenbruk: fisk</string>
|
||||
<string name="poi_aquaculture_mussels">Vattenbruk: musslor</string>
|
||||
<string name="poi_min_age">Lägsta ålder</string>
|
||||
<string name="poi_organic_yes">Ja</string>
|
||||
<string name="poi_organic_no">Nej</string>
|
||||
<string name="poi_organic_only">Endast</string>
|
||||
<string name="poi_traffic_mirror">Trafikspegel</string>
|
||||
<string name="poi_diplomatic_consulate">Konsulat</string>
|
||||
<string name="poi_diplomatic_consulate_general">Generalkonsulat</string>
|
||||
<string name="poi_diplomatic_honorary_consulate">Honorärkonsulat</string>
|
||||
<string name="poi_diplomatic_delegation">Delegation</string>
|
||||
<string name="poi_diplomatic_ambassadors_residence">Ambassadörsresidens</string>
|
||||
<string name="poi_water_tank">Vattentank</string>
|
||||
<string name="poi_length">Längd</string>
|
||||
<string name="poi_wiki_link">Wikipedia</string>
|
||||
<string name="poi_xmas">Jul</string>
|
||||
<string name="poi_xmas_event">Julhändelse</string>
|
||||
<string name="poi_xmas_market">Julmarknad</string>
|
||||
<string name="poi_xmas_pyramid">Julpyramid</string>
|
||||
<string name="poi_xmas_shop">Julbutik</string>
|
||||
<string name="poi_xmas_shop_christmas_tree">Julgranshandel</string>
|
||||
<string name="poi_xmas_tree">Julgran</string>
|
||||
<string name="poi_cuisine">Kök</string>
|
||||
<string name="poi_cuisine_pizza">Pizza</string>
|
||||
<string name="poi_cuisine_burger">Hamburgare</string>
|
||||
<string name="poi_cuisine_coffee">Kaffe</string>
|
||||
<string name="poi_cuisine_sandwich">Smörgås</string>
|
||||
<string name="poi_cuisine_kebab">Kebab</string>
|
||||
<string name="poi_cuisine_doner">Dönerkebab (shawarma)</string>
|
||||
<string name="poi_cuisine_chicken">Kyckling</string>
|
||||
<string name="poi_cuisine_ice_cream">Glass</string>
|
||||
<string name="poi_cuisine_sushi">Sushi</string>
|
||||
<string name="poi_cuisine_snack">Mellanmål</string>
|
||||
<string name="poi_cuisine_yogurt">Yoghurt</string>
|
||||
<string name="poi_cuisine_gyros">Gyros</string>
|
||||
<string name="poi_cuisine_empanada">Empanada</string>
|
||||
<string name="poi_cuisine_crepes">Crêpes</string>
|
||||
<string name="poi_cuisine_yakiniku">Yakiniku</string>
|
||||
<string name="poi_cuisine_suki">Suki</string>
|
||||
<string name="poi_cuisine_udon">Udon</string>
|
||||
<string name="poi_cuisine_brasserie">Brasserie</string>
|
||||
<string name="poi_cuisine_bubble_tea">Bubbelte</string>
|
||||
<string name="poi_cuisine_yakitori">Yakitori</string>
|
||||
<string name="poi_cuisine_sagardotegia">Sagardotegia</string>
|
||||
<string name="poi_cuisine_meat">Kött</string>
|
||||
<string name="poi_cuisine_wings">Vingar</string>
|
||||
<string name="poi_cuisine_waffle">Våfflor</string>
|
||||
<string name="poi_cuisine_chocolate">Choklad</string>
|
||||
<string name="poi_cuisine_wine">Vin</string>
|
||||
<string name="poi_cuisine_potato">Potatis</string>
|
||||
<string name="poi_cuisine_brunch">Brunch</string>
|
||||
<string name="poi_cuisine_sub">Sub</string>
|
||||
<string name="poi_cuisine_pita">Pita</string>
|
||||
<string name="poi_cuisine_fondue">Fondue</string>
|
||||
<string name="poi_cuisine_baguette">Baguette</string>
|
||||
<string name="poi_cuisine_pastel">Pastell</string>
|
||||
<string name="poi_cuisine_burrito">Burrito</string>
|
||||
<string name="poi_cuisine_teriyaki">Teriyaki</string>
|
||||
<string name="poi_cuisine_shawarma">Shawarma</string>
|
||||
<string name="poi_cuisine_regional">Regionalt</string>
|
||||
<string name="poi_cuisine_italian">Italienskt</string>
|
||||
<string name="poi_cuisine_chinese">Kinesiskt</string>
|
||||
<string name="poi_cuisine_mexican">Mexikanskt</string>
|
||||
<string name="poi_cuisine_japanese">Japanskt</string>
|
||||
<string name="poi_cuisine_german">Tyskt</string>
|
||||
<string name="poi_cuisine_indian">Indiskt</string>
|
||||
<string name="poi_cuisine_american">Amerikanskt</string>
|
||||
<string name="poi_cuisine_asian">Asiatiskt</string>
|
||||
<string name="poi_cuisine_french">Franskt</string>
|
||||
<string name="poi_cuisine_greek">Grekiskt</string>
|
||||
<string name="poi_cuisine_thai">Thailändskt</string>
|
||||
<string name="poi_cuisine_international">Internationellt</string>
|
||||
<string name="poi_cuisine_turkish">Turkiskt</string>
|
||||
<string name="poi_cuisine_spanish">Spanskt</string>
|
||||
<string name="poi_cuisine_vietnamese">Vietnamesiskt</string>
|
||||
<string name="poi_cuisine_korean">Koreanskt</string>
|
||||
<string name="poi_cuisine_mediterranean">Medelhavs</string>
|
||||
<string name="poi_cuisine_bavarian">Bayerskt</string>
|
||||
<string name="poi_cuisine_lebanese">"Libanesiskt "</string>
|
||||
<string name="poi_cuisine_russian">Ryskt</string>
|
||||
<string name="poi_cuisine_filipino">Filippinskt</string>
|
||||
<string name="poi_cuisine_portuguese">Portugisiskt</string>
|
||||
<string name="poi_cuisine_georgian">Georgiskt</string>
|
||||
<string name="poi_cuisine_polish">Polskt</string>
|
||||
<string name="poi_cuisine_brazilian">Brasilianskt</string>
|
||||
<string name="poi_cuisine_arab">Arabiskt</string>
|
||||
<string name="poi_cuisine_danish">Danskt</string>
|
||||
<string name="poi_cuisine_indonesian">Indonesiskt</string>
|
||||
<string name="poi_cuisine_african">Afrikanskt</string>
|
||||
<string name="poi_cuisine_caribbean">Karibiskt</string>
|
||||
<string name="poi_cuisine_argentinian">Argentinskt</string>
|
||||
<string name="poi_cuisine_balkan">Balkan</string>
|
||||
<string name="poi_cuisine_peruvian">Peruanskt</string>
|
||||
<string name="poi_cuisine_croatian">Kroatiskt</string>
|
||||
<string name="poi_cuisine_bolivian">Bolivianskt</string>
|
||||
<string name="poi_cuisine_malagasy">Malagassiskt</string>
|
||||
<string name="poi_cuisine_persian">Persiskt</string>
|
||||
<string name="poi_cuisine_moroccan">Marockanskt</string>
|
||||
<string name="poi_cuisine_austrian">Österrikiskt</string>
|
||||
<string name="poi_cuisine_malaysian">Malajiskt</string>
|
||||
<string name="poi_cuisine_irish">Irländskt</string>
|
||||
<string name="poi_cuisine_ethiopian">Etiopiskt</string>
|
||||
<string name="poi_cuisine_hungarian">Ungerskt</string>
|
||||
<string name="poi_cuisine_lao">Laotiskt</string>
|
||||
<string name="poi_cuisine_european">Europeiskt</string>
|
||||
<string name="poi_cuisine_uzbek">Uzbekiskt</string>
|
||||
<string name="poi_cuisine_czech">Tjeckiskt</string>
|
||||
<string name="poi_cuisine_cuban">Kubanskt</string>
|
||||
<string name="poi_cuisine_british">Brittiskt</string>
|
||||
<string name="poi_cuisine_latin_american">Latinamerikanskt</string>
|
||||
<string name="poi_cuisine_nepalese">Nepalesiskt</string>
|
||||
<string name="poi_cuisine_mongolian">Mongoliskt</string>
|
||||
<string name="poi_cuisine_middle_eastern">Mellanöstern</string>
|
||||
<string name="poi_cuisine_ukrainian">Ukrainskt</string>
|
||||
<string name="poi_cuisine_afghan">Afghanskt</string>
|
||||
<string name="poi_cuisine_belgian">Belgiskt</string>
|
||||
<string name="poi_cuisine_basque">Baskiskt</string>
|
||||
<string name="poi_cuisine_swiss">"Schweiziskt "</string>
|
||||
<string name="poi_cuisine_cantonese">Kantonesiskt</string>
|
||||
<string name="poi_cuisine_swedish">Svenskt</string>
|
||||
<string name="poi_cuisine_jamaican">Jamaicanskt</string>
|
||||
<string name="poi_cuisine_armenian">Armeniskt</string>
|
||||
<string name="poi_cuisine_hawaiian">"Hawaiianskt "</string>
|
||||
<string name="poi_cuisine_english">Engelskt</string>
|
||||
<string name="poi_cuisine_pakistani">Pakistanskt</string>
|
||||
<string name="poi_cuisine_taiwanese">Taiwanesiskt</string>
|
||||
<string name="poi_cuisine_tex_mex">Tex-mex</string>
|
||||
<string name="poi_cuisine_dutch">Holländskt</string>
|
||||
<string name="poi_cuisine_syrian">Syrianskt</string>
|
||||
<string name="poi_cuisine_australian">Australienskt</string>
|
||||
<string name="poi_cuisine_cajun">Cajun</string>
|
||||
<string name="poi_cuisine_egyptian">Egyptiskt</string>
|
||||
<string name="poi_cuisine_senegalese">Senegalesiskt</string>
|
||||
<string name="poi_cuisine_jewish">Judiskt</string>
|
||||
<string name="poi_cuisine_bulgarian">Bulgariskt</string>
|
||||
<string name="poi_cuisine_tibetan">Tibetanskt</string>
|
||||
<string name="poi_feeding_place">Plats för utfodring av djur</string>
|
||||
<string name="poi_party">Festutrustning</string>
|
||||
<string name="poi_electrical">Elbutik</string>
|
||||
<string name="poi_locksmith">Låssmed</string>
|
||||
<string name="poi_lighting">Belysning</string>
|
||||
<string name="poi_lottery">Lotterier</string>
|
||||
<string name="poi_gambling_type">Typ</string>
|
||||
<string name="poi_gambling_lottery">Lotteri</string>
|
||||
<string name="poi_gambling_pachinko">Pachinko</string>
|
||||
<string name="poi_gambling_slot_machines">Spelautomater</string>
|
||||
<string name="poi_gambling_betting">Betting</string>
|
||||
<string name="poi_gambling_bingo">Bingo</string>
|
||||
<string name="poi_e_cigarette">E-cigarettbutik</string>
|
||||
<string name="poi_locomotive">Lok</string>
|
||||
<string name="poi_nutrition_supplements">Kosttillskott</string>
|
||||
<string name="poi_photo_studio">Fotostudio</string>
|
||||
<string name="poi_cliff">Klippa</string>
|
||||
<string name="poi_animal_keeping">Djurhållning</string>
|
||||
<string name="poi_animal_keeping_horse">Djurhållning: häst</string>
|
||||
<string name="poi_animal_keeping_sheep">Djurhållning: får</string>
|
||||
<string name="poi_animal_keeping_type_paddock">Typ: paddock</string>
|
||||
<string name="poi_animal_keeping_type_open_stable">Typ: öppet stall</string>
|
||||
<string name="poi_tower_construction_lattice">Konstruktion: fackverk</string>
|
||||
<string name="poi_tower_construction_freestanding">Konstruktion: fristående</string>
|
||||
<string name="poi_tower_construction_dish">Konstruktion: disk</string>
|
||||
<string name="poi_tower_construction_dome">Konstruktion: dom</string>
|
||||
<string name="poi_tower_construction_concealed">Konstruktion: dold</string>
|
||||
<string name="poi_railway_yard">Fraktstation</string>
|
||||
<string name="poi_fast_food_cafeteria">Ja</string>
|
||||
<string name="poi_drink_wine_yes">Vin: ja</string>
|
||||
<string name="poi_drink_wine_retail">Vin: detaljhandel</string>
|
||||
<string name="poi_drink_wine_served">Vin: serveras</string>
|
||||
<string name="poi_energy_supplier">Energileverantör</string>
|
||||
<string name="poi_electronics_repair_computer">Reparation av elektronik: datorer</string>
|
||||
<string name="poi_electronics_repair_appliance">Elektronik reparationer: apparater</string>
|
||||
<string name="poi_electronics_repair_phone">Reparation av elektronik: telefon</string>
|
||||
<string name="poi_electronics_repair_tv">Reparation av elektronik: tv</string>
|
||||
<string name="poi_resort_kids_camp">Barnläger</string>
|
||||
<string name="poi_music_school">Musikskola</string>
|
||||
<string name="poi_language_school">Språkskola</string>
|
||||
<string name="poi_life_ring">Livboj</string>
|
||||
<string name="poi_zoo_safari_park">Safaripark</string>
|
||||
<string name="poi_zoo_birds">Fåglar</string>
|
||||
</resources>
|
|
@ -364,6 +364,7 @@ public class MapActivityActions implements DialogProvider {
|
|||
adapter.addItem(new ContextMenuItem.ItemBuilder()
|
||||
.setTitleId(R.string.context_menu_item_add_waypoint, mapActivity)
|
||||
.setTitle(MAP_CONTEXT_MENU_ADD_GPX_WAYPOINT)
|
||||
.setId(POINT_ADD_GPX_WAYPOINT)
|
||||
.setIcon(R.drawable.ic_action_gnew_label_dark)
|
||||
.setOrder(ADD_GPX_WAYPOINT_ITEM_ORDER)
|
||||
.setListener(listener).createItem());
|
||||
|
|
|
@ -233,7 +233,7 @@ public class DownloadActivityType {
|
|||
}
|
||||
|
||||
public String getBaseUrl(OsmandApplication ctx, String fileName) {
|
||||
String url = "http://" + IndexConstants.INDEX_DOWNLOAD_DOMAIN + "/download?event=2&"
|
||||
String url = "https://" + IndexConstants.INDEX_DOWNLOAD_DOMAIN + "/download?event=2&"
|
||||
+ Version.getVersionAsURLParam(ctx) + "&file=" + encode(fileName);
|
||||
if(this == LIVE_UPDATES_FILE && fileName.length() > 16) {
|
||||
// DATE_AND_EXT_STR_LEN = "_18_06_02.obf.gz".length()
|
||||
|
|
Loading…
Reference in a new issue