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"
|
name: "📚 Outdated FAQ"
|
||||||
about: Report an issue in FAQ
|
about: Report an issue in FAQ
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑🛑
|
||||||
|
|
||||||
Please do not file FAQ issues on the GitHub issues tracker.
|
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"
|
name: "\U0001F41E Bug report"
|
||||||
about: Report a bug in OsmAnd
|
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
|
### Description
|
||||||
|
|
||||||
<!-- ✍️--> A clear and concise description of the problem...
|
|
||||||
|
### How to reproduce?
|
||||||
|
|
||||||
|
|
||||||
## 🔬 Minimal Reproduction
|
### Your Environment
|
||||||
<!--
|
OsmAnd Version:
|
||||||
If the bug is reproducible, please describe steps below:
|
Android/iOS version:
|
||||||
-->
|
Device model:
|
||||||
<!-- ✍️--> 1. Open app, and click on ...
|
|
||||||
|
|
||||||
## 🔥 Exception or Error
|
**Maps used (online or offline):**
|
||||||
<pre><code>
|
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.
|
||||||
<!-- 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?**
|
|
||||||
|
|
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"
|
name: "\U0001F6A9 Routing report"
|
||||||
about: Report a routing issue in OsmAnd
|
about: Report a routing issue in OsmAnd
|
||||||
---
|
---
|
||||||
|
|
||||||
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
<!--🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅🔅
|
||||||
|
|
||||||
Oh hi there! 😄
|
Oh hi there! 😄
|
||||||
|
@ -26,10 +27,12 @@ Please give us the following information so that we can try to **reproduce** you
|
||||||
### Routing engine
|
### Routing engine
|
||||||
|
|
||||||
<!-- Which routing provider was used? (please tick the proper box [x]) -->
|
<!-- Which routing provider was used? (please tick the proper box [x]) -->
|
||||||
|
|
||||||
- [ ] OsmAnd's in-app offline routing
|
- [ ] OsmAnd's in-app offline routing
|
||||||
- [ ] Any online routing provider (YOURS, OpenRouteService, OSRM, etc.)
|
- [ ] Any online routing provider (YOURS, OpenRouteService, OSRM, etc.)
|
||||||
|
|
||||||
### Routing Profile
|
### Routing Profile
|
||||||
|
|
||||||
<!-- What routing profile is chosen in the OsmAnd app? (car, bike, pedestrian, fastest or shortest, etc.) -->
|
<!-- What routing profile is chosen in the OsmAnd app? (car, bike, pedestrian, fastest or shortest, etc.) -->
|
||||||
|
|
||||||
### Start and end points
|
### 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. -->
|
Also, a permalink from [openstreetmap.org](https://www.openstreetmap.org/) can be helpful. -->
|
||||||
|
|
||||||
### Actual and expected routes
|
### Actual and expected routes
|
||||||
|
|
||||||
<!-- Tell us your expected routing and how OsmAnd routes, or add screenshots here. -->
|
<!-- Tell us your expected routing and how OsmAnd routes, or add screenshots here. -->
|
||||||
|
|
||||||
### Is this a regression?
|
### 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? -->
|
<!-- Did this behavior use to work in the previous version? -->
|
||||||
<!-- ✍️--> Yes, the previous version in which this bug was not present was: ....
|
<!-- ✍️--> Yes, the previous version in which this bug was not present was: ....
|
||||||
|
|
||||||
## 🌍 Your Environment
|
## 🌍 Your Environment
|
||||||
|
|
||||||
**OsmAnd Version:**
|
**OsmAnd Version:**
|
||||||
|
|
||||||
<pre><code>
|
<pre><code>
|
||||||
<!-- paste version below -->
|
<!-- paste version below -->
|
||||||
<!-- ✍️-->
|
<!-- ✍️-->
|
||||||
|
@ -57,10 +62,11 @@ Also, a permalink from [openstreetmap.org](https://www.openstreetmap.org/) can b
|
||||||
**Device and Android/iOS version:**
|
**Device and Android/iOS version:**
|
||||||
|
|
||||||
**Maps used (online or offline):**
|
**Maps used (online or offline):**
|
||||||
|
|
||||||
<!-- Please tick the correct box [x] (or both) -->
|
<!-- 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 -->
|
- [ ] Online (tile / raster) maps <!-- Please name it -->
|
||||||
|
|
||||||
|
|
||||||
**Anything else relevant?**
|
**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"
|
name: "\U0001F680 Feature request"
|
||||||
about: Suggest a feature for OsmAnd
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
# 🚀 feature request
|
||||||
|
|
||||||
### Description
|
### 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
|
### Describe the solution you'd like
|
||||||
|
|
||||||
<!-- ✍️--> If you have a solution in mind, please describe it.
|
<!-- ✍️--> If you have a solution in mind, please describe it.
|
||||||
|
|
||||||
|
|
||||||
### Describe alternatives you've considered
|
### Describe alternatives you've considered
|
||||||
|
|
||||||
<!-- ✍️--> Have you considered any alternative solutions or workarounds?
|
<!-- ✍️--> Have you considered any alternative solutions or workarounds?
|
||||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -19,6 +19,10 @@ OsmAndCore_*.aar
|
||||||
.project
|
.project
|
||||||
out/
|
out/
|
||||||
|
|
||||||
|
# Huawei
|
||||||
|
agconnect-services.json
|
||||||
|
OsmAndHms.jks
|
||||||
|
|
||||||
# Android Studio
|
# Android Studio
|
||||||
/.idea
|
/.idea
|
||||||
*.iml
|
*.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.calculateroute.CalculateRouteParams;
|
||||||
|
|
||||||
|
import net.osmand.aidlapi.profile.ExportProfileParams;
|
||||||
|
|
||||||
import net.osmand.aidlapi.gpx.ImportGpxParams;
|
import net.osmand.aidlapi.gpx.ImportGpxParams;
|
||||||
import net.osmand.aidlapi.gpx.ShowGpxParams;
|
import net.osmand.aidlapi.gpx.ShowGpxParams;
|
||||||
import net.osmand.aidlapi.gpx.StartGpxRecordingParams;
|
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.info.AppInfoParams;
|
||||||
|
|
||||||
|
import net.osmand.aidlapi.profile.ExportProfileParams;
|
||||||
|
|
||||||
// NOTE: Add new methods at the end of file!!!
|
// NOTE: Add new methods at the end of file!!!
|
||||||
|
|
||||||
interface IOsmAndAidlInterface {
|
interface IOsmAndAidlInterface {
|
||||||
|
@ -867,4 +871,16 @@ interface IOsmAndAidlInterface {
|
||||||
AppInfoParams getAppInfo();
|
AppInfoParams getAppInfo();
|
||||||
|
|
||||||
boolean setMapMargins(in MapMarginsParams params);
|
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:
|
// Navigation Drawer:
|
||||||
String DRAWER_ITEM_ID_SCHEME = "drawer.action.";
|
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_DASHBOARD_ID = DRAWER_ITEM_ID_SCHEME + "dashboard";
|
||||||
String DRAWER_MAP_MARKERS_ID = DRAWER_ITEM_ID_SCHEME + "map_markers";
|
String DRAWER_MAP_MARKERS_ID = DRAWER_ITEM_ID_SCHEME + "map_markers";
|
||||||
String DRAWER_MY_PLACES_ID = DRAWER_ITEM_ID_SCHEME + "my_places";
|
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 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 String fileName;
|
||||||
private byte[] filePartData;
|
private byte[] filePartData;
|
||||||
private long startTime;
|
private long startTime;
|
||||||
private boolean done;
|
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.fileName = fileName;
|
||||||
this.filePartData = filePartData;
|
this.filePartData = filePartData;
|
||||||
this.startTime = startTime;
|
this.startTime = startTime;
|
||||||
|
@ -37,6 +46,10 @@ public class CopyFileParams extends AidlParams {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public String getDestinationDir() {
|
||||||
|
return destinationDir;
|
||||||
|
}
|
||||||
|
|
||||||
public String getFileName() {
|
public String getFileName() {
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
|
@ -55,23 +68,26 @@ public class CopyFileParams extends AidlParams {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToBundle(Bundle bundle) {
|
public void writeToBundle(Bundle bundle) {
|
||||||
bundle.putString("fileName", fileName);
|
bundle.putString(DESTINATION_DIR_KEY, destinationDir);
|
||||||
bundle.putByteArray("filePartData", filePartData);
|
bundle.putString(FILE_NAME_KEY, fileName);
|
||||||
bundle.putLong("startTime", startTime);
|
bundle.putByteArray(FILE_PART_DATA_KEY, filePartData);
|
||||||
bundle.putBoolean("done", done);
|
bundle.putLong(START_TIME_KEY, startTime);
|
||||||
|
bundle.putBoolean(DONE_KEY, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readFromBundle(Bundle bundle) {
|
protected void readFromBundle(Bundle bundle) {
|
||||||
fileName = bundle.getString("fileName");
|
destinationDir = bundle.getString(DESTINATION_DIR_KEY);
|
||||||
filePartData = bundle.getByteArray("filePartData");
|
fileName = bundle.getString(FILE_NAME_KEY);
|
||||||
startTime = bundle.getLong("startTime");
|
filePartData = bundle.getByteArray(FILE_PART_DATA_KEY);
|
||||||
done = bundle.getBoolean("done");
|
startTime = bundle.getLong(START_TIME_KEY);
|
||||||
|
done = bundle.getBoolean(DONE_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "CopyFileParams {" +
|
return "CopyFileParams {" +
|
||||||
|
" destinationDir=" + destinationDir +
|
||||||
" fileName=" + fileName +
|
" fileName=" + fileName +
|
||||||
", filePartData size=" + filePartData.length +
|
", filePartData size=" + filePartData.length +
|
||||||
", startTime=" + startTime +
|
", startTime=" + startTime +
|
||||||
|
|
|
@ -3,18 +3,31 @@ package net.osmand.aidlapi.customization;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import net.osmand.aidlapi.AidlParams;
|
import net.osmand.aidlapi.AidlParams;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class MapMarginsParams extends AidlParams {
|
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 leftMargin;
|
||||||
private int topMargin;
|
private int topMargin;
|
||||||
private int rightMargin;
|
private int rightMargin;
|
||||||
private int bottomMargin;
|
private int bottomMargin;
|
||||||
|
|
||||||
public MapMarginsParams(String appModeKey, int leftMargin, int topMargin, int rightMargin, int bottomMargin) {
|
public MapMarginsParams(int leftMargin, int topMargin, int rightMargin, int bottomMargin,
|
||||||
this.appModeKey = appModeKey;
|
@Nullable List<String> appModesKeys) {
|
||||||
|
if (appModesKeys != null) {
|
||||||
|
this.appModesKeys.addAll(appModesKeys);
|
||||||
|
}
|
||||||
this.leftMargin = leftMargin;
|
this.leftMargin = leftMargin;
|
||||||
this.topMargin = topMargin;
|
this.topMargin = topMargin;
|
||||||
this.rightMargin = rightMargin;
|
this.rightMargin = rightMargin;
|
||||||
|
@ -37,8 +50,8 @@ public class MapMarginsParams extends AidlParams {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public String getAppModeKey() {
|
public List<String> getAppModesKeys() {
|
||||||
return appModeKey;
|
return appModesKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLeftMargin() {
|
public int getLeftMargin() {
|
||||||
|
@ -59,19 +72,19 @@ public class MapMarginsParams extends AidlParams {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToBundle(Bundle bundle) {
|
public void writeToBundle(Bundle bundle) {
|
||||||
bundle.putString("appModeKey", appModeKey);
|
bundle.putInt(LEFT_MARGIN_KEY, leftMargin);
|
||||||
bundle.putInt("leftMargin", leftMargin);
|
bundle.putInt(TOP_MARGIN_KEY, topMargin);
|
||||||
bundle.putInt("topMargin", topMargin);
|
bundle.putInt(RIGHT_MARGIN_KEY, rightMargin);
|
||||||
bundle.putInt("rightMargin", rightMargin);
|
bundle.putInt(BOTTOM_MARGIN_KEY, bottomMargin);
|
||||||
bundle.putInt("bottomMargin", bottomMargin);
|
bundle.putStringArrayList(APP_MODES_KEYS_KEY, appModesKeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readFromBundle(Bundle bundle) {
|
protected void readFromBundle(Bundle bundle) {
|
||||||
appModeKey = bundle.getString("appModeKey");
|
leftMargin = bundle.getInt(LEFT_MARGIN_KEY);
|
||||||
leftMargin = bundle.getInt("leftMargin");
|
topMargin = bundle.getInt(TOP_MARGIN_KEY);
|
||||||
topMargin = bundle.getInt("topMargin");
|
rightMargin = bundle.getInt(RIGHT_MARGIN_KEY);
|
||||||
rightMargin = bundle.getInt("rightMargin");
|
bottomMargin = bundle.getInt(BOTTOM_MARGIN_KEY);
|
||||||
bottomMargin = bundle.getInt("bottomMargin");
|
appModesKeys = bundle.getStringArrayList(APP_MODES_KEYS_KEY);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,15 +5,31 @@ import android.os.Bundle;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
|
|
||||||
import net.osmand.aidlapi.AidlParams;
|
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 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 Uri profileSettingsUri;
|
||||||
private String latestChanges;
|
private String latestChanges;
|
||||||
private int version;
|
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;
|
this.profileSettingsUri = profileSettingsUri;
|
||||||
|
for (AExportSettingsType settingsType : settingsTypeList) {
|
||||||
|
settingsTypeKeyList.add(settingsType.name());
|
||||||
|
}
|
||||||
|
this.replace = replace;
|
||||||
this.latestChanges = latestChanges;
|
this.latestChanges = latestChanges;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
@ -46,17 +62,29 @@ public class ProfileSettingsParams extends AidlParams {
|
||||||
return profileSettingsUri;
|
return profileSettingsUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArrayList<String> getSettingsTypeKeys() {
|
||||||
|
return settingsTypeKeyList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReplace() {
|
||||||
|
return replace;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeToBundle(Bundle bundle) {
|
public void writeToBundle(Bundle bundle) {
|
||||||
bundle.putInt("version", version);
|
bundle.putInt(VERSION_KEY, version);
|
||||||
bundle.putString("latestChanges", latestChanges);
|
bundle.putString(LATEST_CHANGES_KEY, latestChanges);
|
||||||
bundle.putParcelable("profileSettingsUri", profileSettingsUri);
|
bundle.putParcelable(PROFILE_SETTINGS_URI_KEY, profileSettingsUri);
|
||||||
|
bundle.putStringArrayList(SETTINGS_TYPE_KEY, settingsTypeKeyList);
|
||||||
|
bundle.putBoolean(REPLACE_KEY, replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void readFromBundle(Bundle bundle) {
|
protected void readFromBundle(Bundle bundle) {
|
||||||
version = bundle.getInt("version");
|
version = bundle.getInt(VERSION_KEY);
|
||||||
latestChanges = bundle.getString("latestChanges");
|
latestChanges = bundle.getString(LATEST_CHANGES_KEY);
|
||||||
profileSettingsUri = bundle.getParcelable("profileSettingsUri");
|
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: 'java'
|
||||||
apply plugin: 'maven-publish'
|
apply plugin: 'maven-publish'
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
android
|
android
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,9 @@ dependencies {
|
||||||
implementation 'com.moparisthebest:junidecode:0.1.1'
|
implementation 'com.moparisthebest:junidecode:0.1.1'
|
||||||
implementation 'com.vividsolutions:jts-core:1.14.0'
|
implementation 'com.vividsolutions:jts-core:1.14.0'
|
||||||
implementation 'com.google.openlocationcode:openlocationcode:1.0.4'
|
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
|
// turn off for now
|
||||||
//implementation 'com.atilika.kuromoji:kuromoji-ipadic:0.9.0'
|
//implementation 'com.atilika.kuromoji:kuromoji-ipadic:0.9.0'
|
||||||
implementation 'net.sf.kxml:kxml2:2.1.8'
|
implementation 'net.sf.kxml:kxml2:2.1.8'
|
||||||
|
|
|
@ -14,6 +14,10 @@
|
||||||
|
|
||||||
package com.jwetherell.openmap.common;
|
package com.jwetherell.openmap.common;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class MGRSPoint extends ZonedUTMPoint {
|
public class MGRSPoint extends ZonedUTMPoint {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -104,6 +108,15 @@ public class MGRSPoint extends ZonedUTMPoint {
|
||||||
* an UPPERCASE coordinate string is expected.
|
* an UPPERCASE coordinate string is expected.
|
||||||
*/
|
*/
|
||||||
protected void decode(String mgrsString) throws NumberFormatException {
|
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) {
|
if (mgrsString == null || mgrsString.length() == 0) {
|
||||||
throw new NumberFormatException("MGRSPoint coverting from nothing");
|
throw new NumberFormatException("MGRSPoint coverting from nothing");
|
||||||
}
|
}
|
||||||
|
@ -633,6 +646,97 @@ public class MGRSPoint extends ZonedUTMPoint {
|
||||||
return twoLetter;
|
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}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -52,9 +52,10 @@ public class GPXUtilities {
|
||||||
private static final String DEFAULT_ICON_NAME = "special_star";
|
private static final String DEFAULT_ICON_NAME = "special_star";
|
||||||
private static final String BACKGROUND_TYPE_EXTENSION = "background";
|
private static final String BACKGROUND_TYPE_EXTENSION = "background";
|
||||||
private static final String PROFILE_TYPE_EXTENSION = "profile";
|
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 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 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(
|
private final static NumberFormat latLonFormat = new DecimalFormat("0.00#####", new DecimalFormatSymbols(
|
||||||
|
@ -70,6 +71,7 @@ public class GPXUtilities {
|
||||||
WHITE(0xFFFFFFFF),
|
WHITE(0xFFFFFFFF),
|
||||||
RED(0xFFFF0000),
|
RED(0xFFFF0000),
|
||||||
GREEN(0xFF00FF00),
|
GREEN(0xFF00FF00),
|
||||||
|
DARKGREEN(0xFF006400),
|
||||||
BLUE(0xFF0000FF),
|
BLUE(0xFF0000FF),
|
||||||
YELLOW(0xFFFFFF00),
|
YELLOW(0xFFFFFF00),
|
||||||
CYAN(0xFF00FFFF),
|
CYAN(0xFF00FFFF),
|
||||||
|
@ -324,6 +326,20 @@ public class GPXUtilities {
|
||||||
getExtensionsToWrite().put(PROFILE_TYPE_EXTENSION, profileType);
|
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() {
|
public void removeProfileType() {
|
||||||
getExtensionsToWrite().remove(PROFILE_TYPE_EXTENSION);
|
getExtensionsToWrite().remove(PROFILE_TYPE_EXTENSION);
|
||||||
}
|
}
|
||||||
|
@ -374,11 +390,16 @@ public class GPXUtilities {
|
||||||
|
|
||||||
public static class TrkSegment extends GPXExtensions {
|
public static class TrkSegment extends GPXExtensions {
|
||||||
public boolean generalSegment = false;
|
public boolean generalSegment = false;
|
||||||
|
|
||||||
public List<WptPt> points = new ArrayList<>();
|
public List<WptPt> points = new ArrayList<>();
|
||||||
|
|
||||||
public Object renderer;
|
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) {
|
public List<GPXTrackAnalysis> splitByDistance(double meters, boolean joinSegments) {
|
||||||
return split(getDistanceMetric(), getTimeSplit(), meters, joinSegments);
|
return split(getDistanceMetric(), getTimeSplit(), meters, joinSegments);
|
||||||
|
@ -393,7 +414,6 @@ public class GPXUtilities {
|
||||||
splitSegment(metric, secondaryMetric, metricLimit, splitSegments, this, joinSegments);
|
splitSegment(metric, secondaryMetric, metricLimit, splitSegments, this, joinSegments);
|
||||||
return convert(splitSegments);
|
return convert(splitSegments);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Track extends GPXExtensions {
|
public static class Track extends GPXExtensions {
|
||||||
|
@ -1078,9 +1098,6 @@ public class GPXUtilities {
|
||||||
private List<WptPt> points = new ArrayList<>();
|
private List<WptPt> points = new ArrayList<>();
|
||||||
public List<Route> routes = 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 Exception error = null;
|
||||||
public String path = "";
|
public String path = "";
|
||||||
public boolean showCurrentTrack;
|
public boolean showCurrentTrack;
|
||||||
|
@ -1108,7 +1125,7 @@ public class GPXUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasRoute() {
|
public boolean hasRoute() {
|
||||||
return !routeSegments.isEmpty() && !routeTypes.isEmpty();
|
return getNonEmptyTrkSegments(true).size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<WptPt> getPoints() {
|
public List<WptPt> getPoints() {
|
||||||
|
@ -1218,7 +1235,7 @@ public class GPXUtilities {
|
||||||
GPXTrackAnalysis g = new GPXTrackAnalysis();
|
GPXTrackAnalysis g = new GPXTrackAnalysis();
|
||||||
g.wptPoints = points.size();
|
g.wptPoints = points.size();
|
||||||
g.wptCategoryNames = getWaypointCategories(true);
|
g.wptCategoryNames = getWaypointCategories(true);
|
||||||
List<SplitSegment> splitSegments = new ArrayList<GPXUtilities.SplitSegment>();
|
List<SplitSegment> splitSegments = new ArrayList<>();
|
||||||
for (int i = 0; i < tracks.size(); i++) {
|
for (int i = 0; i < tracks.size(); i++) {
|
||||||
Track subtrack = tracks.get(i);
|
Track subtrack = tracks.get(i);
|
||||||
for (TrkSegment segment : subtrack.segments) {
|
for (TrkSegment segment : subtrack.segments) {
|
||||||
|
@ -1243,6 +1260,15 @@ public class GPXUtilities {
|
||||||
return points;
|
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() {
|
public boolean hasRtePt() {
|
||||||
for (Route r : routes) {
|
for (Route r : routes) {
|
||||||
if (r.points.size() > 0) {
|
if (r.points.size() > 0) {
|
||||||
|
@ -1318,15 +1344,16 @@ public class GPXUtilities {
|
||||||
return pt;
|
return pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TrkSegment getNonEmptyTrkSegment() {
|
public List<TrkSegment> getNonEmptyTrkSegments(boolean routesOnly) {
|
||||||
for (GPXUtilities.Track t : tracks) {
|
List<TrkSegment> segments = new ArrayList<>();
|
||||||
|
for (Track t : tracks) {
|
||||||
for (TrkSegment s : t.segments) {
|
for (TrkSegment s : t.segments) {
|
||||||
if (s.points.size() > 0) {
|
if (!s.generalSegment && s.points.size() > 0 && (!routesOnly || s.hasRoute())) {
|
||||||
return s;
|
segments.add(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTrkSegment(List<WptPt> points) {
|
public void addTrkSegment(List<WptPt> points) {
|
||||||
|
@ -1365,8 +1392,8 @@ public class GPXUtilities {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRoutePoints(List<WptPt> points) {
|
public void addRoutePoints(List<WptPt> points, boolean addRoute) {
|
||||||
if (routes.size() == 0) {
|
if (routes.size() == 0 || addRoute) {
|
||||||
Route route = new Route();
|
Route route = new Route();
|
||||||
routes.add(route);
|
routes.add(route);
|
||||||
}
|
}
|
||||||
|
@ -1608,7 +1635,7 @@ public class GPXUtilities {
|
||||||
bottom = Math.min(bottom, p.getLatitude());
|
bottom = Math.min(bottom, p.getLatitude());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (GPXUtilities.Route route : routes) {
|
for (Route route : routes) {
|
||||||
for (WptPt p : route.points) {
|
for (WptPt p : route.points) {
|
||||||
if (left == 0 && right == 0) {
|
if (left == 0 && right == 0) {
|
||||||
left = p.getLongitude();
|
left = p.getLongitude();
|
||||||
|
@ -1720,7 +1747,7 @@ public class GPXUtilities {
|
||||||
|
|
||||||
public static String asString(GPXFile file) {
|
public static String asString(GPXFile file) {
|
||||||
final Writer writer = new StringWriter();
|
final Writer writer = new StringWriter();
|
||||||
GPXUtilities.writeGpx(writer, file);
|
writeGpx(writer, file);
|
||||||
return writer.toString();
|
return writer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1807,6 +1834,8 @@ public class GPXUtilities {
|
||||||
writeWpt(format, serializer, p);
|
writeWpt(format, serializer, p);
|
||||||
serializer.endTag(null, "trkpt"); //$NON-NLS-1$
|
serializer.endTag(null, "trkpt"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
assignRouteExtensionWriter(segment);
|
||||||
|
writeExtensions(serializer, segment);
|
||||||
serializer.endTag(null, "trkseg"); //$NON-NLS-1$
|
serializer.endTag(null, "trkseg"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
writeExtensions(serializer, track);
|
writeExtensions(serializer, track);
|
||||||
|
@ -1834,7 +1863,6 @@ public class GPXUtilities {
|
||||||
serializer.endTag(null, "wpt"); //$NON-NLS-1$
|
serializer.endTag(null, "wpt"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
assignRouteExtensionWriter(file);
|
|
||||||
writeExtensions(serializer, file);
|
writeExtensions(serializer, file);
|
||||||
|
|
||||||
serializer.endTag(null, "gpx"); //$NON-NLS-1$
|
serializer.endTag(null, "gpx"); //$NON-NLS-1$
|
||||||
|
@ -1847,19 +1875,19 @@ public class GPXUtilities {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assignRouteExtensionWriter(final GPXFile gpxFile) {
|
private static void assignRouteExtensionWriter(final TrkSegment segment) {
|
||||||
if (gpxFile.hasRoute() && gpxFile.getExtensionsWriter() == null) {
|
if (segment.hasRoute() && segment.getExtensionsWriter() == null) {
|
||||||
gpxFile.setExtensionsWriter(new GPXExtensionsWriter() {
|
segment.setExtensionsWriter(new GPXExtensionsWriter() {
|
||||||
@Override
|
@Override
|
||||||
public void writeExtensions(XmlSerializer serializer) {
|
public void writeExtensions(XmlSerializer serializer) {
|
||||||
StringBundle bundle = new StringBundle();
|
StringBundle bundle = new StringBundle();
|
||||||
List<StringBundle> segmentsBundle = new ArrayList<>();
|
List<StringBundle> segmentsBundle = new ArrayList<>();
|
||||||
for (RouteSegment segment : gpxFile.routeSegments) {
|
for (RouteSegment segment : segment.routeSegments) {
|
||||||
segmentsBundle.add(segment.toStringBundle());
|
segmentsBundle.add(segment.toStringBundle());
|
||||||
}
|
}
|
||||||
bundle.putBundleList("route", "segment", segmentsBundle);
|
bundle.putBundleList("route", "segment", segmentsBundle);
|
||||||
List<StringBundle> typesBundle = new ArrayList<>();
|
List<StringBundle> typesBundle = new ArrayList<>();
|
||||||
for (RouteType routeType : gpxFile.routeTypes) {
|
for (RouteType routeType : segment.routeTypes) {
|
||||||
typesBundle.add(routeType.toStringBundle());
|
typesBundle.add(routeType.toStringBundle());
|
||||||
}
|
}
|
||||||
bundle.putBundleList("types", "type", typesBundle);
|
bundle.putBundleList("types", "type", typesBundle);
|
||||||
|
@ -1901,12 +1929,15 @@ public class GPXUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeExtensions(XmlSerializer serializer, GPXExtensions p) throws IOException {
|
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();
|
GPXExtensionsWriter extensionsWriter = p.getExtensionsWriter();
|
||||||
if (!extensionsToRead.isEmpty() || extensionsWriter != null) {
|
if (!extensions.isEmpty() || extensionsWriter != null) {
|
||||||
serializer.startTag(null, "extensions");
|
serializer.startTag(null, "extensions");
|
||||||
if (!extensionsToRead.isEmpty()) {
|
if (!extensions.isEmpty()) {
|
||||||
for (Entry<String, String> s : extensionsToRead.entrySet()) {
|
for (Entry<String, String> s : extensions.entrySet()) {
|
||||||
writeNotNullText(serializer, s.getKey(), s.getValue());
|
writeNotNullText(serializer, s.getKey(), s.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1943,7 +1974,20 @@ public class GPXUtilities {
|
||||||
if (!Float.isNaN(p.heading)) {
|
if (!Float.isNaN(p.heading)) {
|
||||||
p.getExtensionsToWrite().put("heading", String.valueOf(Math.round(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 {
|
private static void writeAuthor(XmlSerializer serializer, Author author) throws IOException {
|
||||||
|
@ -2099,10 +2143,11 @@ public class GPXUtilities {
|
||||||
TrkSegment routeTrackSegment = new TrkSegment();
|
TrkSegment routeTrackSegment = new TrkSegment();
|
||||||
routeTrack.segments.add(routeTrackSegment);
|
routeTrack.segments.add(routeTrackSegment);
|
||||||
Stack<GPXExtensions> parserState = new Stack<>();
|
Stack<GPXExtensions> parserState = new Stack<>();
|
||||||
|
TrkSegment firstSegment = null;
|
||||||
boolean extensionReadMode = false;
|
boolean extensionReadMode = false;
|
||||||
boolean routePointExtension = false;
|
boolean routePointExtension = false;
|
||||||
List<RouteSegment> routeSegments = gpxFile.routeSegments;
|
List<RouteSegment> routeSegments = new ArrayList<>();
|
||||||
List<RouteType> routeTypes = gpxFile.routeTypes;
|
List<RouteType> routeTypes = new ArrayList<>();
|
||||||
boolean routeExtension = false;
|
boolean routeExtension = false;
|
||||||
boolean typesExtension = false;
|
boolean typesExtension = false;
|
||||||
parserState.push(gpxFile);
|
parserState.push(gpxFile);
|
||||||
|
@ -2403,6 +2448,16 @@ public class GPXUtilities {
|
||||||
assert pop instanceof Route;
|
assert pop instanceof Route;
|
||||||
} else if (tag.equals("trkseg")) {
|
} else if (tag.equals("trkseg")) {
|
||||||
Object pop = parserState.pop();
|
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;
|
assert pop instanceof TrkSegment;
|
||||||
} else if (tag.equals("rpt")) {
|
} else if (tag.equals("rpt")) {
|
||||||
Object pop = parserState.pop();
|
Object pop = parserState.pop();
|
||||||
|
@ -2413,6 +2468,10 @@ public class GPXUtilities {
|
||||||
if (!routeTrackSegment.points.isEmpty()) {
|
if (!routeTrackSegment.points.isEmpty()) {
|
||||||
gpxFile.tracks.add(routeTrack);
|
gpxFile.tracks.add(routeTrack);
|
||||||
}
|
}
|
||||||
|
if (!routeSegments.isEmpty() && !routeTypes.isEmpty() && firstSegment != null) {
|
||||||
|
firstSegment.routeSegments = routeSegments;
|
||||||
|
firstSegment.routeTypes = routeTypes;
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
gpxFile.error = e;
|
gpxFile.error = e;
|
||||||
log.error("Error reading gpx", e); //$NON-NLS-1$
|
log.error("Error reading gpx", e); //$NON-NLS-1$
|
||||||
|
|
|
@ -45,7 +45,7 @@ public interface IProgress {
|
||||||
public boolean isInterrupted() {return false;}
|
public boolean isInterrupted() {return false;}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isIndeterminate() {return false;}
|
public boolean isIndeterminate() {return true;}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void finishTask() {}
|
public void finishTask() {}
|
||||||
|
|
|
@ -14,7 +14,8 @@ public class IndexConstants {
|
||||||
public static final String TEMP_SOURCE_TO_LOAD = "temp";
|
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 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 = ".obf"; //$NON-NLS-1$
|
||||||
public static final String BINARY_MAP_INDEX_EXT_ZIP = ".obf.zip"; //$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 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 final static String POI_TABLE = "poi"; //$NON-NLS-1$
|
||||||
|
|
||||||
public static final String INDEX_DOWNLOAD_DOMAIN = "download.osmand.net";
|
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 FONT_INDEX_DIR = "fonts/"; //$NON-NLS-1$
|
||||||
public static final String VOICE_INDEX_DIR = "voice/"; //$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 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 SETTINGS_DIR = "settings/"; //$NON-NLS-1$
|
||||||
public static final String TEMP_DIR = "temp/";
|
public static final String TEMP_DIR = "temp/";
|
||||||
public static final String ROUTING_PROFILES_DIR = "routing/";
|
public static final String ROUTING_PROFILES_DIR = "routing/";
|
||||||
public static final String PLUGINS_DIR = "plugins/";
|
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 FORMAT_SECONDS = 2;
|
||||||
public static final int UTM_FORMAT = 3;
|
public static final int UTM_FORMAT = 3;
|
||||||
public static final int OLC_FORMAT = 4;
|
public static final int OLC_FORMAT = 4;
|
||||||
|
public static final int MGRS_FORMAT = 5;
|
||||||
private static final char DELIM = ':';
|
private static final char DELIM = ':';
|
||||||
private static final char DELIMITER_DEGREES = '°';
|
private static final char DELIMITER_DEGREES = '°';
|
||||||
private static final char DELIMITER_MINUTES = '′';
|
private static final char DELIMITER_MINUTES = '′';
|
||||||
|
|
|
@ -106,9 +106,11 @@ public class TspAnt {
|
||||||
// Allocates all memory.
|
// Allocates all memory.
|
||||||
// Adds 1 to edge lengths to ensure no zero length edges.
|
// Adds 1 to edge lengths to ensure no zero length edges.
|
||||||
public TspAnt readGraph(List<LatLon> intermediates, LatLon start, LatLon end) {
|
public TspAnt readGraph(List<LatLon> intermediates, LatLon start, LatLon end) {
|
||||||
boolean keepEndPoint = end != null;
|
boolean keepEndPoint = end != null;
|
||||||
List<LatLon> l = new ArrayList<LatLon>();
|
List<LatLon> l = new ArrayList<LatLon>();
|
||||||
l.add(start);
|
if (start != null) {
|
||||||
|
l.add(start);
|
||||||
|
}
|
||||||
l.addAll(intermediates);
|
l.addAll(intermediates);
|
||||||
if (keepEndPoint) {
|
if (keepEndPoint) {
|
||||||
l.add(end);
|
l.add(end);
|
||||||
|
|
|
@ -11,8 +11,6 @@ import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import net.osmand.Collator;
|
import net.osmand.Collator;
|
||||||
import net.osmand.CollatorStringMatcher;
|
import net.osmand.CollatorStringMatcher;
|
||||||
|
@ -576,13 +574,12 @@ public class BinaryMapPoiReaderAdapter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!matches) {
|
if (!matches) {
|
||||||
Map<String, String> lt = am.getAdditionalInfo();
|
for (String key : am.getAdditionalInfoKeys()) {
|
||||||
for (Entry<String, String> e : lt.entrySet()) {
|
if(!key.contains("_name") &&
|
||||||
if(!e.getKey().contains("_name") &&
|
!key.equals("brand")) {
|
||||||
!e.getKey().equals("brand")) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
matches = matcher.matches(e.getValue());
|
matches = matcher.matches(am.getAdditionalInfo(key));
|
||||||
if (matches) {
|
if (matches) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -812,7 +809,6 @@ public class BinaryMapPoiReaderAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkCategories(SearchRequest<Amenity> req, PoiRegion region) throws IOException {
|
private boolean checkCategories(SearchRequest<Amenity> req, PoiRegion region) throws IOException {
|
||||||
StringBuilder subType = new StringBuilder();
|
|
||||||
while (true) {
|
while (true) {
|
||||||
int t = codedIS.readTag();
|
int t = codedIS.readTag();
|
||||||
int tag = WireFormat.getTagFieldNumber(t);
|
int tag = WireFormat.getTagFieldNumber(t);
|
||||||
|
|
|
@ -334,14 +334,16 @@ public class GeocodingUtilities {
|
||||||
boolean eqStreet = Algorithms.stringsEqual(gr1.streetName, gr2.streetName);
|
boolean eqStreet = Algorithms.stringsEqual(gr1.streetName, gr2.streetName);
|
||||||
if (eqStreet) {
|
if (eqStreet) {
|
||||||
boolean sameObj = false;
|
boolean sameObj = false;
|
||||||
if (gr1.building != null && gr2.building != null) {
|
if (gr1.city != null && gr2.city != null) {
|
||||||
if (Algorithms.stringsEqual(gr1.building.getName(), gr2.building.getName())) {
|
if (gr1.building != null && gr2.building != null) {
|
||||||
// same building
|
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;
|
sameObj = true;
|
||||||
}
|
}
|
||||||
} else if (gr1.building == null && gr2.building == null) {
|
|
||||||
// same street
|
|
||||||
sameObj = true;
|
|
||||||
}
|
}
|
||||||
if (sameObj) {
|
if (sameObj) {
|
||||||
double cityDist1 = MapUtils.getDistance(gr1.searchPoint, gr1.city.getLocation());
|
double cityDist1 = MapUtils.getDistance(gr1.searchPoint, gr1.city.getLocation());
|
||||||
|
|
|
@ -1,17 +1,7 @@
|
||||||
package net.osmand.data;
|
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.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -21,9 +11,14 @@ import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.zip.GZIPInputStream;
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import gnu.trove.list.array.TIntArrayList;
|
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 {
|
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) {
|
if (additionalInfo == null) {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
return additionalInfo;
|
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) {
|
public void setAdditionalInfo(Map<String, String> additionalInfo) {
|
||||||
this.additionalInfo = null;
|
this.additionalInfo = null;
|
||||||
|
@ -134,7 +163,7 @@ public class Amenity extends MapObject {
|
||||||
}
|
}
|
||||||
this.additionalInfo.put(tag, value);
|
this.additionalInfo.put(tag, value);
|
||||||
if (OPENING_HOURS.equals(tag)) {
|
if (OPENING_HOURS.equals(tag)) {
|
||||||
this.openingHours = value;
|
this.openingHours = unzipContent(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,7 +211,7 @@ public class Amenity extends MapObject {
|
||||||
}
|
}
|
||||||
int maxLen = 0;
|
int maxLen = 0;
|
||||||
String lng = defLang;
|
String lng = defLang;
|
||||||
for (String nm : getAdditionalInfo().keySet()) {
|
for (String nm : getAdditionalInfoKeys()) {
|
||||||
if (nm.startsWith(tag + ":")) {
|
if (nm.startsWith(tag + ":")) {
|
||||||
String key = nm.substring(tag.length() + 1);
|
String key = nm.substring(tag.length() + 1);
|
||||||
String cnt = getAdditionalInfo(tag + ":" + key);
|
String cnt = getAdditionalInfo(tag + ":" + key);
|
||||||
|
@ -204,7 +233,7 @@ public class Amenity extends MapObject {
|
||||||
|
|
||||||
public List<String> getNames(String tag, String defTag) {
|
public List<String> getNames(String tag, String defTag) {
|
||||||
List<String> l = new ArrayList<String>();
|
List<String> l = new ArrayList<String>();
|
||||||
for (String nm : getAdditionalInfo().keySet()) {
|
for (String nm : getAdditionalInfoKeys()) {
|
||||||
if (nm.startsWith(tag + ":")) {
|
if (nm.startsWith(tag + ":")) {
|
||||||
l.add(nm.substring(tag.length() + 1));
|
l.add(nm.substring(tag.length() + 1));
|
||||||
} else if (nm.equals(tag)) {
|
} else if (nm.equals(tag)) {
|
||||||
|
@ -229,7 +258,7 @@ public class Amenity extends MapObject {
|
||||||
if (!Algorithms.isEmpty(enName)) {
|
if (!Algorithms.isEmpty(enName)) {
|
||||||
return enName;
|
return enName;
|
||||||
}
|
}
|
||||||
for (String nm : getAdditionalInfo().keySet()) {
|
for (String nm : getAdditionalInfoKeys()) {
|
||||||
if (nm.startsWith(tag + ":")) {
|
if (nm.startsWith(tag + ":")) {
|
||||||
return getAdditionalInfo(nm);
|
return getAdditionalInfo(nm);
|
||||||
}
|
}
|
||||||
|
@ -345,4 +374,6 @@ public class Amenity extends MapObject {
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,10 @@ public class City extends MapObject {
|
||||||
public double getRadius() {
|
public double getRadius() {
|
||||||
return radius;
|
return radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean storedAsSeparateAdminEntity() {
|
||||||
|
return this != DISTRICT && this != NEIGHBOURHOOD && this != BOROUGH;
|
||||||
|
}
|
||||||
|
|
||||||
public static String valueToString(CityType t) {
|
public static String valueToString(CityType t) {
|
||||||
return t.toString().toLowerCase();
|
return t.toString().toLowerCase();
|
||||||
|
|
|
@ -13,7 +13,6 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -351,8 +350,8 @@ public abstract class MapObject implements Comparable<MapObject> {
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String unzipContent(String str) {
|
String unzipContent(String str) {
|
||||||
if (str != null && str.startsWith(" gz ")) {
|
if (isContentZipped(str)) {
|
||||||
try {
|
try {
|
||||||
int ind = 4;
|
int ind = 4;
|
||||||
byte[] bytes = new byte[str.length() - ind];
|
byte[] bytes = new byte[str.length() - ind];
|
||||||
|
@ -369,6 +368,10 @@ public abstract class MapObject implements Comparable<MapObject> {
|
||||||
}
|
}
|
||||||
br.close();
|
br.close();
|
||||||
str = bld.toString();
|
str = bld.toString();
|
||||||
|
// ugly fix of temporary problem of map generation
|
||||||
|
if(isContentZipped(str)) {
|
||||||
|
str = unzipContent(str);
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -376,6 +379,10 @@ public abstract class MapObject implements Comparable<MapObject> {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isContentZipped(String str) {
|
||||||
|
return str != null && str.startsWith(" gz ");
|
||||||
|
}
|
||||||
|
|
||||||
protected static void parseJSON(JSONObject json, MapObject o) {
|
protected static void parseJSON(JSONObject json, MapObject o) {
|
||||||
if (json.has("name")) {
|
if (json.has("name")) {
|
||||||
o.name = json.getString("name");
|
o.name = json.getString("name");
|
||||||
|
|
|
@ -823,7 +823,7 @@ public class MapPoiTypes {
|
||||||
}
|
}
|
||||||
String name = keyName;
|
String name = keyName;
|
||||||
name = name.replace('_', ' ');
|
name = name.replace('_', ' ');
|
||||||
return Algorithms.capitalizeFirstLetterAndLowercase(name);
|
return Algorithms.capitalizeFirstLetter(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRegisteredType(PoiCategory t) {
|
public boolean isRegisteredType(PoiCategory t) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ public abstract class MapRenderingTypes {
|
||||||
|
|
||||||
private static final Log log = PlatformUtil.getLog(MapRenderingTypes.class);
|
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",
|
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;
|
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_DELETED = -1;
|
||||||
public static final int MODIFY_MODIFIED = 1;
|
public static final int MODIFY_MODIFIED = 1;
|
||||||
public static final int MODIFY_CREATED = 2;
|
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) {
|
public Entity(long id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
@ -241,6 +243,11 @@ public abstract class Entity implements Serializable {
|
||||||
return Collections.unmodifiableMap(tags);
|
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() {
|
public Collection<String> getTagKeySet() {
|
||||||
if (tags == null) {
|
if (tags == null) {
|
||||||
|
|
|
@ -1,30 +1,22 @@
|
||||||
package net.osmand.osm.io;
|
package net.osmand.osm.io;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import com.github.scribejava.core.model.OAuthRequest;
|
||||||
import java.io.BufferedReader;
|
import com.github.scribejava.core.model.Response;
|
||||||
import java.io.File;
|
import com.github.scribejava.core.model.Verb;
|
||||||
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 net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
|
import net.osmand.osm.oauth.OsmOAuthAuthorizationClient;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
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 {
|
public class NetworkUtils {
|
||||||
private static final Log log = PlatformUtil.getLog(NetworkUtils.class);
|
private static final Log log = PlatformUtil.getLog(NetworkUtils.class);
|
||||||
|
private static final String GPX_UPLOAD_USER_AGENT = "OsmGPXUploadAgent";
|
||||||
private static Proxy proxy = null;
|
private static Proxy proxy = null;
|
||||||
|
|
||||||
public static String sendGetRequest(String urlText, String userNamePassword, StringBuilder responseBody){
|
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("\n"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
responseBody.append(s);
|
responseBody.append(s);
|
||||||
|
|
||||||
}
|
}
|
||||||
is.close();
|
is.close();
|
||||||
}
|
}
|
||||||
|
@ -65,9 +56,10 @@ public class NetworkUtils {
|
||||||
return e.getMessage();
|
return e.getMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String BOUNDARY = "CowMooCowMooCowCowCow"; //$NON-NLS-1$
|
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;
|
URL url;
|
||||||
try {
|
try {
|
||||||
boolean firstPrm =!urlText.contains("?");
|
boolean firstPrm =!urlText.contains("?");
|
||||||
|
@ -77,34 +69,48 @@ public class NetworkUtils {
|
||||||
}
|
}
|
||||||
log.info("Start uploading file to " + urlText + " " +fileToUpload.getName());
|
log.info("Start uploading file to " + urlText + " " +fileToUpload.getName());
|
||||||
url = new URL(urlText);
|
url = new URL(urlText);
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn;
|
||||||
conn.setDoInput(true);
|
if (client != null && client.isValidToken()){
|
||||||
conn.setDoOutput(true);
|
OAuthRequest req = new OAuthRequest(Verb.POST, urlText);
|
||||||
conn.setRequestMethod("POST");
|
client.getService().signRequest(client.getAccessToken(), req);
|
||||||
if(userNamePassword != null) {
|
req.addHeader("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
|
||||||
conn.setRequestProperty("Authorization", "Basic " + Base64.encode(userNamePassword)); //$NON-NLS-1$ //$NON-NLS-2$
|
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("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
conn.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$
|
conn.setRequestProperty("User-Agent", "OsmAnd"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
|
||||||
OutputStream ous = conn.getOutputStream();
|
OutputStream ous = conn.getOutputStream();
|
||||||
// for (String key : additionalMapData.keySet()) {
|
ous.write(("--" + BOUNDARY + "\r\n").getBytes());
|
||||||
// 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());
|
|
||||||
String filename = fileToUpload.getName();
|
String filename = fileToUpload.getName();
|
||||||
if(gzip){
|
if (gzip) {
|
||||||
filename+=".gz";
|
filename += ".gz";
|
||||||
}
|
}
|
||||||
ous.write(("content-disposition: form-data; name=\""+formName+"\"; filename=\"" + filename + "\"\r\n").getBytes()); //$NON-NLS-1$ //$NON-NLS-2$
|
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$
|
ous.write(("Content-Type: application/octet-stream\r\n\r\n").getBytes()); //$NON-NLS-1$
|
||||||
InputStream fis = new FileInputStream(fileToUpload);
|
InputStream fis = new FileInputStream(fileToUpload);
|
||||||
BufferedInputStream bis = new BufferedInputStream(fis, 20 * 1024);
|
BufferedInputStream bis = new BufferedInputStream(fis, 20 * 1024);
|
||||||
ous.flush();
|
ous.flush();
|
||||||
if(gzip){
|
if (gzip) {
|
||||||
GZIPOutputStream gous = new GZIPOutputStream(ous, 1024);
|
GZIPOutputStream gous = new GZIPOutputStream(ous, 1024);
|
||||||
Algorithms.streamCopy(bis, gous);
|
Algorithms.streamCopy(bis, gous);
|
||||||
gous.flush();
|
gous.flush();
|
||||||
|
@ -112,8 +118,7 @@ public class NetworkUtils {
|
||||||
} else {
|
} else {
|
||||||
Algorithms.streamCopy(bis, ous);
|
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();
|
ous.flush();
|
||||||
Algorithms.closeStream(bis);
|
Algorithms.closeStream(bis);
|
||||||
Algorithms.closeStream(ous);
|
Algorithms.closeStream(ous);
|
||||||
|
@ -136,7 +141,6 @@ public class NetworkUtils {
|
||||||
responseBody.append("\n"); //$NON-NLS-1$
|
responseBody.append("\n"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
responseBody.append(s);
|
responseBody.append(s);
|
||||||
|
|
||||||
}
|
}
|
||||||
is.close();
|
is.close();
|
||||||
}
|
}
|
||||||
|
@ -157,7 +161,6 @@ public class NetworkUtils {
|
||||||
proxy = null;
|
proxy = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Proxy getProxy() {
|
public static Proxy getProxy() {
|
||||||
return proxy;
|
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) {
|
public void init(Map<String, String> attributes) {
|
||||||
ArrayList<RenderingRuleProperty> props = new ArrayList<RenderingRuleProperty>(attributes.size());
|
ArrayList<RenderingRuleProperty> props = new ArrayList<RenderingRuleProperty>(attributes.size());
|
||||||
intProperties = new int[attributes.size()];
|
intProperties = new int[attributes.size()];
|
||||||
floatProperties = null;
|
floatProperties = new float[attributes.size()];
|
||||||
attributesRef = null;
|
attributesRef = null;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
Iterator<Entry<String, String>> it = attributes.entrySet().iterator();
|
Iterator<Entry<String, String>> it = attributes.entrySet().iterator();
|
||||||
|
@ -58,14 +58,13 @@ public class RenderingRule {
|
||||||
attributesRef[i] = storage.getRenderingAttributeRule(vl.substring(1));
|
attributesRef[i] = storage.getRenderingAttributeRule(vl.substring(1));
|
||||||
} else if (property.isString()) {
|
} else if (property.isString()) {
|
||||||
intProperties[i] = storage.getDictionaryValue(vl);
|
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 {
|
} 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);
|
intProperties[i] = property.parseIntValue(vl);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -95,7 +94,7 @@ public class RenderingRule {
|
||||||
|
|
||||||
public float getFloatPropertyValue(String property) {
|
public float getFloatPropertyValue(String property) {
|
||||||
int i = getPropertyIndex(property);
|
int i = getPropertyIndex(property);
|
||||||
if(i >= 0 && floatProperties != null){
|
if (i >= 0) {
|
||||||
return floatProperties[i];
|
return floatProperties[i];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -155,12 +155,7 @@ public class RenderingRuleProperty {
|
||||||
try {
|
try {
|
||||||
int colon = value.indexOf(':');
|
int colon = value.indexOf(':');
|
||||||
if(colon != -1) {
|
if(colon != -1) {
|
||||||
int c = 0;
|
return (int) Float.parseFloat(value.substring(colon + 1));
|
||||||
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);
|
return (int) Float.parseFloat(value);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
|
@ -190,30 +185,35 @@ public class RenderingRuleProperty {
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
log.error("Rendering parse " + value + " in " + attrName);
|
log.error("Rendering parse " + value + " in " + attrName);
|
||||||
}
|
}
|
||||||
return -1;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public float parseFloatValue(String value){
|
public float parseFloatValue(String value) {
|
||||||
if(type == FLOAT_TYPE){
|
try {
|
||||||
try {
|
if (type == FLOAT_TYPE) {
|
||||||
int colon = value.indexOf(':');
|
int colon = value.indexOf(':');
|
||||||
if(colon != -1) {
|
if (colon != -1) {
|
||||||
if(colon > 0) {
|
if (colon > 0) {
|
||||||
return Float.parseFloat(value.substring(0, colon));
|
return Float.parseFloat(value.substring(0, colon));
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return Float.parseFloat(value);
|
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;
|
} catch (NumberFormatException e) {
|
||||||
} else {
|
log.error("Rendering parse " + value + " in " + attrName);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -244,8 +244,6 @@ public class RenderingRuleStorageProperties {
|
||||||
R_TEXT_HALO_COLOR = registerRuleInternal(RenderingRuleProperty.createOutputColorProperty(TEXT_HALO_COLOR));
|
R_TEXT_HALO_COLOR = registerRuleInternal(RenderingRuleProperty.createOutputColorProperty(TEXT_HALO_COLOR));
|
||||||
R_TEXT_SIZE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(TEXT_SIZE));
|
R_TEXT_SIZE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(TEXT_SIZE));
|
||||||
R_TEXT_ORDER = registerRuleInternal(RenderingRuleProperty.createOutputIntProperty(TEXT_ORDER));
|
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_MIN_DISTANCE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(TEXT_MIN_DISTANCE));
|
||||||
R_TEXT_SHIELD = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty(TEXT_SHIELD));
|
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_3 = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty("icon_3"));
|
||||||
R_ICON_4 = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty("icon_4"));
|
R_ICON_4 = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty("icon_4"));
|
||||||
R_ICON_5 = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty("icon_5"));
|
R_ICON_5 = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty("icon_5"));
|
||||||
|
R_ICON_ORDER = registerRuleInternal(RenderingRuleProperty.createOutputIntProperty(ICON_ORDER));
|
||||||
R_SHIELD = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty(SHIELD));
|
R_SHIELD = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty(SHIELD));
|
||||||
|
R_ICON_VISIBLE_SIZE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(ICON_VISIBLE_SIZE));
|
||||||
|
|
||||||
// polygon/way
|
// polygon/way
|
||||||
R_COLOR = registerRuleInternal(RenderingRuleProperty.createOutputColorProperty(COLOR));
|
R_COLOR = registerRuleInternal(RenderingRuleProperty.createOutputColorProperty(COLOR));
|
||||||
|
|
|
@ -20,10 +20,10 @@ public class RouteExporter {
|
||||||
|
|
||||||
public static final String OSMAND_ROUTER_V2 = "OsmAndRouterV2";
|
public static final String OSMAND_ROUTER_V2 = "OsmAndRouterV2";
|
||||||
|
|
||||||
private String name;
|
private final String name;
|
||||||
private List<RouteSegmentResult> route;
|
private final List<RouteSegmentResult> route;
|
||||||
private List<Location> locations;
|
private final List<Location> locations;
|
||||||
private List<WptPt> points;
|
private final List<WptPt> points;
|
||||||
|
|
||||||
public RouteExporter(String name, List<RouteSegmentResult> route, List<Location> locations, List<WptPt> points) {
|
public RouteExporter(String name, List<RouteSegmentResult> route, List<Location> locations, List<WptPt> points) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -33,6 +33,34 @@ public class RouteExporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public GPXFile exportRoute() {
|
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);
|
RouteDataResources resources = new RouteDataResources(locations);
|
||||||
List<StringBundle> routeItems = new ArrayList<>();
|
List<StringBundle> routeItems = new ArrayList<>();
|
||||||
if (!Algorithms.isEmpty(route)) {
|
if (!Algorithms.isEmpty(route)) {
|
||||||
|
@ -57,15 +85,9 @@ public class RouteExporter {
|
||||||
typeList.add(typeBundle);
|
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();
|
TrkSegment trkSegment = new TrkSegment();
|
||||||
track.segments.add(trkSegment);
|
|
||||||
|
|
||||||
if (locations == null || locations.isEmpty()) {
|
if (locations == null || locations.isEmpty()) {
|
||||||
return gpx;
|
return trkSegment;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < locations.size(); i++) {
|
for (int i = 0; i < locations.size(); i++) {
|
||||||
Location loc = locations.get(i);
|
Location loc = locations.get(i);
|
||||||
|
@ -83,23 +105,17 @@ public class RouteExporter {
|
||||||
}
|
}
|
||||||
trkSegment.points.add(pt);
|
trkSegment.points.add(pt);
|
||||||
}
|
}
|
||||||
if (points != null) {
|
|
||||||
for (WptPt pt : points) {
|
|
||||||
gpx.addPoint(pt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<RouteSegment> routeSegments = new ArrayList<>();
|
List<RouteSegment> routeSegments = new ArrayList<>();
|
||||||
for (StringBundle item : routeItems) {
|
for (StringBundle item : routeItems) {
|
||||||
routeSegments.add(RouteSegment.fromStringBundle(item));
|
routeSegments.add(RouteSegment.fromStringBundle(item));
|
||||||
}
|
}
|
||||||
gpx.routeSegments = routeSegments;
|
trkSegment.routeSegments = routeSegments;
|
||||||
List<RouteType> routeTypes = new ArrayList<>();
|
List<RouteType> routeTypes = new ArrayList<>();
|
||||||
for (StringBundle item : typeList) {
|
for (StringBundle item : typeList) {
|
||||||
routeTypes.add(RouteType.fromStringBundle(item));
|
routeTypes.add(RouteType.fromStringBundle(item));
|
||||||
}
|
}
|
||||||
gpx.routeTypes = routeTypes;
|
trkSegment.routeTypes = routeTypes;
|
||||||
|
return trkSegment;
|
||||||
return gpx;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import net.osmand.GPXUtilities;
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
import net.osmand.GPXUtilities.RouteSegment;
|
import net.osmand.GPXUtilities.RouteSegment;
|
||||||
import net.osmand.GPXUtilities.RouteType;
|
import net.osmand.GPXUtilities.RouteType;
|
||||||
|
import net.osmand.GPXUtilities.TrkSegment;
|
||||||
import net.osmand.GPXUtilities.WptPt;
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
import net.osmand.Location;
|
import net.osmand.Location;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
|
@ -28,10 +29,9 @@ public class RouteImporter {
|
||||||
|
|
||||||
private File file;
|
private File file;
|
||||||
private GPXFile gpxFile;
|
private GPXFile gpxFile;
|
||||||
|
private TrkSegment segment;
|
||||||
|
|
||||||
private List<RouteSegmentResult> route = new ArrayList<>();
|
private final List<RouteSegmentResult> route = new ArrayList<>();
|
||||||
private RouteRegion region = new RouteRegion();
|
|
||||||
private RouteDataResources resources = new RouteDataResources();
|
|
||||||
|
|
||||||
public RouteImporter(File file) {
|
public RouteImporter(File file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
|
@ -41,8 +41,12 @@ public class RouteImporter {
|
||||||
this.gpxFile = gpxFile;
|
this.gpxFile = gpxFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RouteImporter(TrkSegment segment) {
|
||||||
|
this.segment = segment;
|
||||||
|
}
|
||||||
|
|
||||||
public List<RouteSegmentResult> importRoute() {
|
public List<RouteSegmentResult> importRoute() {
|
||||||
if (gpxFile != null) {
|
if (gpxFile != null || segment != null) {
|
||||||
parseRoute();
|
parseRoute();
|
||||||
} else if (file != null) {
|
} else if (file != null) {
|
||||||
FileInputStream fis = null;
|
FileInputStream fis = null;
|
||||||
|
@ -69,19 +73,34 @@ public class RouteImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseRoute() {
|
private void parseRoute() {
|
||||||
collectLocations();
|
if (segment != null) {
|
||||||
collectSegments();
|
parseRoute(segment);
|
||||||
collectTypes();
|
} else if (gpxFile != null) {
|
||||||
for (RouteSegmentResult segment : route) {
|
List<TrkSegment> segments = gpxFile.getNonEmptyTrkSegments(true);
|
||||||
segment.fillNames(resources);
|
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();
|
List<Location> locations = resources.getLocations();
|
||||||
double lastElevation = HEIGHT_UNDEFINED;
|
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) {
|
if (segment.hasRoute()) {
|
||||||
for (WptPt point : gpxFile.tracks.get(0).segments.get(0).points) {
|
for (WptPt point : segment.points) {
|
||||||
Location loc = new Location("", point.getLatitude(), point.getLongitude());
|
Location loc = new Location("", point.getLatitude(), point.getLongitude());
|
||||||
if (!Double.isNaN(point.ele)) {
|
if (!Double.isNaN(point.ele)) {
|
||||||
loc.setAltitude(point.ele);
|
loc.setAltitude(point.ele);
|
||||||
|
@ -94,18 +113,20 @@ public class RouteImporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectSegments() {
|
private List<RouteSegmentResult> collectRouteSegments(RouteRegion region, RouteDataResources resources, TrkSegment segment) {
|
||||||
for (RouteSegment segment : gpxFile.routeSegments) {
|
List<RouteSegmentResult> route = new ArrayList<>();
|
||||||
|
for (RouteSegment routeSegment : segment.routeSegments) {
|
||||||
RouteDataObject object = new RouteDataObject(region);
|
RouteDataObject object = new RouteDataObject(region);
|
||||||
RouteSegmentResult segmentResult = new RouteSegmentResult(object);
|
RouteSegmentResult segmentResult = new RouteSegmentResult(object);
|
||||||
segmentResult.readFromBundle(new RouteDataBundle(resources, segment.toStringBundle()));
|
segmentResult.readFromBundle(new RouteDataBundle(resources, routeSegment.toStringBundle()));
|
||||||
route.add(segmentResult);
|
route.add(segmentResult);
|
||||||
}
|
}
|
||||||
|
return route;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectTypes() {
|
private void collectRouteTypes(RouteRegion region, TrkSegment segment) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (RouteType routeType : gpxFile.routeTypes) {
|
for (RouteType routeType : segment.routeTypes) {
|
||||||
StringBundle bundle = routeType.toStringBundle();
|
StringBundle bundle = routeType.toStringBundle();
|
||||||
String t = bundle.getString("t", null);
|
String t = bundle.getString("t", null);
|
||||||
String v = bundle.getString("v", null);
|
String v = bundle.getString("v", null);
|
||||||
|
|
|
@ -256,7 +256,7 @@ public class RoutePlannerFrontEnd {
|
||||||
if (routeFound) {
|
if (routeFound) {
|
||||||
// route is found - cut the end of the route and move to next iteration
|
// route is found - cut the end of the route and move to next iteration
|
||||||
// start.stepBackRoute = new ArrayList<RouteSegmentResult>();
|
// start.stepBackRoute = new ArrayList<RouteSegmentResult>();
|
||||||
// boolean stepBack = true;
|
// boolean stepBack = true;
|
||||||
boolean stepBack = stepBackAndFindPrevPointInRoute(gctx, gpxPoints, start, next);
|
boolean stepBack = stepBackAndFindPrevPointInRoute(gctx, gpxPoints, start, next);
|
||||||
if (!stepBack) {
|
if (!stepBack) {
|
||||||
// not supported case (workaround increase MAXIMUM_STEP_APPROXIMATION)
|
// not supported case (workaround increase MAXIMUM_STEP_APPROXIMATION)
|
||||||
|
@ -546,8 +546,10 @@ public class RoutePlannerFrontEnd {
|
||||||
if (start != null && start.pnt == null) {
|
if (start != null && start.pnt == null) {
|
||||||
gctx.routePointsSearched++;
|
gctx.routePointsSearched++;
|
||||||
RouteSegmentPoint rsp = findRouteSegment(start.loc.getLatitude(), start.loc.getLongitude(), gctx.ctx, null, false);
|
RouteSegmentPoint rsp = findRouteSegment(start.loc.getLatitude(), start.loc.getLongitude(), gctx.ctx, null, false);
|
||||||
if (MapUtils.getDistance(rsp.getPreciseLatLon(), start.loc) < distThreshold) {
|
if (rsp != null) {
|
||||||
start.pnt = rsp;
|
if (MapUtils.getDistance(rsp.getPreciseLatLon(), start.loc) < distThreshold) {
|
||||||
|
start.pnt = rsp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (start != null && start.pnt != null) {
|
if (start != null && start.pnt != null) {
|
||||||
|
@ -734,7 +736,7 @@ public class RoutePlannerFrontEnd {
|
||||||
res = searchRouteImpl(ctx, points, routeDirection);
|
res = searchRouteImpl(ctx, points, routeDirection);
|
||||||
}
|
}
|
||||||
if (ctx.calculationProgress != null) {
|
if (ctx.calculationProgress != null) {
|
||||||
ctx.calculationProgress.timeToCalculate += (System.nanoTime() - timeToCalculate);
|
ctx.calculationProgress.timeToCalculate = (System.nanoTime() - timeToCalculate);
|
||||||
}
|
}
|
||||||
BinaryRoutePlanner.printDebugMemoryInformation(ctx);
|
BinaryRoutePlanner.printDebugMemoryInformation(ctx);
|
||||||
if (res != null) {
|
if (res != null) {
|
||||||
|
|
|
@ -255,7 +255,8 @@ public class RouteSegmentResult implements StringExternalizable<RouteDataBundle>
|
||||||
@Override
|
@Override
|
||||||
public void writeToBundle(RouteDataBundle bundle) {
|
public void writeToBundle(RouteDataBundle bundle) {
|
||||||
Map<RouteTypeRule, Integer> rules = bundle.getResources().getRules();
|
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("segmentTime", segmentTime, 2);
|
||||||
bundle.putFloat("speed", speed, 2);
|
bundle.putFloat("speed", speed, 2);
|
||||||
if (turnType != null) {
|
if (turnType != null) {
|
||||||
|
@ -271,24 +272,29 @@ public class RouteSegmentResult implements StringExternalizable<RouteDataBundle>
|
||||||
bundle.putString("turnLanes", TurnType.lanesToString(turnLanes));
|
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));
|
bundle.putArray("types", convertTypes(object.types, rules));
|
||||||
|
|
||||||
int start = Math.min(startPointIndex, endPointIndex);
|
int start = Math.min(startPointIndex, endPointIndex);
|
||||||
int end = Math.max(startPointIndex, endPointIndex) + 1;
|
int end = Math.max(startPointIndex, endPointIndex) + 1;
|
||||||
if (object.pointTypes != null && start < object.pointTypes.length) {
|
if (object.pointTypes != null && start < object.pointTypes.length) {
|
||||||
int[][] types = Arrays.copyOfRange(object.pointTypes, start, Math.min(end, 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));
|
bundle.putArray("pointTypes", convertTypes(types, rules));
|
||||||
}
|
}
|
||||||
if (object.nameIds != null) {
|
if (object.nameIds != null) {
|
||||||
bundle.putArray("names", convertNameIds(object.nameIds, rules));
|
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));
|
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));
|
||||||
String[][] names = Arrays.copyOfRange(object.pointNames, start, Math.min(end, object.pointNames.length));
|
if (reversed) {
|
||||||
bundle.putArray("pointNames", convertPointNames(types, names, rules));
|
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;
|
Location prevLocation = null;
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
Location location = resources.getLocation(index);
|
Location location = resources.getLocation(index);
|
||||||
if (location == null) {
|
if (location != null) {
|
||||||
break;
|
double dist = 0;
|
||||||
}
|
if (prevLocation != null) {
|
||||||
double dist = 0;
|
dist = MapUtils.getDistance(prevLocation.getLatitude(), prevLocation.getLongitude(), location.getLatitude(), location.getLongitude());
|
||||||
if (prevLocation != null) {
|
distance += dist;
|
||||||
dist = MapUtils.getDistance(prevLocation.getLatitude(), prevLocation.getLongitude(), location.getLatitude(), location.getLongitude());
|
}
|
||||||
distance += dist;
|
prevLocation = location;
|
||||||
}
|
object.pointsX[i] = MapUtils.get31TileNumberX(location.getLongitude());
|
||||||
prevLocation = location;
|
object.pointsY[i] = MapUtils.get31TileNumberY(location.getLatitude());
|
||||||
object.pointsX[i] = MapUtils.get31TileNumberX(location.getLongitude());
|
if (location.hasAltitude() && object.heightDistanceArray.length > 0) {
|
||||||
object.pointsY[i] = MapUtils.get31TileNumberY(location.getLatitude());
|
object.heightDistanceArray[i * 2] = (float) dist;
|
||||||
if (location.hasAltitude() && object.heightDistanceArray.length > 0) {
|
object.heightDistanceArray[i * 2 + 1] = (float) location.getAltitude();
|
||||||
object.heightDistanceArray[i * 2] = (float) dist;
|
} else {
|
||||||
object.heightDistanceArray[i * 2 + 1] = (float) location.getAltitude();
|
object.heightDistanceArray = new float[0];
|
||||||
} else {
|
}
|
||||||
object.heightDistanceArray = new float[0];
|
|
||||||
}
|
}
|
||||||
if (plus) {
|
if (plus) {
|
||||||
index++;
|
index++;
|
||||||
|
|
|
@ -289,7 +289,8 @@ public class RoutingContext {
|
||||||
if(excludeNotAllowed != null && !excludeNotAllowed.contains(ro.getId())) {
|
if(excludeNotAllowed != null && !excludeNotAllowed.contains(ro.getId())) {
|
||||||
ts.add(ro);
|
ts.add(ro);
|
||||||
}
|
}
|
||||||
} else if(excludeNotAllowed != null && ro.getId() > 0){
|
}
|
||||||
|
if(excludeNotAllowed != null && ro.getId() > 0){
|
||||||
excludeNotAllowed.add(ro.getId());
|
excludeNotAllowed.add(ro.getId());
|
||||||
if(ts.excludedIds == null ){
|
if(ts.excludedIds == null ){
|
||||||
ts.excludedIds = new TLongHashSet();
|
ts.excludedIds = new TLongHashSet();
|
||||||
|
|
|
@ -741,7 +741,7 @@ public class SearchUICore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Algorithms.isEmpty(object.alternateName) && object.object instanceof Amenity) {
|
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)) {
|
if (phrase.getFirstUnknownNameStringMatcher().matches(value)) {
|
||||||
object.alternateName = value;
|
object.alternateName = value;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -33,6 +33,7 @@ import net.osmand.util.LocationParser.ParsedOpenLocationCode;
|
||||||
import net.osmand.util.MapUtils;
|
import net.osmand.util.MapUtils;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -601,7 +602,7 @@ public class SearchCoreFactory {
|
||||||
sr.localeName = object.getName(phrase.getSettings().getLang(),
|
sr.localeName = object.getName(phrase.getSettings().getLang(),
|
||||||
phrase.getSettings().isTransliterate());
|
phrase.getSettings().isTransliterate());
|
||||||
if (!nm.matches(sr.localeName) && !nm.matches(sr.otherNames)
|
if (!nm.matches(sr.localeName) && !nm.matches(sr.otherNames)
|
||||||
&& !nm.matches(object.getAdditionalInfo().values())) {
|
&& !nm.matches(object.getAdditionalInfoValues(false))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
sr.object = object;
|
sr.object = object;
|
||||||
|
@ -922,6 +923,7 @@ public class SearchCoreFactory {
|
||||||
|
|
||||||
public static class SearchAmenityByTypeAPI extends SearchBaseAPI {
|
public static class SearchAmenityByTypeAPI extends SearchBaseAPI {
|
||||||
private static final int BBOX_RADIUS = 10000;
|
private static final int BBOX_RADIUS = 10000;
|
||||||
|
private static final int BBOX_RADIUS_NEAREST = 1000;
|
||||||
private SearchAmenityTypesAPI searchAmenityTypesAPI;
|
private SearchAmenityTypesAPI searchAmenityTypesAPI;
|
||||||
private MapPoiTypes types;
|
private MapPoiTypes types;
|
||||||
private AbstractPoiType unselectedPoiType;
|
private AbstractPoiType unselectedPoiType;
|
||||||
|
@ -1006,7 +1008,14 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
this.nameFilter = nameFilter;
|
this.nameFilter = nameFilter;
|
||||||
if (poiTypeFilter != null) {
|
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();
|
List<BinaryMapIndexReader> offlineIndexes = phrase.getOfflineIndexes();
|
||||||
Set<String> searchedPois = new TreeSet<>();
|
Set<String> searchedPois = new TreeSet<>();
|
||||||
for (BinaryMapIndexReader r : offlineIndexes) {
|
for (BinaryMapIndexReader r : offlineIndexes) {
|
||||||
|
@ -1050,7 +1059,7 @@ public class SearchCoreFactory {
|
||||||
if (!poiAdditionals.isEmpty()) {
|
if (!poiAdditionals.isEmpty()) {
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (String add : poiAdditionals) {
|
for (String add : poiAdditionals) {
|
||||||
if(object.getAdditionalInfo().containsKey(add)) {
|
if (object.getAdditionalInfoKeys().contains(add)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1407,6 +1416,7 @@ public class SearchCoreFactory {
|
||||||
private LatLon olcPhraseLocation;
|
private LatLon olcPhraseLocation;
|
||||||
private ParsedOpenLocationCode cachedParsedCode;
|
private ParsedOpenLocationCode cachedParsedCode;
|
||||||
private final List<String> citySubTypes = Arrays.asList("city", "town", "village");
|
private final List<String> citySubTypes = Arrays.asList("city", "town", "village");
|
||||||
|
private final DecimalFormat latLonFormatter = new DecimalFormat("#.0####");
|
||||||
|
|
||||||
public SearchLocationAndUrlAPI() {
|
public SearchLocationAndUrlAPI() {
|
||||||
super(ObjectType.LOCATION, ObjectType.PARTIAL_LOCATION);
|
super(ObjectType.LOCATION, ObjectType.PARTIAL_LOCATION);
|
||||||
|
@ -1498,7 +1508,7 @@ public class SearchCoreFactory {
|
||||||
sp.priority = SEARCH_LOCATION_PRIORITY;
|
sp.priority = SEARCH_LOCATION_PRIORITY;
|
||||||
|
|
||||||
sp.object = sp.location = ll;
|
sp.object = sp.location = ll;
|
||||||
sp.localeName = ((float) sp.location.getLatitude()) + ", <input> ";
|
sp.localeName = formatLatLon(sp.location.getLatitude()) + ", <input> ";
|
||||||
sp.objectType = ObjectType.PARTIAL_LOCATION;
|
sp.objectType = ObjectType.PARTIAL_LOCATION;
|
||||||
resultMatcher.publish(sp);
|
resultMatcher.publish(sp);
|
||||||
}
|
}
|
||||||
|
@ -1510,7 +1520,7 @@ public class SearchCoreFactory {
|
||||||
SearchResult sp = new SearchResult(phrase);
|
SearchResult sp = new SearchResult(phrase);
|
||||||
sp.priority = SEARCH_LOCATION_PRIORITY;
|
sp.priority = SEARCH_LOCATION_PRIORITY;
|
||||||
sp.object = sp.location = l;
|
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.objectType = ObjectType.LOCATION;
|
||||||
sp.wordsSpan = lw;
|
sp.wordsSpan = lw;
|
||||||
resultMatcher.publish(sp);
|
resultMatcher.publish(sp);
|
||||||
|
@ -1525,7 +1535,7 @@ public class SearchCoreFactory {
|
||||||
sp.object = pnt;
|
sp.object = pnt;
|
||||||
sp.wordsSpan = text;
|
sp.wordsSpan = text;
|
||||||
sp.location = new LatLon(pnt.getLatitude(), pnt.getLongitude());
|
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) {
|
if (pnt.getZoom() > 0) {
|
||||||
sp.preferredZoom = pnt.getZoom();
|
sp.preferredZoom = pnt.getZoom();
|
||||||
}
|
}
|
||||||
|
@ -1555,6 +1565,10 @@ public class SearchCoreFactory {
|
||||||
}
|
}
|
||||||
return cachedParsedCode == null ? SEARCH_LOCATION_PRIORITY : SEARCH_MAX_PRIORITY;
|
return cachedParsedCode == null ? SEARCH_LOCATION_PRIORITY : SEARCH_MAX_PRIORITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String formatLatLon(double latLon) {
|
||||||
|
return latLonFormatter.format(latLon);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String stripBraces(String localeName) {
|
private static String stripBraces(String localeName) {
|
||||||
|
|
|
@ -229,12 +229,14 @@ public class SearchPhrase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int countWords(String w) {
|
public int countWords(String w) {
|
||||||
String[] ws = w.split(ALLDELIMITERS);
|
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
for (int i = 0; i < ws.length; i++) {
|
if (!Algorithms.isEmpty(w)) {
|
||||||
String wd = ws[i].trim();
|
String[] ws = w.split(ALLDELIMITERS);
|
||||||
if (wd.length() > 0) {
|
for (int i = 0; i < ws.length; i++) {
|
||||||
cnt++;
|
String wd = ws[i].trim();
|
||||||
|
if (wd.length() > 0) {
|
||||||
|
cnt++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 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_KEY = new char['’'];
|
||||||
private static char[] CHARS_TO_NORMALIZE_VALUE = 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) {
|
public static String normalizeSearchText(String s) {
|
||||||
boolean norm = false;
|
boolean norm = false;
|
||||||
for (int i = 0; i < s.length() && !norm; i++) {
|
for (int i = 0; i < s.length() && !norm; i++) {
|
||||||
|
@ -119,9 +124,11 @@ public class Algorithms {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getFileNameWithoutExtension(String name) {
|
public static String getFileNameWithoutExtension(String name) {
|
||||||
int i = name.indexOf('.');
|
if (name != null) {
|
||||||
if (i >= 0) {
|
int index = name.lastIndexOf('.');
|
||||||
name = name.substring(0, i);
|
if (index != -1) {
|
||||||
|
return name.substring(0, index);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -293,7 +300,7 @@ public class Algorithms {
|
||||||
FileInputStream in = new FileInputStream(file);
|
FileInputStream in = new FileInputStream(file);
|
||||||
int test = readInt(in);
|
int test = readInt(in);
|
||||||
in.close();
|
in.close();
|
||||||
return test == 0x504b0304;
|
return test == ZIP_FILE_SIGNATURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -322,7 +329,7 @@ public class Algorithms {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int readInt(InputStream in) throws IOException {
|
public static int readInt(InputStream in) throws IOException {
|
||||||
int ch1 = in.read();
|
int ch1 = in.read();
|
||||||
int ch2 = in.read();
|
int ch2 = in.read();
|
||||||
int ch3 = in.read();
|
int ch3 = in.read();
|
||||||
|
@ -879,6 +886,14 @@ public class Algorithms {
|
||||||
return map;
|
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) {
|
public static boolean containsInArrayL(long[] array, long value) {
|
||||||
return Arrays.binarySearch(array, value) >= 0;
|
return Arrays.binarySearch(array, value) >= 0;
|
||||||
}
|
}
|
||||||
|
@ -942,4 +957,20 @@ public class Algorithms {
|
||||||
}
|
}
|
||||||
return res;
|
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;
|
||||||
import com.google.openlocationcode.OpenLocationCode.CodeArea;
|
import com.google.openlocationcode.OpenLocationCode.CodeArea;
|
||||||
import com.jwetherell.openmap.common.LatLonPoint;
|
import com.jwetherell.openmap.common.LatLonPoint;
|
||||||
|
import com.jwetherell.openmap.common.MGRSPoint;
|
||||||
import com.jwetherell.openmap.common.UTMPoint;
|
import com.jwetherell.openmap.common.UTMPoint;
|
||||||
|
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
|
@ -111,7 +112,7 @@ public class LocationParser {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// detect UTM
|
// 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);
|
char ch = all.get(1).toString().charAt(0);
|
||||||
if (Character.isLetter(ch)) {
|
if (Character.isLetter(ch)) {
|
||||||
UTMPoint upoint = new UTMPoint(d.get(2), d.get(1), d.get(0).intValue(), 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);
|
char ch = all.get(1).toString().charAt(0);
|
||||||
String combined = strings.get(2);
|
String combined = strings.get(2);
|
||||||
if (Character.isLetter(ch)) {
|
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
|
// try to find split lat/lon position
|
||||||
int jointNumbers = 0;
|
int jointNumbers = 0;
|
||||||
int lastJoin = 0;
|
int lastJoin = 0;
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.TreeSet;
|
||||||
|
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
|
|
||||||
|
import net.osmand.data.LatLon;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -29,42 +30,52 @@ public class RouteTestingTest {
|
||||||
private TestEntry te;
|
private TestEntry te;
|
||||||
|
|
||||||
|
|
||||||
public RouteTestingTest(String name, TestEntry te) {
|
public RouteTestingTest(String name, TestEntry te) {
|
||||||
this.te = te;
|
this.te = te;
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() throws Exception {
|
public static void setUp() throws Exception {
|
||||||
RouteResultPreparation.PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
|
RouteResultPreparation.PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name = "{index}: {0}")
|
@Parameterized.Parameters(name = "{index}: {0}")
|
||||||
public static Iterable<Object[]> data() throws IOException {
|
public static Iterable<Object[]> data() throws IOException {
|
||||||
String fileName = "/test_routing.json";
|
String fileName = "/test_routing.json";
|
||||||
Reader reader = new InputStreamReader(RouteTestingTest.class.getResourceAsStream(fileName));
|
Reader reader = new InputStreamReader(RouteTestingTest.class.getResourceAsStream(fileName));
|
||||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
TestEntry[] testEntries = gson.fromJson(reader, TestEntry[].class);
|
TestEntry[] testEntries = gson.fromJson(reader, TestEntry[].class);
|
||||||
ArrayList<Object[]> arrayList = new ArrayList<>();
|
ArrayList<Object[]> arrayList = new ArrayList<>();
|
||||||
for(TestEntry te : testEntries) {
|
for (TestEntry te : testEntries) {
|
||||||
if(te.isIgnore()) {
|
if (te.isIgnore()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
arrayList.add(new Object[] {te.getTestName(), te});
|
arrayList.add(new Object[]{te.getTestName(), te});
|
||||||
}
|
}
|
||||||
reader.close();
|
reader.close();
|
||||||
return arrayList;
|
return arrayList;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRouting() throws Exception {
|
public void testRouting() throws Exception {
|
||||||
String fl = "src/test/resources/Routing_test.obf";
|
String fl = "src/test/resources/Routing_test.obf";
|
||||||
RandomAccessFile raf = new RandomAccessFile(fl, "r");
|
RandomAccessFile raf = new RandomAccessFile(fl, "r");
|
||||||
RoutePlannerFrontEnd fe = new RoutePlannerFrontEnd();
|
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();
|
RoutingConfiguration.Builder builder = RoutingConfiguration.getDefault();
|
||||||
Map<String, String> params = te.getParams();
|
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 config = builder.build(params.containsKey("vehicle") ? params.get("vehicle") : "car",
|
||||||
RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3, params);
|
RoutingConfiguration.DEFAULT_MEMORY_LIMIT * 3, params);
|
||||||
RoutingContext ctx = fe.buildRoutingContext(config, null, binaryMapIndexReaders,
|
RoutingContext ctx = fe.buildRoutingContext(config, null, binaryMapIndexReaders,
|
||||||
|
@ -102,6 +113,4 @@ public class RouteTestingTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
android:screenOrientation="unspecified"
|
android:screenOrientation="unspecified"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
|
<activity android:name=".ui.TrackerLogcatActivity" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.MainActivity"
|
android:name=".ui.MainActivity"
|
||||||
android:configChanges="orientation|screenSize"
|
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>
|
</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"/>
|
<include layout="@layout/card_bottom_divider"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</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="location_sharing_status">مشاركة: %1$s</string>
|
||||||
<string name="shared_string_enabled">مفعل</string>
|
<string name="shared_string_enabled">مفعل</string>
|
||||||
<string name="duration_ago">%1$s منذ</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>
|
</resources>
|
|
@ -38,7 +38,7 @@
|
||||||
<string name="shared_string_password">كلمة المرور</string>
|
<string name="shared_string_password">كلمة المرور</string>
|
||||||
<string name="shared_string_continue">استمرار</string>
|
<string name="shared_string_continue">استمرار</string>
|
||||||
<string name="shared_string_cancel">إلغاء</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="shared_string_distance">المسافة</string>
|
||||||
<string name="yard">ياردة</string>
|
<string name="yard">ياردة</string>
|
||||||
<string name="foot">قدم</string>
|
<string name="foot">قدم</string>
|
||||||
|
@ -267,4 +267,8 @@
|
||||||
<string name="status_widget_title">تتبع حالة أوسماند</string>
|
<string name="status_widget_title">تتبع حالة أوسماند</string>
|
||||||
<string name="back_to_osmand">العودة إلى OsmAnd</string>
|
<string name="back_to_osmand">العودة إلى OsmAnd</string>
|
||||||
<string name="duration_ago">%1$s منذ</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>
|
</resources>
|
|
@ -267,4 +267,8 @@
|
||||||
<string name="last_response_duration">Апошні адказ: %1$s таму</string>
|
<string name="last_response_duration">Апошні адказ: %1$s таму</string>
|
||||||
<string name="duration_ago">%1$s таму</string>
|
<string name="duration_ago">%1$s таму</string>
|
||||||
<string name="shared_string_error_short">ERR</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>
|
</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="send_my_location">Envia la meva ubicació</string>
|
||||||
<string name="gps_and_location">Ubicació</string>
|
<string name="gps_and_location">Ubicació</string>
|
||||||
<string name="sharing_time">Temps de compartició</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="open_osmand">Obre l\'OsmAnd</string>
|
||||||
<string name="shared_string_live">En directe</string>
|
<string name="shared_string_live">En directe</string>
|
||||||
<string name="shared_string_bot">Bot</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="last_response_duration">Darrera resposta: fa %1$s</string>
|
||||||
<string name="duration_ago">fa %1$s</string>
|
<string name="duration_ago">fa %1$s</string>
|
||||||
<string name="shared_string_error_short">ERR</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>
|
</resources>
|
|
@ -72,4 +72,6 @@
|
||||||
<string name="shared_string_enabled">Povolen</string>
|
<string name="shared_string_enabled">Povolen</string>
|
||||||
<string name="unit_of_length">Jednotky vzdálenosti</string>
|
<string name="unit_of_length">Jednotky vzdálenosti</string>
|
||||||
<string name="shared_string_appearance">Vzhled</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>
|
</resources>
|
|
@ -269,4 +269,8 @@
|
||||||
<string name="last_response_duration">Sidste svar: %1$s siden</string>
|
<string name="last_response_duration">Sidste svar: %1$s siden</string>
|
||||||
<string name="duration_ago">%1$s siden</string>
|
<string name="duration_ago">%1$s siden</string>
|
||||||
<string name="shared_string_error_short">ERR</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>
|
</resources>
|
|
@ -267,4 +267,8 @@
|
||||||
<string name="last_response_duration">Letzte Antwort: vor %1$s</string>
|
<string name="last_response_duration">Letzte Antwort: vor %1$s</string>
|
||||||
<string name="duration_ago">vor %1$s</string>
|
<string name="duration_ago">vor %1$s</string>
|
||||||
<string name="shared_string_error_short">ERR</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>
|
</resources>
|
|
@ -268,4 +268,8 @@
|
||||||
<string name="last_response_duration">Última respuesta: Hace %1$s</string>
|
<string name="last_response_duration">Última respuesta: Hace %1$s</string>
|
||||||
<string name="duration_ago">Hace %1$s</string>
|
<string name="duration_ago">Hace %1$s</string>
|
||||||
<string name="shared_string_error_short">ERR</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>
|
</resources>
|
|
@ -250,7 +250,7 @@
|
||||||
<string name="set_time_timeline_descr">Elige la hora de visualización</string>
|
<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="start_end_date">Fecha de Inicio — Fin</string>
|
||||||
<string name="saved_messages">Mensajes guardados</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="time_zone">Zona horaria</string>
|
||||||
<string name="units_and_formats">Unidades y formatos</string>
|
<string name="units_and_formats">Unidades y formatos</string>
|
||||||
<string name="unit_of_length_descr">Cambia las unidades de longitud.</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="last_response_duration">Última respuesta: hace %1$s</string>
|
||||||
<string name="duration_ago">hace %1$s</string>
|
<string name="duration_ago">hace %1$s</string>
|
||||||
<string name="shared_string_error_short">ERR</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>
|
</resources>
|
|
@ -267,4 +267,8 @@
|
||||||
<string name="last_response_duration">Viimane vastus: %1$s tagasi</string>
|
<string name="last_response_duration">Viimane vastus: %1$s tagasi</string>
|
||||||
<string name="duration_ago">%1$s tagasi</string>
|
<string name="duration_ago">%1$s tagasi</string>
|
||||||
<string name="shared_string_error_short">ERR</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>
|
</resources>
|
|
@ -38,8 +38,8 @@
|
||||||
<string name="yard">yd</string>
|
<string name="yard">yd</string>
|
||||||
<string name="foot">ft</string>
|
<string name="foot">ft</string>
|
||||||
<string name="mile">mi</string>
|
<string name="mile">mi</string>
|
||||||
<string name="km">کم</string>
|
<string name="km">km</string>
|
||||||
<string name="m">متر</string>
|
<string name="m">m</string>
|
||||||
<string name="nm">nmi</string>
|
<string name="nm">nmi</string>
|
||||||
<string name="min_mile">min/m</string>
|
<string name="min_mile">min/m</string>
|
||||||
<string name="min_km">min/km</string>
|
<string name="min_km">min/km</string>
|
||||||
|
@ -73,4 +73,13 @@
|
||||||
<string name="unit_of_length_descr">یکاهای طول را تغییر دهید.</string>
|
<string name="unit_of_length_descr">یکاهای طول را تغییر دهید.</string>
|
||||||
<string name="unit_of_length">یکاهای طول</string>
|
<string name="unit_of_length">یکاهای طول</string>
|
||||||
<string name="shared_string_appearance">ظاهر</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>
|
</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="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="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="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>
|
</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="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">Tempo de caducidade do búfer</string>
|
||||||
<string name="buffer_time_descr">Tempo máximo para almacenar puntos no 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>
|
</resources>
|
|
@ -268,4 +268,8 @@
|
||||||
<string name="last_response_duration">תגובה אחרונה: לפני %1$s</string>
|
<string name="last_response_duration">תגובה אחרונה: לפני %1$s</string>
|
||||||
<string name="duration_ago">לפני %1$s</string>
|
<string name="duration_ago">לפני %1$s</string>
|
||||||
<string name="shared_string_error_short">שגיאה</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>
|
</resources>
|
|
@ -268,4 +268,8 @@
|
||||||
<string name="last_response_duration">Utolsó válasz: %1$s</string>
|
<string name="last_response_duration">Utolsó válasz: %1$s</string>
|
||||||
<string name="duration_ago">Ennyivel ezelőtt: %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_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>
|
</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_response_date">Ultima risposta: %1$s</string>
|
||||||
<string name="last_update_from_telegram_date">Ultimo aggiornamento da Telegram: %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="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>
|
</resources>
|
|
@ -219,8 +219,8 @@
|
||||||
<string name="shared_string_authorization_descr">国際形式でTelegramを利用する端末の電話番号を入力してください(日本の場合+81を先頭につけて電話番号最初の0を除いた番号を入力)</string>
|
<string name="shared_string_authorization_descr">国際形式でTelegramを利用する端末の電話番号を入力してください(日本の場合+81を先頭につけて電話番号最初の0を除いた番号を入力)</string>
|
||||||
<string name="shared_string_welcome">ようこそ</string>
|
<string name="shared_string_welcome">ようこそ</string>
|
||||||
<string name="yard">ヤード</string>
|
<string name="yard">ヤード</string>
|
||||||
<string name="foot">フィート</string>
|
<string name="foot">ft</string>
|
||||||
<string name="mile">マイル</string>
|
<string name="mile">mi</string>
|
||||||
<string name="km">km</string>
|
<string name="km">km</string>
|
||||||
<string name="m">m</string>
|
<string name="m">m</string>
|
||||||
<string name="nm">海里</string>
|
<string name="nm">海里</string>
|
||||||
|
|
|
@ -179,7 +179,7 @@
|
||||||
<string name="monitoring_is_enabled">Oppsyn er påskrudd</string>
|
<string name="monitoring_is_enabled">Oppsyn er påskrudd</string>
|
||||||
<string name="monitoring_is_disabled">Oppsyn er ikke aktivert</string>
|
<string name="monitoring_is_disabled">Oppsyn er ikke aktivert</string>
|
||||||
<string name="time_on_the_move">Tid i bevegelse</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="average_speed">Gjennomsnittsfart</string>
|
||||||
<string name="open_in_osmand">Vis i OsmAnd</string>
|
<string name="open_in_osmand">Vis i OsmAnd</string>
|
||||||
<string name="end_date">Sluttdato</string>
|
<string name="end_date">Sluttdato</string>
|
||||||
|
@ -267,4 +267,8 @@
|
||||||
<string name="last_response_duration">Siste respons: %1$s siden</string>
|
<string name="last_response_duration">Siste respons: %1$s siden</string>
|
||||||
<string name="duration_ago">%1$s siden</string>
|
<string name="duration_ago">%1$s siden</string>
|
||||||
<string name="shared_string_error_short">FEIL</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>
|
</resources>
|
|
@ -257,4 +257,8 @@
|
||||||
<string name="unit_of_length">Afstand eenheden</string>
|
<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_descr">Definieer de eenheid voor snelheid.</string>
|
||||||
<string name="unit_of_speed_system">Eenheid van 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>
|
</resources>
|
|
@ -267,4 +267,8 @@
|
||||||
<string name="shared_string_error_short">ERR</string>
|
<string name="shared_string_error_short">ERR</string>
|
||||||
<string name="last_response_date">Ostatnia odpowiedź: %1$s</string>
|
<string name="last_response_date">Ostatnia odpowiedź: %1$s</string>
|
||||||
<string name="last_response_duration">Ostatnia odpowiedź: %1$s temu</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>
|
</resources>
|
|
@ -267,4 +267,8 @@
|
||||||
<string name="last_response_duration">Última resposta: %1$s atrás</string>
|
<string name="last_response_duration">Última resposta: %1$s atrás</string>
|
||||||
<string name="duration_ago">%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_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>
|
</resources>
|
|
@ -267,4 +267,8 @@
|
||||||
<string name="last_response_date">Última resposta: %1$s</string>
|
<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="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_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>
|
</resources>
|
|
@ -108,7 +108,7 @@
|
||||||
<string name="not_found_yet">Ainda não encontrado</string>
|
<string name="not_found_yet">Ainda não encontrado</string>
|
||||||
<string name="re_send_location">Reenvie o local</string>
|
<string name="re_send_location">Reenvie o local</string>
|
||||||
<string name="last_available_location">Última localização disponível</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="location_sharing_status">Compartilhamento: %1$s</string>
|
||||||
<string name="shared_string_enabled">Ativado</string>
|
<string name="shared_string_enabled">Ativado</string>
|
||||||
<string name="no_gps_connection">Sem conexão GPS</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_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="get_telegram_after_creating_account">Então pode usar esta app.</string>
|
||||||
<string name="shared_string_all">Todos</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="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="do_not_have_telegram">Não tenho uma conta do Telegram</string>
|
||||||
<string name="enter_phone_number">Digite o número de telefone</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="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="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="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="osmand_service_descr">OsmAnd Tracker é executado em segundo plano com o ecrã desligado.</string>
|
||||||
<string name="shared_string_distance">Distância</string>
|
<string name="shared_string_distance">Distância</string>
|
||||||
<string name="share_location">Compartilhar localização</string>
|
<string name="share_location">Compartilhar localização</string>
|
||||||
|
@ -230,15 +230,15 @@
|
||||||
<string name="m_s">m/s</string>
|
<string name="m_s">m/s</string>
|
||||||
<string name="km_h">km/h</string>
|
<string name="km_h">km/h</string>
|
||||||
<string name="mile_per_hour">mph</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_mph">Milhas por hora</string>
|
||||||
<string name="si_m_s">Metros por segundo</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_min_m">Minutos por milha</string>
|
||||||
<string name="si_nm_h">Milhas náuticas por hora (nó)</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_feet">Milhas/pés</string>
|
||||||
<string name="si_mi_yard">Milhas/jardas</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_nm">Milhas náuticas</string>
|
||||||
<string name="si_mi_meters">Milhas/metros</string>
|
<string name="si_mi_meters">Milhas/metros</string>
|
||||||
<string name="shared_string_hour_short">h</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_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="time_zone">Fuso horário</string>
|
||||||
<string name="units_and_formats">Unidades e formatos</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_length">Unidades de comprimento</string>
|
||||||
<string name="unit_of_speed_system_descr">Definir unidade de velocidade.</string>
|
<string name="unit_of_speed_system_descr">Definir unidade de velocidade.</string>
|
||||||
<string name="unit_of_speed_system">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_response_date">Última resposta: %1$s</string>
|
||||||
<string name="last_update_from_telegram_date">Última atualização do Telegram: %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_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>
|
</resources>
|
|
@ -75,7 +75,7 @@
|
||||||
<string name="by_distance">По расстоянию</string>
|
<string name="by_distance">По расстоянию</string>
|
||||||
<string name="by_name">По имени</string>
|
<string name="by_name">По имени</string>
|
||||||
<string name="by_group">По группе</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="shared_string_sort_by">Сортировать по</string>
|
||||||
<string name="turn_off_all">Отстановить все</string>
|
<string name="turn_off_all">Отстановить все</string>
|
||||||
<string name="shared_string_exit">Выход</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_update_from_telegram_duration">Последнее обновление от Telegram: %1$s назад</string>
|
||||||
<string name="last_response_date">Последний ответ: %1$s</string>
|
<string name="last_response_date">Последний ответ: %1$s</string>
|
||||||
<string name="last_update_from_telegram_date">Последнее обновление от Telegram: %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>
|
</resources>
|
|
@ -268,4 +268,8 @@
|
||||||
<string name="last_response_duration">Ùrtima risposta: %1$s a como</string>
|
<string name="last_response_duration">Ùrtima risposta: %1$s a como</string>
|
||||||
<string name="duration_ago">%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_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>
|
</resources>
|
|
@ -267,4 +267,8 @@
|
||||||
<string name="last_response_date">Последњи одговор: %1$</string>
|
<string name="last_response_date">Последњи одговор: %1$</string>
|
||||||
<string name="last_update_from_telegram_date">Последње ажурирање из Телеграма: %1$</string>
|
<string name="last_update_from_telegram_date">Последње ажурирање из Телеграма: %1$</string>
|
||||||
<string name="shared_string_error_short">Грешка</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>
|
</resources>
|
|
@ -233,7 +233,7 @@
|
||||||
<string name="osmand_service_descr">OsmAnd Tracker, ekran kapalıyken arka planda çalışır.</string>
|
<string name="osmand_service_descr">OsmAnd Tracker, ekran kapalıyken arka planda çalışır.</string>
|
||||||
<string name="share_location">Konumu paylaş</string>
|
<string name="share_location">Konumu paylaş</string>
|
||||||
<string name="sharing_location">Konum paylaşılıyor</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="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_dialog_message">Önce OsmAnd\'ın ücretsiz veya ücretli sürümünü yüklemeniz gerekmektedir</string>
|
||||||
<string name="install_osmand">OsmAnd\'ı yükle</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="last_response_duration">Son cevap: %1$s önce</string>
|
||||||
<string name="duration_ago">%1$s önce</string>
|
<string name="duration_ago">%1$s önce</string>
|
||||||
<string name="shared_string_error_short">HATA</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>
|
</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="not_logged_in">Ви не увійшли до системи</string>
|
||||||
<string name="shared_string_continue">Продовжити</string>
|
<string name="shared_string_continue">Продовжити</string>
|
||||||
<string name="shared_string_cancel">Скасувати</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="no_location_permission">Застосунок не має дозволу до отримання даних позиціювання.</string>
|
||||||
<string name="gps_not_available">Будь ласка, увімкніть «Позиціювання» у системних налаштуваннях</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="osmand_service_descr">OsmAnd Tracker працює у фоновому режимі з вимкненим екраном.</string>
|
||||||
<string name="shared_string_distance">Відстань</string>
|
<string name="shared_string_distance">Відстань</string>
|
||||||
<string name="share_location">Поділитися позицією</string>
|
<string name="share_location">Поділитися позицією</string>
|
||||||
|
@ -267,4 +267,8 @@
|
||||||
<string name="last_response_duration">Остання відповідь: %1$s тому</string>
|
<string name="last_response_duration">Остання відповідь: %1$s тому</string>
|
||||||
<string name="duration_ago">%1$s тому</string>
|
<string name="duration_ago">%1$s тому</string>
|
||||||
<string name="shared_string_error_short">ПМЛК</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>
|
</resources>
|
|
@ -270,4 +270,8 @@
|
||||||
<string name="last_response_duration">最後回應:%1$s 前</string>
|
<string name="last_response_duration">最後回應:%1$s 前</string>
|
||||||
<string name="duration_ago">%1$s 前</string>
|
<string name="duration_ago">%1$s 前</string>
|
||||||
<string name="shared_string_error_short">ERR</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>
|
</resources>
|
|
@ -27,6 +27,7 @@
|
||||||
<dimen name="dialog_welcome_title_top_margin">89dp</dimen>
|
<dimen name="dialog_welcome_title_top_margin">89dp</dimen>
|
||||||
|
|
||||||
<dimen name="list_header_height">48dp</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_header_with_descr_height">42dp</dimen>
|
||||||
|
|
||||||
<dimen name="list_item_height">56dp</dimen>
|
<dimen name="list_item_height">56dp</dimen>
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<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="shared_string_error_short">ERR</string>
|
||||||
<string name="last_update_from_telegram_date">Last update from Telegram: %1$s</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>
|
<string name="last_response_date">Last response: %1$s</string>
|
||||||
|
|
|
@ -3,16 +3,20 @@ package net.osmand.telegram
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.NetworkInfo
|
import android.net.NetworkInfo
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
|
import net.osmand.PlatformUtil
|
||||||
|
import net.osmand.telegram.ui.TrackerLogcatActivity
|
||||||
import net.osmand.telegram.helpers.*
|
import net.osmand.telegram.helpers.*
|
||||||
import net.osmand.telegram.helpers.OsmandAidlHelper.OsmandHelperListener
|
import net.osmand.telegram.helpers.OsmandAidlHelper.OsmandHelperListener
|
||||||
import net.osmand.telegram.helpers.OsmandAidlHelper.UpdatesListener
|
import net.osmand.telegram.helpers.OsmandAidlHelper.UpdatesListener
|
||||||
import net.osmand.telegram.notifications.NotificationHelper
|
import net.osmand.telegram.notifications.NotificationHelper
|
||||||
import net.osmand.telegram.utils.AndroidUtils
|
import net.osmand.telegram.utils.AndroidUtils
|
||||||
import net.osmand.telegram.utils.UiUtils
|
import net.osmand.telegram.utils.UiUtils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
class TelegramApplication : Application() {
|
class TelegramApplication : Application() {
|
||||||
|
|
||||||
|
@ -200,4 +204,33 @@ class TelegramApplication : Application() {
|
||||||
fun runInUIThread(action: (() -> Unit), delay: Long) {
|
fun runInUIThread(action: (() -> Unit), delay: Long) {
|
||||||
uiHandler.postDelayed(action, delay)
|
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.helpers.TelegramHelper.*
|
||||||
import net.osmand.telegram.notifications.TelegramNotification.NotificationType
|
import net.osmand.telegram.notifications.TelegramNotification.NotificationType
|
||||||
import net.osmand.telegram.utils.AndroidUtils
|
import net.osmand.telegram.utils.AndroidUtils
|
||||||
import net.osmand.telegram.utils.OsmandLocationUtils
|
|
||||||
import org.drinkless.td.libcore.telegram.TdApi
|
import org.drinkless.td.libcore.telegram.TdApi
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
@ -377,7 +376,10 @@ class TelegramService : Service(), LocationListener, TelegramIncomingMessagesLis
|
||||||
Log.d(PlatformUtil.TAG, "Send live location error: $code - $message")
|
Log.d(PlatformUtil.TAG, "Send live location error: $code - $message")
|
||||||
when (messageType) {
|
when (messageType) {
|
||||||
TelegramHelper.MESSAGE_TYPE_TEXT -> shareInfo.pendingTdLibText--
|
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 PROXY_PREFERENCES_KEY = "proxy_preferences"
|
||||||
|
|
||||||
private const val SHARING_INITIALIZATION_TIME = 60 * 2L // 2 minutes
|
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
|
private const val GPS_UPDATE_EXPIRED_TIME = 60 * 3L // 3 minutes
|
||||||
|
|
||||||
|
@ -304,27 +304,18 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
|
|
||||||
fun prepareForSharingNewMessages() {
|
fun prepareForSharingNewMessages() {
|
||||||
shareChatsInfo.forEach { (_, shareInfo) ->
|
shareChatsInfo.forEach { (_, shareInfo) ->
|
||||||
prepareForSharingNewMessages(shareInfo)
|
shareInfo.resetMessagesInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun prepareForSharingNewMessages(chatsIds: List<Long>) {
|
fun prepareForSharingNewMessages(chatsIds: List<Long>) {
|
||||||
chatsIds.forEach {
|
chatsIds.forEach {
|
||||||
shareChatsInfo[it]?.also { shareInfo ->
|
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 getChatLivePeriod(chatId: Long) = shareChatsInfo[chatId]?.livePeriod
|
||||||
|
|
||||||
fun getChatsShareInfo() = shareChatsInfo
|
fun getChatsShareInfo() = shareChatsInfo
|
||||||
|
@ -540,14 +531,24 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
if (initTime && initSending) {
|
if (initTime && initSending) {
|
||||||
initializing = true
|
initializing = true
|
||||||
} else {
|
} else {
|
||||||
|
var waitingTimeError = false
|
||||||
val maxWaitingTime = WAITING_TDLIB_TIME * MAX_MESSAGES_IN_TDLIB_PER_CHAT * max(1, chatsCount)
|
val maxWaitingTime = WAITING_TDLIB_TIME * MAX_MESSAGES_IN_TDLIB_PER_CHAT * max(1, chatsCount)
|
||||||
val textSharingError = !shareInfo.lastTextMessageHandled && currentTime - shareInfo.lastSendTextMessageTime > maxWaitingTime
|
val textSharingWaitingTime = currentTime - shareInfo.lastSendTextMessageTime
|
||||||
val mapSharingError = !shareInfo.lastMapMessageHandled && currentTime - shareInfo.lastSendMapMessageTime > maxWaitingTime
|
val mapSharingWaitingTime = currentTime - shareInfo.lastSendMapMessageTime
|
||||||
if (shareInfo.hasSharingError
|
val textSharingError = !shareInfo.lastTextMessageHandled && textSharingWaitingTime > maxWaitingTime
|
||||||
|| (shareTypeValue == SHARE_TYPE_MAP_AND_TEXT && (textSharingError || mapSharingError))
|
val mapSharingError = !shareInfo.lastMapMessageHandled && mapSharingWaitingTime > maxWaitingTime
|
||||||
|| textSharingError && (shareTypeValue == SHARE_TYPE_TEXT)
|
if ((shareTypeValue == SHARE_TYPE_MAP_AND_TEXT && (textSharingError || mapSharingError))
|
||||||
|| mapSharingError && (shareTypeValue == SHARE_TYPE_MAP)
|
|| 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
|
sendChatsErrors = true
|
||||||
locationTime = max(shareInfo.lastTextSuccessfulSendTime, shareInfo.lastMapSuccessfulSendTime)
|
locationTime = max(shareInfo.lastTextSuccessfulSendTime, shareInfo.lastMapSuccessfulSendTime)
|
||||||
chatsIds.add(shareInfo.chatId)
|
chatsIds.add(shareInfo.chatId)
|
||||||
|
@ -1487,6 +1488,27 @@ class TelegramSettings(private val app: TelegramApplication) {
|
||||||
|
|
||||||
fun isPendingMapMessagesLimitReached() = pendingTdLibMap >= MAX_MESSAGES_IN_TDLIB_PER_CHAT
|
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 {
|
companion object {
|
||||||
|
|
||||||
internal const val CHAT_ID_KEY = "chatId"
|
internal const val CHAT_ID_KEY = "chatId"
|
||||||
|
|
|
@ -138,7 +138,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pendingMessagesLimitReached && checkNetworkTypeAllowed) {
|
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 {
|
app.locationMessages.getBufferedTextMessagesForChat(chatId).take(MAX_MESSAGES_IN_TDLIB_PER_CHAT).forEach {
|
||||||
if (!shareInfo.isPendingTextMessagesLimitReached()) {
|
if (!shareInfo.isPendingTextMessagesLimitReached()) {
|
||||||
if (it.deviceName.isEmpty()) {
|
if (it.deviceName.isEmpty()) {
|
||||||
if (!shareInfo.pendingTextMessage && shareInfo.currentTextMessageId != -1L) {
|
if (!shareInfo.pendingTextMessage && shareInfo.isTextMessageIdPresent()) {
|
||||||
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, it, app)
|
val content = OsmandLocationUtils.getTextMessageContent(shareInfo.updateTextMessageId, it, app)
|
||||||
app.telegramHelper.editTextLocation(shareInfo, content)
|
app.telegramHelper.editTextLocation(shareInfo, content)
|
||||||
app.locationMessages.removeBufferedMessage(it)
|
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 {
|
app.locationMessages.getBufferedMapMessagesForChat(chatId).take(MAX_MESSAGES_IN_TDLIB_PER_CHAT).forEach {
|
||||||
if (!shareInfo.isPendingMapMessagesLimitReached()) {
|
if (!shareInfo.isPendingMapMessagesLimitReached()) {
|
||||||
if (it.deviceName.isEmpty()) {
|
if (it.deviceName.isEmpty()) {
|
||||||
if (!shareInfo.pendingMapMessage && shareInfo.currentMapMessageId != -1L) {
|
if (!shareInfo.pendingMapMessage) {
|
||||||
app.telegramHelper.editMapLocation(shareInfo, it)
|
if (shareInfo.isMapMessageIdPresent()) {
|
||||||
|
app.telegramHelper.editMapLocation(shareInfo, it)
|
||||||
|
} else {
|
||||||
|
app.telegramHelper.sendNewMapLocation(shareInfo, it)
|
||||||
|
}
|
||||||
app.locationMessages.removeBufferedMessage(it)
|
app.locationMessages.removeBufferedMessage(it)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -279,7 +283,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pendingMessagesLimitReached) {
|
if (pendingMessagesLimitReached) {
|
||||||
checkNetworkType()
|
updateNetworkType()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +351,7 @@ class ShareLocationHelper(private val app: TelegramApplication) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkNetworkType(){
|
fun updateNetworkType(){
|
||||||
if (app.isInternetConnectionAvailable) {
|
if (app.isInternetConnectionAvailable) {
|
||||||
val networkType = when {
|
val networkType = when {
|
||||||
app.isWifiConnected -> TdApi.NetworkTypeWiFi()
|
app.isWifiConnected -> TdApi.NetworkTypeWiFi()
|
||||||
|
|
|
@ -776,6 +776,7 @@ class TelegramHelper private constructor() {
|
||||||
client?.send(TdApi.CreatePrivateChat(userId, false)) { obj ->
|
client?.send(TdApi.CreatePrivateChat(userId, false)) { obj ->
|
||||||
when (obj.constructor) {
|
when (obj.constructor) {
|
||||||
TdApi.Error.CONSTRUCTOR -> {
|
TdApi.Error.CONSTRUCTOR -> {
|
||||||
|
log.debug("createPrivateChatWithUser ERROR $obj")
|
||||||
val error = obj as TdApi.Error
|
val error = obj as TdApi.Error
|
||||||
if (error.code != IGNORED_ERROR_CODE) {
|
if (error.code != IGNORED_ERROR_CODE) {
|
||||||
shareInfo.hasSharingError = true
|
shareInfo.hasSharingError = true
|
||||||
|
@ -839,7 +840,7 @@ class TelegramHelper private constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopSendingLiveLocationToChat(shareInfo: ShareChatInfo) {
|
fun stopSendingLiveLocationToChat(shareInfo: ShareChatInfo) {
|
||||||
if (shareInfo.currentMapMessageId != -1L && shareInfo.chatId != -1L) {
|
if (!shareInfo.isMapMessageIdPresent() && shareInfo.chatId != -1L) {
|
||||||
shareInfo.lastSendMapMessageTime = (System.currentTimeMillis() / 1000).toInt()
|
shareInfo.lastSendMapMessageTime = (System.currentTimeMillis() / 1000).toInt()
|
||||||
client?.send(
|
client?.send(
|
||||||
TdApi.EditMessageLiveLocation(shareInfo.chatId, shareInfo.currentMapMessageId, null, null)) { obj ->
|
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
|
val messageType = if (isBot) MESSAGE_TYPE_BOT else MESSAGE_TYPE_TEXT
|
||||||
when (obj.constructor) {
|
when (obj.constructor) {
|
||||||
TdApi.Error.CONSTRUCTOR -> {
|
TdApi.Error.CONSTRUCTOR -> {
|
||||||
log.debug("handleTextLocationMessageUpdate - ERROR")
|
log.debug("handleTextLocationMessageUpdate - ERROR $obj")
|
||||||
val error = obj as TdApi.Error
|
val error = obj as TdApi.Error
|
||||||
if (error.code != IGNORED_ERROR_CODE) {
|
if (error.code != IGNORED_ERROR_CODE) {
|
||||||
shareInfo.hasSharingError = true
|
shareInfo.hasSharingError = true
|
||||||
|
|
|
@ -15,7 +15,6 @@ import android.widget.TextView
|
||||||
import androidx.appcompat.widget.ListPopupWindow
|
import androidx.appcompat.widget.ListPopupWindow
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import net.osmand.Location
|
import net.osmand.Location
|
||||||
import net.osmand.data.LatLon
|
import net.osmand.data.LatLon
|
||||||
import net.osmand.telegram.R
|
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 {
|
mainView.findViewById<androidx.swiperefreshlayout.widget.SwipeRefreshLayout>(R.id.swipe_refresh).apply {
|
||||||
setOnRefreshListener {
|
setOnRefreshListener {
|
||||||
app.shareLocationHelper.checkNetworkType()
|
app.shareLocationHelper.updateNetworkType()
|
||||||
app.telegramHelper.scanChatsHistory()
|
app.telegramHelper.scanChatsHistory()
|
||||||
updateList()
|
updateList()
|
||||||
isRefreshing = false
|
isRefreshing = false
|
||||||
|
|
|
@ -213,6 +213,12 @@ class SettingsDialogFragment : BaseDialogFragment() {
|
||||||
DisconnectTelegramBottomSheet.showInstance(childFragmentManager)
|
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
|
return mainView
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ class SharingStatusBottomSheet : DialogFragment() {
|
||||||
if (sharingStatusType.canResendLocation) {
|
if (sharingStatusType.canResendLocation) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
setOnClickListener {
|
setOnClickListener {
|
||||||
app.shareLocationHelper.checkNetworkType()
|
app.shareLocationHelper.updateNetworkType()
|
||||||
app.settings.prepareForSharingNewMessages(sharingStatus.chatsIds)
|
app.settings.prepareForSharingNewMessages(sharingStatus.chatsIds)
|
||||||
app.shareLocationHelper.checkAndSendBufferMessages()
|
app.shareLocationHelper.checkAndSendBufferMessages()
|
||||||
app.forceUpdateMyLocation()
|
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/commons-codec-commons-codec-1.11.jar
|
||||||
libs/OsmAndCore_android-0.1-SNAPSHOT.jar
|
libs/OsmAndCore_android-0.1-SNAPSHOT.jar
|
||||||
|
|
||||||
|
# Huawei
|
||||||
libs/huawei-*.jar
|
libs/huawei-*.jar
|
||||||
huaweidrmlib/
|
huaweidrmlib/
|
||||||
HwDRM_SDK_*
|
HwDRM_SDK_*
|
||||||
drm_strings.xml
|
drm_strings.xml
|
||||||
|
agconnect-services.json
|
||||||
|
OsmAndHms.jks
|
||||||
|
|
||||||
# copy_widget_icons.sh
|
# copy_widget_icons.sh
|
||||||
res/drawable-large/map_*
|
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"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<application>
|
<application
|
||||||
<activity android:name="com.huawei.android.sdk.drm.DrmDialogActivity"
|
android:icon="@mipmap/icon_free"
|
||||||
android:configChanges="screenSize|orientation|keyboardHidden"
|
android:label="@string/app_name_free"
|
||||||
android:exported="false"
|
tools:replace="android:icon, android:label">
|
||||||
android:theme="@android:style/Theme.Translucent">
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="hwc-theme"
|
android:name="com.huawei.hms.client.appid"
|
||||||
android:value="androidhwext:style/Theme.Emui.Translucent" />
|
android:value="101486545" />
|
||||||
</activity>
|
<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
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="net.osmand.huawei.fileprovider"
|
tools:replace="android:authorities"
|
||||||
tools:replace="android:authorities" />
|
android:authorities="net.osmand.huawei.fileprovider"/>
|
||||||
<service
|
|
||||||
android:name="net.osmand.plus.NavigationService"
|
|
||||||
android:process="net.osmand.huawei"
|
|
||||||
tools:replace="android:process" />
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</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_COARSE_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_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.ACCESS_LOCATION_EXTRA_COMMANDS" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.STORAGE" />
|
<uses-permission android:name="android.permission.STORAGE" />
|
||||||
|
@ -52,8 +52,9 @@
|
||||||
<application android:allowBackup="true" android:backupAgent="net.osmand.plus.OsmandBackupAgent"
|
<application android:allowBackup="true" android:backupAgent="net.osmand.plus.OsmandBackupAgent"
|
||||||
android:icon="@mipmap/icon" android:label="@string/app_name"
|
android:icon="@mipmap/icon" android:label="@string/app_name"
|
||||||
android:name="net.osmand.plus.OsmandApplication" android:configChanges="locale"
|
android:name="net.osmand.plus.OsmandApplication" android:configChanges="locale"
|
||||||
android:theme="@style/OsmandDarkTheme" android:restoreAnyVersion="true" android:largeHeap="true"
|
android:theme="@style/OsmandDarkTheme" android:restoreAnyVersion="true" android:largeHeap="true"
|
||||||
android:supportsRtl="true" android:usesCleartextTraffic="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.google.android.backup.api_key" android:value="AEdPqrEAAAAIqF3tNGT66etVBn_vgzpfAY1wmIzKV1Ss6Ku-2A" />
|
||||||
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
|
<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="" />
|
<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.HelpActivity" />
|
||||||
<activity android:name="net.osmand.plus.activities.ExitActivity" />
|
<activity android:name="net.osmand.plus.activities.ExitActivity" />
|
||||||
|
<activity android:name="net.osmand.plus.openplacereviews.OPRWebviewActivity" android:theme="@style/Theme.AppCompat.NoActionBar" />
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
android:authorities="net.osmand.plus.fileprovider"
|
android:authorities="net.osmand.plus.fileprovider"
|
||||||
|
@ -246,6 +248,7 @@
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<data android:scheme="content"/>
|
||||||
<data android:scheme="file"/>
|
<data android:scheme="file"/>
|
||||||
<data android:host="*"/>
|
<data android:host="*"/>
|
||||||
<data android:pathPattern=".*\\.obf" />
|
<data android:pathPattern=".*\\.obf" />
|
||||||
|
@ -261,6 +264,7 @@
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
<data android:scheme="content"/>
|
||||||
<data android:scheme="file"/>
|
<data android:scheme="file"/>
|
||||||
<data android:host="*"/>
|
<data android:host="*"/>
|
||||||
<data android:mimeType="*/*"/>
|
<data android:mimeType="*/*"/>
|
||||||
|
@ -371,6 +375,72 @@
|
||||||
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.xml" />
|
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.xml" />
|
||||||
</intent-filter>
|
</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-->
|
<!--trying to handle emails-->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
@ -399,6 +469,13 @@
|
||||||
<data android:mimeType="text/plain" />
|
<data android:mimeType="text/plain" />
|
||||||
</intent-filter>
|
</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>
|
</activity>
|
||||||
|
|
||||||
<receiver android:name="net.osmand.plus.audionotes.MediaRemoteControlReceiver">
|
<receiver android:name="net.osmand.plus.audionotes.MediaRemoteControlReceiver">
|
||||||
|
@ -408,22 +485,10 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</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.search.SearchActivity" android:label="@string/search_activity" />
|
||||||
<activity android:name="net.osmand.plus.activities.FavoritesListActivity" android:label="@string/favourites_list_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=".myplaces.FavoritesActivity" android:windowSoftInputMode="adjustPan" />
|
||||||
<activity android:name="net.osmand.plus.activities.TrackActivity"/>
|
<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" />
|
<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.wap.qq.com" />
|
||||||
<data android:host="map.qq.com" />
|
<data android:host="map.qq.com" />
|
||||||
<data android:host="maps.apple.com" />
|
<data android:host="maps.apple.com" />
|
||||||
<data android:host="ge0.me" />
|
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
</intent-filter>
|
</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>
|
<intent-filter>
|
||||||
<data android:scheme="http" android:host="openstreetmap.de" android:pathPrefix="/karte" />
|
<data android:scheme="http" android:host="openstreetmap.de" android:pathPrefix="/karte" />
|
||||||
<data android:scheme="https" 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 !! -->
|
<!-- keep android:process on a separate line !! -->
|
||||||
<service
|
<service
|
||||||
android:process="net.osmand.plus"
|
android:process="net.osmand.plus"
|
||||||
android:label="@string/process_navigation_service"
|
android:label="@string/process_navigation_service"
|
||||||
android:name="net.osmand.plus.NavigationService"
|
android:name="net.osmand.plus.NavigationService"
|
||||||
android:foregroundServiceType="location"
|
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/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/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/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/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/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" />
|
<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