Merge branch 'master' into Point_menu_change_route_type
# Conflicts: # OsmAnd/src/net/osmand/plus/measurementtool/RouteBetweenPointsBottomSheetDialogFragment.java
This commit is contained in:
commit
4c100c7366
760 changed files with 44218 additions and 22788 deletions
2
.github/ISSUE_TEMPLATE/2-faq-report.md
vendored
2
.github/ISSUE_TEMPLATE/2-faq-report.md
vendored
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
name: "📚 Outdated FAQ"
|
||||
about: Report an issue in FAQ
|
||||
|
||||
---
|
||||
|
||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||
|
||||
Please do not file FAQ issues on the GitHub issues tracker.
|
||||
|
|
67
.github/ISSUE_TEMPLATE/3-bug-report.md
vendored
67
.github/ISSUE_TEMPLATE/3-bug-report.md
vendored
|
@ -2,68 +2,17 @@
|
|||
name: "\U0001F41E Bug report"
|
||||
about: Report a bug in OsmAnd
|
||||
---
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
|
||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
||||
|
||||
GitHub is our main development tool for our developers. There are hundreds of requests a month and there are relatively few developers.
|
||||
So by opening an issue, please know that your issue will be sent out to all developers and acknowledge that it could be closed without explanation or with just a brief message.
|
||||
Comments on the closed issues are also sent to all developers, so you will definitely will be heard.
|
||||
However, there is no guarantee that a developer will pick up the issue to work on it.
|
||||
|
||||
Please be sure to read our [FAQ](https://osmand.net/help-online) before creating an issue here.
|
||||
|
||||
The best way to get help about an OsmAnd issue is to create a valid and detailed issue.
|
||||
Please give us the following information so that we can try to **reproduce** your issue:
|
||||
|
||||
🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅-->
|
||||
|
||||
# 🐞 bug report
|
||||
|
||||
### Is this a regression?
|
||||
|
||||
<!-- Did this behavior use to work in the previous version? -->
|
||||
<!-- ✍️--> Yes, the previous version in which this bug was not present was: ....
|
||||
|
||||
|
||||
### Description
|
||||
|
||||
<!-- ✍️--> A clear and concise description of the problem...
|
||||
|
||||
### How to reproduce?
|
||||
|
||||
|
||||
## 🔬 Minimal Reproduction
|
||||
<!--
|
||||
If the bug is reproducible, please describe steps below:
|
||||
-->
|
||||
<!-- ✍️--> 1. Open app, and click on ...
|
||||
### Your Environment
|
||||
OsmAnd Version:
|
||||
Android/iOS version:
|
||||
Device model:
|
||||
|
||||
## 🔥 Exception or Error
|
||||
<pre><code>
|
||||
<!-- If the issue is accompanied by an exception or an error, please share it below: -->
|
||||
<!-- ✍️-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
|
||||
## 🌍 Your Environment
|
||||
|
||||
**OsmAnd Version:**
|
||||
<pre><code>
|
||||
<!-- paste version below -->
|
||||
<!-- ✍️-->
|
||||
|
||||
</code></pre>
|
||||
|
||||
**Device and Android/iOS version:**
|
||||
|
||||
**Maps used (online or offline):**
|
||||
<!-- Please tick the correct box [x] (or both) -->
|
||||
- [ ] Offline maps offered within the OsmAnd app for download.
|
||||
<!-- If you have an issue related to offline maps, tell us the exact name of the map file where the issue occurs and its edition date. -->
|
||||
- [ ] Online (tile / raster) maps <!-- Please name it -->
|
||||
|
||||
|
||||
**Anything else relevant?**
|
||||
**Maps used (online or offline):**
|
||||
If you have an issue related to offline maps, tell us the exact name of the map file where the issue occurs and its edition date.
|
||||
|
|
14
.github/ISSUE_TEMPLATE/4-routing-report.md
vendored
14
.github/ISSUE_TEMPLATE/4-routing-report.md
vendored
|
@ -2,6 +2,7 @@
|
|||
name: "\U0001F6A9 Routing report"
|
||||
about: Report a routing issue in OsmAnd
|
||||
---
|
||||
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
|
@ -26,10 +27,12 @@ Please give us the following information so that we can try to **reproduce** you
|
|||
### Routing engine
|
||||
|
||||
<!-- Which routing provider was used? (please tick the proper box [x]) -->
|
||||
|
||||
- [ ] OsmAnd's in-app offline routing
|
||||
- [ ] Any online routing provider (YOURS, OpenRouteService, OSRM, etc.)
|
||||
|
||||
### Routing Profile
|
||||
|
||||
<!-- What routing profile is chosen in the OsmAnd app? (car, bike, pedestrian, fastest or shortest, etc.) -->
|
||||
|
||||
### Start and end points
|
||||
|
@ -38,6 +41,7 @@ Please give us the following information so that we can try to **reproduce** you
|
|||
Also, a permalink from [openstreetmap.org](https://www.openstreetmap.org/) can be helpful. -->
|
||||
|
||||
### Actual and expected routes
|
||||
|
||||
<!-- Tell us your expected routing and how OsmAnd routes, or add screenshots here. -->
|
||||
|
||||
### Is this a regression?
|
||||
|
@ -45,9 +49,10 @@ Also, a permalink from [openstreetmap.org](https://www.openstreetmap.org/) can b
|
|||
<!-- Did this behavior use to work in the previous version? -->
|
||||
<!-- ✍️--> Yes, the previous version in which this bug was not present was: ....
|
||||
|
||||
## 🌍 Your Environment
|
||||
## 🌍 Your Environment
|
||||
|
||||
**OsmAnd Version:**
|
||||
|
||||
<pre><code>
|
||||
<!-- paste version below -->
|
||||
<!-- ✍️-->
|
||||
|
@ -57,10 +62,11 @@ Also, a permalink from [openstreetmap.org](https://www.openstreetmap.org/) can b
|
|||
**Device and Android/iOS version:**
|
||||
|
||||
**Maps used (online or offline):**
|
||||
|
||||
<!-- Please tick the correct box [x] (or both) -->
|
||||
- [ ] Offline maps offered within the OsmAnd app for download.
|
||||
<!-- If you have an issue related to offline maps, tell us the exact name of the map file where the issue occurs and its edition date. -->
|
||||
|
||||
- [ ] Offline maps offered within the OsmAnd app for download.
|
||||
<!-- If you have an issue related to offline maps, tell us the exact name of the map file where the issue occurs and its edition date. -->
|
||||
- [ ] Online (tile / raster) maps <!-- Please name it -->
|
||||
|
||||
|
||||
**Anything else relevant?**
|
||||
|
|
11
.github/ISSUE_TEMPLATE/5-feature-request.md
vendored
11
.github/ISSUE_TEMPLATE/5-feature-request.md
vendored
|
@ -1,18 +1,18 @@
|
|||
---
|
||||
name: "\U0001F680 Feature request"
|
||||
about: Suggest a feature for OsmAnd
|
||||
|
||||
---
|
||||
|
||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||
|
||||
Oh hi there! 😄
|
||||
Oh hi there! 😄
|
||||
|
||||
To expedite issue processing please search open and closed issues before submitting a new one.
|
||||
Existing issues often contain information about workarounds, resolution, or progress updates.
|
||||
|
||||
GitHub is our main development tool for our developers. There are hundreds of requests a month and there are relatively few developers.
|
||||
So by opening an issue, please know that your issue will be sent out to all developers and acknowledge that it could be closed without explanation or with just a brief message.
|
||||
Comments on the closed issues are also sent to all developers, so you will definitely will be heard.
|
||||
Comments on the closed issues are also sent to all developers, so you definitely will be heard.
|
||||
However, there is no guarantee that a developer will pick up the issue to work on it.
|
||||
|
||||
Please be sure to read our [FAQ](https://osmand.net/help-online) before creating an issue here.
|
||||
|
@ -22,12 +22,13 @@ Please be sure to read our [FAQ](https://osmand.net/help-online) before creating
|
|||
# 🚀 feature request
|
||||
|
||||
### Description
|
||||
<!-- ✍️--> A clear and concise description of the problem or missing capability...
|
||||
|
||||
<!-- ✍️ A clear and concise description of the feature... -->
|
||||
|
||||
### Describe the solution you'd like
|
||||
|
||||
<!-- ✍️--> If you have a solution in mind, please describe it.
|
||||
|
||||
|
||||
### Describe alternatives you've considered
|
||||
|
||||
<!-- ✍️--> Have you considered any alternative solutions or workarounds?
|
||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -19,6 +19,10 @@ OsmAndCore_*.aar
|
|||
.project
|
||||
out/
|
||||
|
||||
# Huawei
|
||||
agconnect-services.json
|
||||
OsmAndHms.jks
|
||||
|
||||
# Android Studio
|
||||
/.idea
|
||||
*.iml
|
||||
|
|
157
GPX.md
Normal file
157
GPX.md
Normal file
|
@ -0,0 +1,157 @@
|
|||
The OsmAnd's GPX file format conforms to the GPX 1.1 specification with additional data written as extensions. There are several sections of such data:
|
||||
|
||||
## Track appearance
|
||||
The following parameters are used to customize the appearance of a track on the map. They are used inside the "gpx" tag and apply to all tracks contained in the gpx.
|
||||
#### Parameters
|
||||
* **show_arrows** [*true, false*] - show / hide arrows along the path line.
|
||||
* **width** [*thin, medium, bold, 1-24*] - width of the track line on the map. The thin, medium, and bold are style depended values (should be defined as currentTrackWidth attribute).
|
||||
* **color** [*#AARRGGBB, #RRGGBB*] - color of a track line on the map. Hex value.
|
||||
* **split_type** [*no_split, distance, time*] - split type for a track.
|
||||
* **split_interval** [*double*] - split interval for a track. Distance (meters), time (seconds).
|
||||
|
||||
#### Example:
|
||||
```xml
|
||||
<gpx version="1.1" creator="OsmAndRouterV2" xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
|
||||
...
|
||||
<extensions>
|
||||
<show_arrows>true</show_arrows>
|
||||
<color>#4e4eff</color>
|
||||
<split_type>distance</split_type>
|
||||
<split_interval>2000.0</split_interval>
|
||||
<width>bold</width>
|
||||
</extensions>
|
||||
</gpx>
|
||||
```
|
||||
## Details of a track point (trkpt)
|
||||
Written to a gpx file while recording a track.
|
||||
* **speed** (meters per second)
|
||||
* **heading** (0-359 degrees)
|
||||
|
||||
#### Example:
|
||||
```xml
|
||||
<trkpt lat="52.397799" lon="4.575998">
|
||||
<ele>203</ele>
|
||||
<time>2019-05-08T10:36:43Z</time>
|
||||
<hdop>3</hdop>
|
||||
<extensions>
|
||||
<heading>273</heading>
|
||||
<speed>5.02</speed>
|
||||
</extensions>
|
||||
</trkpt>
|
||||
```
|
||||
|
||||
## Calculated route(s)
|
||||
This data contains all details of a route built with **OsmAnd** (route segments, turns, road names, road types, restrictions, etc.). The route can be completely restored as if just built, even in the absence of the respective offline maps.
|
||||
|
||||
A gpx file may contain several routes. Each of them is contained in a specific segment under **trkseg** / **extensions**. A gpx file is saved in this form when exporting a constructed route or when saving a track that consists of several separate segments via the **Plan a route** functionality.
|
||||
**Plan a route** also adds one (or several, in accordance with the number of contained separate segments / tracks) **rte** blocks to the gpx file, containing route key points (**rtept**).
|
||||
#### Gpx structure:
|
||||
```xml
|
||||
<trk>
|
||||
<trkseg>
|
||||
<!-- List of segment points. The order of the points corresponds to the order and length of the route segments (<route><segment length="x" ... />). -->
|
||||
<!-- The value of the "length" attribute corresponds to the number of points in this segment of the route. -->
|
||||
<trkpt ... ></trkpt>
|
||||
<extensions>
|
||||
<!-- List of route segments -->
|
||||
<route>
|
||||
<segment ... />
|
||||
</route>
|
||||
<!-- Properties of segments included in the route. -->
|
||||
<!-- This data is taken from offline maps during the initial construction of a route. -->
|
||||
<types>
|
||||
<type ... />
|
||||
</types>
|
||||
</extensions>
|
||||
</trkseg>
|
||||
</trk>
|
||||
|
||||
<!-- List of intermediate route points. If there are multiple routes, the order of the rte list matches the order of the route segments. -->
|
||||
<rte>
|
||||
<rtept ... />
|
||||
<!-- For routes built with the "Plan route", the parameters of key points are saved. -->
|
||||
<extensions>
|
||||
<!-- Route profile type for next segment (car, bicycle, pedestrian, etc.). -->
|
||||
<profile>...</profile>
|
||||
<!-- The index of the point in the gpx segment that corresponds to the first point of the calculated route for this segment. -->
|
||||
<trkpt_idx>...</trkpt_idx>
|
||||
</extensions>
|
||||
</rtept>
|
||||
</rte>
|
||||
```
|
||||
|
||||
#### Example:
|
||||
```xml
|
||||
<gpx version="1.1" creator="OsmAndRouterV2" xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
|
||||
<metadata>
|
||||
<name>Fri 06 Nov 2020</name>
|
||||
</metadata>
|
||||
<trk>
|
||||
<name>Fri 06 Nov 2020</name>
|
||||
<trkseg>
|
||||
<trkpt lat="52.3639849" lon="4.8900533">
|
||||
<ele>0.801</ele>
|
||||
</trkpt>
|
||||
<trkpt lat="52.3636917" lon="4.8922849">
|
||||
<ele>0.998</ele>
|
||||
</trkpt>
|
||||
<trkpt lat="52.3636885" lon="4.892309">
|
||||
<ele>1</ele>
|
||||
</trkpt>
|
||||
<trkpt lat="52.3636426" lon="4.8922902">
|
||||
<ele>0.963</ele>
|
||||
</trkpt>
|
||||
<trkpt lat="52.363564" lon="4.8922607">
|
||||
<ele>0.899</ele>
|
||||
</trkpt>
|
||||
|
||||
....
|
||||
|
||||
<extensions>
|
||||
<route>
|
||||
<segment id="7372058" length="3" segmentTime="178.44" speed="1.11" turnType="C" types="0,1,2,3,4,5,6" names="57" />
|
||||
<segment id="334164679" length="5" segmentTime="86.11" speed="1.11" turnType="TR" turnAngle="91.88" types="7,8,0,9,10,11,12,13,6" pointTypes=";;14,15;16,17,18;" names="58" />
|
||||
<segment id="334603581" length="6" segmentTime="75.5" speed="1.11" types="19,20,21,7,8,0,22,9,10,11,12,13,23,6" pointTypes=";14;16,24;16,24;14;" names="58" />
|
||||
<segment id="446707354" length="3" segmentTime="8.32" speed="1.11" turnType="TSLL" turnAngle="-25.44" types="19,25,21,7,8,22,9,1,11,12,13,6" names="58" />
|
||||
...
|
||||
</route>
|
||||
<types>
|
||||
<type t="lit" v="yes" />
|
||||
<type t="oneway" v="yes" />
|
||||
<type t="highway" v="unclassified" />
|
||||
<type t="surface" v="paving_stones" />
|
||||
<type t="maxspeed" v="30" />
|
||||
...
|
||||
</types>
|
||||
</extensions>
|
||||
</trkseg>
|
||||
</trk>
|
||||
|
||||
<rte>
|
||||
<rtept lat="52.3639945" lon="4.8900532">
|
||||
<extensions>
|
||||
<profile>pedestrian</profile>
|
||||
<trkpt_idx>0</trkpt_idx>
|
||||
</extensions>
|
||||
</rtept>
|
||||
<rtept lat="52.3612797" lon="4.8911677">
|
||||
<extensions>
|
||||
<profile>pedestrian</profile>
|
||||
<trkpt_idx>24</trkpt_idx>
|
||||
</extensions>
|
||||
</rtept>
|
||||
<rtept lat="52.356996" lon="4.8912071">
|
||||
<extensions>
|
||||
<profile>pedestrian</profile>
|
||||
<trkpt_idx>89</trkpt_idx>
|
||||
</extensions>
|
||||
</rtept>
|
||||
<rtept lat="52.3542374" lon="4.8947024">
|
||||
<extensions>
|
||||
<profile>pedestrian</profile>
|
||||
<trkpt_idx>121</trkpt_idx>
|
||||
</extensions>
|
||||
</rtept>
|
||||
</rte>
|
||||
</gpx>
|
||||
```
|
|
@ -20,6 +20,8 @@ import net.osmand.aidlapi.mapmarker.UpdateMapMarkerParams;
|
|||
|
||||
import net.osmand.aidlapi.calculateroute.CalculateRouteParams;
|
||||
|
||||
import net.osmand.aidlapi.profile.ExportProfileParams;
|
||||
|
||||
import net.osmand.aidlapi.gpx.ImportGpxParams;
|
||||
import net.osmand.aidlapi.gpx.ShowGpxParams;
|
||||
import net.osmand.aidlapi.gpx.StartGpxRecordingParams;
|
||||
|
@ -103,6 +105,8 @@ import net.osmand.aidlapi.events.AKeyEventsParams;
|
|||
|
||||
import net.osmand.aidlapi.info.AppInfoParams;
|
||||
|
||||
import net.osmand.aidlapi.profile.ExportProfileParams;
|
||||
|
||||
// NOTE: Add new methods at the end of file!!!
|
||||
|
||||
interface IOsmAndAidlInterface {
|
||||
|
@ -867,4 +871,16 @@ interface IOsmAndAidlInterface {
|
|||
AppInfoParams getAppInfo();
|
||||
|
||||
boolean setMapMargins(in MapMarginsParams params);
|
||||
|
||||
boolean exportProfile(in ExportProfileParams params);
|
||||
|
||||
/**
|
||||
* Is any fragment open.
|
||||
*/
|
||||
boolean isFragmentOpen();
|
||||
|
||||
/**
|
||||
* Is contect menu open.
|
||||
*/
|
||||
boolean isMenuOpen();
|
||||
}
|
|
@ -4,6 +4,8 @@ public interface OsmAndCustomizationConstants {
|
|||
|
||||
// Navigation Drawer:
|
||||
String DRAWER_ITEM_ID_SCHEME = "drawer.action.";
|
||||
String DRAWER_SWITCH_PROFILE_ID = DRAWER_ITEM_ID_SCHEME + "switch_profile";
|
||||
String DRAWER_CONFIGURE_PROFILE_ID = DRAWER_ITEM_ID_SCHEME + "configure_profile";
|
||||
String DRAWER_DASHBOARD_ID = DRAWER_ITEM_ID_SCHEME + "dashboard";
|
||||
String DRAWER_MAP_MARKERS_ID = DRAWER_ITEM_ID_SCHEME + "map_markers";
|
||||
String DRAWER_MY_PLACES_ID = DRAWER_ITEM_ID_SCHEME + "my_places";
|
||||
|
|
|
@ -9,12 +9,21 @@ import net.osmand.aidlapi.AidlParams;
|
|||
|
||||
public class CopyFileParams extends AidlParams {
|
||||
|
||||
public static final String DESTINATION_DIR_KEY = "destinationDir";
|
||||
public static final String FILE_NAME_KEY = "fileName";
|
||||
public static final String FILE_PART_DATA_KEY = "filePartData";
|
||||
public static final String START_TIME_KEY = "startTime";
|
||||
public static final String DONE_KEY = "done";
|
||||
private String destinationDir;
|
||||
private String fileName;
|
||||
private byte[] filePartData;
|
||||
private long startTime;
|
||||
private boolean done;
|
||||
|
||||
public CopyFileParams(@NonNull String fileName, @NonNull byte[] filePartData, long startTime, boolean done) {
|
||||
public CopyFileParams(@NonNull String destinationDir, @NonNull String fileName, @NonNull byte[] filePartData,
|
||||
long startTime, boolean done) {
|
||||
|
||||
this.destinationDir = destinationDir;
|
||||
this.fileName = fileName;
|
||||
this.filePartData = filePartData;
|
||||
this.startTime = startTime;
|
||||
|
@ -37,6 +46,10 @@ public class CopyFileParams extends AidlParams {
|
|||
}
|
||||
};
|
||||
|
||||
public String getDestinationDir() {
|
||||
return destinationDir;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return fileName;
|
||||
}
|
||||
|
@ -55,23 +68,26 @@ public class CopyFileParams extends AidlParams {
|
|||
|
||||
@Override
|
||||
public void writeToBundle(Bundle bundle) {
|
||||
bundle.putString("fileName", fileName);
|
||||
bundle.putByteArray("filePartData", filePartData);
|
||||
bundle.putLong("startTime", startTime);
|
||||
bundle.putBoolean("done", done);
|
||||
bundle.putString(DESTINATION_DIR_KEY, destinationDir);
|
||||
bundle.putString(FILE_NAME_KEY, fileName);
|
||||
bundle.putByteArray(FILE_PART_DATA_KEY, filePartData);
|
||||
bundle.putLong(START_TIME_KEY, startTime);
|
||||
bundle.putBoolean(DONE_KEY, done);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromBundle(Bundle bundle) {
|
||||
fileName = bundle.getString("fileName");
|
||||
filePartData = bundle.getByteArray("filePartData");
|
||||
startTime = bundle.getLong("startTime");
|
||||
done = bundle.getBoolean("done");
|
||||
destinationDir = bundle.getString(DESTINATION_DIR_KEY);
|
||||
fileName = bundle.getString(FILE_NAME_KEY);
|
||||
filePartData = bundle.getByteArray(FILE_PART_DATA_KEY);
|
||||
startTime = bundle.getLong(START_TIME_KEY);
|
||||
done = bundle.getBoolean(DONE_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CopyFileParams {" +
|
||||
" destinationDir=" + destinationDir +
|
||||
" fileName=" + fileName +
|
||||
", filePartData size=" + filePartData.length +
|
||||
", startTime=" + startTime +
|
||||
|
|
|
@ -3,18 +3,31 @@ package net.osmand.aidlapi.customization;
|
|||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import net.osmand.aidlapi.AidlParams;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MapMarginsParams extends AidlParams {
|
||||
|
||||
private String appModeKey;
|
||||
public static final String LEFT_MARGIN_KEY = "leftMargin";
|
||||
public static final String TOP_MARGIN_KEY = "topMargin";
|
||||
public static final String RIGHT_MARGIN_KEY = "rightMargin";
|
||||
public static final String BOTTOM_MARGIN_KEY = "bottomMargin";
|
||||
public static final String APP_MODES_KEYS_KEY = "appModesKeys";
|
||||
private ArrayList<String> appModesKeys = new ArrayList<>();
|
||||
private int leftMargin;
|
||||
private int topMargin;
|
||||
private int rightMargin;
|
||||
private int bottomMargin;
|
||||
|
||||
public MapMarginsParams(String appModeKey, int leftMargin, int topMargin, int rightMargin, int bottomMargin) {
|
||||
this.appModeKey = appModeKey;
|
||||
public MapMarginsParams(int leftMargin, int topMargin, int rightMargin, int bottomMargin,
|
||||
@Nullable List<String> appModesKeys) {
|
||||
if (appModesKeys != null) {
|
||||
this.appModesKeys.addAll(appModesKeys);
|
||||
}
|
||||
this.leftMargin = leftMargin;
|
||||
this.topMargin = topMargin;
|
||||
this.rightMargin = rightMargin;
|
||||
|
@ -37,8 +50,8 @@ public class MapMarginsParams extends AidlParams {
|
|||
}
|
||||
};
|
||||
|
||||
public String getAppModeKey() {
|
||||
return appModeKey;
|
||||
public List<String> getAppModesKeys() {
|
||||
return appModesKeys;
|
||||
}
|
||||
|
||||
public int getLeftMargin() {
|
||||
|
@ -59,19 +72,19 @@ public class MapMarginsParams extends AidlParams {
|
|||
|
||||
@Override
|
||||
public void writeToBundle(Bundle bundle) {
|
||||
bundle.putString("appModeKey", appModeKey);
|
||||
bundle.putInt("leftMargin", leftMargin);
|
||||
bundle.putInt("topMargin", topMargin);
|
||||
bundle.putInt("rightMargin", rightMargin);
|
||||
bundle.putInt("bottomMargin", bottomMargin);
|
||||
bundle.putInt(LEFT_MARGIN_KEY, leftMargin);
|
||||
bundle.putInt(TOP_MARGIN_KEY, topMargin);
|
||||
bundle.putInt(RIGHT_MARGIN_KEY, rightMargin);
|
||||
bundle.putInt(BOTTOM_MARGIN_KEY, bottomMargin);
|
||||
bundle.putStringArrayList(APP_MODES_KEYS_KEY, appModesKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromBundle(Bundle bundle) {
|
||||
appModeKey = bundle.getString("appModeKey");
|
||||
leftMargin = bundle.getInt("leftMargin");
|
||||
topMargin = bundle.getInt("topMargin");
|
||||
rightMargin = bundle.getInt("rightMargin");
|
||||
bottomMargin = bundle.getInt("bottomMargin");
|
||||
leftMargin = bundle.getInt(LEFT_MARGIN_KEY);
|
||||
topMargin = bundle.getInt(TOP_MARGIN_KEY);
|
||||
rightMargin = bundle.getInt(RIGHT_MARGIN_KEY);
|
||||
bottomMargin = bundle.getInt(BOTTOM_MARGIN_KEY);
|
||||
appModesKeys = bundle.getStringArrayList(APP_MODES_KEYS_KEY);
|
||||
}
|
||||
}
|
|
@ -5,15 +5,31 @@ import android.os.Bundle;
|
|||
import android.os.Parcel;
|
||||
|
||||
import net.osmand.aidlapi.AidlParams;
|
||||
import net.osmand.aidlapi.profile.AExportSettingsType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static net.osmand.aidlapi.profile.ExportProfileParams.SETTINGS_TYPE_KEY;
|
||||
|
||||
public class ProfileSettingsParams extends AidlParams {
|
||||
|
||||
public static final String VERSION_KEY = "version";
|
||||
public static final String REPLACE_KEY = "replace";
|
||||
public static final String LATEST_CHANGES_KEY = "latestChanges";
|
||||
public static final String PROFILE_SETTINGS_URI_KEY = "profileSettingsUri";
|
||||
private Uri profileSettingsUri;
|
||||
private String latestChanges;
|
||||
private int version;
|
||||
private ArrayList<String> settingsTypeKeyList = new ArrayList<>();
|
||||
boolean replace;
|
||||
|
||||
public ProfileSettingsParams(Uri profileSettingsUri, String latestChanges, int version) {
|
||||
public ProfileSettingsParams(Uri profileSettingsUri, ArrayList<AExportSettingsType> settingsTypeList, boolean replace,
|
||||
String latestChanges, int version) {
|
||||
this.profileSettingsUri = profileSettingsUri;
|
||||
for (AExportSettingsType settingsType : settingsTypeList) {
|
||||
settingsTypeKeyList.add(settingsType.name());
|
||||
}
|
||||
this.replace = replace;
|
||||
this.latestChanges = latestChanges;
|
||||
this.version = version;
|
||||
}
|
||||
|
@ -46,17 +62,29 @@ public class ProfileSettingsParams extends AidlParams {
|
|||
return profileSettingsUri;
|
||||
}
|
||||
|
||||
public ArrayList<String> getSettingsTypeKeys() {
|
||||
return settingsTypeKeyList;
|
||||
}
|
||||
|
||||
public boolean isReplace() {
|
||||
return replace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToBundle(Bundle bundle) {
|
||||
bundle.putInt("version", version);
|
||||
bundle.putString("latestChanges", latestChanges);
|
||||
bundle.putParcelable("profileSettingsUri", profileSettingsUri);
|
||||
bundle.putInt(VERSION_KEY, version);
|
||||
bundle.putString(LATEST_CHANGES_KEY, latestChanges);
|
||||
bundle.putParcelable(PROFILE_SETTINGS_URI_KEY, profileSettingsUri);
|
||||
bundle.putStringArrayList(SETTINGS_TYPE_KEY, settingsTypeKeyList);
|
||||
bundle.putBoolean(REPLACE_KEY, replace);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromBundle(Bundle bundle) {
|
||||
version = bundle.getInt("version");
|
||||
latestChanges = bundle.getString("latestChanges");
|
||||
profileSettingsUri = bundle.getParcelable("profileSettingsUri");
|
||||
version = bundle.getInt(VERSION_KEY);
|
||||
latestChanges = bundle.getString(LATEST_CHANGES_KEY);
|
||||
profileSettingsUri = bundle.getParcelable(PROFILE_SETTINGS_URI_KEY);
|
||||
settingsTypeKeyList = bundle.getStringArrayList(SETTINGS_TYPE_KEY);
|
||||
replace = bundle.getBoolean(REPLACE_KEY);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package net.osmand.aidlapi.profile;
|
||||
|
||||
parcelable AExportSettingsType;
|
|
@ -0,0 +1,11 @@
|
|||
package net.osmand.aidlapi.profile;
|
||||
|
||||
public enum AExportSettingsType {
|
||||
PROFILE,
|
||||
QUICK_ACTIONS,
|
||||
POI_TYPES,
|
||||
MAP_SOURCES,
|
||||
CUSTOM_RENDER_STYLE,
|
||||
CUSTOM_ROUTING,
|
||||
AVOID_ROADS;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package net.osmand.aidlapi.profile;
|
||||
|
||||
parcelable ExportProfileParams;
|
|
@ -0,0 +1,61 @@
|
|||
package net.osmand.aidlapi.profile;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
|
||||
import net.osmand.aidlapi.AidlParams;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ExportProfileParams extends AidlParams {
|
||||
|
||||
public static final String PROFILE_KEY = "profile";
|
||||
public static final String SETTINGS_TYPE_KEY = "settings_type";
|
||||
private String profile;
|
||||
private ArrayList<String> settingsTypeKeyList = new ArrayList<>();
|
||||
|
||||
public ExportProfileParams(String profile, ArrayList<AExportSettingsType> settingsTypeList) {
|
||||
|
||||
this.profile = profile;
|
||||
for (AExportSettingsType settingsType : settingsTypeList) {
|
||||
settingsTypeKeyList.add(settingsType.name());
|
||||
}
|
||||
}
|
||||
|
||||
public ExportProfileParams(Parcel in) {
|
||||
readFromParcel(in);
|
||||
}
|
||||
|
||||
public static final Creator<ExportProfileParams> CREATOR = new Creator<ExportProfileParams>() {
|
||||
@Override
|
||||
public ExportProfileParams createFromParcel(Parcel in) {
|
||||
return new ExportProfileParams(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExportProfileParams[] newArray(int size) {
|
||||
return new ExportProfileParams[size];
|
||||
}
|
||||
};
|
||||
|
||||
public String getProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
||||
public List<String> getSettingsTypeKeys() {
|
||||
return settingsTypeKeyList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToBundle(Bundle bundle) {
|
||||
bundle.putString(PROFILE_KEY, profile);
|
||||
bundle.putStringArrayList(SETTINGS_TYPE_KEY, settingsTypeKeyList);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readFromBundle(Bundle bundle) {
|
||||
profile = bundle.getString(PROFILE_KEY);
|
||||
settingsTypeKeyList = bundle.getStringArrayList(SETTINGS_TYPE_KEY);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
apply plugin: 'java'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
|
||||
configurations {
|
||||
android
|
||||
}
|
||||
|
@ -104,6 +104,9 @@ dependencies {
|
|||
implementation 'com.moparisthebest:junidecode:0.1.1'
|
||||
implementation 'com.vividsolutions:jts-core:1.14.0'
|
||||
implementation 'com.google.openlocationcode:openlocationcode:1.0.4'
|
||||
implementation ('com.github.scribejava:scribejava-apis:7.1.1') {
|
||||
exclude group: "com.fasterxml.jackson.core"
|
||||
}
|
||||
// turn off for now
|
||||
//implementation 'com.atilika.kuromoji:kuromoji-ipadic:0.9.0'
|
||||
implementation 'net.sf.kxml:kxml2:2.1.8'
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
|
||||
package com.jwetherell.openmap.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class MGRSPoint extends ZonedUTMPoint {
|
||||
|
||||
/**
|
||||
|
@ -104,6 +108,15 @@ public class MGRSPoint extends ZonedUTMPoint {
|
|||
* an UPPERCASE coordinate string is expected.
|
||||
*/
|
||||
protected void decode(String mgrsString) throws NumberFormatException {
|
||||
if (mgrsString.contains(" ")) {
|
||||
String[] parts = mgrsString.split(" ");
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (String i : parts) {
|
||||
s.append(i);
|
||||
}
|
||||
mgrsString = s.toString();
|
||||
}
|
||||
|
||||
if (mgrsString == null || mgrsString.length() == 0) {
|
||||
throw new NumberFormatException("MGRSPoint coverting from nothing");
|
||||
}
|
||||
|
@ -633,6 +646,97 @@ public class MGRSPoint extends ZonedUTMPoint {
|
|||
return twoLetter;
|
||||
}
|
||||
|
||||
public String toFlavoredString() {
|
||||
try {
|
||||
List<String> all = new ArrayList<>();
|
||||
for (int i = 0; i <= mgrs.length(); i++) {
|
||||
if (Character.isAlphabetic(mgrs.charAt(i))){
|
||||
all.add(mgrs.substring(0,i+1));
|
||||
all.add(mgrs.substring(i+1,i+3));
|
||||
String remains = mgrs.substring(i+3);
|
||||
all.add(remains.substring(0,remains.length()/2));
|
||||
all.add(remains.substring(remains.length()/2));
|
||||
break;
|
||||
}
|
||||
}
|
||||
StringBuilder os = new StringBuilder();
|
||||
for(String part: all){
|
||||
if (os.length() > 0) os.append(" ");
|
||||
os.append(part);
|
||||
}
|
||||
return os.toString();
|
||||
}catch (Exception e){
|
||||
return mgrs;
|
||||
}
|
||||
}
|
||||
|
||||
public String toFlavoredString(int accuracy) {
|
||||
try {
|
||||
List<String> all = new ArrayList<>();
|
||||
for (int i = 0; i <= mgrs.length(); i++) {
|
||||
if (Character.isAlphabetic(mgrs.charAt(i))){
|
||||
all.add(mgrs.substring(0,i+1));
|
||||
all.add(mgrs.substring(i+1,i+3));
|
||||
String remains = mgrs.substring(i+3);
|
||||
int easting = Integer.parseInt(remains.substring(0,remains.length()/2));
|
||||
int northing = Integer.parseInt(remains.substring(remains.length()/2));
|
||||
double resolution = Math.pow(10, getAccuracy() - accuracy);
|
||||
long roundedEasting = Math.round(easting/resolution);
|
||||
long roundedNorthing = Math.round(northing/resolution);
|
||||
int eastShift = 0;
|
||||
int northShift = 0;
|
||||
if (roundedEasting == resolution*10){
|
||||
roundedEasting = 0L;
|
||||
eastShift = 1;
|
||||
}
|
||||
if (roundedNorthing == resolution*10){
|
||||
roundedNorthing = 0L;
|
||||
northShift = 1;
|
||||
}
|
||||
if (eastShift != 0 || northShift != 0){
|
||||
all.set(1, shiftChar(all.get(1), eastShift, northShift));
|
||||
String zero = "";
|
||||
}
|
||||
|
||||
|
||||
all.add(String.format("%0" + accuracy + "d", roundedEasting));
|
||||
all.add(String.format("%0" + accuracy + "d", roundedNorthing));
|
||||
break;
|
||||
}
|
||||
}
|
||||
StringBuilder os = new StringBuilder();
|
||||
for(String part: all){
|
||||
if (os.length() > 0) os.append(" ");
|
||||
os.append(part);
|
||||
}
|
||||
return os.toString();
|
||||
}catch (Exception e){
|
||||
return toFlavoredString();
|
||||
}
|
||||
}
|
||||
|
||||
private static String shiftChar(String chars, int east, int north){
|
||||
ArrayList<Character> keys = new ArrayList<Character>(
|
||||
Arrays.asList('A','B','C','D','E','F','G','H','J','K','L','M','N','P','Q','R','S','T','U','V','W','X','Y','Z'));
|
||||
StringBuilder s = new StringBuilder();
|
||||
if (east != 0){
|
||||
int idx = keys.indexOf(chars.charAt(0));
|
||||
idx += east;
|
||||
if (idx >= keys.size()) idx -= keys.size();
|
||||
if (idx < 0) idx += keys.size();
|
||||
s.append(keys.get(idx));
|
||||
}else s.append(chars.charAt(0));
|
||||
if (north != 0){
|
||||
int idx = keys.indexOf(chars.charAt(1));
|
||||
idx += north;
|
||||
if (idx >= keys.size()) idx -= keys.size();
|
||||
if (idx < 0) idx += keys.size();
|
||||
s.append(keys.get(idx));
|
||||
}else s.append(chars.charAt(1));
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -52,9 +52,10 @@ public class GPXUtilities {
|
|||
private static final String DEFAULT_ICON_NAME = "special_star";
|
||||
private static final String BACKGROUND_TYPE_EXTENSION = "background";
|
||||
private static final String PROFILE_TYPE_EXTENSION = "profile";
|
||||
private static final String GAP_PROFILE_TYPE = "gap";
|
||||
private static final String TRKPT_INDEX_EXTENSION = "trkpt_idx";
|
||||
|
||||
private final static String GPX_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; //$NON-NLS-1$
|
||||
public final static String GPX_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; //$NON-NLS-1$
|
||||
private final static String GPX_TIME_FORMAT_MILLIS = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; //$NON-NLS-1$
|
||||
|
||||
private final static NumberFormat latLonFormat = new DecimalFormat("0.00#####", new DecimalFormatSymbols(
|
||||
|
@ -70,6 +71,7 @@ public class GPXUtilities {
|
|||
WHITE(0xFFFFFFFF),
|
||||
RED(0xFFFF0000),
|
||||
GREEN(0xFF00FF00),
|
||||
DARKGREEN(0xFF006400),
|
||||
BLUE(0xFF0000FF),
|
||||
YELLOW(0xFFFFFF00),
|
||||
CYAN(0xFF00FFFF),
|
||||
|
@ -324,6 +326,20 @@ public class GPXUtilities {
|
|||
getExtensionsToWrite().put(PROFILE_TYPE_EXTENSION, profileType);
|
||||
}
|
||||
|
||||
public boolean hasProfile() {
|
||||
String profileType = getProfileType();
|
||||
return profileType != null && !GAP_PROFILE_TYPE.equals(profileType);
|
||||
}
|
||||
|
||||
public boolean isGap() {
|
||||
String profileType = getProfileType();
|
||||
return GAP_PROFILE_TYPE.equals(profileType);
|
||||
}
|
||||
|
||||
public void setGap() {
|
||||
setProfileType(GAP_PROFILE_TYPE);
|
||||
}
|
||||
|
||||
public void removeProfileType() {
|
||||
getExtensionsToWrite().remove(PROFILE_TYPE_EXTENSION);
|
||||
}
|
||||
|
@ -374,11 +390,16 @@ public class GPXUtilities {
|
|||
|
||||
public static class TrkSegment extends GPXExtensions {
|
||||
public boolean generalSegment = false;
|
||||
|
||||
public List<WptPt> points = new ArrayList<>();
|
||||
|
||||
public Object renderer;
|
||||
|
||||
public List<RouteSegment> routeSegments = new ArrayList<>();
|
||||
public List<RouteType> routeTypes = new ArrayList<>();
|
||||
|
||||
public boolean hasRoute() {
|
||||
return !routeSegments.isEmpty() && !routeTypes.isEmpty();
|
||||
}
|
||||
|
||||
public List<GPXTrackAnalysis> splitByDistance(double meters, boolean joinSegments) {
|
||||
return split(getDistanceMetric(), getTimeSplit(), meters, joinSegments);
|
||||
|
@ -393,7 +414,6 @@ public class GPXUtilities {
|
|||
splitSegment(metric, secondaryMetric, metricLimit, splitSegments, this, joinSegments);
|
||||
return convert(splitSegments);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Track extends GPXExtensions {
|
||||
|
@ -1078,9 +1098,6 @@ public class GPXUtilities {
|
|||
private List<WptPt> points = new ArrayList<>();
|
||||
public List<Route> routes = new ArrayList<>();
|
||||
|
||||
public List<RouteSegment> routeSegments = new ArrayList<>();
|
||||
public List<RouteType> routeTypes = new ArrayList<>();
|
||||
|
||||
public Exception error = null;
|
||||
public String path = "";
|
||||
public boolean showCurrentTrack;
|
||||
|
@ -1108,7 +1125,7 @@ public class GPXUtilities {
|
|||
}
|
||||
|
||||
public boolean hasRoute() {
|
||||
return !routeSegments.isEmpty() && !routeTypes.isEmpty();
|
||||
return getNonEmptyTrkSegments(true).size() > 0;
|
||||
}
|
||||
|
||||
public List<WptPt> getPoints() {
|
||||
|
@ -1218,7 +1235,7 @@ public class GPXUtilities {
|
|||
GPXTrackAnalysis g = new GPXTrackAnalysis();
|
||||
g.wptPoints = points.size();
|
||||
g.wptCategoryNames = getWaypointCategories(true);
|
||||
List<SplitSegment> splitSegments = new ArrayList<GPXUtilities.SplitSegment>();
|
||||
List<SplitSegment> splitSegments = new ArrayList<>();
|
||||
for (int i = 0; i < tracks.size(); i++) {
|
||||
Track subtrack = tracks.get(i);
|
||||
for (TrkSegment segment : subtrack.segments) {
|
||||
|
@ -1243,6 +1260,15 @@ public class GPXUtilities {
|
|||
return points;
|
||||
}
|
||||
|
||||
public List<WptPt> getRoutePoints(int routeIndex) {
|
||||
List<WptPt> points = new ArrayList<>();
|
||||
if (routes.size() > routeIndex) {
|
||||
Route rt = routes.get(routeIndex);
|
||||
points.addAll(rt.points);
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
public boolean hasRtePt() {
|
||||
for (Route r : routes) {
|
||||
if (r.points.size() > 0) {
|
||||
|
@ -1318,15 +1344,16 @@ public class GPXUtilities {
|
|||
return pt;
|
||||
}
|
||||
|
||||
public TrkSegment getNonEmptyTrkSegment() {
|
||||
for (GPXUtilities.Track t : tracks) {
|
||||
public List<TrkSegment> getNonEmptyTrkSegments(boolean routesOnly) {
|
||||
List<TrkSegment> segments = new ArrayList<>();
|
||||
for (Track t : tracks) {
|
||||
for (TrkSegment s : t.segments) {
|
||||
if (s.points.size() > 0) {
|
||||
return s;
|
||||
if (!s.generalSegment && s.points.size() > 0 && (!routesOnly || s.hasRoute())) {
|
||||
segments.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return segments;
|
||||
}
|
||||
|
||||
public void addTrkSegment(List<WptPt> points) {
|
||||
|
@ -1365,8 +1392,8 @@ public class GPXUtilities {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void addRoutePoints(List<WptPt> points) {
|
||||
if (routes.size() == 0) {
|
||||
public void addRoutePoints(List<WptPt> points, boolean addRoute) {
|
||||
if (routes.size() == 0 || addRoute) {
|
||||
Route route = new Route();
|
||||
routes.add(route);
|
||||
}
|
||||
|
@ -1608,7 +1635,7 @@ public class GPXUtilities {
|
|||
bottom = Math.min(bottom, p.getLatitude());
|
||||
}
|
||||
}
|
||||
for (GPXUtilities.Route route : routes) {
|
||||
for (Route route : routes) {
|
||||
for (WptPt p : route.points) {
|
||||
if (left == 0 && right == 0) {
|
||||
left = p.getLongitude();
|
||||
|
@ -1720,7 +1747,7 @@ public class GPXUtilities {
|
|||
|
||||
public static String asString(GPXFile file) {
|
||||
final Writer writer = new StringWriter();
|
||||
GPXUtilities.writeGpx(writer, file);
|
||||
writeGpx(writer, file);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
|
@ -1807,6 +1834,8 @@ public class GPXUtilities {
|
|||
writeWpt(format, serializer, p);
|
||||
serializer.endTag(null, "trkpt"); //$NON-NLS-1$
|
||||
}
|
||||
assignRouteExtensionWriter(segment);
|
||||
writeExtensions(serializer, segment);
|
||||
serializer.endTag(null, "trkseg"); //$NON-NLS-1$
|
||||
}
|
||||
writeExtensions(serializer, track);
|
||||
|
@ -1834,7 +1863,6 @@ public class GPXUtilities {
|
|||
serializer.endTag(null, "wpt"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
assignRouteExtensionWriter(file);
|
||||
writeExtensions(serializer, file);
|
||||
|
||||
serializer.endTag(null, "gpx"); //$NON-NLS-1$
|
||||
|
@ -1847,19 +1875,19 @@ public class GPXUtilities {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static void assignRouteExtensionWriter(final GPXFile gpxFile) {
|
||||
if (gpxFile.hasRoute() && gpxFile.getExtensionsWriter() == null) {
|
||||
gpxFile.setExtensionsWriter(new GPXExtensionsWriter() {
|
||||
private static void assignRouteExtensionWriter(final TrkSegment segment) {
|
||||
if (segment.hasRoute() && segment.getExtensionsWriter() == null) {
|
||||
segment.setExtensionsWriter(new GPXExtensionsWriter() {
|
||||
@Override
|
||||
public void writeExtensions(XmlSerializer serializer) {
|
||||
StringBundle bundle = new StringBundle();
|
||||
List<StringBundle> segmentsBundle = new ArrayList<>();
|
||||
for (RouteSegment segment : gpxFile.routeSegments) {
|
||||
for (RouteSegment segment : segment.routeSegments) {
|
||||
segmentsBundle.add(segment.toStringBundle());
|
||||
}
|
||||
bundle.putBundleList("route", "segment", segmentsBundle);
|
||||
List<StringBundle> typesBundle = new ArrayList<>();
|
||||
for (RouteType routeType : gpxFile.routeTypes) {
|
||||
for (RouteType routeType : segment.routeTypes) {
|
||||
typesBundle.add(routeType.toStringBundle());
|
||||
}
|
||||
bundle.putBundleList("types", "type", typesBundle);
|
||||
|
@ -1901,12 +1929,15 @@ public class GPXUtilities {
|
|||
}
|
||||
|
||||
private static void writeExtensions(XmlSerializer serializer, GPXExtensions p) throws IOException {
|
||||
Map<String, String> extensionsToRead = p.getExtensionsToRead();
|
||||
writeExtensions(serializer, p.getExtensionsToRead(), p);
|
||||
}
|
||||
|
||||
private static void writeExtensions(XmlSerializer serializer, Map<String, String> extensions, GPXExtensions p) throws IOException {
|
||||
GPXExtensionsWriter extensionsWriter = p.getExtensionsWriter();
|
||||
if (!extensionsToRead.isEmpty() || extensionsWriter != null) {
|
||||
if (!extensions.isEmpty() || extensionsWriter != null) {
|
||||
serializer.startTag(null, "extensions");
|
||||
if (!extensionsToRead.isEmpty()) {
|
||||
for (Entry<String, String> s : extensionsToRead.entrySet()) {
|
||||
if (!extensions.isEmpty()) {
|
||||
for (Entry<String, String> s : extensions.entrySet()) {
|
||||
writeNotNullText(serializer, s.getKey(), s.getValue());
|
||||
}
|
||||
}
|
||||
|
@ -1943,7 +1974,20 @@ public class GPXUtilities {
|
|||
if (!Float.isNaN(p.heading)) {
|
||||
p.getExtensionsToWrite().put("heading", String.valueOf(Math.round(p.heading)));
|
||||
}
|
||||
writeExtensions(serializer, p);
|
||||
Map<String, String> extensions = p.getExtensionsToRead();
|
||||
if (!"rtept".equals(serializer.getName())) {
|
||||
// Leave "profile" and "trkpt" tags for rtept only
|
||||
extensions.remove(PROFILE_TYPE_EXTENSION);
|
||||
extensions.remove(TRKPT_INDEX_EXTENSION);
|
||||
writeExtensions(serializer, extensions, p);
|
||||
} else {
|
||||
// Remove "gap" profile
|
||||
String profile = extensions.get(PROFILE_TYPE_EXTENSION);
|
||||
if (GAP_PROFILE_TYPE.equals(profile)) {
|
||||
extensions.remove(PROFILE_TYPE_EXTENSION);
|
||||
}
|
||||
writeExtensions(serializer, p);
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeAuthor(XmlSerializer serializer, Author author) throws IOException {
|
||||
|
@ -2099,10 +2143,11 @@ public class GPXUtilities {
|
|||
TrkSegment routeTrackSegment = new TrkSegment();
|
||||
routeTrack.segments.add(routeTrackSegment);
|
||||
Stack<GPXExtensions> parserState = new Stack<>();
|
||||
TrkSegment firstSegment = null;
|
||||
boolean extensionReadMode = false;
|
||||
boolean routePointExtension = false;
|
||||
List<RouteSegment> routeSegments = gpxFile.routeSegments;
|
||||
List<RouteType> routeTypes = gpxFile.routeTypes;
|
||||
List<RouteSegment> routeSegments = new ArrayList<>();
|
||||
List<RouteType> routeTypes = new ArrayList<>();
|
||||
boolean routeExtension = false;
|
||||
boolean typesExtension = false;
|
||||
parserState.push(gpxFile);
|
||||
|
@ -2403,6 +2448,16 @@ public class GPXUtilities {
|
|||
assert pop instanceof Route;
|
||||
} else if (tag.equals("trkseg")) {
|
||||
Object pop = parserState.pop();
|
||||
if (pop instanceof TrkSegment) {
|
||||
TrkSegment segment = (TrkSegment) pop;
|
||||
segment.routeSegments = routeSegments;
|
||||
segment.routeTypes = routeTypes;
|
||||
routeSegments = new ArrayList<>();
|
||||
routeTypes = new ArrayList<>();
|
||||
if (firstSegment == null) {
|
||||
firstSegment = segment;
|
||||
}
|
||||
}
|
||||
assert pop instanceof TrkSegment;
|
||||
} else if (tag.equals("rpt")) {
|
||||
Object pop = parserState.pop();
|
||||
|
@ -2413,6 +2468,10 @@ public class GPXUtilities {
|
|||
if (!routeTrackSegment.points.isEmpty()) {
|
||||
gpxFile.tracks.add(routeTrack);
|
||||
}
|
||||
if (!routeSegments.isEmpty() && !routeTypes.isEmpty() && firstSegment != null) {
|
||||
firstSegment.routeSegments = routeSegments;
|
||||
firstSegment.routeTypes = routeTypes;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
gpxFile.error = e;
|
||||
log.error("Error reading gpx", e); //$NON-NLS-1$
|
||||
|
|
|
@ -45,7 +45,7 @@ public interface IProgress {
|
|||
public boolean isInterrupted() {return false;}
|
||||
|
||||
@Override
|
||||
public boolean isIndeterminate() {return false;}
|
||||
public boolean isIndeterminate() {return true;}
|
||||
|
||||
@Override
|
||||
public void finishTask() {}
|
||||
|
|
|
@ -14,7 +14,8 @@ public class IndexConstants {
|
|||
public static final String TEMP_SOURCE_TO_LOAD = "temp";
|
||||
|
||||
public static final String POI_INDEX_EXT = ".poi.odb"; //$NON-NLS-1$
|
||||
|
||||
|
||||
public static final String ZIP_EXT = ".zip"; //$NON-NLS-1$
|
||||
public static final String BINARY_MAP_INDEX_EXT = ".obf"; //$NON-NLS-1$
|
||||
public static final String BINARY_MAP_INDEX_EXT_ZIP = ".obf.zip"; //$NON-NLS-1$
|
||||
|
||||
|
@ -45,6 +46,9 @@ public class IndexConstants {
|
|||
|
||||
public static final String GPX_FILE_EXT = ".gpx"; //$NON-NLS-1$
|
||||
|
||||
public static final String WPT_CHART_FILE_EXT = ".wpt.chart";
|
||||
public static final String SQLITE_CHART_FILE_EXT = ".3d.chart";
|
||||
|
||||
public final static String POI_TABLE = "poi"; //$NON-NLS-1$
|
||||
|
||||
public static final String INDEX_DOWNLOAD_DOMAIN = "download.osmand.net";
|
||||
|
@ -68,9 +72,11 @@ public class IndexConstants {
|
|||
public static final String FONT_INDEX_DIR = "fonts/"; //$NON-NLS-1$
|
||||
public static final String VOICE_INDEX_DIR = "voice/"; //$NON-NLS-1$
|
||||
public static final String RENDERERS_DIR = "rendering/"; //$NON-NLS-1$
|
||||
public static final String ROUTING_XML_FILE= "routing.xml";
|
||||
public static final String ROUTING_XML_FILE = "routing.xml";
|
||||
public static final String SETTINGS_DIR = "settings/"; //$NON-NLS-1$
|
||||
public static final String TEMP_DIR = "temp/";
|
||||
public static final String ROUTING_PROFILES_DIR = "routing/";
|
||||
public static final String PLUGINS_DIR = "plugins/";
|
||||
|
||||
public static final String VOICE_PROVIDER_SUFFIX = "-tts";
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ public class LocationConvert {
|
|||
public static final int FORMAT_SECONDS = 2;
|
||||
public static final int UTM_FORMAT = 3;
|
||||
public static final int OLC_FORMAT = 4;
|
||||
public static final int MGRS_FORMAT = 5;
|
||||
private static final char DELIM = ':';
|
||||
private static final char DELIMITER_DEGREES = '°';
|
||||
private static final char DELIMITER_MINUTES = '′';
|
||||
|
|
|
@ -106,9 +106,11 @@ public class TspAnt {
|
|||
// Allocates all memory.
|
||||
// Adds 1 to edge lengths to ensure no zero length edges.
|
||||
public TspAnt readGraph(List<LatLon> intermediates, LatLon start, LatLon end) {
|
||||
boolean keepEndPoint = end != null;
|
||||
List<LatLon> l = new ArrayList<LatLon>();
|
||||
l.add(start);
|
||||
boolean keepEndPoint = end != null;
|
||||
List<LatLon> l = new ArrayList<LatLon>();
|
||||
if (start != null) {
|
||||
l.add(start);
|
||||
}
|
||||
l.addAll(intermediates);
|
||||
if (keepEndPoint) {
|
||||
l.add(end);
|
||||
|
|
|
@ -11,8 +11,6 @@ import java.util.Arrays;
|
|||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.osmand.Collator;
|
||||
import net.osmand.CollatorStringMatcher;
|
||||
|
@ -576,13 +574,12 @@ public class BinaryMapPoiReaderAdapter {
|
|||
}
|
||||
}
|
||||
if (!matches) {
|
||||
Map<String, String> lt = am.getAdditionalInfo();
|
||||
for (Entry<String, String> e : lt.entrySet()) {
|
||||
if(!e.getKey().contains("_name") &&
|
||||
!e.getKey().equals("brand")) {
|
||||
for (String key : am.getAdditionalInfoKeys()) {
|
||||
if(!key.contains("_name") &&
|
||||
!key.equals("brand")) {
|
||||
continue;
|
||||
}
|
||||
matches = matcher.matches(e.getValue());
|
||||
matches = matcher.matches(am.getAdditionalInfo(key));
|
||||
if (matches) {
|
||||
break;
|
||||
}
|
||||
|
@ -812,7 +809,6 @@ public class BinaryMapPoiReaderAdapter {
|
|||
}
|
||||
|
||||
private boolean checkCategories(SearchRequest<Amenity> req, PoiRegion region) throws IOException {
|
||||
StringBuilder subType = new StringBuilder();
|
||||
while (true) {
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
|
|
|
@ -334,14 +334,16 @@ public class GeocodingUtilities {
|
|||
boolean eqStreet = Algorithms.stringsEqual(gr1.streetName, gr2.streetName);
|
||||
if (eqStreet) {
|
||||
boolean sameObj = false;
|
||||
if (gr1.building != null && gr2.building != null) {
|
||||
if (Algorithms.stringsEqual(gr1.building.getName(), gr2.building.getName())) {
|
||||
// same building
|
||||
if (gr1.city != null && gr2.city != null) {
|
||||
if (gr1.building != null && gr2.building != null) {
|
||||
if (Algorithms.stringsEqual(gr1.building.getName(), gr2.building.getName())) {
|
||||
// same building
|
||||
sameObj = true;
|
||||
}
|
||||
} else if (gr1.building == null && gr2.building == null) {
|
||||
// same street
|
||||
sameObj = true;
|
||||
}
|
||||
} else if (gr1.building == null && gr2.building == null) {
|
||||
// same street
|
||||
sameObj = true;
|
||||
}
|
||||
if (sameObj) {
|
||||
double cityDist1 = MapUtils.getDistance(gr1.searchPoint, gr1.city.getLocation());
|
||||
|
|
|
@ -1,17 +1,7 @@
|
|||
package net.osmand.data;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
@ -21,9 +11,14 @@ import java.util.Map;
|
|||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.osm.PoiCategory;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
|
||||
public class Amenity extends MapObject {
|
||||
|
@ -96,12 +91,46 @@ public class Amenity extends MapObject {
|
|||
}
|
||||
|
||||
|
||||
public Map<String, String> getAdditionalInfo() {
|
||||
// this method should be used carefully
|
||||
public Map<String, String> getInternalAdditionalInfoMap() {
|
||||
if (additionalInfo == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return additionalInfo;
|
||||
}
|
||||
|
||||
public Collection<String> getAdditionalInfoValues(boolean excludeZipped) {
|
||||
if (additionalInfo == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
boolean zipped = false;
|
||||
for(String v : additionalInfo.values()) {
|
||||
if(isContentZipped(v)) {
|
||||
zipped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(zipped) {
|
||||
List<String> r = new ArrayList<>(additionalInfo.size());
|
||||
for(String str : additionalInfo.values()) {
|
||||
if(excludeZipped && isContentZipped(str)) {
|
||||
|
||||
} else {
|
||||
r.add(unzipContent(str));
|
||||
}
|
||||
}
|
||||
return r;
|
||||
} else {
|
||||
return additionalInfo.values();
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<String> getAdditionalInfoKeys() {
|
||||
if (additionalInfo == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return additionalInfo.keySet();
|
||||
}
|
||||
|
||||
public void setAdditionalInfo(Map<String, String> additionalInfo) {
|
||||
this.additionalInfo = null;
|
||||
|
@ -134,7 +163,7 @@ public class Amenity extends MapObject {
|
|||
}
|
||||
this.additionalInfo.put(tag, value);
|
||||
if (OPENING_HOURS.equals(tag)) {
|
||||
this.openingHours = value;
|
||||
this.openingHours = unzipContent(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -182,7 +211,7 @@ public class Amenity extends MapObject {
|
|||
}
|
||||
int maxLen = 0;
|
||||
String lng = defLang;
|
||||
for (String nm : getAdditionalInfo().keySet()) {
|
||||
for (String nm : getAdditionalInfoKeys()) {
|
||||
if (nm.startsWith(tag + ":")) {
|
||||
String key = nm.substring(tag.length() + 1);
|
||||
String cnt = getAdditionalInfo(tag + ":" + key);
|
||||
|
@ -204,7 +233,7 @@ public class Amenity extends MapObject {
|
|||
|
||||
public List<String> getNames(String tag, String defTag) {
|
||||
List<String> l = new ArrayList<String>();
|
||||
for (String nm : getAdditionalInfo().keySet()) {
|
||||
for (String nm : getAdditionalInfoKeys()) {
|
||||
if (nm.startsWith(tag + ":")) {
|
||||
l.add(nm.substring(tag.length() + 1));
|
||||
} else if (nm.equals(tag)) {
|
||||
|
@ -229,7 +258,7 @@ public class Amenity extends MapObject {
|
|||
if (!Algorithms.isEmpty(enName)) {
|
||||
return enName;
|
||||
}
|
||||
for (String nm : getAdditionalInfo().keySet()) {
|
||||
for (String nm : getAdditionalInfoKeys()) {
|
||||
if (nm.startsWith(tag + ":")) {
|
||||
return getAdditionalInfo(nm);
|
||||
}
|
||||
|
@ -345,4 +374,6 @@ public class Amenity extends MapObject {
|
|||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,10 @@ public class City extends MapObject {
|
|||
public double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public boolean storedAsSeparateAdminEntity() {
|
||||
return this != DISTRICT && this != NEIGHBOURHOOD && this != BOROUGH;
|
||||
}
|
||||
|
||||
public static String valueToString(CityType t) {
|
||||
return t.toString().toLowerCase();
|
||||
|
|
|
@ -13,7 +13,6 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
|
@ -351,8 +350,8 @@ public abstract class MapObject implements Comparable<MapObject> {
|
|||
return json;
|
||||
}
|
||||
|
||||
public String unzipContent(String str) {
|
||||
if (str != null && str.startsWith(" gz ")) {
|
||||
String unzipContent(String str) {
|
||||
if (isContentZipped(str)) {
|
||||
try {
|
||||
int ind = 4;
|
||||
byte[] bytes = new byte[str.length() - ind];
|
||||
|
@ -369,6 +368,10 @@ public abstract class MapObject implements Comparable<MapObject> {
|
|||
}
|
||||
br.close();
|
||||
str = bld.toString();
|
||||
// ugly fix of temporary problem of map generation
|
||||
if(isContentZipped(str)) {
|
||||
str = unzipContent(str);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -376,6 +379,10 @@ public abstract class MapObject implements Comparable<MapObject> {
|
|||
return str;
|
||||
}
|
||||
|
||||
boolean isContentZipped(String str) {
|
||||
return str != null && str.startsWith(" gz ");
|
||||
}
|
||||
|
||||
protected static void parseJSON(JSONObject json, MapObject o) {
|
||||
if (json.has("name")) {
|
||||
o.name = json.getString("name");
|
||||
|
|
|
@ -823,7 +823,7 @@ public class MapPoiTypes {
|
|||
}
|
||||
String name = keyName;
|
||||
name = name.replace('_', ' ');
|
||||
return Algorithms.capitalizeFirstLetterAndLowercase(name);
|
||||
return Algorithms.capitalizeFirstLetter(name);
|
||||
}
|
||||
|
||||
public boolean isRegisteredType(PoiCategory t) {
|
||||
|
|
|
@ -27,7 +27,7 @@ public abstract class MapRenderingTypes {
|
|||
|
||||
private static final Log log = PlatformUtil.getLog(MapRenderingTypes.class);
|
||||
public static final String[] langs = new String[] { "af", "als", "ar", "az", "be", "bg", "bn", "bpy", "br", "bs", "ca", "ceb", "cs", "cy", "da", "de", "el", "eo", "es", "et", "eu", "fa", "fi", "fr", "fy", "ga", "gl", "he", "hi", "hsb",
|
||||
"hr", "ht", "hu", "hy", "id", "is", "it", "ja", "ka", "ko", "ku", "la", "lb", "lo", "lt", "lv", "mk", "ml", "mr", "ms", "nds", "new", "nl", "nn", "no", "nv", "os", "pl", "pms", "pt", "ro", "ru", "sc", "sh", "sk", "sl", "sq", "sr", "sv", "sw", "ta", "te", "th", "tl", "tr", "uk", "vi", "vo", "zh", "zh-hans", "zh-hant", };
|
||||
"hr", "ht", "hu", "hy", "id", "is", "it", "ja", "ka", "kn", "ko", "ku", "la", "lb", "lo", "lt", "lv", "mk", "ml", "mr", "ms", "nds", "new", "nl", "nn", "no", "nv", "os", "pl", "pms", "pt", "ro", "ru", "sc", "sh", "sk", "sl", "sq", "sr", "sv", "sw", "ta", "te", "th", "tl", "tr", "uk", "vi", "vo", "zh", "zh-hans", "zh-hant", };
|
||||
|
||||
|
||||
public final static byte RESTRICTION_NO_RIGHT_TURN = 1;
|
||||
|
|
|
@ -114,6 +114,8 @@ public abstract class Entity implements Serializable {
|
|||
public static final int MODIFY_DELETED = -1;
|
||||
public static final int MODIFY_MODIFIED = 1;
|
||||
public static final int MODIFY_CREATED = 2;
|
||||
public static final String POI_TYPE_TAG = "poi_type_tag";
|
||||
public static final String REMOVE_TAG_PREFIX = "----";
|
||||
|
||||
public Entity(long id) {
|
||||
this.id = id;
|
||||
|
@ -241,6 +243,11 @@ public abstract class Entity implements Serializable {
|
|||
return Collections.unmodifiableMap(tags);
|
||||
}
|
||||
|
||||
public boolean isNotValid(String tag) {
|
||||
String val = getTag(tag);
|
||||
return val == null || val.length() == 0 || tag.length() == 0
|
||||
|| tag.startsWith(REMOVE_TAG_PREFIX) || tag.equals(POI_TYPE_TAG);
|
||||
}
|
||||
|
||||
public Collection<String> getTagKeySet() {
|
||||
if (tags == null) {
|
||||
|
|
|
@ -1,30 +1,22 @@
|
|||
package net.osmand.osm.io;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import com.github.scribejava.core.model.OAuthRequest;
|
||||
import com.github.scribejava.core.model.Response;
|
||||
import com.github.scribejava.core.model.Verb;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.osm.oauth.OsmOAuthAuthorizationClient;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class NetworkUtils {
|
||||
private static final Log log = PlatformUtil.getLog(NetworkUtils.class);
|
||||
|
||||
private static final String GPX_UPLOAD_USER_AGENT = "OsmGPXUploadAgent";
|
||||
private static Proxy proxy = null;
|
||||
|
||||
public static String sendGetRequest(String urlText, String userNamePassword, StringBuilder responseBody){
|
||||
|
@ -55,7 +47,6 @@ public class NetworkUtils {
|
|||
responseBody.append("\n"); //$NON-NLS-1$
|
||||
}
|
||||
responseBody.append(s);
|
||||
|
||||
}
|
||||
is.close();
|
||||
}
|
||||
|
@ -65,9 +56,10 @@ public class NetworkUtils {
|
|||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private static final String BOUNDARY = "CowMooCowMooCowCowCow"; //$NON-NLS-1$
|
||||
public static String uploadFile(String urlText, File fileToUpload, String userNamePassword, String formName, boolean gzip, Map<String, String> additionalMapData){
|
||||
public static String uploadFile(String urlText, File fileToUpload, String userNamePassword,
|
||||
OsmOAuthAuthorizationClient client,
|
||||
String formName, boolean gzip, Map<String, String> additionalMapData){
|
||||
URL url;
|
||||
try {
|
||||
boolean firstPrm =!urlText.contains("?");
|
||||
|
@ -77,34 +69,48 @@ public class NetworkUtils {
|
|||
}
|
||||
log.info("Start uploading file to " + urlText + " " +fileToUpload.getName());
|
||||
url = new URL(urlText);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setDoInput(true);
|
||||
conn.setDoOutput(true);
|
||||
conn.setRequestMethod("POST");
|
||||
if(userNamePassword != null) {
|
||||
conn.setRequestProperty("Authorization", "Basic " + Base64.encode(userNamePassword)); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
HttpURLConnection conn;
|
||||
if (client != null && client.isValidToken()){
|
||||
OAuthRequest req = new OAuthRequest(Verb.POST, urlText);
|
||||
client.getService().signRequest(client.getAccessToken(), req);
|
||||
req.addHeader("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
|
||||
try {
|
||||
Response r = client.getHttpClient().execute(GPX_UPLOAD_USER_AGENT, req.getHeaders(), req.getVerb(),
|
||||
req.getCompleteUrl(), fileToUpload);
|
||||
if (r.getCode() != 200) {
|
||||
return r.getBody();
|
||||
}
|
||||
return null;
|
||||
} catch (InterruptedException e) {
|
||||
log.error(e);
|
||||
} catch (ExecutionException e) {
|
||||
log.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setDoInput(true);
|
||||
conn.setDoOutput(true);
|
||||
conn.setRequestMethod("POST");
|
||||
if(userNamePassword != null) {
|
||||
conn.setRequestProperty("Authorization", "Basic " + Base64.encode(userNamePassword)); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
}
|
||||
|
||||
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
conn.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
|
||||
OutputStream ous = conn.getOutputStream();
|
||||
// for (String key : additionalMapData.keySet()) {
|
||||
// ous.write(("--" + BOUNDARY + "\r\n").getBytes());
|
||||
// ous.write(("content-disposition: form-data; name=\"" + key + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
// ous.write((additionalMapData.get(key) + "\r\n").getBytes());
|
||||
// }
|
||||
ous.write(("--" + BOUNDARY+"\r\n").getBytes());
|
||||
ous.write(("--" + BOUNDARY + "\r\n").getBytes());
|
||||
String filename = fileToUpload.getName();
|
||||
if(gzip){
|
||||
filename+=".gz";
|
||||
if (gzip) {
|
||||
filename += ".gz";
|
||||
}
|
||||
ous.write(("content-disposition: form-data; name=\""+formName+"\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$
|
||||
InputStream fis = new FileInputStream(fileToUpload);
|
||||
ous.write(("content-disposition: form-data; name=\"" + formName + "\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$
|
||||
InputStream fis = new FileInputStream(fileToUpload);
|
||||
BufferedInputStream bis = new BufferedInputStream(fis, 20 * 1024);
|
||||
ous.flush();
|
||||
if(gzip){
|
||||
if (gzip) {
|
||||
GZIPOutputStream gous = new GZIPOutputStream(ous, 1024);
|
||||
Algorithms.streamCopy(bis, gous);
|
||||
gous.flush();
|
||||
|
@ -112,8 +118,7 @@ public class NetworkUtils {
|
|||
} else {
|
||||
Algorithms.streamCopy(bis, ous);
|
||||
}
|
||||
|
||||
ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
ous.flush();
|
||||
Algorithms.closeStream(bis);
|
||||
Algorithms.closeStream(ous);
|
||||
|
@ -136,7 +141,6 @@ public class NetworkUtils {
|
|||
responseBody.append("\n"); //$NON-NLS-1$
|
||||
}
|
||||
responseBody.append(s);
|
||||
|
||||
}
|
||||
is.close();
|
||||
}
|
||||
|
@ -157,7 +161,6 @@ public class NetworkUtils {
|
|||
proxy = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Proxy getProxy() {
|
||||
return proxy;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,259 @@
|
|||
package net.osmand.osm.oauth;
|
||||
|
||||
import com.github.scribejava.core.exceptions.OAuthException;
|
||||
import com.github.scribejava.core.httpclient.HttpClient;
|
||||
import com.github.scribejava.core.httpclient.jdk.JDKHttpClientConfig;
|
||||
import com.github.scribejava.core.httpclient.jdk.JDKHttpFuture;
|
||||
import com.github.scribejava.core.httpclient.multipart.MultipartPayload;
|
||||
import com.github.scribejava.core.httpclient.multipart.MultipartUtils;
|
||||
import com.github.scribejava.core.model.*;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class OsmAndJDKHttpClient implements HttpClient {
|
||||
private static final String BOUNDARY = "CowMooCowMooCowCowCow";
|
||||
private final JDKHttpClientConfig config;
|
||||
|
||||
public OsmAndJDKHttpClient() {
|
||||
this(JDKHttpClientConfig.defaultConfig());
|
||||
}
|
||||
|
||||
public OsmAndJDKHttpClient(JDKHttpClientConfig clientConfig) {
|
||||
config = clientConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
byte[] bodyContents, OAuthAsyncRequestCallback<T> callback, OAuthRequest.ResponseConverter<T> converter) {
|
||||
|
||||
return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.BYTE_ARRAY, bodyContents, callback,
|
||||
converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
MultipartPayload bodyContents, OAuthAsyncRequestCallback<T> callback,
|
||||
OAuthRequest.ResponseConverter<T> converter) {
|
||||
|
||||
return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.MULTIPART, bodyContents, callback,
|
||||
converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
String bodyContents, OAuthAsyncRequestCallback<T> callback, OAuthRequest.ResponseConverter<T> converter) {
|
||||
|
||||
return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.STRING, bodyContents, callback,
|
||||
converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Future<T> executeAsync(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
File bodyContents, OAuthAsyncRequestCallback<T> callback, OAuthRequest.ResponseConverter<T> converter) {
|
||||
return doExecuteAsync(userAgent, headers, httpVerb, completeUrl, BodyType.STREAM, bodyContents, callback,
|
||||
converter);
|
||||
}
|
||||
|
||||
private <T> Future<T> doExecuteAsync(String userAgent, Map<String, String> headers, Verb httpVerb,
|
||||
String completeUrl, BodyType bodyType, Object bodyContents, OAuthAsyncRequestCallback<T> callback,
|
||||
OAuthRequest.ResponseConverter<T> converter) {
|
||||
try {
|
||||
final Response response = doExecute(userAgent, headers, httpVerb, completeUrl, bodyType, bodyContents);
|
||||
@SuppressWarnings("unchecked") final T t = converter == null ? (T) response : converter.convert(response);
|
||||
if (callback != null) {
|
||||
callback.onCompleted(t);
|
||||
}
|
||||
return new JDKHttpFuture<>(t);
|
||||
} catch (IOException | RuntimeException e) {
|
||||
if (callback != null) {
|
||||
callback.onThrowable(e);
|
||||
}
|
||||
return new JDKHttpFuture<>(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
byte[] bodyContents) throws InterruptedException, ExecutionException, IOException {
|
||||
return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.BYTE_ARRAY, bodyContents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
MultipartPayload multipartPayloads) throws InterruptedException, ExecutionException, IOException {
|
||||
return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.MULTIPART, multipartPayloads);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
String bodyContents) throws InterruptedException, ExecutionException, IOException {
|
||||
return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.STRING, bodyContents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
File bodyContents) throws InterruptedException, ExecutionException, IOException {
|
||||
return doExecute(userAgent, headers, httpVerb, completeUrl, BodyType.STREAM, bodyContents);
|
||||
}
|
||||
|
||||
private Response doExecute(String userAgent, Map<String, String> headers, Verb httpVerb, String completeUrl,
|
||||
BodyType bodyType, Object bodyContents) throws IOException {
|
||||
final URL url = new URL(completeUrl);
|
||||
final HttpURLConnection connection;
|
||||
if (config.getProxy() == null) {
|
||||
connection = (HttpURLConnection) url.openConnection();
|
||||
} else {
|
||||
connection = (HttpURLConnection) url.openConnection(config.getProxy());
|
||||
}
|
||||
connection.setInstanceFollowRedirects(config.isFollowRedirects());
|
||||
connection.setRequestMethod(httpVerb.name());
|
||||
if (config.getConnectTimeout() != null) {
|
||||
connection.setConnectTimeout(config.getConnectTimeout());
|
||||
}
|
||||
if (config.getReadTimeout() != null) {
|
||||
connection.setReadTimeout(config.getReadTimeout());
|
||||
}
|
||||
addHeaders(connection, headers, userAgent);
|
||||
if (httpVerb.isPermitBody()) {
|
||||
bodyType.setBody(connection, bodyContents, httpVerb.isRequiresBody());
|
||||
}
|
||||
|
||||
try {
|
||||
connection.connect();
|
||||
final int responseCode = connection.getResponseCode();
|
||||
return new Response(responseCode, connection.getResponseMessage(), parseHeaders(connection),
|
||||
responseCode >= 200 && responseCode < 400 ? connection.getInputStream()
|
||||
: connection.getErrorStream());
|
||||
} catch (UnknownHostException e) {
|
||||
throw new OAuthException("The IP address of a host could not be determined.", e);
|
||||
}
|
||||
}
|
||||
|
||||
private enum BodyType {
|
||||
BYTE_ARRAY {
|
||||
@Override
|
||||
void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException {
|
||||
addBody(connection, (byte[]) bodyContents, requiresBody);
|
||||
}
|
||||
},
|
||||
STREAM {
|
||||
@Override
|
||||
void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException {
|
||||
addBody(connection, (File) bodyContents, requiresBody);
|
||||
}
|
||||
},
|
||||
MULTIPART {
|
||||
@Override
|
||||
void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException {
|
||||
addBody(connection, (MultipartPayload) bodyContents, requiresBody);
|
||||
}
|
||||
},
|
||||
STRING {
|
||||
@Override
|
||||
void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody) throws IOException {
|
||||
addBody(connection, ((String) bodyContents).getBytes(), requiresBody);
|
||||
}
|
||||
};
|
||||
|
||||
abstract void setBody(HttpURLConnection connection, Object bodyContents, boolean requiresBody)
|
||||
throws IOException;
|
||||
}
|
||||
|
||||
private static Map<String, String> parseHeaders(HttpURLConnection conn) {
|
||||
final Map<String, String> headers = new HashMap<>();
|
||||
|
||||
for (Map.Entry<String, List<String>> headerField : conn.getHeaderFields().entrySet()) {
|
||||
final String key = headerField.getKey();
|
||||
final String value = headerField.getValue().get(0);
|
||||
if ("Content-Encoding".equalsIgnoreCase(key)) {
|
||||
headers.put("Content-Encoding", value);
|
||||
} else {
|
||||
headers.put(key, value);
|
||||
}
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
private static void addHeaders(HttpURLConnection connection, Map<String, String> headers, String userAgent) {
|
||||
for (Map.Entry<String, String> header : headers.entrySet()) {
|
||||
connection.setRequestProperty(header.getKey(), header.getValue());
|
||||
}
|
||||
|
||||
if (userAgent != null) {
|
||||
connection.setRequestProperty(OAuthConstants.USER_AGENT_HEADER_NAME, userAgent);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addBody(HttpURLConnection connection, File file, boolean requiresBody) throws IOException {
|
||||
if (requiresBody) {
|
||||
String filename = file.getName();
|
||||
String formName = "file";
|
||||
InputStream stream = new FileInputStream(file);
|
||||
connection.setDoInput(true);
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
connection.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
final OutputStream ous = connection.getOutputStream();
|
||||
ous.write(("--" + BOUNDARY + "\r\n").getBytes());
|
||||
ous.write(("content-disposition: form-data; name=\"" + formName + "\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$
|
||||
BufferedInputStream bis = new BufferedInputStream(stream, 20 * 1024);
|
||||
ous.flush();
|
||||
Algorithms.streamCopy(bis, ous);
|
||||
ous.write(("\r\n--" + BOUNDARY + "--\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
ous.flush();
|
||||
Algorithms.closeStream(bis);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addBody(HttpURLConnection connection, byte[] content, boolean requiresBody) throws IOException {
|
||||
final int contentLength = content.length;
|
||||
if (requiresBody || contentLength > 0) {
|
||||
connection.setDoOutput(true);
|
||||
final OutputStream outputStream = prepareConnectionForBodyAndGetOutputStream(connection, contentLength);
|
||||
if (contentLength > 0) {
|
||||
outputStream.write(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addBody(HttpURLConnection connection, MultipartPayload multipartPayload, boolean requiresBody)
|
||||
throws IOException {
|
||||
|
||||
for (Map.Entry<String, String> header : multipartPayload.getHeaders().entrySet()) {
|
||||
connection.setRequestProperty(header.getKey(), header.getValue());
|
||||
}
|
||||
|
||||
if (requiresBody) {
|
||||
final ByteArrayOutputStream os = MultipartUtils.getPayload(multipartPayload);
|
||||
final int contentLength = os.size();
|
||||
connection.setDoOutput(true);
|
||||
final OutputStream outputStream = prepareConnectionForBodyAndGetOutputStream(connection, contentLength);
|
||||
if (contentLength > 0) {
|
||||
os.writeTo(outputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static OutputStream prepareConnectionForBodyAndGetOutputStream(HttpURLConnection connection,
|
||||
int contentLength) throws IOException {
|
||||
connection.setRequestProperty(CONTENT_LENGTH, String.valueOf(contentLength));
|
||||
if (connection.getRequestProperty(CONTENT_TYPE) == null) {
|
||||
connection.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
|
||||
}
|
||||
return connection.getOutputStream();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
// License: GPL. For details, see LICENSE file.
|
||||
package net.osmand.osm.oauth;
|
||||
|
||||
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.builder.api.DefaultApi10a;
|
||||
import com.github.scribejava.core.builder.api.OAuth1SignatureType;
|
||||
import com.github.scribejava.core.httpclient.jdk.JDKHttpClientConfig;
|
||||
import com.github.scribejava.core.model.*;
|
||||
import com.github.scribejava.core.oauth.OAuth10aService;
|
||||
import net.osmand.PlatformUtil;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
/**
|
||||
* An OAuth 1.0 authorization client.
|
||||
*
|
||||
* @since 2746
|
||||
*/
|
||||
public class OsmOAuthAuthorizationClient {
|
||||
private OAuth1RequestToken requestToken;
|
||||
private OAuth1AccessToken accessToken;
|
||||
private final OAuth10aService service;
|
||||
private final OsmAndJDKHttpClient httpClient;
|
||||
public final static Log log = PlatformUtil.getLog(OsmOAuthAuthorizationClient.class);
|
||||
|
||||
public OsmOAuthAuthorizationClient(String key, String secret, DefaultApi10a api) {
|
||||
httpClient = new OsmAndJDKHttpClient(JDKHttpClientConfig.defaultConfig());
|
||||
service = new ServiceBuilder(key)
|
||||
.apiSecret(secret)
|
||||
.httpClient(httpClient)
|
||||
.callback("osmand-oauth://example.com/oauth")
|
||||
.build(api);
|
||||
}
|
||||
|
||||
public static class OsmApi extends DefaultApi10a {
|
||||
@Override
|
||||
public OAuth1SignatureType getSignatureType() {
|
||||
return OAuth1SignatureType.QUERY_STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestTokenEndpoint() {
|
||||
return "https://www.openstreetmap.org/oauth/request_token";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessTokenEndpoint() {
|
||||
return "https://www.openstreetmap.org/oauth/access_token";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAuthorizationBaseUrl() {
|
||||
return "https://www.openstreetmap.org/oauth/authorize";
|
||||
}
|
||||
}
|
||||
|
||||
public static class OsmDevApi extends DefaultApi10a {
|
||||
@Override
|
||||
public OAuth1SignatureType getSignatureType() {
|
||||
return OAuth1SignatureType.QUERY_STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRequestTokenEndpoint() {
|
||||
return "https://master.apis.dev.openstreetmap.org/oauth/request_token";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessTokenEndpoint() {
|
||||
return "https://master.apis.dev.openstreetmap.org/oauth/access_token";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAuthorizationBaseUrl() {
|
||||
return "https://master.apis.dev.openstreetmap.org/oauth/authorize";
|
||||
}
|
||||
}
|
||||
|
||||
public OsmAndJDKHttpClient getHttpClient() {
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public OAuth10aService getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public void setAccessToken(OAuth1AccessToken accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public OAuth1AccessToken getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public Response performRequestWithoutAuth(String url, String requestMethod, String requestBody)
|
||||
throws InterruptedException, ExecutionException, IOException {
|
||||
Verb verb = parseRequestMethod(requestMethod);
|
||||
OAuthRequest req = new OAuthRequest(verb, url);
|
||||
req.setPayload(requestBody);
|
||||
return service.execute(req);
|
||||
}
|
||||
|
||||
public void performGetRequest(String url, OAuthAsyncRequestCallback<Response> callback) {
|
||||
if (accessToken == null) {
|
||||
throw new IllegalStateException("Access token is null");
|
||||
}
|
||||
OAuthRequest req = new OAuthRequest(Verb.GET, url);
|
||||
service.signRequest(accessToken, req);
|
||||
service.execute(req, callback);
|
||||
}
|
||||
|
||||
public Response performRequest(String url, String method, String body)
|
||||
throws InterruptedException, ExecutionException, IOException {
|
||||
service.getApi().getSignatureType();
|
||||
if (accessToken == null) {
|
||||
throw new IllegalStateException("Access token is null");
|
||||
}
|
||||
Verb verbMethod = parseRequestMethod(method);
|
||||
OAuthRequest req = new OAuthRequest(verbMethod, url);
|
||||
req.setPayload(body);
|
||||
service.signRequest(accessToken, req);
|
||||
req.addHeader("Content-Type", "application/xml");
|
||||
return service.execute(req);
|
||||
}
|
||||
|
||||
public OAuth1RequestToken startOAuth() {
|
||||
try {
|
||||
requestToken = service.getRequestToken();
|
||||
} catch (IOException e) {
|
||||
log.error(e);
|
||||
} catch (InterruptedException e) {
|
||||
log.error(e);
|
||||
} catch (ExecutionException e) {
|
||||
log.error(e);
|
||||
}
|
||||
return requestToken;
|
||||
}
|
||||
|
||||
public OAuth1AccessToken authorize(String oauthVerifier) {
|
||||
try {
|
||||
setAccessToken(service.getAccessToken(requestToken, oauthVerifier));
|
||||
} catch (IOException e) {
|
||||
log.error(e);
|
||||
} catch (InterruptedException e) {
|
||||
log.error(e);
|
||||
} catch (ExecutionException e) {
|
||||
log.error(e);
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public boolean isValidToken() {
|
||||
return !(accessToken == null);
|
||||
}
|
||||
|
||||
private Verb parseRequestMethod(String method) {
|
||||
Verb m = Verb.GET;
|
||||
if (method.equals("POST")) {
|
||||
m = Verb.POST;
|
||||
}
|
||||
if (method.equals("PUT")) {
|
||||
m = Verb.PUT;
|
||||
}
|
||||
if (method.equals("DELETE")) {
|
||||
m = Verb.DELETE;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ public class RenderingRule {
|
|||
public void init(Map<String, String> attributes) {
|
||||
ArrayList<RenderingRuleProperty> props = new ArrayList<RenderingRuleProperty>(attributes.size());
|
||||
intProperties = new int[attributes.size()];
|
||||
floatProperties = null;
|
||||
floatProperties = new float[attributes.size()];
|
||||
attributesRef = null;
|
||||
int i = 0;
|
||||
Iterator<Entry<String, String>> it = attributes.entrySet().iterator();
|
||||
|
@ -58,14 +58,13 @@ public class RenderingRule {
|
|||
attributesRef[i] = storage.getRenderingAttributeRule(vl.substring(1));
|
||||
} else if (property.isString()) {
|
||||
intProperties[i] = storage.getDictionaryValue(vl);
|
||||
} else if (property.isFloat()) {
|
||||
if (floatProperties == null) {
|
||||
// lazy creates
|
||||
floatProperties = new float[attributes.size()];
|
||||
}
|
||||
floatProperties[i] = property.parseFloatValue(vl);
|
||||
intProperties[i] = property.parseIntValue(vl);
|
||||
} else {
|
||||
float floatVal = property.parseFloatValue(vl);
|
||||
// if (floatProperties == null && floatVal != 0) {
|
||||
// // lazy creates
|
||||
// floatProperties = new float[attributes.size()];
|
||||
floatProperties[i] = floatVal;
|
||||
// }
|
||||
intProperties[i] = property.parseIntValue(vl);
|
||||
}
|
||||
i++;
|
||||
|
@ -95,7 +94,7 @@ public class RenderingRule {
|
|||
|
||||
public float getFloatPropertyValue(String property) {
|
||||
int i = getPropertyIndex(property);
|
||||
if(i >= 0 && floatProperties != null){
|
||||
if (i >= 0) {
|
||||
return floatProperties[i];
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -155,12 +155,7 @@ public class RenderingRuleProperty {
|
|||
try {
|
||||
int colon = value.indexOf(':');
|
||||
if(colon != -1) {
|
||||
int c = 0;
|
||||
if(colon > 0) {
|
||||
c += (int) Float.parseFloat(value.substring(0, colon));
|
||||
}
|
||||
c += (int) Float.parseFloat(value.substring(colon + 1));
|
||||
return c;
|
||||
return (int) Float.parseFloat(value.substring(colon + 1));
|
||||
}
|
||||
return (int) Float.parseFloat(value);
|
||||
} catch (NumberFormatException e) {
|
||||
|
@ -190,30 +185,35 @@ public class RenderingRuleProperty {
|
|||
} catch (NumberFormatException e) {
|
||||
log.error("Rendering parse " + value + " in " + attrName);
|
||||
}
|
||||
return -1;
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public float parseFloatValue(String value){
|
||||
if(type == FLOAT_TYPE){
|
||||
try {
|
||||
public float parseFloatValue(String value) {
|
||||
try {
|
||||
if (type == FLOAT_TYPE) {
|
||||
int colon = value.indexOf(':');
|
||||
if(colon != -1) {
|
||||
if(colon > 0) {
|
||||
if (colon != -1) {
|
||||
if (colon > 0) {
|
||||
return Float.parseFloat(value.substring(0, colon));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return Float.parseFloat(value);
|
||||
} catch (NumberFormatException e) {
|
||||
log.error("Rendering parse " + value + " in " + attrName);
|
||||
|
||||
} else if (type == INT_TYPE) {
|
||||
int colon = value.indexOf(':');
|
||||
if (colon != -1 && colon > 0) {
|
||||
return Float.parseFloat(value.substring(0, colon));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
} else {
|
||||
return -1;
|
||||
} catch (NumberFormatException e) {
|
||||
log.error("Rendering parse " + value + " in " + attrName);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -244,8 +244,6 @@ public class RenderingRuleStorageProperties {
|
|||
R_TEXT_HALO_COLOR = registerRuleInternal(RenderingRuleProperty.createOutputColorProperty(TEXT_HALO_COLOR));
|
||||
R_TEXT_SIZE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(TEXT_SIZE));
|
||||
R_TEXT_ORDER = registerRuleInternal(RenderingRuleProperty.createOutputIntProperty(TEXT_ORDER));
|
||||
R_ICON_ORDER = registerRuleInternal(RenderingRuleProperty.createOutputIntProperty(ICON_ORDER));
|
||||
R_ICON_VISIBLE_SIZE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(ICON_VISIBLE_SIZE));
|
||||
R_TEXT_MIN_DISTANCE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(TEXT_MIN_DISTANCE));
|
||||
R_TEXT_SHIELD = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty(TEXT_SHIELD));
|
||||
|
||||
|
@ -265,7 +263,9 @@ public class RenderingRuleStorageProperties {
|
|||
R_ICON_3 = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty("icon_3"));
|
||||
R_ICON_4 = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty("icon_4"));
|
||||
R_ICON_5 = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty("icon_5"));
|
||||
R_ICON_ORDER = registerRuleInternal(RenderingRuleProperty.createOutputIntProperty(ICON_ORDER));
|
||||
R_SHIELD = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty(SHIELD));
|
||||
R_ICON_VISIBLE_SIZE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(ICON_VISIBLE_SIZE));
|
||||
|
||||
// polygon/way
|
||||
R_COLOR = registerRuleInternal(RenderingRuleProperty.createOutputColorProperty(COLOR));
|
||||
|
|
|
@ -20,10 +20,10 @@ public class RouteExporter {
|
|||
|
||||
public static final String OSMAND_ROUTER_V2 = "OsmAndRouterV2";
|
||||
|
||||
private String name;
|
||||
private List<RouteSegmentResult> route;
|
||||
private List<Location> locations;
|
||||
private List<WptPt> points;
|
||||
private final String name;
|
||||
private final List<RouteSegmentResult> route;
|
||||
private final List<Location> locations;
|
||||
private final List<WptPt> points;
|
||||
|
||||
public RouteExporter(String name, List<RouteSegmentResult> route, List<Location> locations, List<WptPt> points) {
|
||||
this.name = name;
|
||||
|
@ -33,6 +33,34 @@ public class RouteExporter {
|
|||
}
|
||||
|
||||
public GPXFile exportRoute() {
|
||||
GPXFile gpx = new GPXFile(OSMAND_ROUTER_V2);
|
||||
Track track = new Track();
|
||||
track.name = name;
|
||||
gpx.tracks.add(track);
|
||||
track.segments.add(generateRouteSegment());
|
||||
if (points != null) {
|
||||
for (WptPt pt : points) {
|
||||
gpx.addPoint(pt);
|
||||
}
|
||||
}
|
||||
return gpx;
|
||||
}
|
||||
|
||||
public static GPXFile exportRoute(String name, List<TrkSegment> trkSegments, List<WptPt> points) {
|
||||
GPXFile gpx = new GPXFile(OSMAND_ROUTER_V2);
|
||||
Track track = new Track();
|
||||
track.name = name;
|
||||
gpx.tracks.add(track);
|
||||
track.segments.addAll(trkSegments);
|
||||
if (points != null) {
|
||||
for (WptPt pt : points) {
|
||||
gpx.addPoint(pt);
|
||||
}
|
||||
}
|
||||
return gpx;
|
||||
}
|
||||
|
||||
public TrkSegment generateRouteSegment() {
|
||||
RouteDataResources resources = new RouteDataResources(locations);
|
||||
List<StringBundle> routeItems = new ArrayList<>();
|
||||
if (!Algorithms.isEmpty(route)) {
|
||||
|
@ -57,15 +85,9 @@ public class RouteExporter {
|
|||
typeList.add(typeBundle);
|
||||
}
|
||||
|
||||
GPXFile gpx = new GPXFile(OSMAND_ROUTER_V2);
|
||||
Track track = new Track();
|
||||
track.name = name;
|
||||
gpx.tracks.add(track);
|
||||
TrkSegment trkSegment = new TrkSegment();
|
||||
track.segments.add(trkSegment);
|
||||
|
||||
if (locations == null || locations.isEmpty()) {
|
||||
return gpx;
|
||||
return trkSegment;
|
||||
}
|
||||
for (int i = 0; i < locations.size(); i++) {
|
||||
Location loc = locations.get(i);
|
||||
|
@ -83,23 +105,17 @@ public class RouteExporter {
|
|||
}
|
||||
trkSegment.points.add(pt);
|
||||
}
|
||||
if (points != null) {
|
||||
for (WptPt pt : points) {
|
||||
gpx.addPoint(pt);
|
||||
}
|
||||
}
|
||||
|
||||
List<RouteSegment> routeSegments = new ArrayList<>();
|
||||
for (StringBundle item : routeItems) {
|
||||
routeSegments.add(RouteSegment.fromStringBundle(item));
|
||||
}
|
||||
gpx.routeSegments = routeSegments;
|
||||
trkSegment.routeSegments = routeSegments;
|
||||
List<RouteType> routeTypes = new ArrayList<>();
|
||||
for (StringBundle item : typeList) {
|
||||
routeTypes.add(RouteType.fromStringBundle(item));
|
||||
}
|
||||
gpx.routeTypes = routeTypes;
|
||||
|
||||
return gpx;
|
||||
trkSegment.routeTypes = routeTypes;
|
||||
return trkSegment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import net.osmand.GPXUtilities;
|
|||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.RouteSegment;
|
||||
import net.osmand.GPXUtilities.RouteType;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
|
@ -28,10 +29,9 @@ public class RouteImporter {
|
|||
|
||||
private File file;
|
||||
private GPXFile gpxFile;
|
||||
private TrkSegment segment;
|
||||
|
||||
private List<RouteSegmentResult> route = new ArrayList<>();
|
||||
private RouteRegion region = new RouteRegion();
|
||||
private RouteDataResources resources = new RouteDataResources();
|
||||
private final List<RouteSegmentResult> route = new ArrayList<>();
|
||||
|
||||
public RouteImporter(File file) {
|
||||
this.file = file;
|
||||
|
@ -41,8 +41,12 @@ public class RouteImporter {
|
|||
this.gpxFile = gpxFile;
|
||||
}
|
||||
|
||||
public RouteImporter(TrkSegment segment) {
|
||||
this.segment = segment;
|
||||
}
|
||||
|
||||
public List<RouteSegmentResult> importRoute() {
|
||||
if (gpxFile != null) {
|
||||
if (gpxFile != null || segment != null) {
|
||||
parseRoute();
|
||||
} else if (file != null) {
|
||||
FileInputStream fis = null;
|
||||
|
@ -69,19 +73,34 @@ public class RouteImporter {
|
|||
}
|
||||
|
||||
private void parseRoute() {
|
||||
collectLocations();
|
||||
collectSegments();
|
||||
collectTypes();
|
||||
for (RouteSegmentResult segment : route) {
|
||||
segment.fillNames(resources);
|
||||
if (segment != null) {
|
||||
parseRoute(segment);
|
||||
} else if (gpxFile != null) {
|
||||
List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(true);
|
||||
for (TrkSegment s : segments) {
|
||||
parseRoute(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void collectLocations() {
|
||||
private void parseRoute(TrkSegment segment) {
|
||||
RouteRegion region = new RouteRegion();
|
||||
RouteDataResources resources = new RouteDataResources();
|
||||
|
||||
collectLocations(resources, segment);
|
||||
List<RouteSegmentResult> route = collectRouteSegments(region, resources, segment);
|
||||
collectRouteTypes(region, segment);
|
||||
for (RouteSegmentResult routeSegment : route) {
|
||||
routeSegment.fillNames(resources);
|
||||
}
|
||||
this.route.addAll(route);
|
||||
}
|
||||
|
||||
private void collectLocations(RouteDataResources resources, TrkSegment segment) {
|
||||
List<Location> locations = resources.getLocations();
|
||||
double lastElevation = HEIGHT_UNDEFINED;
|
||||
if (gpxFile.tracks.size() > 0 && gpxFile.tracks.get(0).segments.size() > 0 && gpxFile.tracks.get(0).segments.get(0).points.size() > 0) {
|
||||
for (WptPt point : gpxFile.tracks.get(0).segments.get(0).points) {
|
||||
if (segment.hasRoute()) {
|
||||
for (WptPt point : segment.points) {
|
||||
Location loc = new Location("", point.getLatitude(), point.getLongitude());
|
||||
if (!Double.isNaN(point.ele)) {
|
||||
loc.setAltitude(point.ele);
|
||||
|
@ -94,18 +113,20 @@ public class RouteImporter {
|
|||
}
|
||||
}
|
||||
|
||||
private void collectSegments() {
|
||||
for (RouteSegment segment : gpxFile.routeSegments) {
|
||||
private List<RouteSegmentResult> collectRouteSegments(RouteRegion region, RouteDataResources resources, TrkSegment segment) {
|
||||
List<RouteSegmentResult> route = new ArrayList<>();
|
||||
for (RouteSegment routeSegment : segment.routeSegments) {
|
||||
RouteDataObject object = new RouteDataObject(region);
|
||||
RouteSegmentResult segmentResult = new RouteSegmentResult(object);
|
||||
segmentResult.readFromBundle(new RouteDataBundle(resources, segment.toStringBundle()));
|
||||
segmentResult.readFromBundle(new RouteDataBundle(resources, routeSegment.toStringBundle()));
|
||||
route.add(segmentResult);
|
||||
}
|
||||
return route;
|
||||
}
|
||||
|
||||
private void collectTypes() {
|
||||
private void collectRouteTypes(RouteRegion region, TrkSegment segment) {
|
||||
int i = 0;
|
||||
for (RouteType routeType : gpxFile.routeTypes) {
|
||||
for (RouteType routeType : segment.routeTypes) {
|
||||
StringBundle bundle = routeType.toStringBundle();
|
||||
String t = bundle.getString("t", null);
|
||||
String v = bundle.getString("v", null);
|
||||
|
|
|
@ -256,7 +256,7 @@ public class RoutePlannerFrontEnd {
|
|||
if (routeFound) {
|
||||
// route is found - cut the end of the route and move to next iteration
|
||||
// start.stepBackRoute = new ArrayList<RouteSegmentResult>();
|
||||
// boolean stepBack = true;
|
||||
// boolean stepBack = true;
|
||||
boolean stepBack = stepBackAndFindPrevPointInRoute(gctx, gpxPoints, start, next);
|
||||
if (!stepBack) {
|
||||
// not supported case (workaround increase MAXIMUM_STEP_APPROXIMATION)
|
||||
|
@ -546,8 +546,10 @@ public class RoutePlannerFrontEnd {
|
|||
if (start != null && start.pnt == null) {
|
||||
gctx.routePointsSearched++;
|
||||
RouteSegmentPoint rsp = findRouteSegment(start.loc.getLatitude(), start.loc.getLongitude(), gctx.ctx, null, false);
|
||||
if (MapUtils.getDistance(rsp.getPreciseLatLon(), start.loc) < distThreshold) {
|
||||
start.pnt = rsp;
|
||||
if (rsp != null) {
|
||||
if (MapUtils.getDistance(rsp.getPreciseLatLon(), start.loc) < distThreshold) {
|
||||
start.pnt = rsp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (start != null && start.pnt != null) {
|
||||
|
@ -734,7 +736,7 @@ public class RoutePlannerFrontEnd {
|
|||
res = searchRouteImpl(ctx, points, routeDirection);
|
||||
}
|
||||
if (ctx.calculationProgress != null) {
|
||||
ctx.calculationProgress.timeToCalculate += (System.nanoTime() - timeToCalculate);
|
||||
ctx.calculationProgress.timeToCalculate = (System.nanoTime() - timeToCalculate);
|
||||
}
|
||||
BinaryRoutePlanner.printDebugMemoryInformation(ctx);
|
||||
if (res != null) {
|
||||
|
|
|
@ -255,7 +255,8 @@ public class RouteSegmentResult implements StringExternalizable<RouteDataBundle>
|
|||
@Override
|
||||
public void writeToBundle(RouteDataBundle bundle) {
|
||||
Map<RouteTypeRule, Integer> rules = bundle.getResources().getRules();
|
||||
bundle.putInt("length", (Math.abs(endPointIndex - startPointIndex) + 1) * (endPointIndex >= startPointIndex ? 1 : -1));
|
||||
boolean reversed = endPointIndex < startPointIndex;
|
||||
bundle.putInt("length", Math.abs(endPointIndex - startPointIndex) + 1);
|
||||
bundle.putFloat("segmentTime", segmentTime, 2);
|
||||
bundle.putFloat("speed", speed, 2);
|
||||
if (turnType != null) {
|
||||
|
@ -271,24 +272,29 @@ public class RouteSegmentResult implements StringExternalizable<RouteDataBundle>
|
|||
bundle.putString("turnLanes", TurnType.lanesToString(turnLanes));
|
||||
}
|
||||
}
|
||||
bundle.putLong("id", object.id);
|
||||
bundle.putLong("id", object.id >> 6); // OsmAnd ID to OSM ID
|
||||
bundle.putArray("types", convertTypes(object.types, rules));
|
||||
|
||||
int start = Math.min(startPointIndex, endPointIndex);
|
||||
int end = Math.max(startPointIndex, endPointIndex) + 1;
|
||||
if (object.pointTypes != null && start < object.pointTypes.length) {
|
||||
int[][] types = Arrays.copyOfRange(object.pointTypes, start, Math.min(end, object.pointTypes.length));
|
||||
if (reversed) {
|
||||
Algorithms.reverseArray(types);
|
||||
}
|
||||
bundle.putArray("pointTypes", convertTypes(types, rules));
|
||||
}
|
||||
if (object.nameIds != null) {
|
||||
bundle.putArray("names", convertNameIds(object.nameIds, rules));
|
||||
}
|
||||
if (object.pointNameTypes != null && start < object.pointNameTypes.length) {
|
||||
if (object.pointNameTypes != null && start < object.pointNameTypes.length && object.pointNames != null) {
|
||||
int[][] types = Arrays.copyOfRange(object.pointNameTypes, start, Math.min(end, object.pointNameTypes.length));
|
||||
if (object.pointNames != null) {
|
||||
String[][] names = Arrays.copyOfRange(object.pointNames, start, Math.min(end, object.pointNames.length));
|
||||
bundle.putArray("pointNames", convertPointNames(types, names, rules));
|
||||
String[][] names = Arrays.copyOfRange(object.pointNames, start, Math.min(end, object.pointNames.length));
|
||||
if (reversed) {
|
||||
Algorithms.reverseArray(types);
|
||||
Algorithms.reverseArray(names);
|
||||
}
|
||||
bundle.putArray("pointNames", convertPointNames(types, names, rules));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,22 +333,21 @@ public class RouteSegmentResult implements StringExternalizable<RouteDataBundle>
|
|||
Location prevLocation = null;
|
||||
for (int i = 0; i < length; i++) {
|
||||
Location location = resources.getLocation(index);
|
||||
if (location == null) {
|
||||
break;
|
||||
}
|
||||
double dist = 0;
|
||||
if (prevLocation != null) {
|
||||
dist = MapUtils.getDistance(prevLocation.getLatitude(), prevLocation.getLongitude(), location.getLatitude(), location.getLongitude());
|
||||
distance += dist;
|
||||
}
|
||||
prevLocation = location;
|
||||
object.pointsX[i] = MapUtils.get31TileNumberX(location.getLongitude());
|
||||
object.pointsY[i] = MapUtils.get31TileNumberY(location.getLatitude());
|
||||
if (location.hasAltitude() && object.heightDistanceArray.length > 0) {
|
||||
object.heightDistanceArray[i * 2] = (float) dist;
|
||||
object.heightDistanceArray[i * 2 + 1] = (float) location.getAltitude();
|
||||
} else {
|
||||
object.heightDistanceArray = new float[0];
|
||||
if (location != null) {
|
||||
double dist = 0;
|
||||
if (prevLocation != null) {
|
||||
dist = MapUtils.getDistance(prevLocation.getLatitude(), prevLocation.getLongitude(), location.getLatitude(), location.getLongitude());
|
||||
distance += dist;
|
||||
}
|
||||
prevLocation = location;
|
||||
object.pointsX[i] = MapUtils.get31TileNumberX(location.getLongitude());
|
||||
object.pointsY[i] = MapUtils.get31TileNumberY(location.getLatitude());
|
||||
if (location.hasAltitude() && object.heightDistanceArray.length > 0) {
|
||||
object.heightDistanceArray[i * 2] = (float) dist;
|
||||
object.heightDistanceArray[i * 2 + 1] = (float) location.getAltitude();
|
||||
} else {
|
||||
object.heightDistanceArray = new float[0];
|
||||
}
|
||||
}
|
||||
if (plus) {
|
||||
index++;
|
||||
|
|
|
@ -289,7 +289,8 @@ public class RoutingContext {
|
|||
if(excludeNotAllowed != null && !excludeNotAllowed.contains(ro.getId())) {
|
||||
ts.add(ro);
|
||||
}
|
||||
} else if(excludeNotAllowed != null && ro.getId() > 0){
|
||||
}
|
||||
if(excludeNotAllowed != null && ro.getId() > 0){
|
||||
excludeNotAllowed.add(ro.getId());
|
||||
if(ts.excludedIds == null ){
|
||||
ts.excludedIds = new TLongHashSet();
|
||||
|
|
|
@ -741,7 +741,7 @@ public class SearchUICore {
|
|||
}
|
||||
}
|
||||
if (Algorithms.isEmpty(object.alternateName) && object.object instanceof Amenity) {
|
||||
for (String value : ((Amenity) object.object).getAdditionalInfo().values()) {
|
||||
for (String value : ((Amenity) object.object).getAdditionalInfoValues(true)) {
|
||||
if (phrase.getFirstUnknownNameStringMatcher().matches(value)) {
|
||||
object.alternateName = value;
|
||||
break;
|
||||
|
|
|
@ -33,6 +33,7 @@ import net.osmand.util.LocationParser.ParsedOpenLocationCode;
|
|||
import net.osmand.util.MapUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
@ -601,7 +602,7 @@ public class SearchCoreFactory {
|
|||
sr.localeName = object.getName(phrase.getSettings().getLang(),
|
||||
phrase.getSettings().isTransliterate());
|
||||
if (!nm.matches(sr.localeName) && !nm.matches(sr.otherNames)
|
||||
&& !nm.matches(object.getAdditionalInfo().values())) {
|
||||
&& !nm.matches(object.getAdditionalInfoValues(false))) {
|
||||
return false;
|
||||
}
|
||||
sr.object = object;
|
||||
|
@ -922,6 +923,7 @@ public class SearchCoreFactory {
|
|||
|
||||
public static class SearchAmenityByTypeAPI extends SearchBaseAPI {
|
||||
private static final int BBOX_RADIUS = 10000;
|
||||
private static final int BBOX_RADIUS_NEAREST = 1000;
|
||||
private SearchAmenityTypesAPI searchAmenityTypesAPI;
|
||||
private MapPoiTypes types;
|
||||
private AbstractPoiType unselectedPoiType;
|
||||
|
@ -1006,7 +1008,14 @@ public class SearchCoreFactory {
|
|||
}
|
||||
this.nameFilter = nameFilter;
|
||||
if (poiTypeFilter != null) {
|
||||
QuadRect bbox = phrase.getRadiusBBoxToSearch(BBOX_RADIUS);
|
||||
int radius = BBOX_RADIUS;
|
||||
if (phrase.getRadiusLevel() == 1 && poiTypeFilter instanceof CustomSearchPoiFilter) {
|
||||
String name = ((CustomSearchPoiFilter) poiTypeFilter).getFilterId();
|
||||
if ("std_null".equals(name)) {
|
||||
radius = BBOX_RADIUS_NEAREST;
|
||||
}
|
||||
}
|
||||
QuadRect bbox = phrase.getRadiusBBoxToSearch(radius);
|
||||
List<BinaryMapIndexReader> offlineIndexes = phrase.getOfflineIndexes();
|
||||
Set<String> searchedPois = new TreeSet<>();
|
||||
for (BinaryMapIndexReader r : offlineIndexes) {
|
||||
|
@ -1050,7 +1059,7 @@ public class SearchCoreFactory {
|
|||
if (!poiAdditionals.isEmpty()) {
|
||||
boolean found = false;
|
||||
for (String add : poiAdditionals) {
|
||||
if(object.getAdditionalInfo().containsKey(add)) {
|
||||
if (object.getAdditionalInfoKeys().contains(add)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
@ -1407,6 +1416,7 @@ public class SearchCoreFactory {
|
|||
private LatLon olcPhraseLocation;
|
||||
private ParsedOpenLocationCode cachedParsedCode;
|
||||
private final List<String> citySubTypes = Arrays.asList("city", "town", "village");
|
||||
private final DecimalFormat latLonFormatter = new DecimalFormat("#.0####");
|
||||
|
||||
public SearchLocationAndUrlAPI() {
|
||||
super(ObjectType.LOCATION, ObjectType.PARTIAL_LOCATION);
|
||||
|
@ -1498,7 +1508,7 @@ public class SearchCoreFactory {
|
|||
sp.priority = SEARCH_LOCATION_PRIORITY;
|
||||
|
||||
sp.object = sp.location = ll;
|
||||
sp.localeName = ((float) sp.location.getLatitude()) + ", <input> ";
|
||||
sp.localeName = formatLatLon(sp.location.getLatitude()) + ", <input> ";
|
||||
sp.objectType = ObjectType.PARTIAL_LOCATION;
|
||||
resultMatcher.publish(sp);
|
||||
}
|
||||
|
@ -1510,7 +1520,7 @@ public class SearchCoreFactory {
|
|||
SearchResult sp = new SearchResult(phrase);
|
||||
sp.priority = SEARCH_LOCATION_PRIORITY;
|
||||
sp.object = sp.location = l;
|
||||
sp.localeName = ((float) sp.location.getLatitude()) + ", " + ((float) sp.location.getLongitude());
|
||||
sp.localeName = formatLatLon(sp.location.getLatitude()) + ", " + formatLatLon(sp.location.getLongitude());
|
||||
sp.objectType = ObjectType.LOCATION;
|
||||
sp.wordsSpan = lw;
|
||||
resultMatcher.publish(sp);
|
||||
|
@ -1525,7 +1535,7 @@ public class SearchCoreFactory {
|
|||
sp.object = pnt;
|
||||
sp.wordsSpan = text;
|
||||
sp.location = new LatLon(pnt.getLatitude(), pnt.getLongitude());
|
||||
sp.localeName = ((float)pnt.getLatitude()) +", " + ((float) pnt.getLongitude());
|
||||
sp.localeName = formatLatLon(pnt.getLatitude()) +", " + formatLatLon(pnt.getLongitude());
|
||||
if (pnt.getZoom() > 0) {
|
||||
sp.preferredZoom = pnt.getZoom();
|
||||
}
|
||||
|
@ -1555,6 +1565,10 @@ public class SearchCoreFactory {
|
|||
}
|
||||
return cachedParsedCode == null ? SEARCH_LOCATION_PRIORITY : SEARCH_MAX_PRIORITY;
|
||||
}
|
||||
|
||||
private String formatLatLon(double latLon) {
|
||||
return latLonFormatter.format(latLon);
|
||||
}
|
||||
}
|
||||
|
||||
private static String stripBraces(String localeName) {
|
||||
|
|
|
@ -229,12 +229,14 @@ public class SearchPhrase {
|
|||
}
|
||||
|
||||
public int countWords(String w) {
|
||||
String[] ws = w.split(ALLDELIMITERS);
|
||||
int cnt = 0;
|
||||
for (int i = 0; i < ws.length; i++) {
|
||||
String wd = ws[i].trim();
|
||||
if (wd.length() > 0) {
|
||||
cnt++;
|
||||
if (!Algorithms.isEmpty(w)) {
|
||||
String[] ws = w.split(ALLDELIMITERS);
|
||||
for (int i = 0; i < ws.length; i++) {
|
||||
String wd = ws[i].trim();
|
||||
if (wd.length() > 0) {
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
|
|
|
@ -49,6 +49,11 @@ public class Algorithms {
|
|||
private static char[] CHARS_TO_NORMALIZE_KEY = new char['’'];
|
||||
private static char[] CHARS_TO_NORMALIZE_VALUE = new char['\''];
|
||||
|
||||
public static final int ZIP_FILE_SIGNATURE = 0x504b0304;
|
||||
public static final int XML_FILE_SIGNATURE = 0x3c3f786d;
|
||||
public static final int OBF_FILE_SIGNATURE = 0x08029001;
|
||||
public static final int SQLITE_FILE_SIGNATURE = 0x53514C69;
|
||||
|
||||
public static String normalizeSearchText(String s) {
|
||||
boolean norm = false;
|
||||
for (int i = 0; i < s.length() && !norm; i++) {
|
||||
|
@ -119,9 +124,11 @@ public class Algorithms {
|
|||
}
|
||||
|
||||
public static String getFileNameWithoutExtension(String name) {
|
||||
int i = name.indexOf('.');
|
||||
if (i >= 0) {
|
||||
name = name.substring(0, i);
|
||||
if (name != null) {
|
||||
int index = name.lastIndexOf('.');
|
||||
if (index != -1) {
|
||||
return name.substring(0, index);
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
@ -293,7 +300,7 @@ public class Algorithms {
|
|||
FileInputStream in = new FileInputStream(file);
|
||||
int test = readInt(in);
|
||||
in.close();
|
||||
return test == 0x504b0304;
|
||||
return test == ZIP_FILE_SIGNATURE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -322,7 +329,7 @@ public class Algorithms {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static int readInt(InputStream in) throws IOException {
|
||||
public static int readInt(InputStream in) throws IOException {
|
||||
int ch1 = in.read();
|
||||
int ch2 = in.read();
|
||||
int ch3 = in.read();
|
||||
|
@ -879,6 +886,14 @@ public class Algorithms {
|
|||
return map;
|
||||
}
|
||||
|
||||
public static <T> void reverseArray(T[] array) {
|
||||
for (int i = 0; i < array.length / 2; i++) {
|
||||
T temp = array[i];
|
||||
array[i] = array[array.length - i - 1];
|
||||
array[array.length - i - 1] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean containsInArrayL(long[] array, long value) {
|
||||
return Arrays.binarySearch(array, value) >= 0;
|
||||
}
|
||||
|
@ -942,4 +957,20 @@ public class Algorithms {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static boolean isValidMessageFormat(CharSequence sequence) {
|
||||
if (!isEmpty(sequence)) {
|
||||
int counter = 0;
|
||||
for (int i = 0; i < sequence.length(); i++) {
|
||||
char ch = sequence.charAt(i);
|
||||
if (ch == '{') {
|
||||
counter++;
|
||||
} else if (ch == '}') {
|
||||
counter--;
|
||||
}
|
||||
}
|
||||
return counter == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package net.osmand.util;
|
|||
import com.google.openlocationcode.OpenLocationCode;
|
||||
import com.google.openlocationcode.OpenLocationCode.CodeArea;
|
||||
import com.jwetherell.openmap.common.LatLonPoint;
|
||||
import com.jwetherell.openmap.common.MGRSPoint;
|
||||
import com.jwetherell.openmap.common.UTMPoint;
|
||||
|
||||
import net.osmand.data.LatLon;
|
||||
|
@ -111,7 +112,7 @@ public class LocationParser {
|
|||
return null;
|
||||
}
|
||||
// detect UTM
|
||||
if (all.size() == 4 && d.size() == 3 && all.get(1) instanceof String) {
|
||||
if (all.size() == 4 && d.size() == 3 && all.get(1) instanceof String && ((String) all.get(1)).length() == 1) {
|
||||
char ch = all.get(1).toString().charAt(0);
|
||||
if (Character.isLetter(ch)) {
|
||||
UTMPoint upoint = new UTMPoint(d.get(2), d.get(1), d.get(0).intValue(), ch);
|
||||
|
@ -120,7 +121,7 @@ public class LocationParser {
|
|||
}
|
||||
}
|
||||
|
||||
if (all.size() == 3 && d.size() == 2 && all.get(1) instanceof String) {
|
||||
if (all.size() == 3 && d.size() == 2 && all.get(1) instanceof String && ((String) all.get(1)).length() == 1) {
|
||||
char ch = all.get(1).toString().charAt(0);
|
||||
String combined = strings.get(2);
|
||||
if (Character.isLetter(ch)) {
|
||||
|
@ -135,6 +136,17 @@ public class LocationParser {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//detect MGRS
|
||||
if (all.size() >= 3 && (d.size() == 2 || d.size() == 3) && all.get(1) instanceof String) {
|
||||
try {
|
||||
MGRSPoint mgrsPoint = new MGRSPoint(locPhrase);
|
||||
LatLonPoint ll = mgrsPoint.toLatLonPoint();
|
||||
return validateAndCreateLatLon(ll.getLatitude(), ll.getLongitude());
|
||||
} catch (NumberFormatException e) {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
// try to find split lat/lon position
|
||||
int jointNumbers = 0;
|
||||
int lastJoin = 0;
|
||||
|
|
|
@ -15,6 +15,7 @@ import java.util.TreeSet;
|
|||
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
|
||||
import net.osmand.data.LatLon;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
@ -29,42 +30,52 @@ public class RouteTestingTest {
|
|||
private TestEntry te;
|
||||
|
||||
|
||||
public RouteTestingTest(String name, TestEntry te) {
|
||||
this.te = te;
|
||||
}
|
||||
public RouteTestingTest(String name, TestEntry te) {
|
||||
this.te = te;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
RouteResultPreparation.PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
|
||||
}
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
RouteResultPreparation.PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name = "{index}: {0}")
|
||||
public static Iterable<Object[]> data() throws IOException {
|
||||
String fileName = "/test_routing.json";
|
||||
Reader reader = new InputStreamReader(RouteTestingTest.class.getResourceAsStream(fileName));
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
TestEntry[] testEntries = gson.fromJson(reader, TestEntry[].class);
|
||||
ArrayList<Object[]> arrayList = new ArrayList<>();
|
||||
for(TestEntry te : testEntries) {
|
||||
if(te.isIgnore()) {
|
||||
continue;
|
||||
}
|
||||
arrayList.add(new Object[] {te.getTestName(), te});
|
||||
}
|
||||
reader.close();
|
||||
return arrayList;
|
||||
@Parameterized.Parameters(name = "{index}: {0}")
|
||||
public static Iterable<Object[]> data() throws IOException {
|
||||
String fileName = "/test_routing.json";
|
||||
Reader reader = new InputStreamReader(RouteTestingTest.class.getResourceAsStream(fileName));
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
TestEntry[] testEntries = gson.fromJson(reader, TestEntry[].class);
|
||||
ArrayList<Object[]> arrayList = new ArrayList<>();
|
||||
for (TestEntry te : testEntries) {
|
||||
if (te.isIgnore()) {
|
||||
continue;
|
||||
}
|
||||
arrayList.add(new Object[]{te.getTestName(), te});
|
||||
}
|
||||
reader.close();
|
||||
return arrayList;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test
|
||||
public void testRouting() throws Exception {
|
||||
String fl = "src/test/resources/Routing_test.obf";
|
||||
RandomAccessFile raf = new RandomAccessFile(fl, "r");
|
||||
RoutePlannerFrontEnd fe = new RoutePlannerFrontEnd();
|
||||
|
||||
BinaryMapIndexReader[] binaryMapIndexReaders = { new BinaryMapIndexReader(raf, new File(fl)) };
|
||||
BinaryMapIndexReader[] binaryMapIndexReaders;// = { new BinaryMapIndexReader(raf, new File(fl)) };
|
||||
RoutingConfiguration.Builder builder = RoutingConfiguration.getDefault();
|
||||
Map<String, String> params = te.getParams();
|
||||
if (params.containsKey("map")) {
|
||||
String fl1 = "src/test/resources/" + params.get("map");
|
||||
RandomAccessFile raf1 = new RandomAccessFile(fl1, "r");
|
||||
binaryMapIndexReaders = new BinaryMapIndexReader[]{
|
||||
new BinaryMapIndexReader(raf1, new File(fl1)),
|
||||
new BinaryMapIndexReader(raf, new File(fl))
|
||||
};
|
||||
} else {
|
||||
binaryMapIndexReaders = new BinaryMapIndexReader[]{new BinaryMapIndexReader(raf, new File(fl))};
|
||||
}
|
||||
RoutingConfiguration config = builder.build(params.containsKey("vehicle") ? params.get("vehicle") : "car",
|
||||
RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3, params);
|
||||
RoutingContext ctx = fe.buildRoutingContext(config, null, binaryMapIndexReaders,
|
||||
|
@ -102,6 +113,4 @@ public class RouteTestingTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
android:screenOrientation="unspecified"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<activity android:name=".ui.TrackerLogcatActivity" />
|
||||
<activity
|
||||
android:name=".ui.MainActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
|
|
44
OsmAnd-telegram/res/layout/activity_tracker_logcat.xml
Normal file
44
OsmAnd-telegram/res/layout/activity_tracker_logcat.xml
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/card_bg_color">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/action_bar_height">
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:text="@string/logcat_buffer"
|
||||
android:textColor="@color/app_bar_title_light"
|
||||
android:textSize="@dimen/title_text_size"
|
||||
app:typeface="@string/font_roboto_mono_bold"/>
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/screen_bg_light"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical" />
|
||||
|
||||
</LinearLayout>
|
|
@ -447,6 +447,50 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/list_item_divider"/>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/card_bg_color">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/logcat_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:orientation="vertical">
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/content_padding_standard"
|
||||
android:text="@string/logcat_buffer"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/list_item_title_text_size"
|
||||
app:firstBaselineToTopHeight="28sp"
|
||||
app:typeface="@string/font_roboto_medium" />
|
||||
|
||||
<net.osmand.telegram.ui.views.TextViewEx
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/content_padding_standard"
|
||||
android:text="@string/logcat_buffer_descr"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="@dimen/list_item_description_text_size"
|
||||
app:firstBaselineToTopHeight="20sp"
|
||||
app:lastBaselineToBottomHeight="16sp"
|
||||
app:typeface="@string/font_roboto_regular" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<include layout="@layout/card_bottom_divider"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
18
OsmAnd-telegram/res/layout/item_description_long.xml
Normal file
18
OsmAnd-telegram/res/layout/item_description_long.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:minHeight="@dimen/list_description_height"
|
||||
android:paddingLeft="@dimen/content_padding_standard"
|
||||
android:paddingRight="@dimen/content_padding_standard"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/hint_text_size"
|
||||
android:linksClickable="true"
|
||||
android:lineSpacingMultiplier="@dimen/text_description_line_spacing_multiplier"
|
||||
tools:text="Some long description"
|
||||
android:paddingEnd="@dimen/content_padding_standard"
|
||||
android:paddingStart="@dimen/content_padding_standard" />
|
|
@ -267,4 +267,8 @@
|
|||
<string name="location_sharing_status">مشاركة: %1$s</string>
|
||||
<string name="shared_string_enabled">مفعل</string>
|
||||
<string name="duration_ago">%1$s منذ</string>
|
||||
<string name="shared_string_export">تصدير</string>
|
||||
<string name="logcat_buffer">لوجكات العازلة</string>
|
||||
<string name="logcat_buffer_descr">تحقق من السجلات التفصيلية للتطبيق وشاركها</string>
|
||||
<string name="send_report">إرسال تقرير</string>
|
||||
</resources>
|
|
@ -38,7 +38,7 @@
|
|||
<string name="shared_string_password">كلمة المرور</string>
|
||||
<string name="shared_string_continue">استمرار</string>
|
||||
<string name="shared_string_cancel">إلغاء</string>
|
||||
<string name="shared_string_settings">الإعدادات</string>
|
||||
<string name="shared_string_settings">إعدادات</string>
|
||||
<string name="shared_string_distance">المسافة</string>
|
||||
<string name="yard">ياردة</string>
|
||||
<string name="foot">قدم</string>
|
||||
|
@ -267,4 +267,8 @@
|
|||
<string name="status_widget_title">تتبع حالة أوسماند</string>
|
||||
<string name="back_to_osmand">العودة إلى OsmAnd</string>
|
||||
<string name="duration_ago">%1$s منذ</string>
|
||||
<string name="send_report">إرسال التقرير</string>
|
||||
<string name="shared_string_export">تصدير</string>
|
||||
<string name="logcat_buffer">سجل الاستخدام</string>
|
||||
<string name="logcat_buffer_descr">التحقق من السجلات التفصيلية للتطبيق ومشاركتها</string>
|
||||
</resources>
|
|
@ -267,4 +267,8 @@
|
|||
<string name="last_response_duration">Апошні адказ: %1$s таму</string>
|
||||
<string name="duration_ago">%1$s таму</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="send_report">Даслаць справаздачу</string>
|
||||
<string name="shared_string_export">Экспартаваць</string>
|
||||
<string name="logcat_buffer">Буфер logcat</string>
|
||||
<string name="logcat_buffer_descr">Праверце і падзяліцеся падрабязнымі журналамі праграмы</string>
|
||||
</resources>
|
8
OsmAnd-telegram/res/values-bg/strings.xml
Normal file
8
OsmAnd-telegram/res/values-bg/strings.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="send_report">Изпращане на доклад</string>
|
||||
<string name="last_response_date">Последен отговор: %1$s</string>
|
||||
<string name="last_update_from_telegram_date">Последна актуализация от Telegram: %1$s</string>
|
||||
<string name="shared_string_error_short">ГРЕШКА</string>
|
||||
<string name="shared_string_export">Експорт</string>
|
||||
</resources>
|
|
@ -131,7 +131,7 @@
|
|||
<string name="send_my_location">Envia la meva ubicació</string>
|
||||
<string name="gps_and_location">Ubicació</string>
|
||||
<string name="sharing_time">Temps de compartició</string>
|
||||
<string name="expire_at">"Expiració: "</string>
|
||||
<string name="expire_at">Finalitza</string>
|
||||
<string name="open_osmand">Obre l\'OsmAnd</string>
|
||||
<string name="shared_string_live">En directe</string>
|
||||
<string name="shared_string_bot">Bot</string>
|
||||
|
@ -267,4 +267,8 @@
|
|||
<string name="last_response_duration">Darrera resposta: fa %1$s</string>
|
||||
<string name="duration_ago">fa %1$s</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="shared_string_export">Exporta</string>
|
||||
<string name="logcat_buffer">Memòria intermèdia del Logcat</string>
|
||||
<string name="logcat_buffer_descr">Valida i comparteix enregistraments detallats de l\'aplicació</string>
|
||||
<string name="send_report">Envia un informe</string>
|
||||
</resources>
|
|
@ -72,4 +72,6 @@
|
|||
<string name="shared_string_enabled">Povolen</string>
|
||||
<string name="unit_of_length">Jednotky vzdálenosti</string>
|
||||
<string name="shared_string_appearance">Vzhled</string>
|
||||
<string name="logcat_buffer">Zásobník logcat</string>
|
||||
<string name="logcat_buffer_descr">Zkontrolovat a sdílet podrobné záznamy aplikace</string>
|
||||
</resources>
|
|
@ -269,4 +269,8 @@
|
|||
<string name="last_response_duration">Sidste svar: %1$s siden</string>
|
||||
<string name="duration_ago">%1$s siden</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="shared_string_export">Eksporter</string>
|
||||
<string name="logcat_buffer">Logcat-buffer</string>
|
||||
<string name="logcat_buffer_descr">Kontroller og del detaljerede logfiler for programmet</string>
|
||||
<string name="send_report">Send rapport</string>
|
||||
</resources>
|
|
@ -267,4 +267,8 @@
|
|||
<string name="last_response_duration">Letzte Antwort: vor %1$s</string>
|
||||
<string name="duration_ago">vor %1$s</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="shared_string_export">Export</string>
|
||||
<string name="logcat_buffer">Logcat-Puffer</string>
|
||||
<string name="logcat_buffer_descr">Protokolle der Anwendung einsehen und freigeben</string>
|
||||
<string name="send_report">Bericht senden</string>
|
||||
</resources>
|
|
@ -268,4 +268,8 @@
|
|||
<string name="last_response_duration">Última respuesta: Hace %1$s</string>
|
||||
<string name="duration_ago">Hace %1$s</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="shared_string_export">Exportar</string>
|
||||
<string name="logcat_buffer">Búfer de Logcat</string>
|
||||
<string name="logcat_buffer_descr">Comprueba y comparte los registros detallados de la aplicación</string>
|
||||
<string name="send_report">Enviar informe</string>
|
||||
</resources>
|
|
@ -250,7 +250,7 @@
|
|||
<string name="set_time_timeline_descr">Elige la hora de visualización</string>
|
||||
<string name="start_end_date">Fecha de Inicio — Fin</string>
|
||||
<string name="saved_messages">Mensajes guardados</string>
|
||||
<string name="time_zone_descr">Seleccione la zona horaria que desea mostrar en los mensajes de ubicación.</string>
|
||||
<string name="time_zone_descr">Seleccione la zona horaria a mostrar en sus mensajes de ubicación.</string>
|
||||
<string name="time_zone">Zona horaria</string>
|
||||
<string name="units_and_formats">Unidades y formatos</string>
|
||||
<string name="unit_of_length_descr">Cambia las unidades de longitud.</string>
|
||||
|
@ -268,4 +268,8 @@
|
|||
<string name="last_response_duration">Última respuesta: hace %1$s</string>
|
||||
<string name="duration_ago">hace %1$s</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="shared_string_export">Exportar</string>
|
||||
<string name="logcat_buffer">Búfer de Logcat</string>
|
||||
<string name="logcat_buffer_descr">Selecciona y comparte logs detallados de la app</string>
|
||||
<string name="send_report">Enviar informe</string>
|
||||
</resources>
|
|
@ -267,4 +267,8 @@
|
|||
<string name="last_response_duration">Viimane vastus: %1$s tagasi</string>
|
||||
<string name="duration_ago">%1$s tagasi</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="shared_string_export">Ekspordi</string>
|
||||
<string name="logcat_buffer">Logcati puhver</string>
|
||||
<string name="logcat_buffer_descr">Vaata ja jaga rakenduse detailseid logisid</string>
|
||||
<string name="send_report">Saada ettekanne</string>
|
||||
</resources>
|
|
@ -38,8 +38,8 @@
|
|||
<string name="yard">yd</string>
|
||||
<string name="foot">ft</string>
|
||||
<string name="mile">mi</string>
|
||||
<string name="km">کم</string>
|
||||
<string name="m">متر</string>
|
||||
<string name="km">km</string>
|
||||
<string name="m">m</string>
|
||||
<string name="nm">nmi</string>
|
||||
<string name="min_mile">min/m</string>
|
||||
<string name="min_km">min/km</string>
|
||||
|
@ -73,4 +73,13 @@
|
|||
<string name="unit_of_length_descr">یکاهای طول را تغییر دهید.</string>
|
||||
<string name="unit_of_length">یکاهای طول</string>
|
||||
<string name="shared_string_appearance">ظاهر</string>
|
||||
<string name="last_response_duration">آخرین پاسخ: %1$s پیش</string>
|
||||
<string name="last_update_from_telegram_duration">آخرین بهروزرسانی تلگرام: %1$s پیش</string>
|
||||
<string name="last_response_date">آخرین پاسخ: %1$s</string>
|
||||
<string name="last_update_from_telegram_date">آخرین بهروزرسانی تلگرام: %1$s</string>
|
||||
<string name="shared_string_error_short">خطا</string>
|
||||
<string name="send_report">ارسال گزارش</string>
|
||||
<string name="shared_string_export">برونبرد</string>
|
||||
<string name="logcat_buffer">بافر لاگکت</string>
|
||||
<string name="logcat_buffer_descr">لاگهای جزئی برنامه را بررسی و همرسانی کنید</string>
|
||||
</resources>
|
|
@ -266,4 +266,9 @@
|
|||
<string name="location_history_desc">Cacher les contacts qui ne se sont pas déplacés depuis un temps donné.</string>
|
||||
<string name="set_time_description">Définissez l\'heure à laquelle les contacts et groupes sélectionnés verront votre position en temps réel.</string>
|
||||
<string name="osmand_connect">OsmAnd connect</string>
|
||||
<string name="time_ago">depuis</string>
|
||||
<string name="logcat_buffer">Buffer Logcat</string>
|
||||
<string name="logcat_buffer_descr">Vérifier et partager les logs détaillés de l\'application</string>
|
||||
<string name="shared_string_export">Exporter</string>
|
||||
<string name="send_report">Envoyer le rapport</string>
|
||||
</resources>
|
|
@ -268,4 +268,8 @@
|
|||
<string name="time_zone_descr">Escolle a zona horaria que desexas amosar nas mensaxes de localización.</string>
|
||||
<string name="buffer_time">Tempo de caducidade do búfer</string>
|
||||
<string name="buffer_time_descr">Tempo máximo para almacenar puntos no búfer</string>
|
||||
<string name="shared_string_export">Exportar</string>
|
||||
<string name="logcat_buffer">Búfer de Logcat</string>
|
||||
<string name="logcat_buffer_descr">Verifica e comparte rexistros detallados da aplicación</string>
|
||||
<string name="send_report">Enviar denuncia</string>
|
||||
</resources>
|
|
@ -268,4 +268,8 @@
|
|||
<string name="last_response_duration">תגובה אחרונה: לפני %1$s</string>
|
||||
<string name="duration_ago">לפני %1$s</string>
|
||||
<string name="shared_string_error_short">שגיאה</string>
|
||||
<string name="shared_string_export">ייצוא</string>
|
||||
<string name="logcat_buffer">מכלא Logcat</string>
|
||||
<string name="logcat_buffer_descr">בדיקה ושיתוף יומני תיעוד מפורטים של היישומים</string>
|
||||
<string name="send_report">שליחת דיווח</string>
|
||||
</resources>
|
|
@ -268,4 +268,8 @@
|
|||
<string name="last_response_duration">Utolsó válasz: %1$s</string>
|
||||
<string name="duration_ago">Ennyivel ezelőtt: %1$s</string>
|
||||
<string name="shared_string_error_short">HIBA</string>
|
||||
<string name="shared_string_export">Exportálás</string>
|
||||
<string name="logcat_buffer">Logcat-puffer (hibanapló)</string>
|
||||
<string name="logcat_buffer_descr">Az alkalmazás részletes naplóinak ellenőrzése és megosztása</string>
|
||||
<string name="send_report">Jelentés küldése</string>
|
||||
</resources>
|
274
OsmAnd-telegram/res/values-is/strings.xml
Normal file
274
OsmAnd-telegram/res/values-is/strings.xml
Normal file
|
@ -0,0 +1,274 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="units_and_formats">Einingar og snið</string>
|
||||
<string name="install_osmand">Setja upp OsmAnd</string>
|
||||
<string name="proxy_password">Lykilorð</string>
|
||||
<string name="average_altitude">Meðalhæð</string>
|
||||
<string name="shared_string_hide">Fela</string>
|
||||
<string name="gps_points_in_buffer">sendi (%1$d í biðminni)</string>
|
||||
<string name="re_send_location">Endursenda staðsetningu</string>
|
||||
<string name="searching_for_gps">Staðsetning…</string>
|
||||
<string name="average_speed">Meðalhraði</string>
|
||||
<string name="logcat_buffer_descr">Athugaðu og deildu nákvæmum atvikaskrám úr forritinu</string>
|
||||
<string name="si_mi_meters">Mílur/metrar</string>
|
||||
<string name="password_descr">Lykilorð í Telegram</string>
|
||||
<string name="share_location_as">Deila staðsetningu sem</string>
|
||||
<string name="share_location">Deila staðsetningu</string>
|
||||
<string name="min_logging_distance_descr">Sía: Stilltu lágmarksfjarlægð frá síðustu staðsetningu þar sem punktur er tekinn í skráningu</string>
|
||||
<string name="shared_string_back">Til baka</string>
|
||||
<string name="shared_string_off">Slökkt</string>
|
||||
<string name="no_internet_connection">Engin internettenging</string>
|
||||
<string name="set_time">Stilla tíma</string>
|
||||
<string name="shared_string_accept">Samþykkja</string>
|
||||
<string name="shared_string_second_short">sek</string>
|
||||
<string name="minutes_format">%1$d mín</string>
|
||||
<string name="si_mi_feet">Mílur/fet</string>
|
||||
<string name="shared_string_bot">Vélmenni</string>
|
||||
<string name="osmand_privacy_policy">Meðferð persónuupplýsinga í OsmAnd</string>
|
||||
<string name="sending_location_messages">Sendi staðsetningu</string>
|
||||
<string name="proxy_type">Tegund milliþjóns (proxy)</string>
|
||||
<string name="unit_of_length_descr">Breyta einingum sem notaðar eru við lengdarmælingar.</string>
|
||||
<string name="location_history">Staðsetningaferill</string>
|
||||
<string name="osmand_logo">Merki OsmAnd</string>
|
||||
<string name="error_adding_new_device">Gat ekki bætt við nýju tæki</string>
|
||||
<string name="gps_and_location">Staða</string>
|
||||
<string name="proxy_settings">Stillingar milliþjóns (proxy)</string>
|
||||
<string name="proxy_port">Gátt</string>
|
||||
<string name="by_name">Eftir nafni</string>
|
||||
<string name="time_zone">Tímabelti</string>
|
||||
<string name="min_km">mín/km</string>
|
||||
<string name="m">m</string>
|
||||
<string name="location_recording_enabled">Skráning staðsetningar virk</string>
|
||||
<string name="shared_string_connection">Tenging</string>
|
||||
<string name="si_km_m">Kílómetrar/metrar</string>
|
||||
<string name="last_update_from_telegram_duration">Síðasta uppfærsla frá Telegram: Fyrir %1$s síðan</string>
|
||||
<string name="monitoring_is_disabled">Vöktun er óvirk</string>
|
||||
<string name="status_widget_title">Staða OsmAnd-rakningar</string>
|
||||
<string name="app_name_short">OsmAnd-rakning</string>
|
||||
<string name="shared_string_group">Hópur</string>
|
||||
<string name="min_mile">mín/ml</string>
|
||||
<string name="proxy_server">Netþjónn</string>
|
||||
<string name="turn_off_all">Slökkva á öllu</string>
|
||||
<string name="back_to_osmand">Til baka í OsmAnd</string>
|
||||
<string name="device_name_is_too_long">Heiti tækis er of langt</string>
|
||||
<string name="closing">Loka</string>
|
||||
<string name="hours_and_minutes_format">%1$d klst %2$d mín</string>
|
||||
<string name="si_min_m">Mínútur á mílu</string>
|
||||
<string name="shared_string_minute_short">mín</string>
|
||||
<string name="shared_string_start">Byrja</string>
|
||||
<string name="shared_string_save">Vista</string>
|
||||
<string name="map_and_text">Landakort og texti</string>
|
||||
<string name="shared_string_password">Lykilorð</string>
|
||||
<string name="device_added_successfully">%1$s bætt við.</string>
|
||||
<string name="open_in_osmand">Birta í OsmAnd</string>
|
||||
<string name="last_available_location">Síðasta tiltæka staðsetning</string>
|
||||
<string name="shared_string_sent">Sent</string>
|
||||
<string name="authentication_code">Auðkenningarkóði</string>
|
||||
<string name="search_contacts">Leita í tengiliðum</string>
|
||||
<string name="open_osmand">Opna OsmAnd</string>
|
||||
<string name="shared_string_end">Endar</string>
|
||||
<string name="enter_authentication_code">Settu inn auðkenningarkóða</string>
|
||||
<string name="my_location">Staðsetning mín</string>
|
||||
<string name="shared_string_logout">Skrá út</string>
|
||||
<string name="show_on_map">Birta á korti</string>
|
||||
<string name="sharing_status">Staða deilingar</string>
|
||||
<string name="shared_string_cancel">Hætta við</string>
|
||||
<string name="waiting_for_response_from_telegram">Bíð eftir svari frá Telegram</string>
|
||||
<string name="successfully_sent_and_updated">Tókst að senda og uppfæra</string>
|
||||
<string name="shared_string_select">Velja</string>
|
||||
<string name="si_m_s">Metrar á sekúndu</string>
|
||||
<string name="device_name">Heiti tækis</string>
|
||||
<string name="shared_string_welcome">Velkomin</string>
|
||||
<string name="how_it_works">Hvernig það virkar</string>
|
||||
<string name="direction">Stefna</string>
|
||||
<string name="proxy">Milliþjónn</string>
|
||||
<string name="no_gps_connection">Engin GPS-tenging</string>
|
||||
<string name="send_location_as">Senda staðsetningu sem</string>
|
||||
<string name="points_size">%1$d punktar</string>
|
||||
<string name="yard">yd</string>
|
||||
<string name="shared_string_disable">Gera óvirkt</string>
|
||||
<string name="time_on_the_move">Tími á ferðinni</string>
|
||||
<string name="si_nm_h">Sjómílur á klukkustund (hnútar)</string>
|
||||
<string name="hours_format">%1$d klst</string>
|
||||
<string name="proxy_key">Lykill</string>
|
||||
<string name="background_work">Bakgrunnsvinna</string>
|
||||
<string name="shared_string_install">Setja upp</string>
|
||||
<string name="shared_string_add">Bæta við</string>
|
||||
<string name="shared_string_sort_by">Raða eftir</string>
|
||||
<string name="last_response_date">Síðasta svar: %1$s</string>
|
||||
<string name="shared_string_all">Allt</string>
|
||||
<string name="altitude">Hæð</string>
|
||||
<string name="show_gps_points">Birta GPS-punkta</string>
|
||||
<string name="device_name_cannot_be_empty">Heiti tækis getur ekki verið tómt</string>
|
||||
<string name="shared_string_search">Leita</string>
|
||||
<string name="by_distance">Eftir vegalengd</string>
|
||||
<string name="si_nm">Sjómílur</string>
|
||||
<string name="m_s">m/sek</string>
|
||||
<string name="not_logged_in">Þú ert ekki skráð/ur inn</string>
|
||||
<string name="initializing">Ræsing</string>
|
||||
<string name="min_logging_accuracy">Lágmarksnákvæmni skráningar</string>
|
||||
<string name="shared_string_close">Loka</string>
|
||||
<string name="min_logging_speed">Lágmarkshraði skráninga</string>
|
||||
<string name="process_service">OsmAnd rakningarþjónusta</string>
|
||||
<string name="shared_string_telegram">Telegram</string>
|
||||
<string name="gps_network_not_enabled">Kveikja á \"Staðsetning\"\?</string>
|
||||
<string name="connected_account">Tengdur aðgangur</string>
|
||||
<string name="mile">mi</string>
|
||||
<string name="proxy_username">Notandanafn</string>
|
||||
<string name="shared_string_authorization">Heimild</string>
|
||||
<string name="unit_of_length">Lengdareiningar</string>
|
||||
<string name="gpx_settings">GPX-stillingar</string>
|
||||
<string name="get_telegram_title">Nýskráning í Telegram</string>
|
||||
<string name="shared_string_distance">Vegalengd</string>
|
||||
<string name="shared_string_hour_short">klst</string>
|
||||
<string name="km_h">km/klst</string>
|
||||
<string name="shared_string_login">Skrá inn</string>
|
||||
<string name="last_response">Síðasta svar</string>
|
||||
<string name="start_location_sharing">Deila staðsetningu</string>
|
||||
<string name="foot">ft</string>
|
||||
<string name="shared_string_name">Nafn</string>
|
||||
<string name="duration_ago">%1$s síðan</string>
|
||||
<string name="location_sharing_description">Veldu notendur eða hópa til að deila með staðsetningu þinni.</string>
|
||||
<string name="do_not_have_telegram">Ég er ekki með Telegram-aðgang</string>
|
||||
<string name="monitoring_is_enabled">Vöktun er virk</string>
|
||||
<string name="expire_at">Rennur út</string>
|
||||
<string name="privacy">Gagnaleynd</string>
|
||||
<string name="shared_string_account">Notandaaðgangur</string>
|
||||
<string name="shared_string_enabled">Virkt</string>
|
||||
<string name="precision">Nákvæmni</string>
|
||||
<string name="shared_string_error_short">VILL</string>
|
||||
<string name="stale_location">Ekki á ferð</string>
|
||||
<string name="shared_string_continue">Halda áfram</string>
|
||||
<string name="shared_string_status">Staða</string>
|
||||
<string name="start_end_date">Upphafs — Endadagsetning</string>
|
||||
<string name="proxy_disconnected">Aftengt</string>
|
||||
<string name="nm">sml</string>
|
||||
<string name="shared_string_update">Uppfæra</string>
|
||||
<string name="enter_password">Settu inn lykilorð</string>
|
||||
<string name="shared_string_share">Deila</string>
|
||||
<string name="logcat_buffer">Logcat biðminni</string>
|
||||
<string name="enter_phone_number">Settu inn símanúmer</string>
|
||||
<string name="si_min_km">Mínútur á kílómetra</string>
|
||||
<string name="shared_string_exit">Hætta</string>
|
||||
<string name="shared_string_appearance">Útlit</string>
|
||||
<string name="shared_string_date">Dagsetning</string>
|
||||
<string name="shared_string_later">Síðar</string>
|
||||
<string name="bearing">Stefna</string>
|
||||
<string name="unit_of_speed_system">Hraðaeining</string>
|
||||
<string name="shared_string_map">Landakort</string>
|
||||
<string name="min_logging_speed_descr">Sía: Engin skráning punkta fyrir neðan valinn hraða</string>
|
||||
<string name="in_time">í %1$s</string>
|
||||
<string name="my_location_search_hint">Leit: Hópur eða tengiliður</string>
|
||||
<string name="nm_h">hnútar</string>
|
||||
<string name="km">km</string>
|
||||
<string name="timeline">Tímalína</string>
|
||||
<string name="saved_messages">Vistuð skilaboð</string>
|
||||
<string name="gps_points">GPS-punktar</string>
|
||||
<string name="shared_string_apply">Virkja</string>
|
||||
<string name="min_logging_distance">Lágmarksfjarlægð skráninga</string>
|
||||
<string name="last_update_from_telegram">Síðasta uppfærsla frá Telegram</string>
|
||||
<string name="shared_string_collected">Safnað</string>
|
||||
<string name="logging_out">Skrái út</string>
|
||||
<string name="si_mi_yard">Mílur/yardar</string>
|
||||
<string name="set_time_timeline_descr">Veldu tíma sem á að birta</string>
|
||||
<string name="proxy_credentials">Auðkenni</string>
|
||||
<string name="si_kmh">Kílómetrar á klukkustund</string>
|
||||
<string name="last_response_duration">Síðasta svar: Fyrir %1$s síðan</string>
|
||||
<string name="connecting_to_the_internet">Tengist internetinu</string>
|
||||
<string name="send_report">Senda skýrslu</string>
|
||||
<string name="shared_string_export">Flytja út</string>
|
||||
<string name="si_mph">Mílur á klukkustund</string>
|
||||
<string name="shared_string_ok">Í lagi</string>
|
||||
<string name="shared_string_enable">Virkja</string>
|
||||
<string name="telegram_privacy_policy">Persónuverndarstefna Telegram</string>
|
||||
<string name="active_chats">Virkt spjall</string>
|
||||
<string name="send_my_location">Senda staðsetningu mína</string>
|
||||
<string name="shared_string_suggested">Stungið upp á</string>
|
||||
<string name="go_to_settings">Fara í stillingar</string>
|
||||
<string name="mile_per_hour">mi/klst</string>
|
||||
<string name="sharing_in_background">Deiling í bakgrunni</string>
|
||||
<string name="location_sharing_status">Deiling: %1$s</string>
|
||||
<string name="last_update_from_telegram_date">Síðasta uppfærsla frá Telegram: %1$s</string>
|
||||
<string name="initialization">Byrja</string>
|
||||
<string name="shared_string_sort">Raða</string>
|
||||
<string name="timeline_no_data">Engin gögn</string>
|
||||
<string name="by_group">Eftir hópi</string>
|
||||
<string name="add_device">Bæta við tæki</string>
|
||||
<string name="shared_string_text">Texti</string>
|
||||
<string name="shared_string_settings">Stillingar</string>
|
||||
<string name="show_users_on_map">Birta notendur á kortinu</string>
|
||||
<string name="proxy_connected">Tengt</string>
|
||||
<string name="phone_number_title">Símanúmer</string>
|
||||
<string name="start_date">Upphafsdagsetning</string>
|
||||
<string name="unit_of_speed_system_descr">Skilgreindu einingu fyrir hraða.</string>
|
||||
<string name="time_ago">síðan</string>
|
||||
<string name="enter_code">Settu inn kóða</string>
|
||||
<string name="disable_monitoring">Gera vöktun óvirka</string>
|
||||
<string name="no_location_permission">Forritið hefur ekki heimildir til að nota staðsetningargögn.</string>
|
||||
<string name="end_date">Lokadagsetning</string>
|
||||
<string name="osmand_service">Bakgrunnshamur</string>
|
||||
<string name="osmand_service_descr">OsmAnd-rakning keyrir í bakgrunni á meðan slökkt er á skjá.</string>
|
||||
<string name="not_found_yet">Ekki fundist ennþá</string>
|
||||
<string name="received_gps_points">Móttók GPX-punkta: %1$s</string>
|
||||
<string name="sharing_location">Deili staðsetningu</string>
|
||||
<string name="logout_help_desc">Hvernig á að slökkva á OsmAnd-rakningu úr Telegram</string>
|
||||
<string name="not_sent_yet">Ekki sent ennþá</string>
|
||||
<string name="app_name">OsmAnd nettengdur GPS-rekjari</string>
|
||||
<string name="logout_from_osmand_telegram">Skrá út úr OsmAnd-rakningu\?</string>
|
||||
<string name="stop_sharing_all">Kveikt er á deilingu (slökkva)</string>
|
||||
<string name="disconnect_from_telegram">Hvernig á að slökkva á OsmAnd-rakningu úr Telegram</string>
|
||||
<string name="gps_not_available">Virkjaðu \"Staðsetning\" í stillingunum stýrikerfisins</string>
|
||||
<string name="live_now_description">Tengiliðir og hópar sem deila staðsetningu til þín.</string>
|
||||
<string name="logout_no_internet_msg">Tengstu við internetið til að geta skráð þig til fulls út úr Telegram.</string>
|
||||
<string name="privacy_policy_agree">Með því að smella á \'Halda áfram\', samþykkir þú ákvæði og skilyrði varðandi gagnaleynd hjá Telegram og OsmAnd.</string>
|
||||
<string name="buffer_time">Gildistími biðminnis</string>
|
||||
<string name="sharing_time">Tími deilingar</string>
|
||||
<string name="send_location_as_descr">Veldu hvernig skilaboð með staðsetningu þinni líti út.</string>
|
||||
<string name="install_osmand_dialog_message">Þú þarft fyrst að setja upp ókeypis eða greidda útgáfu OsmAnd</string>
|
||||
<string name="disable_all_sharing_desc">Slekkur á deilingu staðsetningar til allra valinna spjalla (%1$d).</string>
|
||||
<string name="turn_off_location_sharing">Slökkva á deilingu staðsetningar</string>
|
||||
<string name="type_contact_or_group_name">Settu inn nafn tengiliðar eða hóps</string>
|
||||
<string name="timeline_available_for_free_now">Tímalína er eiginleiki sem er núna aðgengilegur ókeypis.</string>
|
||||
<string name="already_registered_in_telegram">Þú þarft skráðan Telegram-aðgang og símanúmer</string>
|
||||
<string name="authentication_code_descr">Telegram hefur sent þér kóða fyrir OsmAnd til að skrá þig inn í notandaaðganginn þinn.</string>
|
||||
<string name="choose_osmand">Veldu hvaða útgáfu OsmAnd þú vilt nota</string>
|
||||
<string name="disable_all_sharing">Gera alla deilingu óvirka</string>
|
||||
<string name="please_update_osmand">Uppfærðu OsmAnd til að skoða gögn á kortinu</string>
|
||||
<string name="time_zone_descr">Veldu tímabelti til birtingar í staðsetningarskilaboðum þínum.</string>
|
||||
<string name="location_service_no_gps_available">Veldu eina af staðsetningarþjónustunum til að deila staðsetningu þinni.</string>
|
||||
<string name="set_visible_time_for_all">Stilla tímabil þar sem allir eru sýnilegir</string>
|
||||
<string name="osmand_connect_desc">Veldu þá útgáfu OsmAnd sem OsmAnd-rakningin notar til að birta staðsetningar.</string>
|
||||
<string name="get_telegram_description_continue">Endilega settu upp Telegram og skráðu notandaaðgang.</string>
|
||||
<string name="shared_string_authorization_descr">Settu inn Telegram-símanúmerið þitt á alþjóðlegu sniði</string>
|
||||
<string name="timeline_description">Virkja vöktun til að vista allar staðsetningar í aðgerðaferli.</string>
|
||||
<string name="visible_time_for_all">Tímabil þar sem allir eru sýnilegir</string>
|
||||
<string name="send_my_location_desc">Stilla minnsta bil á milli deilingar staðsetningar.</string>
|
||||
<string name="buffer_time_descr">Hámarkstími sem punktar eru geymdir í biðminninu</string>
|
||||
<string name="get_telegram_account_first">Þú þarft skráðan Telegram-aðgang til að geta notað deilingu staðsetningar.</string>
|
||||
<string name="phone_number_descr">Símanúmer á alþjóðlegu sniði</string>
|
||||
<string name="choose_osmand_desc">Veldu þá útgáfu OsmAnd þar sem tengiliðir verða birtir á kortinu.</string>
|
||||
<string name="osmand_connect">Tengjast OsmAnd</string>
|
||||
<string name="show_gps_points_descr">Birta fjölda safnaðra og sendra GPS-punkta.</string>
|
||||
<string name="privacy_policy_use_telegram">Telegram (skilaboðaforritið) er notað til að tengjast og eiga í samskiptum við fólk.</string>
|
||||
<string name="get_telegram_after_creating_account">þá geturðu notað þetta forrit.</string>
|
||||
<string name="enter_device_name_description">Gefðu nýja tækinu þínu nafn að hámarki 200 stafir.</string>
|
||||
<string name="timeline_no_data_descr">Við erum ekki með söfnuð gögn fyrir valinn dag</string>
|
||||
<string name="search_contacts_descr">Leita í öllum þínum hópum og tengiliðum.</string>
|
||||
<string name="min_logging_accuracy_descr">Sía: Stilltu lágmarksnákvæmni punkts til að hann sé tekinn í skráningu</string>
|
||||
<string name="location_history_desc">Fela tengiliði sem ekki hafa hreyfst á tilteknu tímabili.</string>
|
||||
<string name="stale_location_desc">Síðasta skiptið sem tengiliður hreyfðist.</string>
|
||||
<string name="last_updated_location">Síðasta uppfærða staðsetning:</string>
|
||||
<string name="enter_another_device_name">Veldu nafn sem þú hefur ekki þegar notað</string>
|
||||
<string name="not_possible_to_send_to_telegram_chats">Ekki mögulegt að senda á Telegram-spjöll:</string>
|
||||
<string name="disconnect_from_telegram_desc">Til að afturkalla heimildir til deilingar á staðsetningu, opnaðu Telegram, farðu í Stillingar → Gagnaleynd og öryggi → Setur, og bittu enda á setu OsmAnd-rakningar.</string>
|
||||
<string name="share_location_as_description_second_line">Þú getur útbúið og skoðað auðkenningu tækis (device ID) í Telegram-biðlaraforritinu með því að nota %1$s spjallvélmennið. %2$s</string>
|
||||
<string name="logout_from_osmand_telegram_descr">Ertu viss að þú viljir skrá þig út úr OsmAnd-rakningu þannig að þú getir ekki lengur deilt þinni staðsetningu eða séð staðsetningu annarra\?</string>
|
||||
<string name="battery_optimization_description">Slokktu á bestun rafhlöðunýtingar fyrir OsmAnd-rakningu svo ekki slökkni á henni þegar forritið fer í bakgrunnsham (t.d. slökkt er á skjá).</string>
|
||||
<string name="privacy_policy_telegram_client">OsmAnd-rakning er eitt af biðlaraforritunum sem nota opna Telegram-kerfið. Tengiliðirnir þínir geta notað eitthvað annað Telegram-biðlaraforrit.</string>
|
||||
<string name="welcome_descr"><b>OsmAnd-rakning</b> gerir þér kleift að deila staðsetningu þinni og að sjá aðra í OsmAnd.<br/><br/>Forritið notar Telegram API-forritsviðmótið, þannig að þú verður að vera með Telegram-aðgang.</string>
|
||||
<string name="share_location_as_description">Ef þú ætlar að tengja mörg tæki við einn Telegram-notandaaðgang, þarftu að nota annað tæki til að deila staðsetningunni þinni.</string>
|
||||
<string name="shared_string_live">Rauntíma</string>
|
||||
<string name="background_work_description">Breyta bestunarstillingum rafhlöðu til að auka stöðugleika í deilingu staðsetningar.</string>
|
||||
<string name="set_time_description">Veldu tímann sem valdir tengiliðir og hópar munu sjá staðsetningu þína í rauntíma.</string>
|
||||
<string name="live_now">Rauntíma núna</string>
|
||||
</resources>
|
|
@ -265,4 +265,6 @@
|
|||
<string name="last_response_date">Ultima risposta: %1$s</string>
|
||||
<string name="last_update_from_telegram_date">Ultimo aggiornamento da Telegram: %1$s</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="logcat_buffer_descr">Controlla e condividi i log dettagliati dell\'applicazione</string>
|
||||
<string name="logcat_buffer">Logcat buffer</string>
|
||||
</resources>
|
|
@ -219,8 +219,8 @@
|
|||
<string name="shared_string_authorization_descr">国際形式でTelegramを利用する端末の電話番号を入力してください(日本の場合+81を先頭につけて電話番号最初の0を除いた番号を入力)</string>
|
||||
<string name="shared_string_welcome">ようこそ</string>
|
||||
<string name="yard">ヤード</string>
|
||||
<string name="foot">フィート</string>
|
||||
<string name="mile">マイル</string>
|
||||
<string name="foot">ft</string>
|
||||
<string name="mile">mi</string>
|
||||
<string name="km">km</string>
|
||||
<string name="m">m</string>
|
||||
<string name="nm">海里</string>
|
||||
|
|
|
@ -179,7 +179,7 @@
|
|||
<string name="monitoring_is_enabled">Oppsyn er påskrudd</string>
|
||||
<string name="monitoring_is_disabled">Oppsyn er ikke aktivert</string>
|
||||
<string name="time_on_the_move">Tid i bevegelse</string>
|
||||
<string name="average_altitude">Gjennomsnittlig høyde</string>
|
||||
<string name="average_altitude">Gjennomsnittshøyde</string>
|
||||
<string name="average_speed">Gjennomsnittsfart</string>
|
||||
<string name="open_in_osmand">Vis i OsmAnd</string>
|
||||
<string name="end_date">Sluttdato</string>
|
||||
|
@ -267,4 +267,8 @@
|
|||
<string name="last_response_duration">Siste respons: %1$s siden</string>
|
||||
<string name="duration_ago">%1$s siden</string>
|
||||
<string name="shared_string_error_short">FEIL</string>
|
||||
<string name="logcat_buffer">Logcat-mellomlager</string>
|
||||
<string name="shared_string_export">Eksporter</string>
|
||||
<string name="logcat_buffer_descr">Sjekk og del detaljert loggføring fra programmet</string>
|
||||
<string name="send_report">Send rapport</string>
|
||||
</resources>
|
|
@ -257,4 +257,8 @@
|
|||
<string name="unit_of_length">Afstand eenheden</string>
|
||||
<string name="unit_of_speed_system_descr">Definieer de eenheid voor snelheid.</string>
|
||||
<string name="unit_of_speed_system">Eenheid van snelheid</string>
|
||||
<string name="send_report">Stuur rapport</string>
|
||||
<string name="shared_string_export">Exporteer naar OSM</string>
|
||||
<string name="logcat_buffer">Logcat buffer</string>
|
||||
<string name="logcat_buffer_descr">Controleer en deel gedetailleerde logs van de app</string>
|
||||
</resources>
|
|
@ -267,4 +267,8 @@
|
|||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="last_response_date">Ostatnia odpowiedź: %1$s</string>
|
||||
<string name="last_response_duration">Ostatnia odpowiedź: %1$s temu</string>
|
||||
<string name="shared_string_export">Eksportuj</string>
|
||||
<string name="logcat_buffer">Bufor katalogu dziennika</string>
|
||||
<string name="logcat_buffer_descr">Sprawdzanie i udostępnianie szczegółowych logów aplikacji</string>
|
||||
<string name="send_report">Wyślij raport</string>
|
||||
</resources>
|
|
@ -267,4 +267,8 @@
|
|||
<string name="last_response_duration">Última resposta: %1$s atrás</string>
|
||||
<string name="duration_ago">%1$s atrás</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="shared_string_export">Exportar</string>
|
||||
<string name="logcat_buffer">Buffer de Logcat</string>
|
||||
<string name="logcat_buffer_descr">Verifique e compartilhe registros detalhados do aplicativo</string>
|
||||
<string name="send_report">Enviar o relatório</string>
|
||||
</resources>
|
|
@ -267,4 +267,8 @@
|
|||
<string name="last_response_date">Última resposta: %1$s</string>
|
||||
<string name="last_update_from_telegram_date">Última atualização do Telegram: %1$s</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="shared_string_export">Exportar</string>
|
||||
<string name="logcat_buffer">Buffer de logcat</string>
|
||||
<string name="logcat_buffer_descr">Verifique e compartilhe registos detalhados da app</string>
|
||||
<string name="send_report">Enviar o relatório</string>
|
||||
</resources>
|
|
@ -108,7 +108,7 @@
|
|||
<string name="not_found_yet">Ainda não encontrado</string>
|
||||
<string name="re_send_location">Reenvie o local</string>
|
||||
<string name="last_available_location">Última localização disponível</string>
|
||||
<string name="sharing_status">Status de compartilhamento</string>
|
||||
<string name="sharing_status">Estado de compartilhamento</string>
|
||||
<string name="location_sharing_status">Compartilhamento: %1$s</string>
|
||||
<string name="shared_string_enabled">Ativado</string>
|
||||
<string name="no_gps_connection">Sem conexão GPS</string>
|
||||
|
@ -163,7 +163,7 @@
|
|||
<string name="get_telegram_description_continue">Por favor, instale o Telegram e configure uma conta.</string>
|
||||
<string name="get_telegram_after_creating_account">Então pode usar esta app.</string>
|
||||
<string name="shared_string_all">Todos</string>
|
||||
<string name="shared_string_off">Desativado</string>
|
||||
<string name="shared_string_off">Desligado</string>
|
||||
<string name="already_registered_in_telegram">Precisa de uma conta e número de telefone registados no Telegram</string>
|
||||
<string name="do_not_have_telegram">Não tenho uma conta do Telegram</string>
|
||||
<string name="enter_phone_number">Digite o número de telefone</string>
|
||||
|
@ -204,7 +204,7 @@
|
|||
<string name="no_location_permission">A app não tem permissão para acessar os dados de localização.</string>
|
||||
<string name="gps_not_available">Por favor, ligue \"Localização\" nas configurações do sistema</string>
|
||||
<string name="location_service_no_gps_available">Selecione um dos provedores de localização para compartilhar sua localização.</string>
|
||||
<string name="osmand_service">Modo em segundo plano</string>
|
||||
<string name="osmand_service">Modo de fundo</string>
|
||||
<string name="osmand_service_descr">OsmAnd Tracker é executado em segundo plano com o ecrã desligado.</string>
|
||||
<string name="shared_string_distance">Distância</string>
|
||||
<string name="share_location">Compartilhar localização</string>
|
||||
|
@ -230,15 +230,15 @@
|
|||
<string name="m_s">m/s</string>
|
||||
<string name="km_h">km/h</string>
|
||||
<string name="mile_per_hour">mph</string>
|
||||
<string name="si_kmh">Quilômetros por hora</string>
|
||||
<string name="si_kmh">Quilómetros por hora</string>
|
||||
<string name="si_mph">Milhas por hora</string>
|
||||
<string name="si_m_s">Metros por segundo</string>
|
||||
<string name="si_min_km">Minutos por quilômetro</string>
|
||||
<string name="si_min_km">Minutos por quilómetro</string>
|
||||
<string name="si_min_m">Minutos por milha</string>
|
||||
<string name="si_nm_h">Milhas náuticas por hora (nó)</string>
|
||||
<string name="si_mi_feet">Milhas/pés</string>
|
||||
<string name="si_mi_yard">Milhas/jardas</string>
|
||||
<string name="si_km_m">Quilômetros/metros</string>
|
||||
<string name="si_km_m">Quilómetros/metros</string>
|
||||
<string name="si_nm">Milhas náuticas</string>
|
||||
<string name="si_mi_meters">Milhas/metros</string>
|
||||
<string name="shared_string_hour_short">h</string>
|
||||
|
@ -252,7 +252,7 @@
|
|||
<string name="time_zone_descr">Selecione o fuso horário a mostrar nas suas mensagens de localização.</string>
|
||||
<string name="time_zone">Fuso horário</string>
|
||||
<string name="units_and_formats">Unidades e formatos</string>
|
||||
<string name="unit_of_length_descr">Alterar unidade de distância.</string>
|
||||
<string name="unit_of_length_descr">Alterar a unidade de medida de distância.</string>
|
||||
<string name="unit_of_length">Unidades de comprimento</string>
|
||||
<string name="unit_of_speed_system_descr">Definir unidade de velocidade.</string>
|
||||
<string name="unit_of_speed_system">Unidade de velocidade</string>
|
||||
|
@ -267,4 +267,8 @@
|
|||
<string name="last_response_date">Última resposta: %1$s</string>
|
||||
<string name="last_update_from_telegram_date">Última atualização do Telegram: %1$s</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="send_report">Enviar o relatório</string>
|
||||
<string name="shared_string_export">Exportar</string>
|
||||
<string name="logcat_buffer">Buffer de logcat</string>
|
||||
<string name="logcat_buffer_descr">Verifique e compartilhe registos detalhados da app</string>
|
||||
</resources>
|
|
@ -75,7 +75,7 @@
|
|||
<string name="by_distance">По расстоянию</string>
|
||||
<string name="by_name">По имени</string>
|
||||
<string name="by_group">По группе</string>
|
||||
<string name="shared_string_sort">Сортировать</string>
|
||||
<string name="shared_string_sort">Сортировка</string>
|
||||
<string name="shared_string_sort_by">Сортировать по</string>
|
||||
<string name="turn_off_all">Отстановить все</string>
|
||||
<string name="shared_string_exit">Выход</string>
|
||||
|
@ -267,4 +267,8 @@
|
|||
<string name="last_update_from_telegram_duration">Последнее обновление от Telegram: %1$s назад</string>
|
||||
<string name="last_response_date">Последний ответ: %1$s</string>
|
||||
<string name="last_update_from_telegram_date">Последнее обновление от Telegram: %1$s</string>
|
||||
<string name="shared_string_export">Экспорт</string>
|
||||
<string name="logcat_buffer">Буфер Logcat</string>
|
||||
<string name="logcat_buffer_descr">Проверьте и поделитесь подробными журналами приложения</string>
|
||||
<string name="send_report">Отправить отчёт</string>
|
||||
</resources>
|
|
@ -268,4 +268,8 @@
|
|||
<string name="last_response_duration">Ùrtima risposta: %1$s a como</string>
|
||||
<string name="duration_ago">%1$s a como</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="shared_string_export">Esporta</string>
|
||||
<string name="logcat_buffer">Buffer de Logcat</string>
|
||||
<string name="logcat_buffer_descr">Verìfica e cumpartzi sos registros de s\'aplicatzione fatos a sa minuda</string>
|
||||
<string name="send_report">Imbia resumu</string>
|
||||
</resources>
|
|
@ -267,4 +267,8 @@
|
|||
<string name="last_response_date">Последњи одговор: %1$</string>
|
||||
<string name="last_update_from_telegram_date">Последње ажурирање из Телеграма: %1$</string>
|
||||
<string name="shared_string_error_short">Грешка</string>
|
||||
<string name="shared_string_export">Извези</string>
|
||||
<string name="logcat_buffer">Logcat бафер</string>
|
||||
<string name="logcat_buffer_descr">Проверите и поделите детаљне записе апликације</string>
|
||||
<string name="send_report">Пошаљи извештај</string>
|
||||
</resources>
|
|
@ -233,7 +233,7 @@
|
|||
<string name="osmand_service_descr">OsmAnd Tracker, ekran kapalıyken arka planda çalışır.</string>
|
||||
<string name="share_location">Konumu paylaş</string>
|
||||
<string name="sharing_location">Konum paylaşılıyor</string>
|
||||
<string name="process_service">OsmAnd Tracker servisi</string>
|
||||
<string name="process_service">OsmAnd Tracker hizmeti</string>
|
||||
<string name="osmand_logo">OsmAnd logosu</string>
|
||||
<string name="install_osmand_dialog_message">Önce OsmAnd\'ın ücretsiz veya ücretli sürümünü yüklemeniz gerekmektedir</string>
|
||||
<string name="install_osmand">OsmAnd\'ı yükle</string>
|
||||
|
@ -267,4 +267,8 @@
|
|||
<string name="last_response_duration">Son cevap: %1$s önce</string>
|
||||
<string name="duration_ago">%1$s önce</string>
|
||||
<string name="shared_string_error_short">HATA</string>
|
||||
<string name="shared_string_export">Dışa aktar</string>
|
||||
<string name="logcat_buffer">Logcat tamponu</string>
|
||||
<string name="logcat_buffer_descr">Uygulamanın ayrıntılı günlük kayıtlarına göz atın ve paylaşın</string>
|
||||
<string name="send_report">Rapor gönder</string>
|
||||
</resources>
|
52
OsmAnd-telegram/res/values-tzm/strings.xml
Normal file
52
OsmAnd-telegram/res/values-tzm/strings.xml
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="shared_string_back">Aɣul</string>
|
||||
<string name="shared_string_share">Bḍu</string>
|
||||
<string name="enter_phone_number">Ssekcem uṭṭun n utilifun</string>
|
||||
<string name="shared_string_all">Akk</string>
|
||||
<string name="shared_string_bot">Abut</string>
|
||||
<string name="shared_string_live">Usrid</string>
|
||||
<string name="in_time">g %1$s</string>
|
||||
<string name="shared_string_account">Amiḍan</string>
|
||||
<string name="shared_string_close">Rgel</string>
|
||||
<string name="shared_string_group">Tarabbut</string>
|
||||
<string name="time_ago">aya</string>
|
||||
<string name="shared_string_exit">Ffeɣ</string>
|
||||
<string name="shared_string_sort_by">Fren s</string>
|
||||
<string name="shared_string_sort">Fren</string>
|
||||
<string name="by_group">S trabbut</string>
|
||||
<string name="by_name">S isem</string>
|
||||
<string name="shared_string_name">Isem</string>
|
||||
<string name="share_location_as">Bḍu adɣar am</string>
|
||||
<string name="add_device">Rnu allal</string>
|
||||
<string name="shared_string_save">Ḥḍu</string>
|
||||
<string name="shared_string_status">Addad</string>
|
||||
<string name="go_to_settings">Ddu ɣer tesɣal</string>
|
||||
<string name="sending_location_messages">Azan n udɣar</string>
|
||||
<string name="shared_string_hide">Ssentel</string>
|
||||
<string name="shared_string_add">Rnu</string>
|
||||
<string name="last_update_from_telegram">Taleqqemt tameggarut seg Tiligṛam</string>
|
||||
<string name="map_and_text">Takaṛḍa d uḍṛiṣ</string>
|
||||
<string name="shared_string_text">Aḍṛiṣ</string>
|
||||
<string name="shared_string_map">Takaṛḍa</string>
|
||||
<string name="send_location_as">Azen adɣar am</string>
|
||||
<string name="start_date">Asakud n usenti</string>
|
||||
<string name="shared_string_date">Asakud</string>
|
||||
<string name="shared_string_update">Ssedɣi</string>
|
||||
<string name="shared_string_telegram">Tiligṛam</string>
|
||||
<string name="shared_string_ok">WAX</string>
|
||||
<string name="shared_string_search">Rzu</string>
|
||||
<string name="direction">Tanila</string>
|
||||
<string name="privacy">Tinnutla</string>
|
||||
<string name="proxy">Apṛuksi</string>
|
||||
<string name="proxy_settings">Tisɣal n Upṛuksi</string>
|
||||
<string name="proxy_connected">Izdey</string>
|
||||
<string name="proxy_type">Anaw n upṛuksi</string>
|
||||
<string name="proxy_password">Taguri n uzray</string>
|
||||
<string name="proxy_key">Tasarut</string>
|
||||
<string name="gpx_settings">Tisɣal n GPX</string>
|
||||
<string name="shared_string_select">Stey</string>
|
||||
<string name="shared_string_start">Ssenti</string>
|
||||
<string name="back_to_osmand">Aɣul ɣer OsmAnd</string>
|
||||
<string name="duration_ago">%1$s aya</string>
|
||||
</resources>
|
|
@ -115,10 +115,10 @@
|
|||
<string name="not_logged_in">Ви не увійшли до системи</string>
|
||||
<string name="shared_string_continue">Продовжити</string>
|
||||
<string name="shared_string_cancel">Скасувати</string>
|
||||
<string name="shared_string_settings">Налаштування</string>
|
||||
<string name="shared_string_settings">Параметри</string>
|
||||
<string name="no_location_permission">Застосунок не має дозволу до отримання даних позиціювання.</string>
|
||||
<string name="gps_not_available">Будь ласка, увімкніть «Позиціювання» у системних налаштуваннях</string>
|
||||
<string name="osmand_service">Фоновий режим</string>
|
||||
<string name="osmand_service">Режим тла</string>
|
||||
<string name="osmand_service_descr">OsmAnd Tracker працює у фоновому режимі з вимкненим екраном.</string>
|
||||
<string name="shared_string_distance">Відстань</string>
|
||||
<string name="share_location">Поділитися позицією</string>
|
||||
|
@ -267,4 +267,8 @@
|
|||
<string name="last_response_duration">Остання відповідь: %1$s тому</string>
|
||||
<string name="duration_ago">%1$s тому</string>
|
||||
<string name="shared_string_error_short">ПМЛК</string>
|
||||
<string name="shared_string_export">Експорт</string>
|
||||
<string name="logcat_buffer">Буфер logcat</string>
|
||||
<string name="logcat_buffer_descr">Переглянути та надіслати докладний журнал застосунку</string>
|
||||
<string name="send_report">Надіслати звіт</string>
|
||||
</resources>
|
|
@ -270,4 +270,8 @@
|
|||
<string name="last_response_duration">最後回應:%1$s 前</string>
|
||||
<string name="duration_ago">%1$s 前</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="send_report">傳送報告</string>
|
||||
<string name="shared_string_export">匯出</string>
|
||||
<string name="logcat_buffer">Logcat 緩衝</string>
|
||||
<string name="logcat_buffer_descr">檢查及分享應用程式的詳細紀錄</string>
|
||||
</resources>
|
|
@ -27,6 +27,7 @@
|
|||
<dimen name="dialog_welcome_title_top_margin">89dp</dimen>
|
||||
|
||||
<dimen name="list_header_height">48dp</dimen>
|
||||
<dimen name="list_description_height">44dp</dimen>
|
||||
<dimen name="list_header_with_descr_height">42dp</dimen>
|
||||
|
||||
<dimen name="list_item_height">56dp</dimen>
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="send_report">Send report</string>
|
||||
<string name="logcat_buffer_descr">Check and share detailed logs of the app</string>
|
||||
<string name="logcat_buffer">Logcat buffer</string>
|
||||
<string name="shared_string_export">Export</string>
|
||||
<string name="shared_string_error_short">ERR</string>
|
||||
<string name="last_update_from_telegram_date">Last update from Telegram: %1$s</string>
|
||||
<string name="last_response_date">Last response: %1$s</string>
|
||||
|
|
|
@ -3,16 +3,20 @@ package net.osmand.telegram
|
|||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkInfo
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
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.utils.AndroidUtils
|
||||
import net.osmand.telegram.utils.UiUtils
|
||||
import java.io.File
|
||||
|
||||
class TelegramApplication : Application() {
|
||||
|
||||
|
@ -200,4 +204,33 @@ class TelegramApplication : Application() {
|
|||
fun runInUIThread(action: (() -> Unit), delay: Long) {
|
||||
uiHandler.postDelayed(action, delay)
|
||||
}
|
||||
|
||||
fun sendCrashLog(file: File) {
|
||||
val intent = Intent(Intent.ACTION_SEND)
|
||||
intent.putExtra(Intent.EXTRA_EMAIL, arrayOf("crash@osmand.net"))
|
||||
intent.putExtra(Intent.EXTRA_STREAM, AndroidUtils.getUriForFile(this, file))
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
intent.type = "vnd.android.cursor.dir/email"
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, "OsmAnd bug")
|
||||
val text = StringBuilder()
|
||||
text.append("\nDevice : ").append(Build.DEVICE)
|
||||
text.append("\nBrand : ").append(Build.BRAND)
|
||||
text.append("\nModel : ").append(Build.MODEL)
|
||||
text.append("\nProduct : ").append(Build.PRODUCT)
|
||||
text.append("\nBuild : ").append(Build.DISPLAY)
|
||||
text.append("\nVersion : ").append(Build.VERSION.RELEASE)
|
||||
text.append("\nApp : ").append(getString(R.string.app_name_short))
|
||||
try {
|
||||
val info = packageManager.getPackageInfo(packageName, 0)
|
||||
if (info != null) {
|
||||
text.append("\nApk Version : ").append(info.versionName).append(" ").append(info.versionCode)
|
||||
}
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
PlatformUtil.getLog(TrackerLogcatActivity::class.java).error("", e)
|
||||
}
|
||||
intent.putExtra(Intent.EXTRA_TEXT, text.toString())
|
||||
val chooserIntent = Intent.createChooser(intent, getString(R.string.send_report))
|
||||
chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
startActivity(chooserIntent)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import net.osmand.telegram.helpers.TelegramHelper
|
|||
import net.osmand.telegram.helpers.TelegramHelper.*
|
||||
import net.osmand.telegram.notifications.TelegramNotification.NotificationType
|
||||
import net.osmand.telegram.utils.AndroidUtils
|
||||
import net.osmand.telegram.utils.OsmandLocationUtils
|
||||
import org.drinkless.td.libcore.telegram.TdApi
|
||||
import java.util.*
|
||||
|
||||
|
@ -377,7 +376,10 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
|||
Log.d(PlatformUtil.TAG, "Send live location error: $code - $message")
|
||||
when (messageType) {
|
||||
TelegramHelper.MESSAGE_TYPE_TEXT -> shareInfo.pendingTdLibText--
|
||||
TelegramHelper.MESSAGE_TYPE_MAP -> shareInfo.pendingTdLibMap--
|
||||
TelegramHelper.MESSAGE_TYPE_MAP -> {
|
||||
shareInfo.pendingTdLibMap--
|
||||
shareInfo.currentMapMessageId = -1L
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ private const val PROXY_ENABLED = "proxy_enabled"
|
|||
private const val PROXY_PREFERENCES_KEY = "proxy_preferences"
|
||||
|
||||
private const val SHARING_INITIALIZATION_TIME = 60 * 2L // 2 minutes
|
||||
private const val WAITING_TDLIB_TIME = 3 // 3 seconds
|
||||
private const val WAITING_TDLIB_TIME = 7 // 7 seconds
|
||||
|
||||
private const val GPS_UPDATE_EXPIRED_TIME = 60 * 3L // 3 minutes
|
||||
|
||||
|
@ -304,27 +304,18 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
|
||||
fun prepareForSharingNewMessages() {
|
||||
shareChatsInfo.forEach { (_, shareInfo) ->
|
||||
prepareForSharingNewMessages(shareInfo)
|
||||
shareInfo.resetMessagesInfo()
|
||||
}
|
||||
}
|
||||
|
||||
fun prepareForSharingNewMessages(chatsIds: List<Long>) {
|
||||
chatsIds.forEach {
|
||||
shareChatsInfo[it]?.also { shareInfo ->
|
||||
prepareForSharingNewMessages(shareInfo)
|
||||
shareInfo.resetMessagesInfo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun prepareForSharingNewMessages(shareInfo: ShareChatInfo) {
|
||||
shareInfo.pendingTdLibText = 0
|
||||
shareInfo.pendingTdLibMap = 0
|
||||
shareInfo.currentTextMessageId = -1L
|
||||
shareInfo.currentMapMessageId = -1L
|
||||
shareInfo.pendingTextMessage = false
|
||||
shareInfo.pendingMapMessage = false
|
||||
}
|
||||
|
||||
fun getChatLivePeriod(chatId: Long) = shareChatsInfo[chatId]?.livePeriod
|
||||
|
||||
fun getChatsShareInfo() = shareChatsInfo
|
||||
|
@ -540,14 +531,24 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
if (initTime && initSending) {
|
||||
initializing = true
|
||||
} else {
|
||||
var waitingTimeError = false
|
||||
val maxWaitingTime = WAITING_TDLIB_TIME * MAX_MESSAGES_IN_TDLIB_PER_CHAT * max(1, chatsCount)
|
||||
val textSharingError = !shareInfo.lastTextMessageHandled && currentTime - shareInfo.lastSendTextMessageTime > maxWaitingTime
|
||||
val mapSharingError = !shareInfo.lastMapMessageHandled && currentTime - shareInfo.lastSendMapMessageTime > maxWaitingTime
|
||||
if (shareInfo.hasSharingError
|
||||
|| (shareTypeValue == SHARE_TYPE_MAP_AND_TEXT && (textSharingError || mapSharingError))
|
||||
|| textSharingError && (shareTypeValue == SHARE_TYPE_TEXT)
|
||||
|| mapSharingError && (shareTypeValue == SHARE_TYPE_MAP)
|
||||
) {
|
||||
val textSharingWaitingTime = currentTime - shareInfo.lastSendTextMessageTime
|
||||
val mapSharingWaitingTime = currentTime - shareInfo.lastSendMapMessageTime
|
||||
val textSharingError = !shareInfo.lastTextMessageHandled && textSharingWaitingTime > maxWaitingTime
|
||||
val mapSharingError = !shareInfo.lastMapMessageHandled && mapSharingWaitingTime > maxWaitingTime
|
||||
if ((shareTypeValue == SHARE_TYPE_MAP_AND_TEXT && (textSharingError || mapSharingError))
|
||||
|| textSharingError && (shareTypeValue == SHARE_TYPE_TEXT)
|
||||
|| mapSharingError && (shareTypeValue == SHARE_TYPE_MAP)) {
|
||||
waitingTimeError = true
|
||||
log.debug("Send chats error for share type \"$shareTypeValue\"" +
|
||||
"\nMax waiting time: ${maxWaitingTime}s" +
|
||||
"\nLast text message handled: ${shareInfo.lastTextMessageHandled}" +
|
||||
"\nText sharing waiting time: ${textSharingWaitingTime}s" +
|
||||
"\nLast map message handled: ${shareInfo.lastMapMessageHandled}" +
|
||||
"\nMap sharing waiting time: ${mapSharingWaitingTime}s")
|
||||
}
|
||||
if (shareInfo.hasSharingError || waitingTimeError) {
|
||||
sendChatsErrors = true
|
||||
locationTime = max(shareInfo.lastTextSuccessfulSendTime, shareInfo.lastMapSuccessfulSendTime)
|
||||
chatsIds.add(shareInfo.chatId)
|
||||
|
@ -1487,6 +1488,27 @@ class TelegramSettings(private val app: TelegramApplication) {
|
|||
|
||||
fun isPendingMapMessagesLimitReached() = pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT
|
||||
|
||||
fun resetMessagesInfo() {
|
||||
resetTextMessageInfo()
|
||||
resetMapMessageInfo()
|
||||
}
|
||||
|
||||
fun resetTextMessageInfo() {
|
||||
pendingTdLibText = 0
|
||||
currentTextMessageId = -1L
|
||||
pendingTextMessage = false
|
||||
}
|
||||
|
||||
fun resetMapMessageInfo() {
|
||||
pendingTdLibMap = 0
|
||||
currentMapMessageId = -1L
|
||||
pendingMapMessage = false
|
||||
}
|
||||
|
||||
fun isTextMessageIdPresent() = currentTextMessageId != -1L
|
||||
|
||||
fun isMapMessageIdPresent() = currentMapMessageId != -1L
|
||||
|
||||
companion object {
|
||||
|
||||
internal const val CHAT_ID_KEY = "chatId"
|
||||
|
|
|
@ -138,7 +138,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
if (pendingMessagesLimitReached && checkNetworkTypeAllowed) {
|
||||
checkNetworkType()
|
||||
updateNetworkType()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
app.locationMessages.getBufferedTextMessagesForChat(chatId).take(MAX_MESSAGES_IN_TDLIB_PER_CHAT).forEach {
|
||||
if (!shareInfo.isPendingTextMessagesLimitReached()) {
|
||||
if (it.deviceName.isEmpty()) {
|
||||
if (!shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) {
|
||||
if (!shareInfo.pendingTextMessage && shareInfo.isTextMessageIdPresent()) {
|
||||
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, it, app)
|
||||
app.telegramHelper.editTextLocation(shareInfo, content)
|
||||
app.locationMessages.removeBufferedMessage(it)
|
||||
|
@ -180,8 +180,12 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
app.locationMessages.getBufferedMapMessagesForChat(chatId).take(MAX_MESSAGES_IN_TDLIB_PER_CHAT).forEach {
|
||||
if (!shareInfo.isPendingMapMessagesLimitReached()) {
|
||||
if (it.deviceName.isEmpty()) {
|
||||
if (!shareInfo.pendingMapMessage && shareInfo.currentMapMessageId != -1L) {
|
||||
app.telegramHelper.editMapLocation(shareInfo, it)
|
||||
if (!shareInfo.pendingMapMessage) {
|
||||
if (shareInfo.isMapMessageIdPresent()) {
|
||||
app.telegramHelper.editMapLocation(shareInfo, it)
|
||||
} else {
|
||||
app.telegramHelper.sendNewMapLocation(shareInfo, it)
|
||||
}
|
||||
app.locationMessages.removeBufferedMessage(it)
|
||||
}
|
||||
} else {
|
||||
|
@ -279,7 +283,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
if (pendingMessagesLimitReached) {
|
||||
checkNetworkType()
|
||||
updateNetworkType()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,7 +351,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
|||
}
|
||||
}
|
||||
|
||||
fun checkNetworkType(){
|
||||
fun updateNetworkType(){
|
||||
if (app.isInternetConnectionAvailable) {
|
||||
val networkType = when {
|
||||
app.isWifiConnected -> TdApi.NetworkTypeWiFi()
|
||||
|
|
|
@ -776,6 +776,7 @@ class TelegramHelper private constructor() {
|
|||
client?.send(TdApi.CreatePrivateChat(userId, false)) { obj ->
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
log.debug("createPrivateChatWithUser ERROR $obj")
|
||||
val error = obj as TdApi.Error
|
||||
if (error.code != IGNORED_ERROR_CODE) {
|
||||
shareInfo.hasSharingError = true
|
||||
|
@ -839,7 +840,7 @@ class TelegramHelper private constructor() {
|
|||
}
|
||||
|
||||
fun stopSendingLiveLocationToChat(shareInfo: ShareChatInfo) {
|
||||
if (shareInfo.currentMapMessageId != -1L && shareInfo.chatId != -1L) {
|
||||
if (!shareInfo.isMapMessageIdPresent() && shareInfo.chatId != -1L) {
|
||||
shareInfo.lastSendMapMessageTime = (System.currentTimeMillis() / 1000).toInt()
|
||||
client?.send(
|
||||
TdApi.EditMessageLiveLocation(shareInfo.chatId, shareInfo.currentMapMessageId, null, null)) { obj ->
|
||||
|
@ -969,7 +970,7 @@ class TelegramHelper private constructor() {
|
|||
val messageType = if (isBot) MESSAGE_TYPE_BOT else MESSAGE_TYPE_TEXT
|
||||
when (obj.constructor) {
|
||||
TdApi.Error.CONSTRUCTOR -> {
|
||||
log.debug("handleTextLocationMessageUpdate - ERROR")
|
||||
log.debug("handleTextLocationMessageUpdate - ERROR $obj")
|
||||
val error = obj as TdApi.Error
|
||||
if (error.code != IGNORED_ERROR_CODE) {
|
||||
shareInfo.hasSharingError = true
|
||||
|
|
|
@ -15,7 +15,6 @@ import android.widget.TextView
|
|||
import androidx.appcompat.widget.ListPopupWindow
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import net.osmand.Location
|
||||
import net.osmand.data.LatLon
|
||||
import net.osmand.telegram.R
|
||||
|
@ -99,7 +98,7 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
|
|||
|
||||
mainView.findViewById<androidx.swiperefreshlayout.widget.SwipeRefreshLayout>(R.id.swipe_refresh).apply {
|
||||
setOnRefreshListener {
|
||||
app.shareLocationHelper.checkNetworkType()
|
||||
app.shareLocationHelper.updateNetworkType()
|
||||
app.telegramHelper.scanChatsHistory()
|
||||
updateList()
|
||||
isRefreshing = false
|
||||
|
|
|
@ -213,6 +213,12 @@ class SettingsDialogFragment : BaseDialogFragment() {
|
|||
DisconnectTelegramBottomSheet.showInstance(childFragmentManager)
|
||||
}
|
||||
|
||||
mainView.findViewById<View>(R.id.logcat_row).setOnClickListener {
|
||||
val intent = Intent(activity, TrackerLogcatActivity::class.java)
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
app.startActivity(intent)
|
||||
}
|
||||
|
||||
return mainView
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ class SharingStatusBottomSheet : DialogFragment() {
|
|||
if (sharingStatusType.canResendLocation) {
|
||||
if (i == 0) {
|
||||
setOnClickListener {
|
||||
app.shareLocationHelper.checkNetworkType()
|
||||
app.shareLocationHelper.updateNetworkType()
|
||||
app.settings.prepareForSharingNewMessages(sharingStatus.chatsIds)
|
||||
app.shareLocationHelper.checkAndSendBufferMessages()
|
||||
app.forceUpdateMyLocation()
|
||||
|
|
|
@ -0,0 +1,271 @@
|
|||
package net.osmand.telegram.ui
|
||||
|
||||
import android.os.AsyncTask
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import net.osmand.PlatformUtil
|
||||
import net.osmand.telegram.R
|
||||
import net.osmand.telegram.TelegramApplication
|
||||
import java.io.*
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.*
|
||||
|
||||
class TrackerLogcatActivity : AppCompatActivity() {
|
||||
private var logcatAsyncTask: LogcatAsyncTask? = null
|
||||
private val logs: MutableList<String> = ArrayList()
|
||||
private var adapter: LogcatAdapter? = null
|
||||
private val LEVELS = arrayOf("D", "I", "W", "E")
|
||||
private var filterLevel = 1
|
||||
private lateinit var recyclerView: RecyclerView
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
val app: TelegramApplication = getApplication() as TelegramApplication
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_tracker_logcat)
|
||||
|
||||
val toolbar = findViewById<Toolbar>(R.id.toolbar).apply {
|
||||
navigationIcon = app.uiUtils.getThemedIcon(R.drawable.ic_arrow_back)
|
||||
setNavigationOnClickListener { onBackPressed() }
|
||||
}
|
||||
setSupportActionBar(toolbar)
|
||||
setupIntermediateProgressBar()
|
||||
|
||||
adapter = LogcatAdapter()
|
||||
recyclerView = findViewById<View>(R.id.recycler_view) as RecyclerView
|
||||
recyclerView!!.layoutManager = LinearLayoutManager(this)
|
||||
recyclerView!!.adapter = adapter
|
||||
}
|
||||
|
||||
protected fun setupIntermediateProgressBar() {
|
||||
val progressBar = ProgressBar(this)
|
||||
progressBar.visibility = View.GONE
|
||||
progressBar.isIndeterminate = true
|
||||
val supportActionBar = supportActionBar
|
||||
if (supportActionBar != null) {
|
||||
supportActionBar.setDisplayShowCustomEnabled(true)
|
||||
supportActionBar.customView = progressBar
|
||||
setSupportProgressBarIndeterminateVisibility(false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setSupportProgressBarIndeterminateVisibility(visible: Boolean) {
|
||||
val supportActionBar = supportActionBar
|
||||
if (supportActionBar != null) {
|
||||
supportActionBar.customView.visibility = if (visible) View.VISIBLE else View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
startLogcatAsyncTask()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
stopLogcatAsyncTask()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
val app: TelegramApplication = applicationContext as TelegramApplication
|
||||
val share: MenuItem = menu.add(0, SHARE_ID, 0, R.string.shared_string_export)
|
||||
share.icon = app.uiUtils.getThemedIcon(R.drawable.ic_action_share)
|
||||
share.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
|
||||
val level = menu.add(0, LEVEL_ID, 0, "")
|
||||
level.title = getFilterLevel()
|
||||
level.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
|
||||
return super.onCreateOptionsMenu(menu)
|
||||
}
|
||||
|
||||
private fun getFilterLevel(): String {
|
||||
return "*:" + LEVELS[filterLevel]
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
val itemId = item.itemId
|
||||
when (itemId) {
|
||||
android.R.id.home -> {
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
LEVEL_ID -> {
|
||||
filterLevel++
|
||||
if (filterLevel >= LEVELS.size) {
|
||||
filterLevel = 0
|
||||
}
|
||||
item.title = getFilterLevel()
|
||||
stopLogcatAsyncTask()
|
||||
logs.clear()
|
||||
adapter!!.notifyDataSetChanged()
|
||||
startLogcatAsyncTask()
|
||||
return true
|
||||
}
|
||||
SHARE_ID -> {
|
||||
startSaveLogsAsyncTask()
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun startSaveLogsAsyncTask() {
|
||||
val saveLogsAsyncTask = SaveLogsAsyncTask(this, logs)
|
||||
saveLogsAsyncTask.execute()
|
||||
}
|
||||
|
||||
private fun startLogcatAsyncTask() {
|
||||
logcatAsyncTask = LogcatAsyncTask(this, getFilterLevel())
|
||||
logcatAsyncTask!!.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)
|
||||
}
|
||||
|
||||
private fun stopLogcatAsyncTask() {
|
||||
if (logcatAsyncTask != null && logcatAsyncTask!!.status == AsyncTask.Status.RUNNING) {
|
||||
logcatAsyncTask!!.cancel(false)
|
||||
logcatAsyncTask!!.stopLogging()
|
||||
}
|
||||
}
|
||||
|
||||
private inner class LogcatAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val inflater = LayoutInflater.from(viewGroup.context)
|
||||
val itemView = inflater.inflate(R.layout.item_description_long, viewGroup, false) as TextView
|
||||
itemView.gravity = Gravity.CENTER_VERTICAL
|
||||
return LogViewHolder(itemView)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
if (holder is LogViewHolder) {
|
||||
val log = getLog(position)
|
||||
holder.logTextView.text = log
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return logs.size
|
||||
}
|
||||
|
||||
private fun getLog(position: Int): String {
|
||||
return logs[position]
|
||||
}
|
||||
|
||||
private inner class LogViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val logTextView: TextView = itemView.findViewById(R.id.description)
|
||||
}
|
||||
}
|
||||
|
||||
class SaveLogsAsyncTask internal constructor(logcatActivity: TrackerLogcatActivity, logs: Collection<String>) : AsyncTask<Void?, String?, File?>() {
|
||||
private val logcatActivity: WeakReference<TrackerLogcatActivity>
|
||||
private val logs: Collection<String>
|
||||
|
||||
override fun onPreExecute() {
|
||||
val activity = logcatActivity.get()
|
||||
activity?.setSupportProgressBarIndeterminateVisibility(true)
|
||||
}
|
||||
|
||||
override fun doInBackground(vararg voids: Void?): File {
|
||||
val app: TelegramApplication = logcatActivity.get()?.applicationContext as TelegramApplication
|
||||
val file = File(app.getExternalFilesDir(null), LOGCAT_PATH)
|
||||
try {
|
||||
if (file.exists()) {
|
||||
file.delete()
|
||||
}
|
||||
val stringBuilder = StringBuilder()
|
||||
for (log in logs) {
|
||||
stringBuilder.append(log)
|
||||
stringBuilder.append("\n")
|
||||
}
|
||||
if (file.parentFile.canWrite()) {
|
||||
val writer = BufferedWriter(FileWriter(file, true))
|
||||
writer.write(stringBuilder.toString())
|
||||
writer.close()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
log.error(e)
|
||||
}
|
||||
return file
|
||||
}
|
||||
|
||||
override fun onPostExecute(file: File?) {
|
||||
val activity = logcatActivity.get()
|
||||
if (activity != null && file != null) {
|
||||
val app: TelegramApplication = activity.applicationContext as TelegramApplication
|
||||
activity.setSupportProgressBarIndeterminateVisibility(false)
|
||||
app.sendCrashLog(file)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
this.logcatActivity = WeakReference(logcatActivity)
|
||||
this.logs = logs
|
||||
}
|
||||
}
|
||||
|
||||
class LogcatAsyncTask internal constructor(logcatActivity: TrackerLogcatActivity?, filterLevel: String) : AsyncTask<Void?, String?, Void?>() {
|
||||
private var processLogcat: Process? = null
|
||||
private val logcatActivity: WeakReference<TrackerLogcatActivity?>
|
||||
private val filterLevel: String
|
||||
|
||||
override fun doInBackground(vararg voids: Void?): Void? {
|
||||
try {
|
||||
val filter = android.os.Process.myPid().toString()
|
||||
val command = arrayOf("logcat", filterLevel, "--pid=$filter", "-T", MAX_BUFFER_LOG.toString())
|
||||
processLogcat = Runtime.getRuntime().exec(command)
|
||||
val bufferedReader = BufferedReader(InputStreamReader(processLogcat?.inputStream))
|
||||
var line: String?
|
||||
while (bufferedReader.readLine().also { line = it } != null && logcatActivity.get() != null) {
|
||||
if (isCancelled) {
|
||||
break
|
||||
}
|
||||
publishProgress(line)
|
||||
}
|
||||
stopLogging()
|
||||
} catch (e: IOException) { // ignore
|
||||
} catch (e: Exception) {
|
||||
log.error(e)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onProgressUpdate(vararg values: String?) {
|
||||
if (values.size > 0 && !isCancelled) {
|
||||
val activity = logcatActivity.get()
|
||||
if (activity != null) {
|
||||
val autoscroll = !activity.recyclerView!!.canScrollVertically(1)
|
||||
for (s in values) {
|
||||
if (s != null) {
|
||||
activity.logs.add(s)
|
||||
}
|
||||
}
|
||||
activity.adapter!!.notifyDataSetChanged()
|
||||
if (autoscroll) {
|
||||
activity.recyclerView!!.scrollToPosition(activity.logs.size - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun stopLogging() {
|
||||
if (processLogcat != null) {
|
||||
processLogcat!!.destroy()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
this.logcatActivity = WeakReference(logcatActivity)
|
||||
this.filterLevel = filterLevel
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val LOGCAT_PATH = "logcat.log"
|
||||
private const val MAX_BUFFER_LOG = 10000
|
||||
private const val SHARE_ID = 0
|
||||
private const val LEVEL_ID = 1
|
||||
private val log = PlatformUtil.getLog(TrackerLogcatActivity::class.java)
|
||||
}
|
||||
}
|
3
OsmAnd/.gitignore
vendored
3
OsmAnd/.gitignore
vendored
|
@ -13,10 +13,13 @@ libs/it.unibo.alice.tuprolog-tuprolog-3.2.1.jar
|
|||
libs/commons-codec-commons-codec-1.11.jar
|
||||
libs/OsmAndCore_android-0.1-SNAPSHOT.jar
|
||||
|
||||
# Huawei
|
||||
libs/huawei-*.jar
|
||||
huaweidrmlib/
|
||||
HwDRM_SDK_*
|
||||
drm_strings.xml
|
||||
agconnect-services.json
|
||||
OsmAndHms.jks
|
||||
|
||||
# copy_widget_icons.sh
|
||||
res/drawable-large/map_*
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<application
|
||||
android:icon="@mipmap/icon_free"
|
||||
android:label="@string/app_name_free"
|
||||
tools:replace="android:icon">
|
||||
<meta-data
|
||||
android:name="com.facebook.sdk.ApplicationId"
|
||||
android:value="fb131313131043971"/>
|
||||
<activity
|
||||
android:name="net.osmand.plus.activities.MapActivity"
|
||||
android:theme="@style/FirstSplashScreenCustom"
|
||||
tools:replace="android:theme"/>
|
||||
<service
|
||||
android:name="net.osmand.plus.NavigationService"
|
||||
android:process="net.osmand.freecustom"
|
||||
tools:replace="android:process"/>
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="net.osmand.freecustom.fileprovider"
|
||||
tools:replace="android:authorities"/>
|
||||
</application>
|
||||
</manifest>
|
|
@ -2,24 +2,31 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<application>
|
||||
<activity android:name="com.huawei.android.sdk.drm.DrmDialogActivity"
|
||||
android:configChanges="screenSize|orientation|keyboardHidden"
|
||||
android:exported="false"
|
||||
android:theme="@android:style/Theme.Translucent">
|
||||
<meta-data
|
||||
android:name="hwc-theme"
|
||||
android:value="androidhwext:style/Theme.Emui.Translucent" />
|
||||
</activity>
|
||||
<application
|
||||
android:icon="@mipmap/icon_free"
|
||||
android:label="@string/app_name_free"
|
||||
tools:replace="android:icon, android:label">
|
||||
|
||||
<meta-data
|
||||
android:name="com.huawei.hms.client.appid"
|
||||
android:value="101486545" />
|
||||
<meta-data
|
||||
android:name="com.huawei.hms.client.cpid"
|
||||
android:value="890031000000000038" />
|
||||
|
||||
<activity
|
||||
android:name="net.osmand.plus.activities.MapActivity"
|
||||
android:theme="@style/FirstSplashScreenFree"
|
||||
tools:replace="android:theme"/>
|
||||
|
||||
<service
|
||||
android:name="net.osmand.plus.NavigationService"
|
||||
tools:replace="android:process"
|
||||
android:process="net.osmand.huawei"/>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="net.osmand.huawei.fileprovider"
|
||||
tools:replace="android:authorities" />
|
||||
<service
|
||||
android:name="net.osmand.plus.NavigationService"
|
||||
android:process="net.osmand.huawei"
|
||||
tools:replace="android:process" />
|
||||
tools:replace="android:authorities"
|
||||
android:authorities="net.osmand.huawei.fileprovider"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<application>
|
||||
<activity android:name="com.huawei.android.sdk.drm.DrmDialogActivity"
|
||||
android:configChanges="screenSize|orientation|keyboardHidden"
|
||||
android:exported="false"
|
||||
android:theme="@android:style/Theme.Translucent">
|
||||
<meta-data
|
||||
android:name="hwc-theme"
|
||||
android:value="androidhwext:style/Theme.Emui.Translucent" />
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="net.osmand.plus.huawei.fileprovider"
|
||||
tools:replace="android:authorities" />
|
||||
<service
|
||||
android:name="net.osmand.plus.NavigationService"
|
||||
android:process="net.osmand.plus.huawei"
|
||||
tools:replace="android:process" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -7,7 +7,7 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
|
||||
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.STORAGE" />
|
||||
|
@ -52,8 +52,9 @@
|
|||
<application android:allowBackup="true" android:backupAgent="net.osmand.plus.OsmandBackupAgent"
|
||||
android:icon="@mipmap/icon" android:label="@string/app_name"
|
||||
android:name="net.osmand.plus.OsmandApplication" android:configChanges="locale"
|
||||
android:theme="@style/OsmandDarkTheme" android:restoreAnyVersion="true" android:largeHeap="true"
|
||||
android:supportsRtl="true" android:usesCleartextTraffic="true">
|
||||
android:theme="@style/OsmandDarkTheme" android:restoreAnyVersion="true" android:largeHeap="true"
|
||||
android:supportsRtl="true" android:usesCleartextTraffic="true"
|
||||
android:hasFragileUserData="true" android:requestLegacyExternalStorage="true">
|
||||
|
||||
<meta-data android:name="com.google.android.backup.api_key" android:value="AEdPqrEAAAAIqF3tNGT66etVBn_vgzpfAY1wmIzKV1Ss6Ku-2A" />
|
||||
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
|
||||
|
@ -65,7 +66,8 @@
|
|||
<meta-data android:name="com.sec.minimode.icon.landscape.normal" android:resource="@mipmap/icon" android:value="" />
|
||||
<activity android:name="net.osmand.plus.activities.HelpActivity" />
|
||||
<activity android:name="net.osmand.plus.activities.ExitActivity" />
|
||||
|
||||
<activity android:name="net.osmand.plus.openplacereviews.OPRWebviewActivity" android:theme="@style/Theme.AppCompat.NoActionBar" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="net.osmand.plus.fileprovider"
|
||||
|
@ -246,6 +248,7 @@
|
|||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content"/>
|
||||
<data android:scheme="file"/>
|
||||
<data android:host="*"/>
|
||||
<data android:pathPattern=".*\\.obf" />
|
||||
|
@ -261,6 +264,7 @@
|
|||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="content"/>
|
||||
<data android:scheme="file"/>
|
||||
<data android:host="*"/>
|
||||
<data android:mimeType="*/*"/>
|
||||
|
@ -371,6 +375,72 @@
|
|||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.xml" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter
|
||||
android:label="@string/app_name"
|
||||
android:priority="50">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:host="*"/>
|
||||
<data android:pathPattern=".*\\.wpt.chart" />
|
||||
<data android:pathPattern=".*\\..*\\.wpt.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.wpt.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.wpt.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.wpt.chart" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter
|
||||
android:label="@string/app_name"
|
||||
android:priority="50">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:host="*"/>
|
||||
<data android:mimeType="*/*"/>
|
||||
<data android:pathPattern=".*\\.wpt.chart" />
|
||||
<data android:pathPattern=".*\\..*\\.wpt.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.wpt.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.wpt.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.wpt.chart" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter
|
||||
android:label="@string/app_name"
|
||||
android:priority="50">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:host="*"/>
|
||||
<data android:pathPattern=".*\\.3d.chart" />
|
||||
<data android:pathPattern=".*\\..*\\.3d.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.3d.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.3d.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.3d.chart" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter
|
||||
android:label="@string/app_name"
|
||||
android:priority="50">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="file"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:host="*"/>
|
||||
<data android:mimeType="*/*"/>
|
||||
<data android:pathPattern=".*\\.3d.chart" />
|
||||
<data android:pathPattern=".*\\..*\\.3d.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\.3d.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\.3d.chart" />
|
||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.3d.chart" />
|
||||
</intent-filter>
|
||||
|
||||
<!--trying to handle emails-->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
@ -399,6 +469,13 @@
|
|||
<data android:mimeType="text/plain" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="osmand-oauth" />
|
||||
</intent-filter>
|
||||
|
||||
</activity>
|
||||
|
||||
<receiver android:name="net.osmand.plus.audionotes.MediaRemoteControlReceiver">
|
||||
|
@ -408,22 +485,10 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity android:name="net.osmand.plus.activities.SettingsActivity" android:label="@string/shared_string_settings" android:configChanges="keyboardHidden|orientation" />
|
||||
<activity android:name="net.osmand.plus.activities.SettingsGeneralActivity" android:configChanges="keyboardHidden|orientation" />
|
||||
<activity android:name="net.osmand.plus.activities.SettingsNavigationActivity" android:configChanges="keyboardHidden|orientation" />
|
||||
<activity android:name="net.osmand.plus.monitoring.SettingsMonitoringActivity" android:configChanges="keyboardHidden|orientation" />
|
||||
|
||||
<activity android:name="net.osmand.plus.osmedit.SettingsOsmEditingActivity" android:configChanges="keyboardHidden|orientation" />
|
||||
<activity android:name="net.osmand.plus.development.SettingsDevelopmentActivity" android:configChanges="keyboardHidden|orientation" />
|
||||
<activity android:name="net.osmand.plus.audionotes.SettingsAudioVideoActivity" android:configChanges="keyboardHidden|orientation" />
|
||||
<activity android:name="net.osmand.access.SettingsAccessibilityActivity" android:configChanges="keyboardHidden|orientation" />
|
||||
|
||||
<activity android:name="net.osmand.plus.activities.search.SearchActivity" android:label="@string/search_activity" />
|
||||
<activity android:name="net.osmand.plus.activities.FavoritesListActivity" android:label="@string/favourites_list_activity" />
|
||||
<activity android:name=".myplaces.FavoritesActivity" android:windowSoftInputMode="adjustPan" />
|
||||
<activity android:name="net.osmand.plus.activities.TrackActivity"/>
|
||||
<activity android:name="net.osmand.plus.activities.PluginsActivity" />
|
||||
<activity android:name="net.osmand.plus.activities.PluginActivity" />
|
||||
<activity android:name="net.osmand.plus.activities.ContributionVersionActivity" android:configChanges="keyboardHidden|orientation" android:label="@string/contribution_activity" />
|
||||
|
||||
|
||||
|
@ -484,11 +549,17 @@
|
|||
<data android:host="map.wap.qq.com" />
|
||||
<data android:host="map.qq.com" />
|
||||
<data android:host="maps.apple.com" />
|
||||
<data android:host="ge0.me" />
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<data android:host="ge0.me" android:scheme="https"/>
|
||||
<data android:host="ge0.me" android:scheme="http"/>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<data android:scheme="http" android:host="openstreetmap.de" android:pathPrefix="/karte" />
|
||||
<data android:scheme="https" android:host="openstreetmap.de" android:pathPrefix="/karte" />
|
||||
|
@ -953,7 +1024,7 @@
|
|||
|
||||
<!-- keep android:process on a separate line !! -->
|
||||
<service
|
||||
android:process="net.osmand.plus"
|
||||
android:process="net.osmand.plus"
|
||||
android:label="@string/process_navigation_service"
|
||||
android:name="net.osmand.plus.NavigationService"
|
||||
android:foregroundServiceType="location"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
<asset source="voice/cs/cs_tts.js" destination="voice/cs-tts/cs_tts.js" mode="overwriteOnlyIfExists" />
|
||||
<asset source="voice/da/da_tts.js" destination="voice/da-tts/da_tts.js" mode="overwriteOnlyIfExists" />
|
||||
<asset source="voice/de/de_tts.js" destination="voice/de-tts/de_tts.js" mode="alwaysOverwriteOrCopy" />
|
||||
<asset source="voice/de-casual/de-casual_tts.js" destination="voice/de-casual-tts/de-casual_tts.js" mode="overwriteOnlyIfExists" />
|
||||
<asset source="voice/el/el_tts.js" destination="voice/el-tts/el_tts.js" mode="overwriteOnlyIfExists" />
|
||||
<asset source="voice/en/en_tts.js" destination="voice/en-tts/en_tts.js" mode="alwaysOverwriteOrCopy" />
|
||||
<asset source="voice/en-gb/en-gb_tts.js" destination="voice/en-gb-tts/en-gb_tts.js" mode="overwriteOnlyIfExists" />
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue