Merge branch 'master' into Redesign-voice

This commit is contained in:
Vitaliy 2021-04-20 19:12:31 +03:00
commit daf31151f6
118 changed files with 7568 additions and 2265 deletions

View file

@ -16,13 +16,11 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.zip.GZIPInputStream;
@ -183,7 +181,9 @@ public abstract class MapObject implements Comparable<MapObject> {
public String getName(String lang, boolean transliterate) {
if (lang != null && lang.length() > 0) {
if (lang.equals("en")) {
return getEnName(transliterate);
// for some objects like wikipedia, english name is stored 'name' tag
String enName = getEnName(transliterate);
return !Algorithms.isEmpty(enName) ? enName : getName();
} else {
// get name
if (names != null) {

View file

@ -5,8 +5,11 @@ import net.osmand.data.QuadRect;
import net.osmand.util.Algorithms;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class WorldRegion implements Serializable {
@ -212,4 +215,22 @@ public class WorldRegion implements Serializable {
}
return false;
}
public static List<WorldRegion> removeDuplicates(List<WorldRegion> regions) {
List<WorldRegion> copy = new ArrayList<>(regions);
Set<WorldRegion> duplicates = new HashSet<>();
for (int i = 0; i < copy.size() - 1; i++) {
WorldRegion r1 = copy.get(i);
for (int j = i + 1; j < copy.size(); j++) {
WorldRegion r2 = copy.get(j);
if (r1.containsRegion(r2)) {
duplicates.add(r2);
} else if (r2.containsRegion(r1)) {
duplicates.add(r1);
}
}
}
copy.removeAll(duplicates);
return copy;
}
}

View file

@ -55,7 +55,9 @@ public class SearchResult {
public double getSumPhraseMatchWeight() {
// if result is a complete match in the search we prioritize it higher
boolean match = requiredSearchPhrase.countWords(localeName) <= getSelfWordCount();
int localWordsMatched = alternateName != null ?
requiredSearchPhrase.countWords(alternateName) : requiredSearchPhrase.countWords(localeName) ;
boolean match = localWordsMatched <= getSelfWordCount();
double res = ObjectType.getTypeWeight(match ? objectType : null);
if (parentSearchResult != null) {
res = res + parentSearchResult.getSumPhraseMatchWeight() / MAX_TYPE_WEIGHT;

View file

@ -80,9 +80,9 @@ public class SearchUICoreTest {
if (files != null) {
for (File file : files) {
String fileName = file.getName();
if(fileName.endsWith(".json")) {
if (fileName.endsWith(".json")) {
String name = fileName.substring(0, fileName.length() - ".json".length());
arrayList.add(new Object[] {name, file});
arrayList.add(new Object[] { name, file });
}
}
}
@ -191,10 +191,10 @@ public class SearchUICoreTest {
if (!Algorithms.stringsEqual(expected, present)) {
System.out.println(String.format("Phrase: %s", phrase));
System.out.println(String.format("Mismatch for '%s' != '%s'. Result: ", expected, present));
}
for (SearchResult r : searchResults) {
System.out.println(String.format("\t\"%s\",", formatResult(false, r, phrase)));
}
}
Assert.assertEquals(expected, present);
}
}

View file

@ -119,4 +119,28 @@
<string name="connecting_to_the_internet">Konektante al Interreto</string>
<string name="initializing">Komencante</string>
<string name="sending_location_messages">Sendante lokon</string>
<string name="password_descr">Pasvorto de Telegram</string>
<string name="enter_password">Tajpu pasvorton</string>
<string name="show_on_map">Montri sur mapo</string>
<string name="hours_format">%1$d h</string>
<string name="minutes_format">%1$d min</string>
<string name="hours_and_minutes_format">%1$d h %2$d min</string>
<string name="shared_string_sent">Sendita</string>
<string name="not_logged_in">Vi ne estas salutinta</string>
<string name="closing">Fermante</string>
<string name="logging_out">Adiaŭante</string>
<string name="initialization">Lanĉante</string>
<string name="shared_string_logout">Adiaŭi</string>
<string name="shared_string_login">Saluti</string>
<string name="osmand_service">Fona reĝimo</string>
<string name="shared_string_off">Malaktiva</string>
<string name="shared_string_all">Ĉiuj</string>
<string name="shared_string_close">Fermi</string>
<string name="shared_string_exit">Eliri</string>
<string name="shared_string_save">Konservi</string>
<string name="shared_string_disable">Malaktivigi</string>
<string name="shared_string_apply">Apliki</string>
<string name="unit_of_length_descr">Ŝanĝi unuojn por reprezenti distancoj.</string>
<string name="logcat_buffer">Bufro logcat</string>
<string name="logcat_buffer_descr">Legi kaj kunhavigi detalajn protokolojn de la aplikaĵo</string>
</resources>

View file

@ -22,7 +22,7 @@
<string name="proxy_port">ポート</string>
<string name="proxy_server">サーバー</string>
<string name="shared_string_connection">接続</string>
<string name="shared_string_enable">有効</string>
<string name="shared_string_enable">有効</string>
<string name="proxy_type">プロキシタイプ</string>
<string name="proxy_connected">接続しました</string>
<string name="proxy_disconnected">切断しました</string>

View file

@ -16,20 +16,34 @@
android:focusable="true"
android:orientation="vertical"
android:clickable="true"
tools:background="@drawable/bg_bottom_menu_dark">
tools:ignore="UselessParent">
<ProgressBar
android:id="@+id/snap_to_road_progress_bar"
style="?android:attr/progressBarStyleHorizontal"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:visibility="gone"
tools:visibility="visible" />
android:layout_height="wrap_content">
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/bg_contextmenu_shadow_top_light" />
<ProgressBar
android:id="@+id/snap_to_road_progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:background="?attr/list_background_color"
android:visibility="invisible"
tools:visibility="visible" />
</FrameLayout>
<LinearLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="?attr/list_background_color">
<RelativeLayout
android:id="@+id/up_down_row"
@ -53,6 +67,19 @@
android:background="@null"
tools:src="@drawable/ic_action_ruler"/>
<include
layout="@layout/custom_icon_radio_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/content_padding_half"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/content_padding_half"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:background="@null" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/up_down_button"
android:layout_width="wrap_content"
@ -65,6 +92,7 @@
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:background="@null"
android:visibility="gone"
tools:src="@drawable/ic_action_arrow_down"/>
<TextView

View file

@ -659,6 +659,7 @@
<!-- CENTER -->
<FrameLayout
android:id="@+id/top_controls_container"
android:layout_width="fill_parent"
android:layout_height="wrap_content">

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/custom_radio_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/btn_bg_border_inactive"
android:baselineAligned="false"
android:minHeight="@dimen/dialog_button_height"
android:orientation="horizontal">
<include
layout="@layout/custom_radio_btn_icon_item"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<include
layout="@layout/custom_radio_btn_icon_item"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:background="?attr/selectableItemBackground"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="@dimen/content_padding_small_half"
android:paddingBottom="@dimen/content_padding_small_half"
android:paddingLeft="@dimen/content_padding_small"
android:paddingRight="@dimen/content_padding_small">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:layout_gravity="center"
tools:src="@drawable/ic_action_info_dark"/>
</FrameLayout>

View file

@ -13,293 +13,314 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/bg_bottom_menu_dark"
android:orientation="vertical"
android:clickable="true"
android:focusable="true">
<ProgressBar
android:id="@+id/snap_to_road_progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:visibility="gone"
tools:visibility="visible" />
<RelativeLayout
android:id="@+id/up_down_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_up_down_row_height"
android:background="?attr/selectableItemBackground">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/main_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_text_button_padding"
android:layout_marginLeft="@dimen/measurement_tool_text_button_padding"
android:layout_marginRight="@dimen/measurement_tool_text_button_padding"
android:layout_marginStart="@dimen/measurement_tool_text_button_padding"
android:background="@null"
tools:src="@drawable/ic_action_ruler"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/up_down_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:background="@null"
tools:src="@drawable/ic_action_arrow_down"/>
<TextView
android:id="@+id/measurement_distance_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/measurement_tool_button_padding"
android:layout_marginEnd="@dimen/text_margin_small"
android:layout_marginLeft="@dimen/measurement_tool_text_button_padding"
android:layout_marginRight="@dimen/text_margin_small"
android:layout_marginStart="@dimen/measurement_tool_text_button_padding"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:textAppearance="@style/TextAppearance.ListItemCategoryTitle"
tools:text="724 m,"/>
<TextView
android:id="@+id/measurement_points_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/measurement_tool_button_padding"
android:layout_toEndOf="@id/measurement_distance_text_view"
android:layout_toRightOf="@id/measurement_distance_text_view"
android:layout_alignEnd="@id/up_down_button"
android:layout_alignRight="@id/up_down_button"
android:textAppearance="@style/TextAppearance.ListItemCategoryTitle"
tools:text="points: 3" />
<TextView
android:id="@+id/distance_to_center_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/measurement_points_text_view"
android:layout_alignStart="@+id/measurement_distance_text_view"
android:layout_alignLeft="@+id/measurement_distance_text_view"
android:maxLines="1"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text=" 700 m" />
<TextView
android:id="@+id/move_point_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/text_margin_small"
android:layout_marginLeft="@dimen/measurement_tool_text_margin"
android:layout_marginRight="@dimen/text_margin_small"
android:layout_marginStart="@dimen/measurement_tool_text_margin"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:text="@string/move_point"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
<TextView
android:id="@+id/add_point_before_after_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/text_margin_small"
android:layout_marginLeft="@dimen/measurement_tool_text_margin"
android:layout_marginRight="@dimen/text_margin_small"
android:layout_marginStart="@dimen/measurement_tool_text_margin"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"
tools:text="@string/add_point_after"/>
</RelativeLayout>
android:focusable="true"
tools:ignore="UselessParent">
<FrameLayout
android:id="@+id/info_type_buttons_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
layout="@layout/custom_radio_buttons"
<View
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_button_height"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginBottom="@dimen/measurement_tool_content_padding_medium" />
android:layout_height="0dp"
android:background="@drawable/bg_contextmenu_shadow_top_light" />
<ProgressBar
android:id="@+id/snap_to_road_progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:background="?attr/list_background_color"
android:visibility="invisible"
tools:visibility="visible" />
</FrameLayout>
<FrameLayout
android:id="@+id/cards_container"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_info_cards_container_height"
android:visibility="gone" />
<View
android:id="@+id/bottom_panel_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider" />
<LinearLayout
android:id="@+id/measure_mode_controls"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_controls_height"
android:paddingTop="@dimen/measurement_tool_button_margin"
android:paddingBottom="@dimen/measurement_tool_button_margin"
android:paddingLeft="@dimen/measurement_tool_button_margin"
android:paddingRight="@dimen/measurement_tool_button_margin"
android:paddingStart="@dimen/measurement_tool_button_margin"
android:paddingEnd="@dimen/measurement_tool_button_margin">
android:layout_height="wrap_content"
android:background="?attr/list_background_color"
android:orientation="vertical">
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<RelativeLayout
android:id="@+id/up_down_row"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_up_down_row_height"
android:background="?attr/selectableItemBackground">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/options_button"
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/main_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:gravity="center_vertical"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_text_button_padding"
android:layout_marginLeft="@dimen/measurement_tool_text_button_padding"
android:layout_marginRight="@dimen/measurement_tool_text_button_padding"
android:layout_marginStart="@dimen/measurement_tool_text_button_padding"
android:background="@null"
tools:src="@drawable/ic_action_ruler"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/up_down_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/bottom_sheet_content_margin"
android:layout_marginLeft="@dimen/bottom_sheet_content_margin"
android:layout_marginRight="@dimen/bottom_sheet_content_margin"
android:layout_marginStart="@dimen/bottom_sheet_content_margin"
android:background="@null"
tools:src="@drawable/ic_action_arrow_down"/>
<TextView
android:id="@+id/measurement_distance_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/measurement_tool_button_padding"
android:layout_marginEnd="@dimen/text_margin_small"
android:layout_marginLeft="@dimen/measurement_tool_text_button_padding"
android:layout_marginRight="@dimen/text_margin_small"
android:layout_marginStart="@dimen/measurement_tool_text_button_padding"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:textAppearance="@style/TextAppearance.ListItemCategoryTitle"
tools:text="724 m,"/>
<TextView
android:id="@+id/measurement_points_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/measurement_tool_button_padding"
android:layout_toEndOf="@id/measurement_distance_text_view"
android:layout_toRightOf="@id/measurement_distance_text_view"
android:layout_alignEnd="@id/up_down_button"
android:layout_alignRight="@id/up_down_button"
android:textAppearance="@style/TextAppearance.ListItemCategoryTitle"
tools:text="points: 3" />
<TextView
android:id="@+id/distance_to_center_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/measurement_points_text_view"
android:layout_alignStart="@+id/measurement_distance_text_view"
android:layout_alignLeft="@+id/measurement_distance_text_view"
android:maxLines="1"
android:paddingStart="@dimen/measurement_tool_text_button_padding_small"
android:paddingLeft="@dimen/measurement_tool_text_button_padding_small"
android:paddingEnd="@dimen/measurement_tool_text_button_padding_small"
android:paddingRight="@dimen/measurement_tool_text_button_padding_small"
android:text="@string/shared_string_options"
android:textColor="?attr/color_dialog_buttons"
osmand:typeface="@string/font_roboto_medium"/>
</FrameLayout>
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
tools:text=" 700 m" />
<ImageButton
android:id="@+id/undo_point_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/measurement_tool_undo_redo_padding_small"
android:contentDescription="@string/shared_string_undo"
tools:src="@drawable/ic_action_undo_dark"/>
<TextView
android:id="@+id/move_point_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/text_margin_small"
android:layout_marginLeft="@dimen/measurement_tool_text_margin"
android:layout_marginRight="@dimen/text_margin_small"
android:layout_marginStart="@dimen/measurement_tool_text_margin"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:text="@string/move_point"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"/>
<ImageButton
android:id="@+id/redo_point_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/measurement_tool_button_padding"
android:layout_marginStart="@dimen/measurement_tool_button_padding"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/measurement_tool_undo_redo_padding_small"
android:contentDescription="@string/shared_string_redo"
tools:src="@drawable/ic_action_redo_dark"/>
<TextView
android:id="@+id/add_point_before_after_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/text_margin_small"
android:layout_marginLeft="@dimen/measurement_tool_text_margin"
android:layout_marginRight="@dimen/text_margin_small"
android:layout_marginStart="@dimen/measurement_tool_text_margin"
android:layout_toEndOf="@id/main_icon"
android:layout_toRightOf="@id/main_icon"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:visibility="gone"
tools:text="@string/add_point_after"/>
</RelativeLayout>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
android:id="@+id/info_type_buttons_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/add_point_button"
layout="@layout/bottom_sheet_dialog_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:minWidth="@dimen/measurement_tool_button_width" />
layout="@layout/custom_radio_buttons"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_button_height"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginBottom="@dimen/measurement_tool_content_padding_medium" />
</FrameLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/move_point_controls"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_controls_height"
android:visibility="gone">
<include
android:id="@+id/apply_move_point_button"
layout="@layout/bottom_sheet_dialog_button"
android:layout_width="wrap_content"
android:layout_height="@dimen/measurement_tool_button_height"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_button_margin"
android:layout_marginRight="@dimen/measurement_tool_button_margin"
android:minWidth="@dimen/measurement_tool_button_width" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/cancel_move_point_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="@dimen/measurement_tool_button_margin"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:padding="@dimen/measurement_tool_text_button_padding_small"
android:text="@string/shared_string_cancel"
android:textColor="?attr/color_dialog_buttons"
osmand:typeface="@string/font_roboto_medium"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/add_point_before_after_controls"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_controls_height"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="gone">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/cancel_point_before_after_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="@dimen/measurement_tool_button_margin"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:padding="@dimen/measurement_tool_text_button_padding_small"
android:text="@string/shared_string_cancel"
android:textColor="?attr/color_dialog_buttons"
osmand:typeface="@string/font_roboto_medium"/>
<FrameLayout
android:id="@+id/cards_container"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_info_cards_container_height"
android:visibility="gone" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
android:id="@+id/bottom_panel_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider" />
<include
android:id="@+id/apply_point_before_after_point_button"
android:layout_height="@dimen/measurement_tool_button_height"
android:layout_gravity="center_vertical"
android:layout_width="@dimen/measurement_tool_button_width"
android:layout_marginEnd="@dimen/measurement_tool_button_margin"
android:layout_marginRight="@dimen/measurement_tool_button_margin"
layout="@layout/bottom_sheet_dialog_button" />
<LinearLayout
android:id="@+id/measure_mode_controls"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_controls_height"
android:paddingTop="@dimen/measurement_tool_button_margin"
android:paddingBottom="@dimen/measurement_tool_button_margin"
android:paddingLeft="@dimen/measurement_tool_button_margin"
android:paddingRight="@dimen/measurement_tool_button_margin"
android:paddingStart="@dimen/measurement_tool_button_margin"
android:paddingEnd="@dimen/measurement_tool_button_margin">
<include
android:id="@+id/add_point_before_after_button"
android:layout_height="@dimen/measurement_tool_button_height"
android:layout_gravity="center_vertical"
android:layout_width="@dimen/measurement_tool_button_width"
android:layout_marginEnd="@dimen/measurement_tool_button_margin"
android:layout_marginRight="@dimen/measurement_tool_button_margin"
layout="@layout/bottom_sheet_dialog_button" />
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/options_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:paddingStart="@dimen/measurement_tool_text_button_padding_small"
android:paddingLeft="@dimen/measurement_tool_text_button_padding_small"
android:paddingEnd="@dimen/measurement_tool_text_button_padding_small"
android:paddingRight="@dimen/measurement_tool_text_button_padding_small"
android:text="@string/shared_string_options"
android:textColor="?attr/color_dialog_buttons"
osmand:typeface="@string/font_roboto_medium"/>
</FrameLayout>
<ImageButton
android:id="@+id/undo_point_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/measurement_tool_undo_redo_padding_small"
android:contentDescription="@string/shared_string_undo"
tools:src="@drawable/ic_action_undo_dark"/>
<ImageButton
android:id="@+id/redo_point_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/measurement_tool_button_padding"
android:layout_marginStart="@dimen/measurement_tool_button_padding"
android:background="?attr/selectableItemBackground"
android:padding="@dimen/measurement_tool_undo_redo_padding_small"
android:contentDescription="@string/shared_string_redo"
tools:src="@drawable/ic_action_redo_dark"/>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<include
android:id="@+id/add_point_button"
layout="@layout/bottom_sheet_dialog_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
android:minWidth="@dimen/measurement_tool_button_width" />
</FrameLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/move_point_controls"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_controls_height"
android:visibility="gone">
<include
android:id="@+id/apply_move_point_button"
layout="@layout/bottom_sheet_dialog_button"
android:layout_width="wrap_content"
android:layout_height="@dimen/measurement_tool_button_height"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/measurement_tool_button_margin"
android:layout_marginRight="@dimen/measurement_tool_button_margin"
android:minWidth="@dimen/measurement_tool_button_width" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/cancel_move_point_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="@dimen/measurement_tool_button_margin"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:padding="@dimen/measurement_tool_text_button_padding_small"
android:text="@string/shared_string_cancel"
android:textColor="?attr/color_dialog_buttons"
osmand:typeface="@string/font_roboto_medium"/>
</RelativeLayout>
<LinearLayout
android:id="@+id/add_point_before_after_controls"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_controls_height"
android:gravity="center_vertical"
android:orientation="horizontal"
android:visibility="gone">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/cancel_point_before_after_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="@dimen/measurement_tool_button_margin"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:padding="@dimen/measurement_tool_text_button_padding_small"
android:text="@string/shared_string_cancel"
android:textColor="?attr/color_dialog_buttons"
osmand:typeface="@string/font_roboto_medium"/>
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"/>
<include
android:id="@+id/apply_point_before_after_point_button"
android:layout_height="@dimen/measurement_tool_button_height"
android:layout_gravity="center_vertical"
android:layout_width="@dimen/measurement_tool_button_width"
android:layout_marginEnd="@dimen/measurement_tool_button_margin"
android:layout_marginRight="@dimen/measurement_tool_button_margin"
layout="@layout/bottom_sheet_dialog_button" />
<include
android:id="@+id/add_point_before_after_button"
android:layout_height="@dimen/measurement_tool_button_height"
android:layout_gravity="center_vertical"
android:layout_width="@dimen/measurement_tool_button_width"
android:layout_marginEnd="@dimen/measurement_tool_button_margin"
android:layout_marginRight="@dimen/measurement_tool_button_margin"
layout="@layout/bottom_sheet_dialog_button" />
</LinearLayout>
</LinearLayout>

View file

@ -4,6 +4,9 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/list_background_color"
android:clickable="true"
android:focusable="true"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView

View file

@ -31,7 +31,7 @@
tools:text="Some title" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/description"
android:id="@+id/title_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/title"
@ -60,6 +60,54 @@
</RelativeLayout>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/primary_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dialog_content_margin"
android:letterSpacing="@dimen/description_letter_spacing"
android:orientation="vertical"
android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
android:visibility="gone"
app:typeface="@string/font_roboto_regular"
tools:text="@string/srtm_download_single_help_message"
tools:visibility="visible" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/secondary_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding_small"
android:letterSpacing="@dimen/description_letter_spacing"
android:orientation="vertical"
android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
android:visibility="gone"
app:typeface="@string/font_roboto_regular"
tools:text="@string/srtm_download_list_help_message"
tools:visibility="visible" />
<include
layout="@layout/custom_radio_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding_half"
android:visibility="gone"
tools:visibility="visible" />
<LinearLayout
android:id="@+id/select_all_button"
android:layout_width="match_parent"
@ -67,12 +115,12 @@
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:minHeight="@dimen/bottom_sheet_list_item_height"
android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingTop="@dimen/content_padding_small"
android:paddingEnd="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:paddingBottom="@dimen/content_padding_small"
android:paddingStart="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding">
android:paddingBottom="@dimen/content_padding_small">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/check_box_title"

View file

@ -64,7 +64,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_padding_small"
android:layout_gravity="center_vertical"
android:paddingStart="@dimen/content_padding_small"
android:paddingLeft="@dimen/content_padding_small"
android:paddingTop="@dimen/content_padding_small_half"

View file

@ -1,8 +1,6 @@
<?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"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
@ -13,78 +11,13 @@
android:layout_height="@dimen/list_content_padding"
android:background="?attr/activity_background_color" />
<include
layout="@layout/divider" />
<include layout="@layout/divider" />
<FrameLayout
android:id="@+id/subscriptions_list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:id="@+id/support_region_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="?android:attr/selectableItemBackground"
android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding">
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="@dimen/setting_list_item_group_height"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/map_widget_height"
android:layout_marginRight="@dimen/map_widget_height"
app:srcCompat="@drawable/ic_world_globe_dark"
app:tint="?attr/default_icon_color" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginTop="@dimen/content_padding_small"
android:layout_marginBottom="@dimen/content_padding_small"
android:layout_gravity="center_vertical"
android:orientation="vertical">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/support_region_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/default_list_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="@string/osm_live_support_region"/>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/support_region"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:text="@string/osm_live_support_region"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="@string/clear_updates_proposition_message"/>
</LinearLayout>
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
app:srcCompat="@drawable/ic_action_settings"
app:tint="?attr/default_icon_color" />
</LinearLayout>
<include layout="@layout/simple_divider_item" />
<LinearLayout
android:id="@+id/report_container"
android:layout_width="match_parent"
@ -206,8 +139,7 @@
android:layout_height="wrap_content"
android:background="?attr/activity_background_color">
<include
layout="@layout/card_bottom_divider" />
<include layout="@layout/card_bottom_divider" />
</FrameLayout>

View file

@ -32,7 +32,6 @@
android:id="@+id/troubleshooting_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/map_widget_height"
android:layout_marginRight="@dimen/map_widget_height"
android:paddingBottom="@dimen/dialog_content_bottom_margin"

File diff suppressed because it is too large Load diff

View file

@ -3926,4 +3926,6 @@
<string name="poi_karate">Karate</string>
<string name="poi_office_diplomatic">Diplomatische Vertretung</string>
<string name="poi_bay_filter">Art der Bucht</string>
<string name="poi_plateau">Plateau</string>
<string name="poi_club_social">Freizeitclub</string>
</resources>

View file

@ -3856,7 +3856,7 @@
\nSie können sich mit der sicheren OAuth-Methode anmelden oder Ihren Benutzernamen und Ihr Passwort verwenden.</string>
<string name="use_login_password">Benutzername und Passwort verwenden</string>
<string name="login_account">Konto</string>
<string name="user_login">Benutzername</string>
<string name="user_login">Anmelden</string>
<string name="markers_history">Historie der Marker</string>
<string name="send_files_to_openstreetmap">GPX-Datei an OpenStreetMap senden</string>
<string name="enter_text_separated">Geben Sie durch Komma getrennte Tags ein.</string>

View file

@ -3926,4 +3926,6 @@
<string name="poi_hoops">Korboj</string>
<string name="poi_bay_filter">Tipo de golfo</string>
<string name="poi_office_diplomatic">Diplomatia oficejo</string>
<string name="poi_plateau">Altebenaĵo</string>
<string name="poi_club_social">Socia klubejo</string>
</resources>

View file

@ -3926,4 +3926,6 @@
<string name="poi_hoops">Aros</string>
<string name="poi_office_diplomatic">Oficina diplomática</string>
<string name="poi_bay_filter">Tipo de bahía</string>
<string name="poi_plateau">Meseta (altiplano)</string>
<string name="poi_club_social">Club social</string>
</resources>

View file

@ -3924,4 +3924,5 @@
<string name="poi_hoops">Kosárlabdapalánkok</string>
<string name="poi_office_diplomatic">Diplomáciai iroda</string>
<string name="poi_bay_filter">Öböl típusa</string>
<string name="poi_plateau">Fennsík</string>
</resources>

View file

@ -3926,4 +3926,5 @@
<string name="poi_karate">Karate</string>
<string name="poi_office_diplomatic">Sendiskrifstofa</string>
<string name="poi_bay_filter">Gerð flóa</string>
<string name="poi_plateau">Háslétta</string>
</resources>

View file

@ -1173,7 +1173,7 @@ POIの更新は利用できません</string>
<string name="save_as_favorites_points">お気に入りのグループとして保存</string>
<string name="select_destination_and_intermediate_points">目的地の設定</string>
<string name="layer_amenity_label">施設の名称</string>
<string name="loading_smth">ロード中 %1$s </string>
<string name="loading_smth">%1$sをロード中…</string>
<string name="map_widget_plain_time">現在時刻</string>
<string name="shared_string_waypoint">経由地点</string>
<string name="selected_gpx_info_show">"
@ -1446,7 +1446,7 @@ POIの更新は利用できません</string>
<string name="routing_settings_2">ナビゲーション設定</string>
<string name="general_settings_2">全般設定</string>
<string name="shared_string_ellipsis"></string>
<string name="shared_string_enable">有効</string>
<string name="shared_string_enable">有効</string>
<string name="shared_string_disable">無効化</string>
<string name="shared_string_selected">選択済み</string>
<string name="shared_string_deselect">選択解除</string>
@ -2818,9 +2818,9 @@ POIの更新は利用できません</string>
<string name="osm_live_subscriptions">サブスクリプション</string>
<string name="powered_by_osmand">By OsmAnd</string>
<string name="osm_live_plan_pricing">プランと料金</string>
<string name="osm_live_payment_monthly_title"></string>
<string name="osm_live_payment_monthly_title"></string>
<string name="osm_live_payment_3_months_title">3ヶ月毎</string>
<string name="osm_live_payment_annual_title"></string>
<string name="osm_live_payment_annual_title"></string>
<string name="osm_live_payment_month_cost_descr">%1$s / 月</string>
<string name="osm_live_payment_month_cost_descr_ex">%1$.2f %2$s / 月</string>
<string name="osm_live_payment_discount_descr">%1$s割引</string>
@ -3172,7 +3172,7 @@ POIの更新は利用できません</string>
<string name="app_mode_utv">横並び(サイドバイサイド)形式</string>
<string name="rendering_attr_piste_difficulty_aerialway_name">索道(リフトやロープウェイなど)</string>
<string name="rendering_attr_piste_difficulty_connection_name">リフト間接続</string>
<string name="shared_string_calculate">計算</string>
<string name="shared_string_calculate">計算する</string>
<string name="shared_string_osmand_usage">OsmAndの合計使用容量</string>
<string name="shared_sting_tiles">タイル</string>
<string name="shared_string_maps">マップ</string>
@ -3703,9 +3703,9 @@ POIの更新は利用できません</string>
\n
\n国の法律に基づいて、使用を望むかどうかを決定する必要があります。
\n
\n%1$sを選択すると、スピードカメラに関するアラートと警告機能を使用できます。
\n%1$sを選択すると、スピードカメラに関するアラートと警告機能を使用できます。
\n
\n%2$sを選択すると、スピードカメラに関するすべてのデータ(警告、通知、POI)が、OsmAndの再インストールを行うまで削除されます。</string>
\n%2$sを選択すると、スピードカメラに関するすべてのデータ(警告、通知、POI)が、OsmAndの再インストールを行うまで削除されます。</string>
<string name="keep_active">機能を維持</string>
<string name="shared_string_uninstall">アンインストール</string>
<string name="speed_cameras_alert">一部の国では、スピードカメラの事前警告は法律で禁止されています。</string>
@ -4078,4 +4078,26 @@ POIの更新は利用できません</string>
<string name="app_mode_wheelchair_forward">基本前進のみの車椅子</string>
<string name="track_coloring_solid">通常色</string>
<string name="in_case_of_reverse_direction">逆方向の場合</string>
<string name="no_purchases">購入済みの品目はありません</string>
<string name="new_device_account">新しい端末 / 新規アカウント</string>
<string name="contact_support_description">ご不明な点がございましたら、%1$sまでお問い合わせください。</string>
<string name="empty_purchases_description">購入した品目がここに表示されない場合は、\"%1$s\"をタップするか、サポートチームにお問い合わせください。</string>
<string name="contact_support">サポート問い合わせ先</string>
<string name="troubleshooting">トラブルシューティング</string>
<string name="troubleshooting_description">購入に関して問題が発生した場合は、このリンクを参照してください。</string>
<string name="osmand_live">OsmAnd Live</string>
<string name="next_billing_date">次回請求日: %1$s</string>
<string name="osmand_live_cancelled">キャンセル済み</string>
<string name="in_grace_period">猶予期間中</string>
<string name="on_hold">保留中</string>
<string name="expired">期限切れ</string>
<string name="update_all_maps_added">%1$sに追加された全マップを更新しますか</string>
<string name="user_points">ユーザーポイント</string>
<string name="exit_number">出口番号</string>
<string name="announce_when_exceeded">超過した場合の通知</string>
<string name="output">出力</string>
<string name="annual_subscription">年毎のサブスクリプション</string>
<string name="monthly_subscription">月毎のサブスクリプション</string>
<string name="three_months_subscription">3ヶ月毎のサブスクリプション</string>
<string name="renew_subscription">サブスクリプションの更新</string>
</resources>

View file

@ -1802,7 +1802,7 @@ failu(s)?
<string name="first_usage_item">Sākt lietot</string>
<string name="first_usage_item_description">Kā lejupielādēt kartes un pamatiestatījumu lietošana</string>
<string name="navigation_item_description">Navigācija</string>
<string name="planning_trip_item">Ceļa plānošana</string>
<string name="planning_trip_item">Ceļojuma plānošana</string>
<string name="faq_item">BUJ</string>
<string name="faq_item_description">Biežāk uzdotie jautājumi</string>
<string name="map_viewing_item">Kartes skatīšana</string>
@ -2162,7 +2162,6 @@ Apraksta laukumu: %1$s x %2$s</string>
<string name="shared_string_time">Laiks</string>
<string name="total_distance">Maršruta garums</string>
<string name="routing_attr_height_obstacles_name">Lietot elevācijas datus</string>
<string name="relief_smoothness_factor_descr">Ieteicamais reljefs: līdzens vai kalnains.</string>
<string name="shared_string_slope">Slīpums</string>
<string name="lang_ber">Berberu</string>
@ -2415,7 +2414,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
<string name="show_map">Rādīt karti</string>
<string name="route_is_calculated">Maršruts aprēķināts</string>
<string name="round_trip">Turp un atpakaļ</string>
<string name="plan_route_no_markers_toast">Jums vajag pievienot vismaz vienu marķieri, lai lietotu šo funkciju.</string>
<string name="plan_route_no_markers_toast">Lai lietotu šo funkciju, vajag pievienot vismaz vienu marķieri.</string>
<string name="osn_modify_dialog_error">Piezīmei nevarēja veikt izmaiņas</string>
<string name="osn_modify_dialog_title">Labot piezīmi</string>
<string name="context_menu_item_modify_note">!abot OSM piezīmi</string>
@ -2429,7 +2428,7 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
<string name="routing_attr_avoid_ice_roads_fords_name">No ledus ceļiem un brasla</string>
<string name="routing_attr_avoid_ice_roads_fords_description">Izvairīties no ledus ceļiem un brasliem.</string>
<string name="use_location">Lietot pozīciju</string>
<string name="add_location_as_first_point_descr">Pievienot jūsu atrašanās vietu kā sākuma punktu maršrutam.</string>
<string name="add_location_as_first_point_descr">Pievienot patreizējo atrašanās vietu kā sākuma punktu ideālā maršruta izveidei.</string>
<string name="my_location">Mana pozīcija</string>
<string name="shared_string_finish">Finišs</string>
<string name="plan_route">Plānot maršrutu</string>
@ -3333,4 +3332,19 @@ No Afganistānas līdz Zimbabvei, no Austrālijas līdz ASV, Argentīna, Brazīl
<string name="select_items_for_import">Izvēlieties lietas, ko importēt.</string>
<string name="use_dev_url_descr">Lietot dev.openstreetmap.org nevis openstreetmap.org OSM piezīmju/ POI / GPX augšuielādei un testēšanai.</string>
<string name="use_dev_url">Lietot dev.openstreetmap.org</string>
<string name="plan_a_route">Plānot maršrutu</string>
<string name="plan_route_last_edited">Pēdējo reizi labots</string>
<string name="plan_route_import_track">Importēt treku</string>
<string name="plan_route_open_existing_track">Atvērt saglabāto treku</string>
<string name="plan_route_create_new_route">Veidot jaunu maršrutu</string>
<string name="plan_route_select_track_file_for_open">Izvēlieties treka failu atvēršanai.</string>
<string name="plan_route_exit_dialog_descr">Vai tiešām gribat atmest visas izmaiņas ieplānotajā maršrutā\?</string>
<string name="plan_route_trim_before">Griezt pirms</string>
<string name="plan_route_trim_after">Griezt pēc</string>
<string name="plan_route_change_route_type_before">Mainīt maršruta veidu pirms</string>
<string name="plan_route_change_route_type_after">Mainīt maršruta veidu pēc</string>
<string name="plan_route_join_segments">Pievienot segmentus</string>
<string name="plan_route_split_before">Sadalīt pirms</string>
<string name="plan_route_split_after">Sadalīt pēc</string>
<string name="plan_route_add_new_segment">Pievienot jaunu segmentu</string>
</resources>

View file

@ -4056,13 +4056,13 @@
<string name="customize_route_line">Zmień trasę nawigacji</string>
<string name="shared_string_route_line">Trasa nawigacji</string>
<string name="expired">Wygasł</string>
<string name="release_4_0_beta">OsmAnd Live aktualizacje przeniesiono do \"Pobrane &gt; Aktualizacje\"
<string name="release_4_0_beta">Aktualizacje OsmAnd Live przeniesiono do \"Pobrane &gt; Aktualizacje\"
\n
\n •Ślady mogą być pokolorowane względem wysokości, prędkości, wzniesień.
\n
\n • Dodano opcję zmiany wyglądu trasy nawigacji
\n
\n • zaktualizowano okno \"Nagrywanie Trasy\"
\n • Zaktualizowano okno \"Nagrywanie Trasy\"
\n
\n</string>
<string name="map_quick_action_pattern">%1$s → …</string>

View file

@ -3918,4 +3918,13 @@
<string name="poi_jiu_jitsu">Jiu-jitsu</string>
<string name="poi_karate">Karatê</string>
<string name="poi_hoops">Aros</string>
<string name="poi_club_social">Clube social</string>
<string name="poi_plateau">Planalto</string>
<string name="poi_office_diplomatic">Escritório diplomático</string>
<string name="poi_kickboxing">Kickboxe</string>
<string name="poi_cycle_polo">Polo de bicicleta</string>
<string name="poi_curling">Curling</string>
<string name="poi_cliff_diving">Mergulho de falésia</string>
<string name="poi_zurkhaneh_sport">Zurkhaneh</string>
<string name="poi_bay_filter">Tipo de baía</string>
</resources>

View file

@ -3758,7 +3758,7 @@
<string name="shared_string_file_name">Nome do arquivo</string>
<string name="number_of_gpx_files_selected_pattern">%s arquivos de trilha selecionados</string>
<string name="disable_recording_once_app_killed_descrp">O registro de trilhas fará uma pausa quando o aplicativo for encerrado (por meio de aplicativos recentes). (A indicação de segundo plano do OsmAnd desaparece da barra de notificação do Android.)</string>
<string name="save_global_track_interval_descr">Especifique o intervalo de registro para a gravação geral da trilha (ligado por meio do widget de \'gravação de viagem\' no mapa).</string>
<string name="save_global_track_interval_descr">Especifique o intervalo de registro para o registro geral da trilha (ativado por meio do widget de \'gravação de viagem\' no mapa).</string>
<string name="gpx_monitoring_stop">Pausar gravação de viagem</string>
<string name="gpx_monitoring_start">Retomar a gravação da viagem</string>
<string name="system_default_theme">Padrão do sistema</string>
@ -4049,15 +4049,15 @@
<string name="shared_string_route_line">Linha de rota</string>
<string name="route_line_use_map_style_appearance">A linha de rota seria usada %1$s especificado no estilo de mapa selecionado: %2$s.</string>
<string name="specify_color_for_map_mode">Especifique a cor para o modo de mapa: %1$s.</string>
<string name="release_4_0_beta">"• As atualizações do OsmAnd Live foram movidas para \"Downloads &gt; Atualizações\"
<string name="release_4_0_beta">• As atualizações do OsmAnd Live foram movidas para \"Downloads &gt; Atualizações\"
\n
\n • As trilhas agora podem ser coloridas por altitude, velocidade ou inclinação.
\n• As trilhas agora podem ser coloridas por altitude, velocidade ou inclinação.
\n
\n • Adicionada opção para alterar a aparência da linha da rota de navegação
\n• Adicionada opção para alterar a aparência da linha da rota de navegação
\n
\n • Caixa de diálogo \"Gravação de viagem\" atualizada
\n• Caixa de diálogo \"Gravação de viagem\" atualizada
\n
\n"</string>
\n</string>
<string name="no_purchases">Você não tem nenhuma compra</string>
<string name="new_device_account">Novo dispositivo / nova conta</string>
<string name="contact_support_description">Se você tiver alguma dúvida, entre em contato conosco em %1$s.</string>

View file

@ -58,7 +58,7 @@
<string name="poi_greengrocer">Loja de frutas e verduras</string>
<string name="poi_seafood">Peixaria</string>
<string name="poi_confectionery">Confeitaria</string>
<string name="poi_ice_cream">Geladaria</string>
<string name="poi_ice_cream">Gelataria</string>
<string name="poi_supermarket">Supermercado</string>
<string name="poi_tea">Loja de chás</string>
<string name="poi_pasta">Loja de massas</string>
@ -80,7 +80,7 @@
<string name="poi_carpet">Loja de tapetes</string>
<string name="poi_charity">Loja de caridade</string>
<string name="poi_chemist">Loja de produtos de higiene pessoal</string>
<string name="poi_clothes">Pronto a vestir</string>
<string name="poi_clothes">Pronto-a-vestir</string>
<string name="poi_clothes_children">Vestuário infantil</string>
<string name="poi_shoes">Sapataria</string>
<string name="poi_candles">Loja de velas</string>
@ -248,7 +248,7 @@
<string name="poi_shoes_type">Tipo</string>
<string name="poi_fire_hydrant_type">Tipo</string>
<string name="poi_fire_hydrant_position">Localização</string>
<string name="poi_water_source">Fonte de água</string>
<string name="poi_water_source">Origem da água</string>
<string name="poi_payment_toll_type">Forma de pagamento</string>
<string name="poi_traffic_signals_sound">Som</string>
<string name="poi_highway_crossing_type">Tipo</string>
@ -296,7 +296,7 @@
<string name="poi_fireplace">Lareira</string>
<string name="poi_beach_surface_type">Superfície</string>
<string name="poi_nudism">Nudismo</string>
<string name="poi_diet">Dieta</string>
<string name="poi_diet">Pratos</string>
<string name="poi_massage_type">Tipo de massagem</string>
<string name="poi_tents">Tendas</string>
<string name="poi_washing_machine">Máquina de lavar roupa</string>
@ -576,7 +576,7 @@
<string name="poi_pharmacy">Farmácia</string>
<string name="poi_hospital">Hospital</string>
<string name="poi_doctors">Consultório médico</string>
<string name="poi_clinic">Clínica;Centro de saúde;Unidade de Saúde;Posto Médico</string>
<string name="poi_clinic">Clínica/centro de saúde/USF/posto médico</string>
<string name="poi_first_aid">Primeiros socorros</string>
<string name="poi_dentist">Dentista</string>
<string name="poi_nursing_home">Clínica geriátrica</string>
@ -732,24 +732,24 @@
<string name="poi_lean_to">Galpão</string>
<string name="poi_hunting_lodge">Cabana de caça</string>
<string name="poi_place_of_worship">Local de culto</string>
<string name="poi_religion_christian">Cristianismo</string>
<string name="poi_religion_jewish">Judaísmo</string>
<string name="poi_religion_muslim">Islamismo</string>
<string name="poi_religion_sikh">Sikhismo</string>
<string name="poi_religion_buddhist">Budismo</string>
<string name="poi_religion_hindu">Hinduísmo</string>
<string name="poi_religion_shinto">Xintoísmo</string>
<string name="poi_religion_taoist">Taoísmo</string>
<string name="poi_religion_christian">Cristã</string>
<string name="poi_religion_jewish">Judaica</string>
<string name="poi_religion_muslim">Islâmica</string>
<string name="poi_religion_sikh">Siquista</string>
<string name="poi_religion_buddhist">Budista</string>
<string name="poi_religion_hindu">Hinduísta</string>
<string name="poi_religion_shinto">Xintoísma</string>
<string name="poi_religion_taoist">Taoísma</string>
<string name="poi_religion_voodoo">Vodu</string>
<string name="poi_religion_unitarian_universalist">Unitário-Universalismo</string>
<string name="poi_religion_unitarian_universalist">Unitário-universalista</string>
<string name="poi_religion_multifaith">Multirreligiosa</string>
<string name="poi_religion_jain">Jainismo</string>
<string name="poi_religion_spiritualist">Espiritualismo</string>
<string name="poi_religion_bahai">Bahaísmo</string>
<string name="poi_religion_scientologist">Cientologismo</string>
<string name="poi_religion_pagan">Paganismo</string>
<string name="poi_religion_jain">Jainista</string>
<string name="poi_religion_spiritualist">Espiritualista</string>
<string name="poi_religion_bahai">Bahaísta</string>
<string name="poi_religion_scientologist">Cientologista</string>
<string name="poi_religion_pagan">Paganista</string>
<string name="poi_religion_tenrikyo">Tenrikyo</string>
<string name="poi_religion_zoroastrian">Zoroastrismo</string>
<string name="poi_religion_zoroastrian">Zoroastrista</string>
<string name="poi_denomination_catholic">Católica</string>
<string name="poi_denomination_baptist">Batista</string>
<string name="poi_denomination_roman_catholic">Católica romana</string>
@ -828,7 +828,7 @@
<string name="poi_travel_agent">Agência de viagens</string>
<string name="poi_viewpoint">Miradouro</string>
<string name="poi_camp_site">Local de acampamento</string>
<string name="poi_caravan_site">Local de caravanas</string>
<string name="poi_caravan_site">Parque de caravanas</string>
<string name="poi_picnic_table">Mesa de piquenique</string>
<string name="poi_spring">Nascente</string>
<string name="poi_hot_spring">Fonte termal</string>
@ -914,7 +914,7 @@
<string name="poi_bar">Bar</string>
<string name="poi_pub">Taberna</string>
<string name="poi_food_court">Praça de alimentação</string>
<string name="poi_drinking_water">Fonte de água potável</string>
<string name="poi_drinking_water">Bebedouro (água potável para beber)</string>
<string name="poi_barbecue">Churrasqueira</string>
<string name="poi_craft_agricultural_engines">Máquinas agrícolas</string>
<string name="poi_craft_basket_maker">Cesteiro</string>
@ -1004,7 +1004,7 @@
<string name="poi_sinkhole">Sumidouro</string>
<string name="poi_waterfall">Queda de água;Cascata;Salto;Catarata</string>
<string name="poi_river">Rio</string>
<string name="poi_stream">Ribeiro;Ribeira;Córrego</string>
<string name="poi_stream">Ribeiro(a)</string>
<string name="poi_rapids">Rápidos</string>
<string name="poi_cape">Cabo</string>
<string name="poi_beach">Praia</string>
@ -1122,7 +1122,7 @@
<string name="poi_wiki_lang_zh">Wiki em chinês</string>
<string name="poi_wiki_lang_af">Wiki em africâner</string>
<string name="poi_wiki_lang_als">Wiki em alsaciano</string>
<string name="poi_wiki_lang_az">Wiki em azeri</string>
<string name="poi_wiki_lang_az">Wiki em azerbaijanês</string>
<string name="poi_wiki_lang_bn">Wiki em bengali</string>
<string name="poi_wiki_lang_bpy">Wiki em bishnupriya</string>
<string name="poi_wiki_lang_br">Wiki em bretão</string>
@ -1384,7 +1384,7 @@
<string name="poi_water_characteristic_mineral">Mineral</string>
<string name="poi_water_characteristic_mud">Lama</string>
<string name="poi_water_characteristic_sulfuric">Sulfurosa</string>
<string name="poi_water_point">Ponto de água</string>
<string name="poi_water_point">Ponto de água em grande quantidade (para caravanas ou garrafões)</string>
<string name="poi_information_guidepost">Poste com direções</string>
<string name="poi_information_board">Painel</string>
<string name="poi_information_map">Mapa</string>
@ -1650,32 +1650,32 @@
<string name="poi_payment_yandexmoney_no">Não aceita Yandex.Money</string>
<string name="poi_description_payment">Detalhes de pagamento</string>
<string name="poi_events_venue">Salão de eventos</string>
<string name="poi_diet_vegetarian_filter_yes">Vegetariana</string>
<string name="poi_diet_vegetarian_few">Vegetariana (alguns)</string>
<string name="poi_diet_vegetarian_only">Apenas vegetariana</string>
<string name="poi_diet_vegetarian_yes">Vegetariana</string>
<string name="poi_diet_vegetarian_no">Dieta vegetariana: não</string>
<string name="poi_diet_vegan_filter_yes">Vegana</string>
<string name="poi_diet_vegan_only">Apenas vegana</string>
<string name="poi_diet_vegan_yes">Vegana</string>
<string name="poi_diet_vegan_no">Dieta vegana: não</string>
<string name="poi_diet_gluten_free_filter_yes">Livre de glúten</string>
<string name="poi_diet_gluten_free_only">Apenas livre de glúten</string>
<string name="poi_diet_gluten_free_yes">Livre de glúten</string>
<string name="poi_diet_gluten_free_no">Dieta livre de glúten: não</string>
<string name="poi_diet_kosher_filter_yes">Kosher (judaica)</string>
<string name="poi_diet_kosher_only">Apenas kosher</string>
<string name="poi_diet_kosher_yes">Kosher</string>
<string name="poi_diet_kosher_no">Dieta kosher: não</string>
<string name="poi_diet_halal_filter_yes">Halal (árabe)</string>
<string name="poi_diet_halal_only">Apenas halal</string>
<string name="poi_diet_halal_yes">Halal</string>
<string name="poi_diet_halal_no">Dieta halal: não</string>
<string name="poi_diet_lactose_free_filter_yes">Livre de lactose</string>
<string name="poi_diet_lactose_free_only">Apenas livre de lactose</string>
<string name="poi_diet_lactose_free_yes">Livre de lactose</string>
<string name="poi_diet_lactose_free_no">Dieta livre de lactose: não</string>
<string name="poi_diet_pescetarian_yes">Piscitariana (peixes e vegetais)</string>
<string name="poi_diet_vegetarian_filter_yes">Pratos vegetarianos: sim</string>
<string name="poi_diet_vegetarian_few">Pratos vegetarianos: alguns</string>
<string name="poi_diet_vegetarian_only">Pratos vegetarianos: só vegetarianos</string>
<string name="poi_diet_vegetarian_yes">Pratos vegetarianos: sim</string>
<string name="poi_diet_vegetarian_no">Pratos vegetarianos: não</string>
<string name="poi_diet_vegan_filter_yes">Pratos veganos: sim</string>
<string name="poi_diet_vegan_only">Pratos veganos: só veganos</string>
<string name="poi_diet_vegan_yes">Pratos veganos: sim</string>
<string name="poi_diet_vegan_no">Pratos veganos: não</string>
<string name="poi_diet_gluten_free_filter_yes">Pratos livres de glúten: sim</string>
<string name="poi_diet_gluten_free_only">Pratos livres de glúten: unicamente</string>
<string name="poi_diet_gluten_free_yes">Pratos livres de glúten: sim</string>
<string name="poi_diet_gluten_free_no">Pratos livres de glúten: não</string>
<string name="poi_diet_kosher_filter_yes">Pratos kosher (judaica): sim</string>
<string name="poi_diet_kosher_only">Pratos kosher (judaica): unicamente</string>
<string name="poi_diet_kosher_yes">Pratos kosher (judaica): sim</string>
<string name="poi_diet_kosher_no">Pratos kosher (judaica): não</string>
<string name="poi_diet_halal_filter_yes">Pratos halal (árabe): sim</string>
<string name="poi_diet_halal_only">Pratos halal (árabe): apenas</string>
<string name="poi_diet_halal_yes">Pratos halal (árabe): sim</string>
<string name="poi_diet_halal_no">Pratos halal (árabe): não</string>
<string name="poi_diet_lactose_free_filter_yes">Pratos sem lactose: sim</string>
<string name="poi_diet_lactose_free_only">Pratos sem lactose: unicamente</string>
<string name="poi_diet_lactose_free_yes">Pratos sem lactose: sim</string>
<string name="poi_diet_lactose_free_no">Pratos sem lactose: não</string>
<string name="poi_diet_pescetarian_yes">Pratos piscitariana (peixes e vegetais): sim</string>
<string name="poi_drive_in_yes">Sim</string>
<string name="poi_drive_in_no">Serviço a conduzir: não</string>
<string name="poi_drive_through_yes">Sim</string>
@ -2365,7 +2365,7 @@
<string name="poi_historic_threshing_floor">Eira histórica</string>
<string name="poi_historic_gallows">Forca histórica</string>
<string name="poi_historic_railway">Ferrovia histórica</string>
<string name="poi_square">Praça;Praceta</string>
<string name="poi_square">Praça/praceta/largo</string>
<string name="poi_artist_name">Artista</string>
<string name="poi_sculptor">Escultor</string>
<string name="poi_building_type_church">Tipo de edifício: igreja</string>
@ -3926,4 +3926,6 @@
<string name="poi_water_source_well">Poço</string>
<string name="poi_office_diplomatic">Gabinete diplomático</string>
<string name="poi_bay_filter">Tipo de baía</string>
<string name="poi_plateau">Planalto</string>
<string name="poi_club_social">Clube social</string>
</resources>

View file

@ -37,7 +37,7 @@
<string name="poi_filter_food_shop">Supermercado</string>
<string name="poi_filter_for_tourists">Para turistas</string>
<string name="poi_filter_fuel">Combustível</string>
<string name="poi_filter_namefinder">Pesquisar nome on-line</string>
<string name="poi_filter_namefinder">Pesquisar nome online</string>
<string name="reading_cached_tiles">A ler mosaicos temporários…</string>
<string name="version_index_is_big_for_memory">O índice \'\'{0}\'\' não coube na memória</string>
<string name="version_index_is_not_supported">A versão do índice \'\'{0}\'\' não é suportada</string>
@ -159,12 +159,12 @@
\nAgora só é possível ver o mapa pré-carregado, não descarregar novas áreas.</string>
<string name="unzipping_file">A descomprimir o ficheiro…</string>
<string name="route_tr">Vire à direita e continue em</string>
<string name="route_tshr">Vire fortemente à direita e continue em</string>
<string name="route_tslr">Vire levemente à direita e continue em</string>
<string name="route_tshr">Vire acentuadamente à direita e continue em</string>
<string name="route_tslr">Vire ligeiramente à direita e continue em</string>
<string name="route_tl">Vire à esquerda e continue em</string>
<string name="route_tshl">Vire fortemente à esquerda e continue em</string>
<string name="route_tsll">Vire levemente à esquerda e continue em</string>
<string name="route_tu">Inverta o sentido da marcha e continue em</string>
<string name="route_tshl">Vire acentuadamente à esquerda e continue em</string>
<string name="route_tsll">Vire ligeiramente à esquerda e continue em</string>
<string name="route_tu">Faça inversão de marcha e continue em</string>
<string name="route_head">Comece em</string>
<string name="first_time_continue">Continuar</string>
<string name="first_time_download">Descarregar regiões</string>
@ -214,14 +214,14 @@
<string name="search_nothing_found">Não foi encontrado nada</string>
<string name="searching">A pesquisar…</string>
<string name="searching_address">A pesquisar o endereço …</string>
<string name="search_osm_nominatim">Pesquisa on-line usando OSM Nominatim</string>
<string name="search_osm_nominatim">Pesquisa na Internet usando OSM Nominatim</string>
<string name="hint_search_online">Pesquisa online: número da casa, rua, cidade</string>
<string name="search_offline_address">Pesquisa offline</string>
<string name="search_online_address">Pesquisa online</string>
<string name="max_level_download_tile">Nível máximo de zoom</string>
<string name="max_level_download_tile_descr">Não navegar em mapas on-line para níveis de ampliação além deste.</string>
<string name="max_level_download_tile_descr">Não navegar em mapas online para níveis de ampliação além deste.</string>
<string name="route_general_information">Distância total %1$s, tempo de viagem %2$d h %3$d min.</string>
<string name="router_service_descr">Serviço de navegação on-line ou off-line.</string>
<string name="router_service_descr">Serviço de navegação online ou offline.</string>
<string name="router_service">Serviço de navegação</string>
<string name="sd_dir_not_accessible">A pasta de armazenamento não está acessível no cartão de memória!</string>
<string name="download_question">Descarregar {0} - {1} \?</string>
@ -395,18 +395,18 @@
<string name="modify_transparency">Definir a transparência (0 - transparente, 255 - opaco)</string>
<string name="confirm_interrupt_download">Cancelar o descarregamento\?</string>
<string name="basemap_was_selected_to_download">O mapa base, necessário para fornecer funcionalidade básica, está na fila de descarregamentos.</string>
<string name="local_indexes_cat_tile">Mosaicos de mapas on-line e em ficheiros temporários</string>
<string name="local_indexes_cat_tile">Mosaicos de mapas online e em ficheiros temporários</string>
<string name="local_indexes_cat_map">Mapas padrão (vetorial)</string>
<string name="map_online_plugin_is_not_installed">Ative a extensão de \'Mapas on-line\' para selecionar diferentes origens de mapas</string>
<string name="map_online_data">Mapas on-line e mosaicos</string>
<string name="map_online_plugin_is_not_installed">Ative a extensão de \'Mapas online\' para selecionar diferentes origens de mapas</string>
<string name="map_online_data">Mapas online e mosaicos</string>
<string name="map_online_data_descr">Usar mapas online (descarregar e armazenar mosaicos no cartão de memória).</string>
<string name="shared_string_online_maps">Mapas on-line</string>
<string name="online_map_settings_descr">Configurar origens de mosaicos ou de mapas on-line.</string>
<string name="osmand_rastermaps_plugin_description">Aceda a muitos tipos de mapas on-line (também chamados de mosaico ou raster) pré-definidos do OpenStreetMap (como Mapnik) para imagens de satélite e camadas especiais, como mapas aquáticos, climáticos, geológicos, camadas de sombra de relevo, etc.
<string name="online_map_settings_descr">Configurar origens de mosaicos ou de mapas online.</string>
<string name="osmand_rastermaps_plugin_description">Aceda a muitos tipos de mapas online (também chamados de mosaico ou raster) pré-definidos do OpenStreetMap (como Mapnik) para imagens de satélite e camadas especiais, como mapas aquáticos, climáticos, geológicos, camadas de sombra de relevo, etc.
\n
\nQuaisquer desses mapas podem ser usados como mapa principal (base) para ser mostrado no OsmAnd ou na camada superior ou inferior para outro mapa base (como o mapa off-line normal de OsmAnd). Para tornar qualquer camada inferior do mapa mais visível, certos elementos do mapa vetorial do OsmAnd podem facilmente ser ocultados através do menu \'Configurar mapa\'.
\nQuaisquer desses mapas podem ser usados como mapa principal (base) para ser mostrado no OsmAnd ou na camada superior ou inferior para outro mapa base (como o mapa offline normal de OsmAnd). Para tornar qualquer camada inferior do mapa mais visível, certos elementos do mapa vetorial do OsmAnd podem facilmente ser ocultados através do menu \'Configurar mapa\'.
\n
\nOs mosaicos dos mapas podem ser obtidos diretamente através de origens on-line ou podem ser preparados para uso off-line (e copiados manualmente para o diretório de dados do OsmAnd) como uma base de dados sqlite, que pode ser produzido por uma variedade de ferramentas de terceiros para preparação de mapas.</string>
\nOs mosaicos dos mapas podem ser obtidos diretamente através de origens online ou podem ser preparados para uso offline (e copiados manualmente para o diretório de dados do OsmAnd) como uma base de dados sqlite, que pode ser produzido por uma variedade de ferramentas de terceiros para preparação de mapas.</string>
<string name="osmand_background_plugin_description">Mostra as configurações para ativar o rastreamento em segundo plano e a navegação, despertando periodicamente o dispositivo GPS (com o ecrã desligado).</string>
<string name="osmand_accessibility_description">Mostra os recursos de acessibilidade do dispositivo disponíveis diretamente no OsmAnd. Facilita, por exemplo, o ajuste da velocidade da fala para vozes TTS, configurando a navegação no ecrã do teclado direcional, usando um trackball para controlo da ampliação, ou feedback texto-para-fala, por exemplo, para anunciar automaticamente a sua posição.</string>
<string name="osmand_development_plugin_description">Mostra configurações para recursos de desenvolvimento e depuração como testar ou simular roteamento, o desempenho de renderização do ecrã ou solicitação de voz. Essas configurações são destinadas a programadores e não são necessárias para o utilizador em geral.</string>
@ -465,7 +465,7 @@
<string name="left">para a esquerda</string>
<string name="front_left">para a frente à esquerda</string>
<string name="oclock">horas</string>
<string name="towards">em direção a</string>
<string name="towards">para</string>
<string name="accuracy">Precisão</string>
<string name="altitude">Altitude</string>
<string name="no_info">Sem informação</string>
@ -493,11 +493,11 @@
<string name="local_openstreetmap_descr_title">Edição assíncrona de OSM:</string>
<string name="local_openstreetmap_settings">POIs / notas guardados no dispositivo</string>
<string name="local_openstreetmap_settings_descr">Mostrar e gerir POIs/notas do OSM guardados localmente.</string>
<string name="live_monitoring_interval_descr">Especifique o intervalo de rastreamento on-line.</string>
<string name="live_monitoring_interval">Intervalo de rastreamento on-line</string>
<string name="live_monitoring_interval_descr">Especifique o intervalo de rastreamento online.</string>
<string name="live_monitoring_interval">Intervalo de rastreamento online</string>
<string name="live_monitoring_url_descr">Especifique o endereço web com a sintaxe de parâmetros: lat={0}, lon={1}, data/hora={2}, hdop={3}, altitude={4}, velocidade={5}, bearing={6}.</string>
<string name="live_monitoring_url">Endereço web de rastreamento on-line</string>
<string name="gpx_monitoring_disabled_warn">Registo de trajeto usando widget GPX ou via \'Gravação de viagem\' nas configurações.</string>
<string name="live_monitoring_url">Endereço web de rastreamento online</string>
<string name="gpx_monitoring_disabled_warn">Registo de trajeto usando widget GPX ou via \'Gravar viagem\' nas configurações.</string>
<string name="show_current_gpx_title">Mostrar rota atual</string>
<string name="free_version_message">Pode descarregar ou atualizar %1$s mapas.</string>
<string name="free_version_title">Versão gratuita</string>
@ -562,7 +562,7 @@
<string name="shared_string_undefined">Sem definir</string>
<string name="search_position_map_view">Centro do mapa atual</string>
<string name="select_search_position">Origem:</string>
<string name="context_menu_item_search">Pesquisar nas proximidades</string>
<string name="context_menu_item_search">Pesquisar perto daqui</string>
<string name="route_successfully_saved_at">Rota guardada como \'%1$s\'.</string>
<string name="filename_input">Nome do ficheiro:</string>
<string name="file_with_name_already_exist">Já existe um ficheiro com o mesmo nome.</string>
@ -665,9 +665,9 @@
<string name="context_menu_item_share_location">Partilhar localização</string>
<string name="add_waypoint_dialog_added">Foi adicionado o ponto de passagem GPX \'\'{0}\'\'</string>
<string name="add_waypoint_dialog_title">Acrescentar ponto ao trilho GPX gravado</string>
<string name="osmand_routing_experimental">Navegação OsmAnd off-line ainda é uma função experimental e não funciona em distâncias superiores a cerca de 20 km.
<string name="osmand_routing_experimental">Navegação OsmAnd offline ainda é uma função experimental e não funciona em distâncias superiores a cerca de 20 km.
\n
\nO serviço de navegação está temporariamente mudado para CloudMade on-line.</string>
\nO serviço de navegação está temporariamente mudado para CloudMade online.</string>
<string name="specified_dir_doesnt_exist">Não foi possível encontrar a pasta especificada.</string>
<string name="application_dir">Local de armazenamento</string>
<string name="osmand_net_previously_installed">Todos os dados offline na aplicação instalada antiga serão suportados pela nova, mas os pontos Favoritos devem ser exportados da aplicação antiga e depois importados na nova.</string>
@ -717,7 +717,7 @@
<string name="osmand_parking_plugin_description">Permite gravar onde o seu carro foi estacionado e quanto tempo de estacionamento resta (se houver um limite de tempo).
\nA localização e o tempo ficam visíveis no painel de controlo do OsmAnd e num widget no ecrã do mapa. Um alarme pode ser adicionado ao calendário Android como lembrete.</string>
<string name="osmand_parking_plugin_name">Local de estacionamento</string>
<string name="context_menu_item_add_parking_point">Marcar local de estacionamento</string>
<string name="context_menu_item_add_parking_point">Marcar estacionamento</string>
<string name="context_menu_item_delete_parking_point">Eliminar um marcador de estacionamento</string>
<string name="starting_point_too_far">Ponto de partida demasiado distante da estrada mais próxima.</string>
<string name="shared_location">Local partilhado</string>
@ -736,7 +736,7 @@
<string name="continue_follow_previous_route_auto">Continuar a navegação a seguir que ficou antes inacabada\? (%1$s segundos)</string>
<string name="show_cameras">Radares de velocidade</string>
<string name="show_traffic_warnings">Informações de circulação</string>
<string name="avoid_toll_roads">Sem estradas com portagem</string>
<string name="avoid_toll_roads">Evitar estradas com portagem</string>
<string name="map_widget_top_text">Nome da rua</string>
<string name="map_widget_config">Configuração do ecrã</string>
<string name="map_widget_back_to_loc">Onde estou</string>
@ -763,10 +763,10 @@
\na execução em segundo plano</string>
<string name="show_warnings_title">Mostrar alertas…</string>
<string name="show_warnings_descr">Configure avisos de trânsito (limites de velocidade, portagens, lombas, passadeiras, túneis), radares e a faixa de rodagem.</string>
<string name="avoid_motorway">Sem autoestradas</string>
<string name="avoid_motorway">Evitar autoestradas</string>
<string name="snap_to_road">Ajustar à estrada</string>
<string name="osmand_short_description_80_chars">Visualização e navegação móvel de mapas globais do OSM offline e online</string>
<string name="osmand_plus_short_description_80_chars">OsmAnd é uma aplicação de navegação de código aberto para mapas off-line e on-line</string>
<string name="osmand_plus_short_description_80_chars">OsmAnd é uma aplicação de navegação de código aberto para mapas offline e online</string>
<string name="filterpoi_activity">Criar filtro de POI</string>
<string name="select_navigation_mode">Meio de transporte:</string>
<string name="day_night_info_description">Nascer do sol: %1$s
@ -776,8 +776,8 @@
<string name="map_widget_renderer">Estilo de renderização</string>
<string name="layer_map_appearance">Configurar ecrã</string>
<string name="show_lanes">Mostrar faixas de rodagem</string>
<string name="avoid_unpaved">Sem estradas não pavimentadas</string>
<string name="avoid_ferries">Sem balsas/ferries</string>
<string name="avoid_unpaved">Evitar estradas não pavimentadas</string>
<string name="avoid_ferries">Evitar balsas/ferries</string>
<string name="avoid_in_routing_title">Evitar…</string>
<string name="map_widget_fluorescent">Rotas fluorescentes</string>
<string name="map_widget_show_ruler">Régua</string>
@ -810,7 +810,7 @@
<string name="rendering_attr_roadColors_description">Selecione um esquema de cores de estrada:</string>
<string name="rendering_attr_roadColors_name">Esquema de cores</string>
<string name="map_widget_show_destination_arrow">Ver direção para o destino</string>
<string name="enable_plugin_monitoring_services">Ative a extensão de \"Gravação de viagem\" para usar serviços de registo de posição (registo GPX, rastreamento on-line)</string>
<string name="enable_plugin_monitoring_services">Ative a extensão de \"Gravar viagem\" para usar serviços de registo de posição (registo GPX, rastreamento online)</string>
<string name="non_optimal_route_calculation">Calcular rota possivelmente não ideal em longas distâncias</string>
<string name="gps_not_available">Ative o GPS nas configurações</string>
<string name="map_widget_monitoring_services">Serviços de registo</string>
@ -852,7 +852,7 @@
<string name="search_villages_and_postcodes">Pesquisar mais povoações/códigos postais</string>
<string name="dropbox_plugin_description">Sincroniza trilhos e notas de vídeo/áudio com a sua conta Dropbox.</string>
<string name="av_def_action_video">Gravar vídeo</string>
<string name="av_def_action_audio">Gravar audio</string>
<string name="av_def_action_audio">Gravar áudio</string>
<string name="av_widget_action_descr">Ação predefinida do widget:</string>
<string name="av_widget_action">Ação widget padrão</string>
<string name="av_video_format">Formato de saída de vídeo</string>
@ -883,7 +883,7 @@
<string name="clear_dest_confirm">Tem a certeza que quer limpar o seu destino (e destinos intermédios)\?</string>
<string name="precise_routing_mode_descr">Calcula rotas precisas sem falhas, mas com distância limitada e lento.</string>
<string name="precise_routing_mode">Roteamento preciso (alfa)</string>
<string name="recording_context_menu_precord">Tirar uma foto</string>
<string name="recording_context_menu_precord">Tirar uma fotografia</string>
<string name="dropbox_plugin_name">Extensão Dropbox</string>
<string name="intermediate_points_change_order">Alterar ordem</string>
<string name="srtm_paid_version_msg">Por favor, considere comprar a extensão \'Curvas de nível\' para apoiar o desenvolvimento.</string>
@ -891,7 +891,7 @@
<string name="av_def_action_choose">A pedido\?</string>
<string name="av_video_format_descr">Formato de saída de vídeo:</string>
<string name="av_use_external_recorder_descr">Usar gravador do sistema para vídeo.</string>
<string name="av_use_external_camera_descr">Utilizar a aplicação do sistema para fotos.</string>
<string name="av_use_external_camera_descr">Utilizar a aplicação do sistema para tirar fotografias.</string>
<string name="av_use_external_camera">Usar aplicação da câmara</string>
<string name="recording_playing">A reproduzir o áudio da gravação.
\n%1$s</string>
@ -901,7 +901,7 @@
<string name="shared_string_control_stop">Parar</string>
<string name="shared_string_control_start">Iniciar</string>
<string name="map_widget_av_notes">Notas de áudio/vídeo</string>
<string name="osmand_srtm_short_description_80_chars">Extensão OsmAnd para curvas de nível off-line</string>
<string name="osmand_srtm_short_description_80_chars">Extensão OsmAnd para curvas de nível offline</string>
<string name="map_widget_distancemeasurement">Medição da distância</string>
<string name="audionotes_location_not_defined">O local para associar à nota ainda não está definido. Toque em \"Usar posição…\" para atribuir uma nota ao local especificado.</string>
<string name="map_widget_audionotes">Notas de áudio</string>
@ -909,8 +909,8 @@
<string name="audionotes_plugin_name">Notas de áudio/vídeo</string>
<string name="index_srtm_parts">Partes</string>
<string name="index_srtm_ele">Curvas de nível</string>
<string name="recording_photo_description">Foto %1$s de %2$s</string>
<string name="av_def_action_picture">Tirar uma foto</string>
<string name="recording_photo_description">Fotografia %1$s de %2$s</string>
<string name="av_def_action_picture">Tirar uma fotografia</string>
<string name="osmand_srtm_long_description_1000_chars">Esta extensão disponibiliza \'Curvas de nível\' e \'Sombras de relevo\', que podem ser aplicadas nos mapas padrão do OsmAnd. Estas funcionalidades podem ser apreciadas por atletas, caminhantes e qualquer pessoa interessada na informação do relevo de uma paisagem.
\n
\nOs dados globais (entre as latitudes 70° norte e 70° sul) são baseados nas medições do SRTM (Shuttle Radar Topography Mission) e do ASTER (Advanced Spaceborn Thermal Emission and Reflection Radiometer), um instrumento de imagens no satélite \'Terra\', o satélite principal do Sistema de Observação da Terra da NASA. O ASTER é um esforço conjunto da NASA, do Ministério da Economia, Comércio e Indústria do Japão e do Sistema Espacial Japonês (J-spacesystems).</string>
@ -948,7 +948,7 @@
<string name="files_limit">%1$d ficheiros restantes</string>
<string name="available_downloads_left">Faltam %1$d ficheiros para descarregar</string>
<string name="install_paid">Versão completa</string>
<string name="cancel_route">Descartar a rota\?</string>
<string name="cancel_route">Cancelar a rota\?</string>
<string name="cancel_navigation">Parar navegação</string>
<string name="local_osm_changes_backup_successful">Ficheiro de alterações OSM %1$s gerado</string>
<string name="local_osm_changes_backup_failed">Não foi possível fazer a cópia de segurança das alterações do OSM.</string>
@ -1082,7 +1082,7 @@
<string name="app_mode_aircraft">Aeronave</string>
<string name="local_osm_changes_delete_all_confirm">Tem a certeza que quer eliminar %1$d alterações no OSM\?</string>
<string name="shared_string_delete_all">Eliminar tudo</string>
<string name="amenity_type_osmwiki">Wikipédia (off-line)</string>
<string name="amenity_type_osmwiki">Wikipédia (offline)</string>
<string name="amenity_type_seamark">Marca marítima</string>
<string name="app_modes_choose_descr">Escolha os perfis a mostrar.</string>
<string name="app_modes_choose">Perfis da aplicação</string>
@ -1113,7 +1113,7 @@
<string name="lang_en">Inglês</string>
<string name="lang_af">Africâner</string>
<string name="lang_hy">Arménio</string>
<string name="calculate_osmand_route_without_internet">Cálculo off-line do segmento de rota OsmAnd</string>
<string name="calculate_osmand_route_without_internet">Calcular segmento de rota OsmAnd sem Internet</string>
<string name="gpx_option_calculate_first_last_segment">Calcular rota de OsmAnd para o primeiro e último segmento da rota</string>
<string name="use_displayed_track_for_navigation">Usar o trajeto indicado para a navegação\?</string>
<string name="keep_and_add_destination_point">Adicionar como destino posterior</string>
@ -1125,13 +1125,13 @@
<string name="route_info">Informações da rota</string>
<string name="routing_attr_prefer_motorway_name">Preferir autoestradas</string>
<string name="routing_attr_prefer_motorway_description">Preferir autoestradas</string>
<string name="routing_attr_avoid_toll_name">Sem estradas com portagem</string>
<string name="routing_attr_avoid_toll_name">Evitar portagens</string>
<string name="routing_attr_avoid_toll_description">Evitar estradas com portagem</string>
<string name="routing_attr_avoid_unpaved_name">Sem estradas não pavimentadas</string>
<string name="routing_attr_avoid_unpaved_name">Evitar estradas não pavimentadas</string>
<string name="routing_attr_avoid_unpaved_description">Evitar estradas não pavimentadas</string>
<string name="routing_attr_avoid_ferries_name">Sem balsas/ferries</string>
<string name="routing_attr_avoid_ferries_name">Evitar balsas/ferries</string>
<string name="routing_attr_avoid_ferries_description">Evita balsas/ferries</string>
<string name="routing_attr_avoid_motorway_name">Sem autoestradas</string>
<string name="routing_attr_avoid_motorway_name">Evitar autoestradas</string>
<string name="routing_attr_avoid_motorway_description">Evita autoestradas</string>
<string name="routing_attr_weight_name">Peso máximo</string>
<string name="routing_attr_weight_description">Especifique o limite de peso permitido para veículos em rotas.</string>
@ -1141,7 +1141,7 @@
<string name="copying_osmand_one_file_descr">A copiar o ficheiro (%s) para novo destino…</string>
<string name="copying_osmand_files_descr">A copiar os ficheiros OsmAnd para o novo destino (%s)…</string>
<string name="copying_osmand_files">A copiar ficheiros de dados do OsmAnd…</string>
<string name="calculate_osmand_route_gpx">Cálculo de rota OsmAnd off-line</string>
<string name="calculate_osmand_route_gpx">Cálculo de rota OsmAnd offline</string>
<string name="app_mode_truck">Camião</string>
<string name="lang_eu">Basco</string>
<string name="lang_be">Bielorrusso</string>
@ -1323,7 +1323,7 @@
<string name="storage_directory">Armazenamento do mapa</string>
<string name="shared_string_copy">Copiar</string>
<string name="filter_poi_hint">Filtrar por nome</string>
<string name="search_poi_category_hint">Digite para pesquisar tudo</string>
<string name="search_poi_category_hint">Digite para pesquisar em tudo</string>
<string name="shared_string_is_open">Aberto agora</string>
<string name="rendering_attr_OSMMapperAssistant_name">Assistente de mapeador OSM</string>
<string name="agps_info">Informação A-GPS</string>
@ -1353,7 +1353,7 @@
<string name="rendering_attr_streetLighting_name">Iluminação pública</string>
<string name="rendering_value__name">Predefinido</string>
<string name="rendering_value_highContrastRoads_name">Estradas em alto contraste</string>
<string name="welcome_text">OsmAnd fornece mapas de navegação globais e navegação off-line.</string>
<string name="welcome_text">OsmAnd fornece mapas de navegação globais e navegação offline.</string>
<string name="welcome_header">Bem-vindo(a)</string>
<string name="current_route">Rota atual</string>
<string name="osm_changes_added_to_local_edits">Mudanças no OSM adicionadas ao conjunto de alterações local</string>
@ -1398,7 +1398,7 @@
<string name="shared_string_currently_recording_track">A gravar o trajeto</string>
<string name="shared_string_audio">Áudio</string>
<string name="shared_string_video">Vídeo</string>
<string name="shared_string_photo">Foto</string>
<string name="shared_string_photo">Fotografia</string>
<string name="route_points">Pontos de rota</string>
<string name="track_segments">Segmentos do trajeto</string>
<string name="track_points">Pontos do trajeto</string>
@ -1410,13 +1410,13 @@
<string name="share_note">Partilhar nota</string>
<string name="location_on_map">Posição:\n Lat %1$s\n Lon %2$s</string>
<string name="notes">Notas de áudio/vídeo</string>
<string name="online_map">Mapa on-line</string>
<string name="online_map">Mapa online</string>
<string name="roads_only">Apenas estradas</string>
<string name="rendering_attr_pisteRoutes_name">Pistas de esqui</string>
<string name="free">%1$s livre</string>
<string name="device_memory">Memória do dispositivo</string>
<string name="world_ski_missing">Para mostrar mapas de esqui, tem de descarregar o mapa off-line especial.</string>
<string name="nautical_maps_missing">Para mostrar mapas náuticos, tem de descarregar o mapa off-line especial.</string>
<string name="world_ski_missing">Para mostrar mapas de esqui, tem de descarregar o mapa offline especial.</string>
<string name="nautical_maps_missing">Para mostrar mapas náuticos, tem de descarregar o mapa offline especial.</string>
<string name="edit_group">Editar grupo</string>
<string name="parking_place">Lugar de estacionamento</string>
<string name="version_settings">Compilações</string>
@ -1426,7 +1426,7 @@
<string name="wake_on_voice">Ligar o ecrã</string>
<string name="configure_map">Configurar mapa</string>
<string name="shared_string_waypoints">Pontos de rota</string>
<string name="shared_string_dismiss">Descartar</string>
<string name="shared_string_dismiss">Cancelar</string>
<string name="rendering_category_others">Outros atributos do mapa</string>
<string name="rendering_attr_showAccess_name">Mostrar restrições de acesso e portagens</string>
<string name="rendering_attr_showSurfaceGrade_name">Mostrar qualidade da via</string>
@ -1471,7 +1471,7 @@
<string name="show_on_start_description">\'Desligado\' abre o mapa diretamente.</string>
<string name="show_on_start">Mostrar no arranque</string>
<string name="copied_to_clipboard">Copiado para a área de transferência</string>
<string name="osm_save_offline">Guardar off-line</string>
<string name="osm_save_offline">Guardar offline</string>
<string name="osm_edit_modified_poi">POI do OpenStreetMap alterado</string>
<string name="impassable_road_desc">Escolha as estradas que quer evitar durante a navegação.</string>
<string name="shared_string_sound">Som</string>
@ -1535,7 +1535,7 @@
<string name="av_locations_descr">Ficheiro GPX com localizações.</string>
<string name="av_locations">Localizações</string>
<string name="plugin_settings">Extensões</string>
<string name="routing_attr_avoid_shuttle_train_name">Sem comboio vaivém</string>
<string name="routing_attr_avoid_shuttle_train_name">Evitar comboios vaivém</string>
<string name="routing_attr_avoid_shuttle_train_description">Evita usar comboios vaivém, em pequenos trajetos predefinidos como aeroportos</string>
<string name="traffic_warning_hazard">Perigo</string>
<string name="rendering_value_boldOutline_name">Contorno em negrito</string>
@ -1545,8 +1545,8 @@
<string name="rendering_value_defaultTranslucentCyan_name">Padrão (ciano translúcido)</string>
<string name="rendering_attr_currentTrackColor_name">Cor GPX</string>
<string name="rendering_attr_currentTrackColor_description">Cor GPX</string>
<string name="rendering_attr_currentTrackWidth_name">Espessura GPX</string>
<string name="rendering_attr_currentTrackWidth_description">Espessura GPX</string>
<string name="rendering_attr_currentTrackWidth_name">Espessura dos trilhos GPX</string>
<string name="rendering_attr_currentTrackWidth_description">Espessura dos trilhos GPX</string>
<string name="rendering_value_red_name">Vermelho</string>
<string name="rendering_value_translucent_red_name">Vermelho translúcido</string>
<string name="rendering_value_translucent_orange_name">Laranja translúcido</string>
@ -1593,7 +1593,7 @@
<string name="download_wikipedia_files">Quer descarregar dados adicionais da Wikipédia (%1$s MB)\?</string>
<string name="gps_network_not_enabled">O serviço de localização não está ativado. Quer ativá-lo\?</string>
<string name="shared_string_import2osmand">Importar para o OsmAnd</string>
<string name="read_full_article">Ler o artigo completo (on-line)</string>
<string name="read_full_article">Ler o artigo completo (na Internet)</string>
<string name="shared_string_wikipedia">Wikipédia</string>
<string name="local_indexes_cat_wiki">Wikipédia</string>
<string name="shared_string_show_details">Mostrar detalhes</string>
@ -1659,7 +1659,7 @@
<string name="map_mode">Modo do mapa</string>
<string name="rendering_value_thin_name">Fino</string>
<string name="rendering_value_medium_name">Médio</string>
<string name="rendering_value_bold_name">Negrito</string>
<string name="rendering_value_bold_name">Grosso</string>
<string name="storage_permission_restart_is_required">Agora a aplicação está autorizada a gravar no armazenamento externo, mas primeiro é necessário reiniciar a aplicação.</string>
<string name="shared_string_move_up">Mover ↑</string>
<string name="shared_string_move_down">Mover ↓</string>
@ -1807,14 +1807,14 @@
<string name="search_another_country">Selecionar outra região</string>
<string name="shared_string_change">Alterar</string>
<string name="storage_directory_card">Cartão de memória</string>
<string name="skip_map_downloading_desc">Não tem nenhum mapa off-line instalado. Pode escolher um mapa na lista ou descarregar mapas mais tarde através do \'menu - %1$s\'.</string>
<string name="skip_map_downloading_desc">Não tem nenhum mapa offline instalado. Pode escolher um mapa na lista ou descarregar mapas mais tarde através do \'menu - %1$s\'.</string>
<string name="shared_string_markers">Marcadores</string>
<string name="coordinates_format">Formato de coordenadas</string>
<string name="use_system_keyboard">Usar teclado do sistema</string>
<string name="fast_coordinates_input_descr">Escolher formato de introdução de coordenada. Poderá sempre alterá-lo ao selecionar \'Opções\'.</string>
<string name="fast_coordinates_input">Introdução rápida de coordenadas</string>
<string name="routing_attr_avoid_ice_roads_fords_name">Sem estradas de gelo ou vaus</string>
<string name="routing_attr_avoid_ice_roads_fords_description">Evitar estradas de gelo e vaus.</string>
<string name="routing_attr_avoid_ice_roads_fords_name">Evitar estradas de gelo ou vaus</string>
<string name="routing_attr_avoid_ice_roads_fords_description">Evitar estradas de gelo e vaus (passagens em riachos baixos).</string>
<string name="use_location">Usar posição</string>
<string name="add_location_as_first_point_descr">Adicionar a sua posição como ponto de partida para planear uma rota perfeita.</string>
<string name="my_location">A minha posição</string>
@ -1825,8 +1825,8 @@
<string name="marker_save_as_track_descr">Exporte os seus marcadores para um ficheiro que pode especificar aqui:</string>
<string name="move_to_history">Mover para histórico</string>
<string name="group_will_be_removed_after_restart">O grupo terá desaparecido na próxima vez que iniciar a aplicação.</string>
<string name="show_guide_line">Mostrar linhas direcionais</string>
<string name="show_arrows_on_the_map">Mostrar setas no mapa</string>
<string name="show_guide_line">Mostrar linhas para marcadores</string>
<string name="show_arrows_on_the_map">Mostrar setas para marcadores</string>
<string name="show_passed">Mostrar passado</string>
<string name="hide_passed">Esconder o passado</string>
<string name="remove_from_map_markers">Remover dos \'Marcadores do mapa\'</string>
@ -1884,7 +1884,7 @@
<string name="mapillary_menu_title_tile_cache">Ficheiros temporários dos mosaicos</string>
<string name="wrong_user_name">Nome de utilizador errado</string>
<string name="shared_string_to">Para</string>
<string name="mapillary_menu_date_from">A partir de</string>
<string name="mapillary_menu_date_from">De</string>
<string name="mapillary_menu_descr_dates">Ver apenas imagens adicionadas</string>
<string name="mapillary_menu_title_dates">Data</string>
<string name="mapillary_menu_edit_text_hint">Introduza nome de utilizador</string>
@ -1900,15 +1900,15 @@
<string name="shared_string_install">Instalar</string>
<string name="improve_coverage_mapillary">Melhorar cobertura fotográfica com Mapillary</string>
<string name="improve_coverage_install_mapillary_desc">Instale o Mapillary para adicionar fotos a este local do mapa.</string>
<string name="online_photos">Fotos on-line</string>
<string name="shared_string_add_photos">Adicionar fotos</string>
<string name="no_photos_descr">Não há fotos aqui.</string>
<string name="online_photos">Fotografias na Internet</string>
<string name="shared_string_add_photos">Adicionar fotografias</string>
<string name="no_photos_descr">Não há fotografias aqui.</string>
<string name="mapillary_action_descr">Partilhe as suas imagens ao nível do solo no Mapillary.</string>
<string name="mapillary_widget">Widget Mapillary</string>
<string name="mapillary_widget_descr">Permite contribuir rapidamente para o Mapillary.</string>
<string name="mapillary_descr">Fotos on-line ao nível da rua para todos. Descubra locais, colabore, capture o mundo.</string>
<string name="mapillary_descr">Fotografias online ao nível da rua para todos. Descubra locais, colabore, capture o mundo.</string>
<string name="mapillary">Mapillary</string>
<string name="plugin_mapillary_descr">Fotos ao nível da rua para todos. Descubra locais, colabore, capture o mundo.</string>
<string name="plugin_mapillary_descr">Fotografias ao nível da rua para todos. Descubra locais, colabore, capture o mundo.</string>
<string name="private_access_routing_req">O seu destino está localizado numa área de acesso privado. Permitir uso de estradas privadas para esta viagem\?</string>
<string name="restart_search">Reiniciar pesquisa</string>
<string name="increase_search_radius">Aumentar raio de pesquisa</string>
@ -2023,15 +2023,15 @@
<string name="rendering_value_high_name">Alto</string>
<string name="rendering_value_medium_w_name">Médio</string>
<string name="rendering_value_low_name">Baixo</string>
<string name="rendering_attr_contourWidth_description">Largura das curvas de nível</string>
<string name="rendering_attr_contourWidth_name">Largura das curvas de nível</string>
<string name="rendering_attr_contourWidth_description">Espessura das curvas de nível</string>
<string name="rendering_attr_contourWidth_name">Espessura das curvas de nível</string>
<string name="rendering_attr_hideWaterPolygons_description">Água</string>
<string name="rendering_attr_hideWaterPolygons_name">Ocultar água</string>
<string name="routing_attr_allow_motorway_name">Utilizar autoestradas</string>
<string name="routing_attr_allow_motorway_description">Permitir autoestradas.</string>
<string name="wiki_around">Artigos da Wikipédia próximos</string>
<string name="search_map_hint">Cidade ou região</string>
<string name="route_roundabout_short">Use a saída %1$d e continue</string>
<string name="route_roundabout_short">Saia na %1$d saída para</string>
<string name="upload_poi">Enviar pontos de interesse (POI)</string>
<string name="route_calculation">Cálculo da rota</string>
<string name="gpx_no_tracks_title">Ainda não tem nenhuns ficheiros de trilhos</string>
@ -2046,7 +2046,7 @@
<string name="shared_string_paused">Em pausa</string>
<string name="shared_string_trip">Viagem</string>
<string name="shared_string_recorded">Gravado</string>
<string name="shared_string_record">Registo</string>
<string name="shared_string_record">Gravar</string>
<string name="gpx_logging_no_data">Sem dados</string>
<string name="rendering_attr_contourColorScheme_description">Esquema de cores das curvas de nível</string>
<string name="save_track_min_speed">Velocidade mínima para registo</string>
@ -2132,8 +2132,8 @@
<string name="thank_you_for_feedback">Obrigado pelos seus comentários</string>
<string name="search_street">Procurar rua</string>
<string name="shared_string_restore">Restaurar</string>
<string name="keep_passed_markers_descr">Os marcadores adicionados como um grupo de favoritos ou ponto de rota GPX marcados como Passado permanecerão no mapa. Se o grupo não estiver ativo, os marcadores desaparecerão do mapa.</string>
<string name="keep_passed_markers">Manter marcadores passados no mapa</string>
<string name="keep_passed_markers_descr">Os marcadores adicionados como um grupo de favoritos ou ponto de rota GPX marcados como visitado (passado) permanecerão no mapa. Se o grupo não estiver ativo, os marcadores desaparecerão do mapa.</string>
<string name="keep_passed_markers">Manter marcadores visitados</string>
<string name="more_transport_on_stop_hint">Outros transportes disponíveis nesta paragem.</string>
<string name="ask_for_location_permission">Por favor, conceda ao OsmAnd o acesso à localização para continuar.</string>
<string name="markers_remove_dialog_msg">Eliminar o marcador de mapa \'%s\'\?</string>
@ -2213,7 +2213,7 @@
<string name="shared_string_wifi_only">Apenas em Wi-Fi</string>
<string name="select_travel_book">Selecione um livro de viagem</string>
<string name="shared_string_travel_book">Livro de viagens</string>
<string name="online_webpage_warning">Página disponível apenas on-line. Abrir no navegador da web\?</string>
<string name="online_webpage_warning">Página disponível apenas online. Abrir no navegador da web\?</string>
<string name="images_cache">Cache de imagens</string>
<string name="delete_search_history">Eliminar histórico de pesquisa</string>
<string name="download_images">Descarregar imagens</string>
@ -2240,11 +2240,11 @@
<string name="enter_lon">Digite a longitude</string>
<string name="enter_lat">Digite a latitude</string>
<string name="enter_lat_and_lon">Digite a latitude e a longitude</string>
<string name="dd_mm_ss_format">DD°MMSS″</string>
<string name="dd_dddddd_format">DD.DDDDDD°</string>
<string name="dd_ddddd_format">DD.DDDDD°</string>
<string name="dd_mm_mmmm_format">DD°MM.MMMM</string>
<string name="dd_mm_mmm_format">DD°MM.MMM</string>
<string name="dd_mm_ss_format">GG°MMSS″</string>
<string name="dd_dddddd_format">GG.GGGGGG°</string>
<string name="dd_ddddd_format">GG.GGGGG°</string>
<string name="dd_mm_mmmm_format">GG°MM.MMMM</string>
<string name="dd_mm_mmm_format">GG°MM.MMM</string>
<string name="east_abbreviation">E</string>
<string name="west_abbreviation">O</string>
<string name="south_abbreviation">S</string>
@ -2300,7 +2300,7 @@
<string name="one_tap_active_descr">Toque num marcador no mapa para movê-lo para a parte superior dos marcadores ativos sem abrir o menu de contexto.</string>
<string name="one_tap_active">\'Um toque\' ativo</string>
<string name="empty_state_av_notes">Faça notas!</string>
<string name="empty_state_av_notes_desc">Adicione notas de áudio, vídeo ou foto em qualquer ponto do mapa, usando o widget ou o menu de contexto.</string>
<string name="empty_state_av_notes_desc">Adicione notas de áudio, vídeo ou fotografia em qualquer ponto do mapa, usando o widget ou o menu de contexto.</string>
<string name="notes_by_date">Notas de áudio/vídeo por data</string>
<string name="by_date">Por data</string>
<string name="by_type">Por tipo</string>
@ -2321,7 +2321,7 @@
<string name="shared_string_two">Dois</string>
<string name="shared_string_one">Um</string>
<string name="show_guide_line_descr">Mostrar linha direcional desde a sua posição até os locais dos marcadores ativos.</string>
<string name="show_arrows_descr">Mostrar uma ou duas setas indicando a direção para os marcadores ativos.</string>
<string name="show_arrows_descr">Mostrar uma ou duas setas indicando a direção em linha reta para os marcadores ativos.</string>
<string name="distance_indication_descr">Escolher como mostrar a distância para os marcadores ativos.</string>
<string name="active_markers_descr">Especifique a quantidade de indicadores de orientação.</string>
<string name="digits_quantity">Número de casas decimais</string>
@ -2330,7 +2330,7 @@
<string name="show_number_pad">Mostrar teclado numérico</string>
<string name="shared_string_paste">Colar</string>
<string name="go_to_next_field">Próximo campo</string>
<string name="rename_marker">Renomear marcador</string>
<string name="rename_marker">Alterar nome do marcador</string>
<string name="tap_on_map_to_hide_interface_descr">Um toque no mapa mostra/esconde os botões de controlo e widgets.</string>
<string name="tap_on_map_to_hide_interface">Modo ecrã cheio</string>
<string name="mark_passed">Marcador visitado</string>
@ -2424,7 +2424,7 @@
\nRepresenta área: %1$s x %2$s</string>
<string name="speed_limit_exceed">Tolerância do limite de velocidade</string>
<string name="speed_limit_exceed_message">Selecione a margem de tolerância de limite de velocidade, acima do qual receberá um aviso de voz.</string>
<string name="fav_point_emoticons_message">O nome do favorito foi alterado para %1$s para facilitar guardar corretamente a cadeia de caracteres com emoticons num ficheiro.</string>
<string name="fav_point_emoticons_message">O nome do favorito foi alterado para %1$s para poder guardar corretamente o texto com emoticons num ficheiro.</string>
<string name="print_route">Imprimir rota</string>
<string name="fav_point_dublicate">Nome de favorito duplicado</string>
<string name="fav_point_dublicate_message">O nome do favorito especificado já está a ser utilizado, foi alterado para %1$s para evitar a duplicação.</string>
@ -2459,9 +2459,9 @@
<string name="forward">Avançar</string>
<string name="home">Painel de controlo</string>
<string name="live_monitoring_m_descr">Enviar o rastreamento para um serviço web especificado, se o registo de GPX estiver ligado.</string>
<string name="live_monitoring_m">Rastreamento on-line (requer GPX)</string>
<string name="live_monitoring_start">Iniciar rastreamento on-line</string>
<string name="live_monitoring_stop">Parar rastreamento on-line</string>
<string name="live_monitoring_m">Rastreamento online (requer GPX)</string>
<string name="live_monitoring_start">Iniciar rastreamento online</string>
<string name="live_monitoring_stop">Parar rastreamento online</string>
<string name="gpx_start_new_segment">Iniciar novo segmento</string>
<string name="rendering_attr_hideNonVehicleHighways_name">Estradas não transitáveis</string>
<string name="rendering_attr_hideText_name">Texto</string>
@ -2487,9 +2487,9 @@
<string name="lang_zh_cn">Chinês (simplificado)</string>
<string name="lang_zh_hk">Chinês (Hong Kong)</string>
<string name="lang_zh_tw">Chinês (tradicional)</string>
<string name="routing_attr_avoid_stairs_name">Sem escadas</string>
<string name="routing_attr_avoid_stairs_name">Evitar escadas</string>
<string name="routing_attr_avoid_stairs_description">Evita escadas</string>
<string name="routing_attr_avoid_borders_name">Sem passagens por fronteiras</string>
<string name="routing_attr_avoid_borders_name">Evitar passagens por fronteiras</string>
<string name="routing_attr_avoid_borders_description">Evita cruzar fronteiras nacionais</string>
<string name="routing_attr_height_name">Altura máxima</string>
<string name="routing_attr_height_description">Especifique a altura permitida do veículo nas rotas.</string>
@ -2504,7 +2504,7 @@
\n
\nPoderá usar o navegador visual e por voz, ver POIs (pontos de interesse), criar e gerir trilhos GPX, usar (através de uma extensão) curvas de nível e dados de altitude, escolher entre os modos motorista, ciclista e pedestre, editar o OpenStreetMap e muito mais.</string>
<string name="osmand_extended_description_part2">Navegação GPS
\n• Escolha entre modos off-line (sem tarifa de roaming quando estiver no exterior) ou on-line (mais rápido)
\n• Escolha entre modos offline (sem tarifa de roaming quando estiver no exterior) ou online (mais rápido)
\n• Orientação por voz passo-a-passo lhe guia ao longo do caminho (vozes gravadas e sintetizadas)
\n• A rota é recalculada sempre que se desviar dela
\n• Orientação de pista, nomes de ruas e tempo estimado de chegada ajudará ao longo do caminho
@ -2515,14 +2515,14 @@
\n• Suporta pontos intermédios no seu itinerário
\n• Grave ou envie um trilho GPX e siga-a
\n</string>
<string name="osmand_extended_description_part3">Mapa
\n• Mostra POIs (ponto de interesse) perto de si
\n• Ajusta o mapa na sua direção de movimento (ou bússola)
\n• Mostra a sua posição e direção para onde está olhando
\n• Partilhe sua posição para que seus amigos possam encontrá-lo
\n• Mantém seus lugares mais importantes em \'Favoritos\'
\n• Permite-lhe escolher como mostrar nomes no mapa: em inglês, local ou escrita fonética
\n• Mostra mapas on-line especializados, vista de satélite (do Bing), sobreposições diferentes como trajetos GPX de navegação/turismo e camadas adicionais com transparência personalizável
<string name="osmand_extended_description_part3">Mapa
\n• Mostra POIs (ponto de interesse) perto de si
\n• Ajusta o mapa na sua direção de movimento (ou bússola)
\n• Mostra a sua posição e direção para onde está olhando
\n• Partilhe sua posição para que seus amigos possam encontrá-lo
\n• Mantém seus lugares mais importantes em \'Favoritos\'
\n• Permite-lhe escolher como mostrar nomes no mapa: em inglês, local ou escrita fonética
\n• Mostra mapas online especializados, vista de satélite (do Bing), sobreposições diferentes como trajetos GPX de navegação/turismo e camadas adicionais com transparência personalizável
\n</string>
<string name="osmand_extended_description_part4">Esqui
\nA extensão de mapas de esqui OsmAnd Ski permite que veja pistas de esqui com nível de complexidade e algumas informações adicionais, como localização de elevadores e outras instalações invernais.</string>
@ -2565,7 +2565,7 @@
\n
\nAlgumas das características principais:</string>
<string name="osmand_plus_extended_description_part2">Navegação
\n• Funciona on-line (rápido) ou off-line (sem custos de roaming quando estiver no estrangeiro)
\n• Funciona online (rápido) ou offline (sem custos de roaming quando estiver no estrangeiro)
\n• Orientação por voz passo a passo (vozes gravadas e sintetizadas)
\n• Orientação de trajetos opcionais, visualização do nome da rua e tempo estimado de chegada
\n• Suporta pontos intermédios do seu itinerário
@ -2585,7 +2585,7 @@
\n • Dados do OpenStreetMap disponíveis por país ou região
\n • POIs da Wikipédia, ótimo para passeios turísticos
\n • Descarregamentos grátis ilimitados, diretamente da aplicação
\n • Mapas off-line vetoriais compactos e atualizados mensalmente
\n • Mapas offline vetoriais compactos e atualizados mensalmente
\n
\n • Escolha entre região completa ou apenas a rede rodoviária (exemplo: o Japão inteiro tem 700 MB e a rede rodoviária tem apenas 200 MB)</string>
<string name="osmand_plus_extended_description_part5">Recursos de segurança
@ -2598,15 +2598,15 @@
\n• Visualização de caminhos a pé, pistas de caminhadas e ciclovias, ideal para atividades ao ar livre
\n• Navegação e modos de visualização especiais para bicicleta e pedestres
\n• Paragens de transporte público opcionais (autocarro, elétrico, comboio) incluindo nomes de linhas
\n• Gravação opcional de viagem para ficheiro GPX local ou serviço on-line
\n• Gravação opcional de viagem para ficheiro GPX local ou serviço online
\n• Visualização opcional de velocidade e altitudes
\n• Visualização de curvas de nível e sombreamento de relevo (com uma extensão adicional)</string>
<string name="osmand_plus_extended_description_part7">Contribua diretamente para o OpenStreetMap
\n • Envie relatórios de erros.
\n • Envie trilhos GPX para o OpenStreetMap diretamente da aplicação.
\n • Adicione POIs e envie-os diretamente para o OpenStreetMap (ou mais tarde se estiver desconectado da Internet).
\n • Gravação de viagem opcional também em plano de fundo (enquanto o dispositivo está no modo adormecido).
\n O OsmAnd é um programa de fonte aberta desenvolvido ativamente. Todos podem contribuir para a aplicação reportando erros, a melhorar as traduções ou a programar novas funcionalidades. Além disso, o projeto conta com contribuições financeiras para financiar a programação e testes de novas funcionalidades.
\n• Envie relatórios de erros.
\n• Envie trilhos GPX para o OpenStreetMap diretamente da aplicação.
\n• Adicione POIs e envie-os diretamente para o OpenStreetMap (ou mais tarde se estiver desconectado da Internet).
\n• Gravar viagem opcional também em plano de fundo (enquanto o dispositivo está no modo adormecido).
\n O OsmAnd é um programa de fonte aberta desenvolvido ativamente. Todos podem contribuir para a aplicação reportando erros, a melhorar as traduções ou a programar novas funcionalidades. Além disso, o projeto conta com contribuições financeiras para financiar a programação e testes de novas funcionalidades.
\n</string>
<string name="osmand_plus_extended_description_part8">Cobertura de mapa e qualidade aproximada:
\n• Europa Ocidental: ****
@ -2627,7 +2627,7 @@
<string name="arrival_distance_factor_normally">Normal</string>
<string name="arrival_distance_factor_late">Atrasado</string>
<string name="arrival_distance_factor_at_last">Nos últimos metros</string>
<string name="live_monitoring_max_interval_to_send">Buffer de tempo para rastreamento on-line</string>
<string name="live_monitoring_max_interval_to_send">Buffer de tempo para rastreamento online</string>
<string name="live_monitoring_max_interval_to_send_desrc">Especificar um buffer de tempo para manter locais para enviar sem conexão</string>
<string name="index_name_netherlands">Europa - Países Baixos</string>
<string name="shared_string_others">Outros</string>
@ -2636,7 +2636,7 @@
<string name="favourites_context_menu_add">Adicionar favorito</string>
<string name="poi_action_delete">eliminar</string>
<string name="poi_dialog_reopen">Reabrir</string>
<string name="av_camera_pic_size">Tamanho da foto</string>
<string name="av_camera_pic_size">Tamanho da fotografia</string>
<string name="av_camera_pic_size_descr">Definir o tamanho da imagem</string>
<string name="get_plugin">Obter</string>
<string name="use_fast_recalculation">Recálculo de rota inteligente</string>
@ -2657,7 +2657,7 @@
<string name="shared_string_undo">Desfazer</string>
<string name="app_name_osmand">OsmAnd</string>
<string name="offline_maps_and_navigation">Mapas e navegação
\noff-line</string>
\noffline</string>
<string name="commit_poi">Enviar POI</string>
<string name="tab_title_basic">Básico</string>
<string name="tab_title_advanced">Avançado</string>
@ -2685,7 +2685,7 @@
<string name="file_size_in_mb">%.1f MB</string>
<string name="update_all">Atualizar tudo (%1$s MB)</string>
<string name="save_poi_too_many_uppercase">O nome contém demasiadas letras maiúsculas. Continuar\?</string>
<string name="configure_screen_quick_action">Ação rápida</string>
<string name="configure_screen_quick_action">Botão de ação rápida</string>
<string name="quick_action_item_action">Ação %d</string>
<string name="quick_action_item_screen">Ecrã %d</string>
<string name="quick_action_add_marker">Adicionar marcador de mapa</string>
@ -2694,25 +2694,25 @@
<string name="quick_action_map_style_switch">O estilo do mapa foi alterado para \"%s\".</string>
<string name="quick_action_take_audio_note">Nova nota de áudio</string>
<string name="quick_action_take_video_note">Nova nota de vídeo</string>
<string name="quick_action_take_photo_note">Nova nota de foto</string>
<string name="quick_action_take_photo_note">Nova nota de fotografia</string>
<string name="quick_action_add_osm_bug">Adicionar nota OSM</string>
<string name="quick_action_navigation_voice">Ligar/desligar voz</string>
<string name="quick_action_navigation_voice_off">Ativar voz</string>
<string name="quick_action_navigation_voice_on">Desativar voz</string>
<string name="quick_action_add_parking">Adicionar local de estacionamento</string>
<string name="quick_action_new_action">Adicionar ação</string>
<string name="quick_action_edit_action">Editar ação</string>
<string name="quick_action_edit_action">Editar botão de ação rápida</string>
<string name="quick_action_add_favorite">Adicionar favorito</string>
<string name="dialog_add_action_title">Adicionar ação</string>
<string name="quick_actions_delete">Eliminar ação</string>
<string name="quick_actions_delete_text">Tem a certeza de que quer eliminar a ação \"%s\"\?</string>
<string name="quick_actions_delete">Eliminar botão de ação rápida</string>
<string name="quick_actions_delete_text">Tem a certeza de que quer eliminar o botão de ação rápida \"%s\"\?</string>
<string name="quick_favorites_show_favorites_dialog">Mostrar lista dos favoritos</string>
<string name="quick_favorites_name_preset">Nome do modelo</string>
<string name="quick_action_add_marker_descr">O botão é para adicionar um marcador de mapa no local do centro do ecrã.</string>
<string name="quick_action_add_gpx_descr">Um botão para adicionar um ponto de rota GPX no local do centro do ecrã.</string>
<string name="quick_action_take_audio_note_descr">Um botão para adicionar uma nota de áudio no local do centro do ecrã.</string>
<string name="quick_action_take_video_note_descr">Um botão para adicionar uma nota de vídeo no local do centro do ecrã.</string>
<string name="quick_action_take_photo_note_descr">Um botão para adicionar uma nota de foto no local do centro do ecrã.</string>
<string name="quick_action_take_photo_note_descr">Um botão para adicionar uma nota de fotografia no local do centro do ecrã.</string>
<string name="quick_action_add_osm_bug_descr">Um botão para adicionar uma nota OSM no local do centro do ecrã.</string>
<string name="quick_action_add_poi_descr">Um botão para adicionar um POI no local do centro do ecrã.</string>
<string name="quick_action_navigation_voice_descr">Um botão para ativar ou desativar a orientação por voz durante a navegação.</string>
@ -2720,8 +2720,8 @@
<string name="quick_action_interim_dialog">Mostrar uma janela temporal</string>
<string name="favorite_autofill_toast_text">" guardado em "</string>
<string name="favorite_empty_place_name">Local</string>
<string name="quick_action_duplicates">O nome da ação rápida foi alterado para %1$s para evitar duplicação.</string>
<string name="quick_action_duplicate">Nome de ação rápida duplicado</string>
<string name="quick_action_duplicates">O nome do botão de ação rápida foi alterado para %1$s para evitar duplicação.</string>
<string name="quick_action_duplicate">Nome do botão de ação rápida duplicado</string>
<string name="quick_action_showhide_favorites_descr">Uma alternância para mostrar ou ocultar os pontos favoritos no mapa.</string>
<string name="quick_action_showhide_poi_descr">Uma alternância para mostrar ou ocultar POIs no mapa.</string>
<string name="quick_action_poi_show">Mostrar %1$s</string>
@ -2754,9 +2754,9 @@
<string name="quick_action_map_source_action">Adicionar origem do mapa</string>
<string name="quick_action_map_source_switch">A origem do mapa foi alterada para \"%s\".</string>
<string name="quick_action_btn_tutorial_title">Mudar posição do botão</string>
<string name="quick_action_btn_tutorial_descr">Segure e arraste o botão para mudar a sua posição no ecrã.</string>
<string name="quick_action_btn_tutorial_descr">Pressione e segure arrastando o botão para mudar a sua posição no ecrã.</string>
<string name="shared_string_action_name">Nome da ação</string>
<string name="mappilary_no_internet_desc">As fotos do Mapillary só estão disponíveis on-line.</string>
<string name="mappilary_no_internet_desc">As fotografias do Mapillary só estão disponíveis online.</string>
<string name="retry">Repetir</string>
<string name="add_route_points">Adicionar pontos de rota</string>
<string name="add_waypoint">Adicionar ponto de passagem</string>
@ -2782,7 +2782,7 @@
<string name="show_tunnels">Túneis</string>
<string name="download_wikipedia_description">Descarregar artigos da Wikipédia de %1$s para lê-los offline.</string>
<string name="download_wikipedia_label">Descarregar dados da Wikipédia</string>
<string name="open_in_browser_wiki">Abrir artigo on-line</string>
<string name="open_in_browser_wiki">Abrir artigo na Internet</string>
<string name="open_in_browser_wiki_description">Ver artigo no navegador web.</string>
<string name="download_wiki_region_placeholder">esta região</string>
<string name="wiki_article_search_text">A procurar o artigo wiki correspondente</string>
@ -2890,17 +2890,17 @@
<string name="show_more">Mostrar mais</string>
<string name="tracks_on_map">Trilhos mostrados</string>
<string name="quick_action_show_hide_gpx_tracks_descr">Um botão para mostrar ou ocultar trilhos selecionados no mapa.</string>
<string name="routing_attr_avoid_tram_name">Sem elétricos</string>
<string name="routing_attr_avoid_tram_name">Evitar elétricos</string>
<string name="routing_attr_avoid_tram_description">Evita elétricos</string>
<string name="routing_attr_avoid_bus_name">Sem autocarros</string>
<string name="routing_attr_avoid_bus_name">Evitar autocarros</string>
<string name="routing_attr_avoid_bus_description">Evita autocarros e troleicarros</string>
<string name="routing_attr_avoid_share_taxi_name">Sem táxis partilhados</string>
<string name="routing_attr_avoid_share_taxi_name">Evitar táxis partilhados</string>
<string name="routing_attr_avoid_share_taxi_description">Evita táxis partilhados</string>
<string name="routing_attr_avoid_train_name">Sem comboios</string>
<string name="routing_attr_avoid_train_name">Evitar comboios</string>
<string name="routing_attr_avoid_train_description">Evitar comboios</string>
<string name="routing_attr_avoid_subway_name">Sem metropolitanos</string>
<string name="routing_attr_avoid_subway_name">Evitar metropolitanos</string>
<string name="routing_attr_avoid_subway_description">Evitar metropolitanos subterrâneos e de superfície</string>
<string name="routing_attr_avoid_ferry_name">Sem balsas/ferries</string>
<string name="routing_attr_avoid_ferry_name">Evitar balsas/ferries</string>
<string name="routing_attr_avoid_ferry_description">Evita balsas/ferries</string>
<string name="shared_string_milliradians">Milirradianos</string>
<string name="rendering_attr_surface_sett_name">Paralelos</string>
@ -2997,7 +2997,7 @@
<string name="third_party_routing_type">Roteamento de terceiros</string>
<string name="application_profiles_descr">Escolha os perfis mostrados na aplicação.</string>
<string name="application_profiles">Perfis da aplicação</string>
<string name="quick_action_need_to_add_item_to_list">Adicione pelo menos um item à lista nas configurações de \'Ação rápida\'</string>
<string name="quick_action_need_to_add_item_to_list">Adicione pelo menos um item à lista nas configurações de \'Botão de ações rápidas\'</string>
<string name="routing_attr_piste_type_downhill_name">Esqui alpino e descendente</string>
<string name="routing_attr_piste_type_downhill_description">Pistas para esqui alpino ou downhill e acesso a teleféricos de esqui.</string>
<string name="routing_attr_piste_type_nordic_name">Esqui de travessia e nórdico</string>
@ -3118,7 +3118,7 @@
<string name="years_5">Anos</string>
<string name="months_3">Três meses</string>
<string name="price_free">Grátis</string>
<string name="get_discount_title">Obter %1$d %2$s com %3$s de desconto.</string>
<string name="get_discount_title">Obtenha %1$d %2$s com %3$s de desconto.</string>
<string name="get_discount_second_part">depois %1$s</string>
<string name="cancel_subscription">Cancelar subscrição</string>
<string name="price_and_discount">%1$s - Poupe %2$s</string>
@ -3133,7 +3133,7 @@
<string name="coordinates_format_info">O formato selecionado será aplicado em toda a aplicação.</string>
<string name="pref_selected_by_default_for_profiles">Esta configuração é selecionada por padrão para os perfis: %s</string>
<string name="change_default_settings">Alterar a configuração</string>
<string name="discard_changes">Descartar alteração</string>
<string name="discard_changes">Cancelar alteração</string>
<string name="apply_to_current_profile">Aplicar só a \"%1$s\"</string>
<string name="apply_to_all_profiles">Aplicar a todos os perfis</string>
<string name="start_up_message_pref">Mensagem de inicialização</string>
@ -3525,7 +3525,7 @@
<string name="select_wikipedia_article_langs">Selecione as línguas dos artigos da Wikipédia no mapa. Mude para qualquer língua disponível enquanto lê o artigo.</string>
<string name="mapillary_item">OsmAnd + Mapillary</string>
<string name="tracker_item">OsmAnd Tracker</string>
<string name="quick_action_item">Ação rápida</string>
<string name="quick_action_item">Botão de ações rápidas</string>
<string name="radius_ruler_item">Régua radial</string>
<string name="measure_distance_item">Medir distância</string>
<string name="travel_item">Viagem (Wikivoyage e Wikipédia)</string>
@ -3604,9 +3604,9 @@
<string name="pseudo_mercator_projection">Projeção pseudo-Mercator</string>
<string name="one_image_per_tile">Um ficheiro de imagem por mosaico</string>
<string name="sqlite_db_file">Ficheiro SQLiteDB</string>
<string name="online_map_name_helper_text">Forneça um nome para a origem do mapa on-line.</string>
<string name="online_map_url_helper_text">Introduza ou cole o URL para a origem on-line.</string>
<string name="edit_online_source">Editar origem on-line</string>
<string name="online_map_name_helper_text">Forneça um nome para a origem do mapa online.</string>
<string name="online_map_url_helper_text">Introduza ou cole o URL para a origem online.</string>
<string name="edit_online_source">Editar origem online</string>
<string name="expire_time">Tempo de validade</string>
<string name="mercator_projection">Projeção de Mercator</string>
<string name="storage_format">Formato de armazenamento</string>
@ -3648,7 +3648,7 @@
\nSelecione %1$s e receberá alertas e avisos sobre radares de velocidade.
\n
\nSelecione %2$s e yodos os dados relacionados a radares de velocidade: alertas, notificações, POIs serão eliminados até que o OsmAnd seja completamente reinstalado.</string>
<string name="plugin_wikipedia_description">Obter informações sobre pontos de interesse da Wikipédia. Um guia de bolso off-line para ver artigos sobre locais e destinos.</string>
<string name="plugin_wikipedia_description">Obter informações sobre pontos de interesse da Wikipédia. Um guia de bolso offline para ver artigos sobre locais e destinos.</string>
<string name="app_mode_motor_scooter">Scooter</string>
<string name="quick_action_remove_next_destination">Eliminar o ponto de destino mais próximo</string>
<string name="search_download_wikipedia_maps">Descarregar mapas da Wikipédia</string>
@ -3704,7 +3704,7 @@
<string name="add_to_a_track">Adicionar a um trilho</string>
<string name="add_hidden_group_info">O ponto adicionado não será visível no mapa, já que o grupo selecionado está escondido, pode encontrá-lo em \"%s\".</string>
<string name="track_show_start_finish_icons">Mostrar ícones de início e fim</string>
<string name="select_track_width">Selecionar a largura</string>
<string name="select_track_width">Selecionar espessura da linha do trilho</string>
<string name="gpx_split_interval_descr">Selecione o intervalo em que as marcas com distância ou tempo no trilho serão mostradas.</string>
<string name="gpx_split_interval_none_descr">Selecione a opção de divisão desejada: por tempo ou por distância.</string>
<string name="shared_string_custom">Personalizado</string>
@ -3715,7 +3715,7 @@
<string name="plan_route_open_existing_track">Abrir trilho existente</string>
<string name="plan_route_select_track_file_for_open">Selecione um ficheiro de trilho para abrir.</string>
<string name="plan_route_create_new_route">Criar nova rota</string>
<string name="shared_string_done">Pronto</string>
<string name="shared_string_done">Feito</string>
<string name="overwrite_track">Substituir trilho</string>
<string name="save_as_new_track">Guardar como novo trilho</string>
<string name="reverse_route">Rota inversa</string>
@ -3759,9 +3759,9 @@
<string name="save_track_to_gpx_globally">Registar o trilho num ficheiro GPX</string>
<string name="layer_gpx_layer">Trilhos</string>
<string name="context_menu_item_add_waypoint">Adicionar ponto de passagem de trilho</string>
<string name="map_widget_monitoring">Gravação de viagem</string>
<string name="map_widget_monitoring">Gravar viagem</string>
<string name="monitoring_control_start">Gravar</string>
<string name="save_global_track_interval_descr">Especifique o intervalo de registo para a gravação geral do trilho (ligado através do widget de \'gravação de viagem\' no mapa).</string>
<string name="save_global_track_interval_descr">Especifique o intervalo de registo para a gravação geral do trilho (ligado através do widget de \'Gravar viagem\' no mapa).</string>
<string name="gpx_monitoring_stop">Pausar a gravação da viagem</string>
<string name="gpx_monitoring_start">Retomar a gravação da viagem</string>
<string name="system_default_theme">Predefinição do sistema</string>
@ -3865,10 +3865,10 @@
<string name="osm_edit_close_note">Fechar nota do OSM</string>
<string name="osm_edit_comment_note">Comentário de nota do OSM</string>
<string name="osm_login_descr">Pode iniciar sessão pelo método seguro OAuth ou use o seu nome de utilizador e a palavra-passe.</string>
<string name="shared_string_add_photo">Adicionar foto</string>
<string name="shared_string_add_photo">Adicionar fotografia</string>
<string name="register_on_openplacereviews">Crie uma conta em
\nOpenPlaceReviews.org</string>
<string name="register_on_openplacereviews_desc">As fotos são fornecidas pelo projeto de dados abertos OpenPlaceReviews.org. Para enviar as suas fotos tem de criar uma conta no site.</string>
<string name="register_on_openplacereviews_desc">As fotografias são fornecidas pelo projeto de dados abertos OpenPlaceReviews.org. Para enviar as suas fotografias tem de criar uma conta nesse site.</string>
<string name="register_opr_create_new_account">Criar uma conta</string>
<string name="register_opr_have_account">Já tenho uma conta</string>
<string name="shared_string_search_history">Histórico de pesquisa</string>
@ -3932,12 +3932,12 @@
<string name="analyze_by_intervals">Analisar por intervalos</string>
<string name="upload_to_openstreetmap">Enviar para OpenStreetMap</string>
<string name="edit_track">Editar trilho</string>
<string name="rename_track">Renomear trilho</string>
<string name="rename_track">Alterar nome do trilho</string>
<string name="change_folder">Mudar pasta</string>
<string name="hillshade_slope_contour_lines">Sombras de relevo / declives / curvas de nível</string>
<string name="open_place_reviews_plugin_description">OpenPlaceReviews é um projeto comunitário sobre lugares públicos como restaurantes, hotéis, museus, pontos de passagem. Recolhe toda a informação pública sobre eles, como fotos, resenhas, ligações para outros sistemas OpenStreetMap, Wikipédia.
<string name="open_place_reviews_plugin_description">OpenPlaceReviews é um projeto comunitário sobre lugares públicos como restaurantes, hotéis, museus, locais etc. Recolhe toda a informação pública sobre eles, como fotografias, classificações/avaliações, ligações para outros sistemas como o OpenStreetMap e a Wikipédia.
\n
\nTodos os dados do OpenPlaceReviews estão abertos e disponíveis para todos: http://openplacereviews.org/data.
\nTodos os dados do OpenPlaceReviews estão abertos e disponíveis para todos: http://openplacereviews.org/data
\n
\nPode ler mais em: http://openplacereviews.org</string>
<string name="open_place_reviews">OpenPlaceReviews</string>
@ -3962,11 +3962,11 @@
<string name="live_update_delete_updates_msg">Tem a certeza que quer eliminar todas as %s atualizações OsmAnd Live\?</string>
<string name="release_4_0_beta">• Atualizações OsmAnd Live movidas para \"Descarregamentos &gt; Atualizações\"
\n
\n • Os trilhos podem ser agora coloridos conforme a altitude, velocidade e declive.
\n• Os trilhos podem ser agora coloridos conforme a altitude, velocidade e declive.
\n
\n • Adicionada opção para alterar a aparência da linha de rota de navegação
\n• Adicionada opção para alterar a aparência da linha de rota de navegação
\n
\n • Janela de diálogo \"Gravação do trilho\" atualizada
\n• Janela de diálogo \"Gravação do trilho\" atualizada
\n
\n</string>
<string name="routing_attr_height_obstacles_description">O roteamento pode evitar subidas íngremes.</string>

View file

@ -141,8 +141,8 @@
<string name="routing_attr_height_obstacles_name">Использовать данные о высотах</string>
<string name="quick_action_duplicates">Действие переименовано в %1$s, чтобы избежать дублирования.</string>
<string name="quick_action_duplicate">Обнаружен дубликат имени</string>
<string name="quick_action_showhide_favorites_descr">Переключатель, чтобы показать или скрыть избранные точки на карте.</string>
<string name="quick_action_showhide_poi_descr">Переключатель, чтобы показать или скрыть POI на карте.</string>
<string name="quick_action_showhide_favorites_descr">Переключатель для отображения или скрытия избранных точек на карте.</string>
<string name="quick_action_showhide_poi_descr">Переключатель для отображения или скрытия POI на карте.</string>
<string name="quick_action_add_category">Категория</string>
<string name="quick_action_add_create_items">Действия</string>
<string name="quick_action_fav_name_descr">Если оставить это поле пустым, то оно будет автоматически заполнено адресом или названием места.</string>
@ -3660,7 +3660,7 @@
<string name="vessel_height_warning">Вы можете указать высоту судна, чтобы избегать низких мостов. Имейте в виду, что если мост раздвижной, будет использована его высота в открытом состоянии.</string>
<string name="vessel_height_limit_description">Укажите высоту судна, чтобы избежать низких мостов. Имейте в виду, что если мост раздвижной, будет использована его высота в открытом состоянии.</string>
<string name="vessel_width_limit_description">Укажите ширину судна, чтобы избежать узких мостов</string>
<string name="quick_action_showhide_mapillary_descr">Переключатель, чтобы показать или скрыть слой Mapillary на карте.</string>
<string name="quick_action_showhide_mapillary_descr">Переключатель для отображения или скрытия слоя Mapillary на карте.</string>
<string name="shared_string_legal">Законодательство</string>
<string name="speed_cameras_legal_descr">В некоторых странах и регионах использование предупреждений о камерах контроля скорости запрещено законом.
\n

View file

@ -3894,4 +3894,38 @@
<string name="poi_local_ref">Riferimentu locale</string>
<string name="poi_geodesist">Geodesista</string>
<string name="poi_conference_centre">Tzentru pro cunferèntzias</string>
<string name="poi_wakeboarding">Wakeboard</string>
<string name="poi_ultimate">Ultimate</string>
<string name="poi_speedway">Pista pro mototziclismu</string>
<string name="poi_horseshoes">Tiru de ferros de caddu</string>
<string name="poi_cycle_polo">Polo in bitzicleta</string>
<string name="poi_curling">Curling</string>
<string name="poi_crossfit">Crossfit</string>
<string name="poi_cockfighting">Lutas de puddos</string>
<string name="poi_cliff_diving">Imbèrghidas dae sos iscameddos</string>
<string name="poi_bobsleigh">Bob</string>
<string name="poi_biathlon">Biathlon</string>
<string name="poi_water_ski">Iscì de abba</string>
<string name="poi_water_polo">Polo de abba</string>
<string name="poi_zurkhaneh_sport">Zurkhaneh</string>
<string name="poi_wrestling">Luta</string>
<string name="poi_weightlifting">Artziada de pesos</string>
<string name="poi_office_diplomatic">Ufìtziu diplomàticu</string>
<string name="poi_kickboxing">Kickboxing</string>
<string name="poi_fencing">Ischerma</string>
<string name="poi_bullfighting">Corrida</string>
<string name="poi_aikido">Aikido</string>
<string name="poi_taekwondo">Taekwondo</string>
<string name="poi_table_soccer">Biliardinu</string>
<string name="poi_sumo">Sumo</string>
<string name="poi_snooker">Snooker</string>
<string name="poi_shot_put">Tiru de su pesu</string>
<string name="poi_pilates">Pilates</string>
<string name="poi_jiu_jitsu">Jiu-jitsu</string>
<string name="poi_karate">Karatè</string>
<string name="poi_hoops">Canisteddos</string>
<string name="poi_camp_pitch">Pratzola de acampamentu</string>
<string name="poi_bay_filter">Casta de baia</string>
<string name="poi_club_social">Tzìrculu sotziale</string>
<string name="poi_plateau">Artipranu</string>
</resources>

View file

@ -1769,7 +1769,7 @@
<string name="shared_string_commit">Imbia</string>
<string name="osm_edit_modified_poi">PDI OSM modificadu</string>
<string name="osm_edit_deleted_poi">PDI OSM iscantzelladu</string>
<string name="copied_to_clipboard">Copiadu in sos apuntos</string>
<string name="copied_to_clipboard">Copiadu in punta de billete</string>
<string name="osm_save_offline">Sarva in sa memòria (impreu chene lìnia)</string>
<string name="rendering_attr_currentTrackColor_description">Colore GPX</string>
<string name="rendering_attr_currentTrackWidth_description">Largària GPX</string>
@ -4046,4 +4046,41 @@
<string name="lost_data_warning">Totu sos datos non sarvados s\'ant a pèrdere.</string>
<string name="show_start_dialog">Ammustra su diàlogu de incumintzu</string>
<string name="specify_color_for_map_mode">Dislinda unu colore pro sa modalidade pro sa mapa: %1$s.</string>
<string name="release_4_0_beta">• Agiornamentos de OsmAnd Live (OSmAnd in direta) tramudados cara a \"Iscarrigamentos &gt; Agiornamentos\"
\n
\n • Sas rastas como si podent colorizare pro artària, lestresa, o pendèntzia.
\n
\n • Annanghidura de s\'optzione pro mudare s\'aparèntzia de sa lìnia de navigatzione de s\'àndala
\n
\n • Agiornamentu de sa ventanedda de diàlogu \"Registratzione de su biàgiu\"
\n
\n</string>
<string name="in_grace_period">In perìodu de gràtzia</string>
<string name="osmand_live">OsmAnd in direta</string>
<string name="app_mode_gap">Divàriu</string>
<string name="trip_recording_logging_interval_info">S\'intervallu de registratzione impostat sa frecuèntzia cun sa cale OsmAnd at a pedire sos datos de sa positzione atuale.</string>
<string name="trip_recording_show_start_dialog_setting">Si est disabilitadu sa registratzione at a incumintzare a pustis de su tocu in subra de su widget o de s\'elementu de su menù, brinchende sa ventanedda de diàlogu de cunfirma.</string>
<string name="customize_route_line">Personaliza sa lìnia de s\'àndala</string>
<string name="shared_string_route_line">Lìnia de s\'àndala</string>
<string name="route_line_use_map_style_appearance">Pro sa lìnia de s\'àndala s\'at a impreare su %1$s dislindadu in s\'istile de sa mapa ischertadu: %2$s.</string>
<string name="no_purchases">Non tenes còmpora peruna</string>
<string name="new_device_account">Dispositivu nou / contu nou</string>
<string name="contact_support_description">Si tenes preguntas cuntata·nos a su %1$s.</string>
<string name="empty_purchases_description">Si sa còmpora tua non benit ammustrada inoghe toca in “%1$s” o cuntata su grupu de suportu nostru.</string>
<string name="contact_support">Cuntata su suportu</string>
<string name="troubleshooting">Risolutzione de problemas</string>
<string name="troubleshooting_description">Si tenes problemas cun sa còmpora sighi custu ligàmene, pro praghere.</string>
<string name="annual_subscription">Abbonamentu annuale</string>
<string name="monthly_subscription">Abbonamentu mensile</string>
<string name="three_months_subscription">Abbonamentu trimestrale</string>
<string name="next_billing_date">Data de addèbitu imbeniente: %1$s</string>
<string name="osmand_live_cancelled">Annulladu</string>
<string name="renew_subscription">Rinnova s\'abbonamentu</string>
<string name="on_hold">In isetu</string>
<string name="expired">Iscadidu</string>
<string name="update_all_maps_added">Agiornare totu sas mapas annànghidas a %1$s\?</string>
<string name="exit_number">Nùmeru de essida</string>
<string name="announce_when_exceeded">Avisa in casu de barigamentu</string>
<string name="user_points">Puntos de s\'impreadore</string>
<string name="output">Essida</string>
</resources>

View file

@ -1494,7 +1494,7 @@
<string name="local_osm_changes_upload_all_confirm">Naozaj chcete odoslať %1$d zmien do OSM\?</string>
<string name="confirmation_to_clear_history">Vymazať históriu?</string>
<string name="osmand_parking_overdue">prekročený čas</string>
<string name="confirm_usage_speed_cameras">Vo viacerých krajinách (ako Nemecko, Francúzsko, Taliansko) je použitie varovaní pred rýchlostnými radarmi/kamerami zakázané zákonom (nelegálne). OsmAnd nepreberá žiadnu zodpovednosť ak porušíte zákon. Stlačte \"Áno\" len ak ste na to oprávnený použiť túto funkciu.</string>
<string name="confirm_usage_speed_cameras">Vo viacerých krajinách (ako Nemecko, Francúzsko, Taliansko) je použitie varovaní pred rýchlostnými radarmi/kamerami zakázané zákonom. OsmAnd nepreberá žiadnu zodpovednosť ak porušíte zákon. Stlačte \"Áno\" len ak ste oprávnený použiť túto funkciu.</string>
<string name="welmode_download_maps">Stiahnuť mapy</string>
<string name="welcome_select_region">Vyberte svoj región, aby bolo možné správne nastaviť dopravné predpisy:</string>
<string name="welcome_text">OsmAnd poskytuje celosvetové offline mapy a offline navigáciu.</string>
@ -2729,7 +2729,7 @@
<string name="wikipedia_offline">Wikipédia offline</string>
<string name="contour_lines_hillshade_maps">Vrstevnice &amp; tieňované svahy</string>
<string name="unlock_all_features">Odomknite všetky funkcie OsmAnd</string>
<string name="download_wikipedia_description">Stiahnite články Wikipédie pre %1$s pre ich čítanie offline.</string>
<string name="download_wikipedia_description">Stiahnite články Wikipédie pre %1$s na ich čítanie offline.</string>
<string name="download_wikipedia_label">Stiahnuť údaje Wikipédie</string>
<string name="open_in_browser_wiki">Otvoriť článok online</string>
<string name="open_in_browser_wiki_description">Zobraziť článok vo webovom prehliadači.</string>
@ -4006,7 +4006,7 @@
<string name="routing_attr_driving_style_description">Zvoľte účel jazdy pre získanie kratšej, rýchlejšej alebo bezpečnejšej trasy</string>
<string name="map_orientation_threshold_descr">Neotáčať mapu, ak je rýchlosť nižšia ako hranica</string>
<string name="restart">Reštartovať</string>
<string name="shared_strings_all_regions">Všetky regióny</string>
<string name="shared_strings_all_regions">Všetky oblasti</string>
<string name="delete_number_files_question">Zmazať %1$d súborov\?</string>
<string name="track_recording_stop_without_saving">Zastaviť bez uloženia</string>
<string name="track_recording_save_and_stop">Uložiť a zastaviť záznam</string>

View file

@ -3867,4 +3867,45 @@
<string name="poi_water_source_river">Река</string>
<string name="poi_vaccination_covid19">Цепљење: Ковид 19</string>
<string name="poi_health_specialty_vaccination_yes">Цепљење</string>
<string name="poi_club_social">Друштвени клуб</string>
<string name="poi_plateau">Плато</string>
<string name="poi_office_diplomatic">Дипломатско представништво</string>
<string name="poi_kickboxing">Кик-бокс</string>
<string name="poi_fencing">Мачевање</string>
<string name="poi_curling">Курлинг</string>
<string name="poi_crossfit">Кросфит</string>
<string name="poi_cockfighting">Туча петлова</string>
<string name="poi_bullfighting">Борба са биковима</string>
<string name="poi_bobsleigh">Боб</string>
<string name="poi_biathlon">Биатлон</string>
<string name="poi_aikido">Аикидо</string>
<string name="poi_water_ski">Водено скијање</string>
<string name="poi_water_polo">Ватерполо</string>
<string name="poi_wrestling">Рвање</string>
<string name="poi_weightlifting">Дизање тегова</string>
<string name="poi_wakeboarding">Вејкбординг</string>
<string name="poi_ultimate">Ултимат</string>
<string name="poi_taekwondo">Таеквондо</string>
<string name="poi_table_soccer">Футсал</string>
<string name="poi_sumo">Сумо</string>
<string name="poi_snooker">Снукер</string>
<string name="poi_piste_status_open">Стање стазе: отворена</string>
<string name="poi_patrolled_no">Обилажена: не</string>
<string name="poi_patrolled_yes">Обилажена: да</string>
<string name="poi_piste_name">Име стазе</string>
<string name="poi_piste_ski_jump">Ски скок</string>
<string name="poi_wildlife_crossing_bat_tunnel">Тунел за слепе мишеве</string>
<string name="poi_wildlife_crossing_bat_bridge">Мост за слепе мишеве</string>
<string name="poi_wildlife_crossing">Прелаз за дивљач</string>
<string name="poi_swimming_area">Део за пливање</string>
<string name="poi_lavoir">Појило</string>
<string name="poi_waste_transfer_station">Станица за пренос отпада</string>
<string name="poi_weightbridge">Колска вага</string>
<string name="poi_ranger_station">Шумарска станица</string>
<string name="poi_water_source_tube_well">Цевни бунар</string>
<string name="poi_water_source_well">Бунар</string>
<string name="poi_water_source_powered_pump">Електрична пумпа</string>
<string name="poi_water_source_water_tank">Танк са водом</string>
<string name="poi_water_source_tap">Чесма</string>
<string name="poi_bay_filter">Тип залива</string>
</resources>

View file

@ -662,7 +662,7 @@
<string name="share_osm_edits_subject">ОСМ измене дељене преко OsmAnd-а</string>
<string name="osm_edit_created_poi">OSM тачка од интереса је направљена</string>
<string name="nm">nmi</string>
<string name="nm_h">kn</string>
<string name="nm_h">чв</string>
<string name="min_mile">min/m</string>
<string name="min_km">min/km</string>
<string name="m_s">m/s</string>
@ -922,7 +922,7 @@
<string name="rendering_attr_roadColors_name">Образац боја путева</string>
<string name="enable_plugin_monitoring_services">Омогућите додатак за „снимање путовања“ ради коришћења услуга бележења (GPX бележење, праћење положаја на мрежи)</string>
<string name="non_optimal_route_calculation">Рачунај могућу приближну путању за велике раздаљине</string>
<string name="gps_not_available">Омогућите GPS у поставкама</string>
<string name="gps_not_available">Омогућите GPS у подешавањима</string>
<string name="map_widget_monitoring_services">Услуге бележења путање</string>
<string name="no_route">Нема пута</string>
<string name="arrived_at_intermediate_point">Стигли сте на пролазно одредиште</string>
@ -1005,7 +1005,7 @@
<string name="new_filter_desc">Молимо, унесите име новог филтера који ће бити придодат језичку „Категорије“.</string>
<string name="osm_live_payment_desc">Чланарина се наплаћује по одабраном периоду. Можете је отказати на Гугл плеју кад год пожелите.</string>
<string name="donation_to_osm">Прилог ОСМ заједници</string>
<string name="donation_to_osm_desc">Део Вашег прилога ће бити послат корисницима ОСМ-а. Чланарина остаје иста.</string>
<string name="donation_to_osm_desc">Део Ваше чланарине ће бити послат корисницима ОСМ-а. Чланарина остаје иста.</string>
<string name="osm_live_subscription_desc">Чланарина омогућава часовне, дневне и седмичне надоградње, и неограничена преузимања свих карата.</string>
<string name="get_it">Добавите је</string>
<string name="get_for">Добавите за %1$s</string>
@ -1062,9 +1062,9 @@
<string name="access_direction_audio_feedback_descr">Указуј на правац циљне тачке звуком.</string>
<string name="access_direction_haptic_feedback">Упутства трешењем</string>
<string name="access_direction_haptic_feedback_descr">Указуј на правац циљне тачке трешњом.</string>
<string name="use_osm_live_routing_description">Омогући навођење живих измена ОСМ-а.</string>
<string name="use_osm_live_routing_description">Омогући навођење измена ОСМ-а уживо.</string>
<string name="use_osm_live_routing">Навођење уживо ОСМ-а</string>
<string name="access_no_destination">Одредиште није подешено</string>
<string name="access_no_destination">Додатак за приступачност: Одредиште није подешено</string>
<string name="access_category_choice">Изаберите категорију</string>
<string name="storage_directory_readonly_desc">Пребачено на интерну меморију пошто је означено складиште за податке заштићено од писања. Изаберите фасциклу за складиште у коју може да се пише.</string>
<string name="save_track_interval_descr">Наведите интервал логовања снимања путање приликом навођења</string>
@ -1221,7 +1221,7 @@
<string name="rendering_attr_horseRoutes_name">Коњске стазе</string>
<string name="share_geo">положај:</string>
<string name="lang_br">Бретонски</string>
<string name="hillshade_menu_download_descr">Преузмите слој са сенчењем да бисте видели рељеф на карти.</string>
<string name="hillshade_menu_download_descr">Преузмите карту слоја са сенчењем да бисте видели рељеф на карти.</string>
<string name="hillshade_purchase_header">Инсталирајте додатак \"Изохипсе\" да прикажете нагиб вертикалних области.</string>
<string name="shared_string_plugin">Додатак</string>
<string name="display_zoom_level">Приказ нивоа увеличања: %1$s</string>
@ -1234,11 +1234,11 @@
<string name="shared_string_add_photos">Додај слике</string>
<string name="no_photos_descr">Нема слика овде.</string>
<string name="mapillary_action_descr">Поделите Ваш поглед са улице преко Мапилара.</string>
<string name="mapillary_widget">Справица Мапилара</string>
<string name="mapillary_widget_descr">Омогућава брзи допринос Мапилару.</string>
<string name="open_mapillary">Отвори Мапилар</string>
<string name="mapillary_widget">Mapillary справица</string>
<string name="mapillary_widget_descr">Омогућава брзи допринос Mapillary-ју.</string>
<string name="open_mapillary">Отвори Mapillary</string>
<string name="mapillary_descr">Мрежне слике улица за све. Откријте места, сарађујте, освојите свет.</string>
<string name="mapillary">Мапилари</string>
<string name="mapillary">Mapillary</string>
<string name="plugin_mapillary_descr">Мрежне слике улица за све. Откријте места, сарађујте, освојите свет.</string>
<string name="private_access_routing_req">Ваше одредиште се налази на приватном поседу. Дозволити коришћење приватних путева на овом путовању\?</string>
<string name="restart_search">Препокрени претрагу</string>
@ -1512,8 +1512,8 @@
<string name="import_gpx_failed_descr">Не могу да увезем фајл. Проверите да ли OsmAnd има дозволе за читање фајла.</string>
<string name="distance_moving">Растојање је исправљено</string>
<string name="mapillary_image">Слика са Мапилара</string>
<string name="improve_coverage_mapillary">Побољшајте покривеност слика користећи Мапилар</string>
<string name="improve_coverage_install_mapillary_desc">Инсталирајте програм Мапилар (Mapillary) да додате слике на ову локацију на карти.</string>
<string name="improve_coverage_mapillary">Побољшајте покривеност слика користећи Mapillary</string>
<string name="improve_coverage_install_mapillary_desc">Инсталирајте програм Mapillary да додате слике на ову локацију на карти.</string>
<string name="subscribe_email_desc">Претплатите се на нашу дописну листу за попуст и добијте још 3 преузимања карти!</string>
<string name="depth_contour_descr">Изобате мора (изохипсе дубине) и карте поморских ознака.</string>
<string name="sea_depth_thanks">Хвала Вам на куповини „Поморских изобата“</string>
@ -1861,7 +1861,7 @@
<string name="quick_action_btn_tutorial_title">Помери дугме</string>
<string name="quick_action_btn_tutorial_descr">Дуго држање и превлачење дугмета га помера по екрану.</string>
<string name="shared_string_action_name">Име радње</string>
<string name="mappilary_no_internet_desc">Слике са Мапилара је могуће видети само ако сте повезани на интернет.</string>
<string name="mappilary_no_internet_desc">Слике са Mapillary-ја је могуће видети само ако сте повезани на интернет.</string>
<string name="retry">Покушај поново</string>
<string name="empty_state_favourites">Додај омиљене</string>
<string name="empty_state_favourites_desc">Увезите Омиљене тачке или их додајте означавајући их као ознаке на карти.</string>
@ -2134,7 +2134,7 @@
<string name="plugin_install_needs_network">Морате имати интернет да бисте инсталирали овај додатак.</string>
<string name="get_plugin">Преузми</string>
<string name="use_fast_recalculation">Пмаетно прерачунавање пута</string>
<string name="use_fast_recalculation_desc">Прерачунава само почетни део руте. Може се користити за дуга путовања.</string>
<string name="use_fast_recalculation_desc">Прерачунава само почетни део руте, корисно за дуга путовања.</string>
<string name="do_you_like_osmand">Да ли Вам се OsmAnd свиђа?</string>
<string name="we_really_care_about_your_opinion">Важно нам је да чујемо Ваше мишљење.</string>
<string name="rate_this_app">Оцените ову апликацију</string>
@ -2543,7 +2543,7 @@
<string name="update_poi_error_local">Не могу да ажурирам локални списак тачака од интереса.</string>
<string name="quick_action_add_gpx_descr">Дугме за додавање GPX пролазне тачке на средину екрана.</string>
<string name="show_images">Прикажи слике</string>
<string name="purchase_cancelled_dialog_title">Укинули сте чланарину за OsmAnd Live</string>
<string name="purchase_cancelled_dialog_title">Отказали сте чланарину за OsmAnd уживо</string>
<string name="purchase_cancelled_dialog_descr">Обновите чланарину да наставите да користите све ове функционалности:</string>
<string name="gpxup_identifiable">Може да се користи за идентификацију</string>
<string name="gpxup_trackable">Може да се користи за праћење</string>
@ -2581,7 +2581,7 @@
<string name="default_render_descr">Стил опште намене. Густи градови су приказани јасно. Приказује изохипсе, путање, квалитет подлоге, забране приступа, блокаде путева, исцртавање путева по SAC алпској скали, објекти за спортове на брзацима.</string>
<string name="open_wikipedia_link_online">Отвори Википедија везу са интернетом</string>
<string name="open_wikipedia_link_online_description">Веза ће бити отворена у веб читачу.</string>
<string name="read_wikipedia_offline_description">Да бисте читали чланке са Википедије и Wikivoyage-а, претплатите се на OsmAnd Live.</string>
<string name="read_wikipedia_offline_description">Да бисте читали чланке са Википедије и Wikivoyage-а, купите чланарину на OsmAnd уживо.</string>
<string name="how_to_open_link">Како да отворим везу?</string>
<string name="read_wikipedia_offline">Читај Википедију ван мреже</string>
<string name="download_all">Преузми све</string>
@ -2703,7 +2703,7 @@
\n - Окретањем мапе према компасу или правцу кретања
\n - Навођењем у праву траку, приказ ограничења брзине, снимљени и синтетизовани гласови за навођење
\n</string>
<string name="get_osmand_live">Набавите OsmAnd Live да откључате ове могућности: дневна ажурирања карти са неограниченим бројем скидања, сви и плаћени и бесплатни додаци, Википедија, Wikivoyage и још много тога.</string>
<string name="get_osmand_live">Набавите OsmAnd уживо да откључате ове могућности: дневна ажурирања карти са неограниченим бројем скидања, сви и плаћени и бесплатни додаци, Википедија, Wikivoyage и још много тога.</string>
<string name="osmand_extended_description_part3">Карта
\n • Приказ тачака од интереса око Вас
\n • Подешавање карте према правцу кретања (или компасу)
@ -2777,14 +2777,14 @@
<string name="osm_live_payment_month_cost_descr">%1$s / месечно</string>
<string name="osm_live_payment_month_cost_descr_ex">%1$.2f %2$s / месечно</string>
<string name="osm_live_payment_discount_descr">Уштедите %1$s</string>
<string name="osm_live_payment_current_subscription">Тренутна претплата</string>
<string name="osm_live_payment_current_subscription">Тренутна чланарина</string>
<string name="osm_live_payment_renews_monthly">Месечно обнављање</string>
<string name="osm_live_payment_renews_quarterly">Квартално обнављање</string>
<string name="osm_live_payment_renews_annually">Годишње обнављање</string>
<string name="default_price_currency_format">%1$.2f %2$s</string>
<string name="osm_live_payment_header">Период плаћања:</string>
<string name="osm_live_payment_contribute_descr">Донације помажу финансирање OSM картографа.</string>
<string name="osm_live_subscriptions">Претплате</string>
<string name="osm_live_subscriptions">Чланарине</string>
<string name="mapillary_menu_title_pano">Прикажи само слике од 360°</string>
<string name="shared_string_launch">Покрени</string>
<string name="lang_gn_py">Гварани</string>
@ -2894,8 +2894,8 @@
<string name="tracks_on_map">Приказане путање</string>
<string name="sit_on_the_stop">Укрцавање на стајању</string>
<string name="quick_action_show_hide_gpx_tracks_descr">Дугме које приказује или сакрива одабране путање са карте.</string>
<string name="use_osm_live_public_transport_description">Омогући јавни превоз на OsmAnd Live изменама.</string>
<string name="use_osm_live_public_transport">OsmAnd Live јавни превоз</string>
<string name="use_osm_live_public_transport_description">Омогући јавни превоз на OsmAnd уживо изменама.</string>
<string name="use_osm_live_public_transport">OsmAnd уживо јавни превоз</string>
<string name="rendering_attr_surface_sett_name">Калдрма</string>
<string name="rendering_attr_surface_paving_stones_name">Поплочано камење</string>
<string name="rendering_attr_highway_class_motorway_name">Ауто-пут</string>
@ -3119,7 +3119,7 @@
<string name="get_discount_first_part">%1$s првих %2$s</string>
<string name="get_discount_first_few_part">%1$s првих %2$s</string>
<string name="get_discount_second_part">онда %1$s</string>
<string name="cancel_subscription">Поништи претплату</string>
<string name="cancel_subscription">Поништи чланарину</string>
<string name="price_and_discount">%1$s • Уштеди %2$s</string>
<string name="configure_profile_info">Поставке за профил:</string>
<string name="utm_format_descr">OsmAnd користи UTM Standard format који је сличан, али није истоветан као UTM NATO format.</string>
@ -3330,7 +3330,7 @@
<string name="login_and_pass">Корисничко име и лозинка</string>
<string name="plugin_global_prefs_info">Ова подешавања додатака су глобална и примењују се на све профиле</string>
<string name="osm_editing">OSM уређивање</string>
<string name="osm_edits_view_descr">Све своје још увек не отпремљене измене или ОСМ белешке можете погледати у %1$s. Отпремљене тачке се не приказују у ОсмАнду.</string>
<string name="osm_edits_view_descr">Погледајте све Ваше још увек неотпремљене измене или ОСМ белешке у %1$s. Отпремљене тачке се не више приказују.</string>
<string name="app_mode_osm">OSM</string>
<string name="select_nav_icon_descr">Иконица која се приказује за време навођења или померања.</string>
<string name="select_map_icon_descr">Иконица која се приказује у мировању.</string>
@ -3484,7 +3484,7 @@
<string name="measure_distance_item">Измери удаљеност</string>
<string name="travel_item">Путовање (Wikivoyage и Википедија)</string>
<string name="favorites_item">Омиљени</string>
<string name="subscription_osmandlive_item">Претплата - OsmAnd уживо</string>
<string name="subscription_osmandlive_item">Чланарина - OsmAnd уживо</string>
<string name="osmand_purchases_item">OsmAnd куповине</string>
<string name="legend_item_description">Упутство за легенду карте.</string>
<string name="navigation_profiles_item">Профили навођења</string>
@ -3650,9 +3650,9 @@
<string name="context_menu_actions">Акције Контекст менија</string>
<string name="osm_live_payment_subscription_management">Наплатом ће бити оптерећен ваш Гугл Плеј налог при потврди куповине.
\n
\n Претплата се аутоматски обнавља уколико није отказана пре датума обнове. Ваш налог биће задужен периодом обнове (месец / три месеца / годину дана) само на дан обнове.
\nЧланарина се аутоматски обнавља уколико није отказана пре датума обнове. Ваш налог биће задужен периодом обнове (месец / три месеца / годину дана) само на дан обнове.
\n
\n Претплатама можете управљати и отказати их тако што ћете отићи на ваша Гугл Плеј подешавања.</string>
\nЧланаринама можете управљати и отказати их тако што ћете отићи на ваша Гугл Плеј подешавања.</string>
<string name="release_3_7">• Нове офлајн мапе нагиба
\n
\n • Пуно прилагођавање Фаворита и ГПКС тачака прилагођавање боја, икона, облика
@ -3683,9 +3683,9 @@
<string name="lenght_limit_description">Унесите дужину возила, нека ограничења пута могу бити примењена за дужа возила.</string>
<string name="quick_action_remove_next_destination">Обриши најближу одредишну тачку</string>
<string name="please_provide_point_name_error">Молимо одредите име тачке</string>
<string name="quick_action_remove_next_destination_descr">Тренутна одредишна тачка биће уклоњена. Ако је она одредишна, стопираће се навигација.</string>
<string name="quick_action_remove_next_destination_descr">Уклања тренутну одредишну тачку. Ако је она и завршна тачка, навођење ће се зауставити.</string>
<string name="search_download_wikipedia_maps">Преузмите мапе Википедије</string>
<string name="plugin_wikipedia_description">Информације о тачкама од интереса потражите на Википедији. То је ваш џепни ванмрежни водич - само укључите додатак Википедија и уживајте у чланцима о објектима око вас.</string>
<string name="plugin_wikipedia_description">Информације о тачкама од интереса потражите на Википедији, џепном ванмрежном водичу који има чланке о местима и одредиштима.</string>
<string name="app_mode_enduro_motorcycle">Ендуро скутер</string>
<string name="app_mode_motor_scooter">Скутер</string>
<string name="app_mode_wheelchair">Инвалидска колица</string>
@ -3723,7 +3723,7 @@
<string name="navigation_profile">Навигацијски профил</string>
<string name="route_between_points_add_track_desc">Изаберите датотеку записа којој ће се додати нови сегмент.</string>
<string name="street_level_imagery">Слике на нивоу улице</string>
<string name="plan_route_exit_dialog_descr">Да ли сте сигурни да желите да одбаците све промене на планираној рути затварањем\?</string>
<string name="plan_route_exit_dialog_descr">Да ли сте сигурни да желите да одбаците све промене на планираној рути\?</string>
<string name="in_case_of_reverse_direction">У случају обрнутог правца</string>
<string name="shared_string_save_as_gpx">Сачувај као нову датотеку стазе</string>
<string name="add_segment_to_the_track">Додај у датотеку стазе</string>
@ -3761,9 +3761,9 @@
<string name="gpx_monitoring_stop">Паузирај снимање пута</string>
<string name="one_point_error">Додајте бар две тачке.</string>
<string name="osm_edit_logout_success">Одјављен</string>
<string name="gpx_upload_private_visibility_descr">„Приватно“ значи да се траг не појављује ни на једној јавној листи, али су тачке праћења у њему у нехронолошком редоследу доступне путем јавног ГПС АПИ-ја без временских ознака.</string>
<string name="gpx_upload_identifiable_visibility_descr">„Могуће је идентификовати“ значи да ће се траг јавно приказати у вашим ГПС траговима и у јавним списковима ГПС трагова, тј. други корисници ће моћи да преузму необрађени траг и повежу га са вашим корисничким именом. Јавни подаци о временским тачкама трага из ГПС АПИ-ја који се сервирају путем АПИ-ја за тачке праћења имаће референцу на вашу оригиналну страницу праћења.</string>
<string name="gpx_upload_trackable_visibility_descr">„Следљиво“ значи да се траг не приказује нигде на јавним листама, али обрађене тачке праћења са временским ознакама у њима (које не могу бити директно повезане са вама) иду кроз преузимања са јавног ГПС АПИ-ја.</string>
<string name="gpx_upload_private_visibility_descr">„Приватно“ значи да се траг не појављује ни на једној јавној листи, али су тачке праћења у њему у нехронолошком редоследу доступне путем јавног GPS API-ја без временских ознака.</string>
<string name="gpx_upload_identifiable_visibility_descr">„Могуће је идентификовати“ значи да ће се траг јавно приказати у Вашим GPS траговима и у јавним списковима GPS трагова, тј. други корисници ће моћи да преузму необрађени траг и повежу га са Вашим корисничким именом. Јавни подаци о временским тачкама трага из GPS API-ја који се сервирају путем API-ја за тачке праћења имаће референцу на вашу оригиналну страницу праћења.</string>
<string name="gpx_upload_trackable_visibility_descr">„Следљиво“ значи да се траг не приказује нигде на јавним листама, али обрађене тачке праћења са временским ознакама у њима (које не могу бити директно повезане са вама) иду кроз преузимања са јавног GPS API-ја.</string>
<string name="osm_edit_close_note">Затвори ОСМ белешку</string>
<string name="osm_edit_comment_note">Коментар ОСМ напомене</string>
<string name="osm_login_descr">Можете се пријавити користећи безбедан ОАут метод или користити своје корисничко име и лозинку.</string>
@ -3776,12 +3776,12 @@
<string name="shared_string_search_history">Претрага</string>
<string name="app_mode_kayak">Кајак</string>
<string name="app_mode_motorboat">Моторни чамац</string>
<string name="add_to_mapillary">Додај у Мапилари</string>
<string name="add_to_opr">Додај у ОпенПлејсРевјуз</string>
<string name="add_photos_descr">ОсмАнд приказује фотографије из неколико извора:
\nОпенПлејсРевјуз - ПОИ фотографије;
\nМапилари - слике на нивоу улице;
\nВеб / Викимедиа - ПОИ фотографије наведене у подацима ОпенСтритМап.</string>
<string name="add_to_mapillary">Додај у Mapillary</string>
<string name="add_to_opr">Додај у OpenPlaceReviews</string>
<string name="add_photos_descr">OsmAnd приказује фотографије из неколико извора:
\nOpenPlaceReviews - фотографије тачака од интереса;
\nMapillary - слике на нивоу улице;
\nВеб / Викимедија - фотографије тачака од интереса наведене у OpenStreetMap подацима.</string>
<string name="shared_string_resources">Ресурси</string>
<string name="approximate_file_size">Приближна величина датотеке</string>
<string name="select_data_to_export">Изаберите податке за извоз у датотеку.</string>
@ -3795,7 +3795,7 @@
<string name="mgrs_format_descr">ОсмАнд користи МГРС, који је сличан УТМ НАТО формату.</string>
<string name="simplified_track">Поједностављена стаза</string>
<string name="simplified_track_description">Само линија руте ће бити сачувана, а путне тачке ће бити избрисане.</string>
<string name="disable_recording_once_app_killed_descrp">Паузираће евидентирање стазе када се апликација убије (преко скорашњих програма). (Индикатор рада OsmAnd-а у позадини тада нестаје из обавештајне траке.)</string>
<string name="disable_recording_once_app_killed_descrp">Евидентирање стазе ће бити паузирано када се апликација убије (преко скорашњих програма). (Индикатор рада OsmAnd-а у позадини тада нестаје из обавештајне траке.)</string>
<string name="save_global_track_interval_descr">Наведите интервал евидентирања за опште снимање стаза (укључено помоћу виџета „Снимање путовања“ на мапи).</string>
<string name="gpx_monitoring_start">Наставите снимање путовања</string>
<string name="system_default_theme">Системско подразумевана</string>
@ -3827,17 +3827,17 @@
<string name="sort_name_descending">Име: З - А</string>
<string name="sort_name_ascending">Име: А - З</string>
<string name="contour_lines_thanks">Хвала вам што сте купили „Контурне линије“</string>
<string name="osm_live_payment_desc_hw">Претплата се наплаћује по изабраном периоду. Откажите га у АппГалери у било ком тренутку.</string>
<string name="osm_live_payment_subscription_management_hw">Уплата ће бити наплаћена са вашег рачуна АппГалери при потврди куповине.
<string name="osm_live_payment_desc_hw">Чланарина се наплаћује по изабраном периоду. Откажите је у AppGallery у било ком тренутку.</string>
<string name="osm_live_payment_subscription_management_hw">Уплата ће бити наплаћена са вашег рачуна AppGallery при потврди куповине.
\n
\nПретплата се аутоматски обнавља уколико није отказана пре датума обнове. Ваш рачун ће бити задужен за период обнове (месец / три месеца / година) само на датум обнове.
\nЧланарина се аутоматски обнавља уколико није отказана пре датума обнове. Ваш рачун ће бити задужен за период обнове (месец / три месеца / година) само на датум обнове.
\n
\nПретплатама можете управљати и отказати их тако што ћете отићи у подешавања апликације АппГалери.</string>
\nЧланаринама можете управљати и отказати их тако што ћете отићи у подешавања апликације AppGallery.</string>
<string name="routing_attr_avoid_footways_description">Избегавајте пешачке стазе</string>
<string name="routing_attr_avoid_footways_name">Избегавајте пешачке стазе</string>
<string name="development">Развој</string>
<string name="use_live_public_transport">ОсмАнд лајв подаци</string>
<string name="use_live_routing">ОсмАнд лајв подаци</string>
<string name="use_live_public_transport">OsmAnd уживо подаци</string>
<string name="use_live_routing">OsmAnd уживо подаци</string>
<string name="complex_routing_descr">Двофазно усмеравање за аутомобилску навигацију.</string>
<string name="use_native_pt">Развој матичног јавног превоза</string>
<string name="use_native_pt_desc">Пребаците се на Јава (безбедан) прорачун рутирања јавног превоза</string>
@ -3847,9 +3847,9 @@
<string name="file_already_imported">Датотека је већ увезена у ОсмАнд</string>
<string name="use_two_phase_routing">Користите двофазни алгоритам усмеравања А*</string>
<string name="shared_string_graph">Графикон</string>
<string name="message_need_calculate_route_before_show_graph">%1$s подаци доступни само на путевима, морате израчунати руту користећи „Рута између тачака“ да бисте је добили.</string>
<string name="message_graph_will_be_available_after_recalculation">Сачекајте поновно израчунавање руте.
\nГрафикон ће бити доступан након поновног израчунавања.</string>
<string name="message_need_calculate_route_before_show_graph">%1$s подаци доступни само на путевима, израчунајте руту користећи „Рута између тачака“ да бисте видели графике.</string>
<string name="message_graph_will_be_available_after_recalculation">Молимо сачекајте.
\nГрафикон ће бити доступан након поновног израчунавања путање.</string>
<string name="shared_string_local_maps">Локалне мапе</string>
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
<string name="app_mode_gap">Размак</string>
@ -3871,15 +3871,15 @@
<string name="use_login_password">Користите корисничко име и лозинку</string>
<string name="login_account">Налог</string>
<string name="user_login">Пријавите се</string>
<string name="manage_subscription">Управљајте претплатом</string>
<string name="subscription_payment_issue_title">Постоји проблем са вашом претплатом. Кликните на дугме да бисте отворили подешавања претплате за Гугле Плеј и да бисте поправили начин плаћања.</string>
<string name="subscription_expired_title">Претплата на ОсмАнд лајв је истекла</string>
<string name="subscription_paused_title">Претплата на ОсмАнд лајв је паузирана</string>
<string name="subscription_on_hold_title">Претплата на ОсмАнд лајв је на чекању</string>
<string name="manage_subscription">Управљајте чланарином</string>
<string name="subscription_payment_issue_title">Постоји проблем са Вашом чланарином. Кликните на дугме да бисте отворили подешавања претплате за Гугле Плеј и да бисте поправили начин плаћања.</string>
<string name="subscription_expired_title">Чланарина за OsmAnd уживо је истекла</string>
<string name="subscription_paused_title">Чланарина на OsmAnd уживо је паузирана</string>
<string name="subscription_on_hold_title">Чланарина на OsmAnd уживо је на чекању</string>
<string name="markers_history">Историја маркера</string>
<string name="send_files_to_openstreetmap">Пошаљите ГПКС датотеку на ОпенСтритМап</string>
<string name="enter_text_separated">Унесите ознаке одвојене зарезом.</string>
<string name="gpx_upload_public_visibility_descr">„Јавно“ значи да је траг јавно приказан у вашим ГПС траговима и на јавним ГПС траговима, као и на јавном списку трагова са временским ознакама у сировом облику. Подаци који се приказују путем АПИ-ја не упућују на вашу страницу трагова. Временске ознаке праћења нису доступне путем јавног ГПС АПИ-ја и тачке праћења нису хронолошки поређане.</string>
<string name="gpx_upload_public_visibility_descr">„Јавно“ значи да је траг јавно приказан у вашим GPS траговима и на јавним GPS траговима, као и на јавном списку трагова са временским ознакама у сировом облику. Подаци који се приказују путем API-ја не упућују на вашу страницу трагова. Временске ознаке праћења нису доступне путем јавног GPS API-ја и тачке праћења нису хронолошки поређане.</string>
<string name="cannot_upload_image">Није могуће отпремити слику, покушајте поново касније</string>
<string name="select_picture">Изаберите слику</string>
<string name="select_groups_for_import">Изаберите групе које ће бити увезене.</string>
@ -3895,11 +3895,11 @@
<string name="plan_route_add_new_segment">Додајте нови сегмент</string>
<string name="release_3_9">• Додата је опција за извоз и увоз свих података, укључујући подешавања, ресурсе, моја места
\n
\n • Планирање руте: графикони за сегменте са рутом, додата је могућност креирања и уређивања вишеструких сегмената стаза
\n • Планирање руте: графикони за сегменте са рутом, и додата је могућност креирања и уређивања вишеструких сегмената стаза
\n
\n • Додан је метод аутентификације ОАут за ОпенСтритМап, побољшан кориснички интерфејс ОСМ дијалога
\n
\n • Прилагођене боје за омиљене и путне тачаке стаза
\n • Подршка за прилагођене боје за омиљене и пролазне тачке путања
\n
\n</string>
<string name="activity_type_water_name">Вода</string>
@ -3959,7 +3959,7 @@
<string name="routing_engine_vehicle_type_cycling_electric">Екетрични бициклизам</string>
<string name="routing_engine_vehicle_type_cycling_mountain">Планински бициклизам</string>
<string name="routing_engine_vehicle_type_cycling_road">Друмски бициклизам</string>
<string name="routing_engine_vehicle_type_cycling_regular">Стаднардни бициклизам</string>
<string name="routing_engine_vehicle_type_cycling_regular">Стандардни бициклизам</string>
<string name="routing_engine_vehicle_type_hgv">Теретни камион</string>
<string name="routing_engine_vehicle_type_small_truck">Камионет</string>
<string name="routing_engine_vehicle_type_truck">Камион</string>
@ -3988,4 +3988,98 @@
<string name="rename_track">Преименуј путању</string>
<string name="trip_recording_save_and_continue">Сачувај и настави</string>
<string name="lost_data_warning">Сви несачувани подаци ће бити изгубљени.</string>
<string name="routing_attr_prefer_hiking_routes_description">Преферира планинске пешачке путеве</string>
<string name="routing_attr_prefer_hiking_routes_name">Преферирај планинске пешачке путеве</string>
<string name="routing_attr_allow_intermittent_description">Дозвољава водене токове који некад пресуше</string>
<string name="routing_attr_allow_streams_description">Дозвољава потоке и одвоје</string>
<string name="routing_attr_allow_streams_name">Дозволи потоке и одводе</string>
<string name="routing_attr_allow_intermittent_name">Дозволи несталне водене токове</string>
<string name="shared_string_api_key">Кључ API-ја</string>
<string name="shared_string_server_url">Адреса сервера</string>
<string name="shared_string_enter_param">Унесите параметар</string>
<string name="keep_it_empty_if_not">Задржи је празном ако није</string>
<string name="online_routing_example_hint">Адреса са свим параметрима ће изгледати овако:</string>
<string name="test_route_calculation">Тестирај израчунавање пута</string>
<string name="shared_string_folders">Фасцикле</string>
<string name="select_folder">Одаберите фасциклу</string>
<string name="select_folder_descr">Одаберите фасциклу или додајте нову</string>
<string name="analyze_by_intervals">Анализирај интервале поделе</string>
<string name="upload_to_openstreetmap">Отпреми на OpenStreetMap</string>
<string name="change_folder">Измени фасциклу</string>
<string name="shared_string_sec">сек</string>
<string name="announcement_time_passing">Пролажење</string>
<string name="announcement_time_approach">Прилазак</string>
<string name="announcement_time_prepare_long">Припрема унапред</string>
<string name="announcement_time_prepare">Припрема</string>
<string name="announcement_time_off_route">Ван пута</string>
<string name="announcement_time_arrive">Долазак на одредиште</string>
<string name="shared_string_turn">Скретање</string>
<string name="announcement_time_intervals">Интервали времена и удаљености</string>
<string name="announcement_time_descr">Времена објава различитих гласовних навођења зависе од типа објаве, као и тренутне и подразумеване брзине навођења.</string>
<string name="online_routing_engines">Мрежни усмеривачи</string>
<string name="routing_engine_vehicle_type_foot">Пешке</string>
<string name="routing_engine_vehicle_type_driving">Вожња аутомобила</string>
<string name="edit_online_routing_engine">Измени мрежни усмеривач</string>
<string name="add_online_routing_engine">Додај мрежни усмеривач</string>
<string name="online_routing_engine">Мрежни усмеривач</string>
<string name="delete_online_routing_engine">Обриши овај мрежни усмеривач\?</string>
<string name="delete_waypoints">Обриши пролазну тачку</string>
<string name="copy_to_map_markers">Копирај у ознаке карте</string>
<string name="hillshade_slope_contour_lines">Рељеф / Нагиб / Контурне линије</string>
<string name="open_place_reviews">OpenPlaceReviews</string>
<string name="login_open_place_reviews">Пријавите се за OpenPlaceReviews</string>
<string name="activity_type_offroad_name">Вожња ван пута</string>
<string name="quick_action_coordinates_widget_descr">Прекидач да на карти покаже или сакрије справицу са координатама.</string>
<string name="map_widget_distance_by_tap">Удаљеност по кликтању</string>
<string name="latest_openstreetmap_update">Последње OpenStreetMap ажурирање доступно:</string>
<string name="trip_recording_logging_interval_info">Временски интервал бележења на који ће OsmAnd да пита за податке о тренутној позицији.</string>
<string name="show_start_dialog">Прикажи почетни дијалог</string>
<string name="trip_recording_show_start_dialog_setting">Ако се искључи, снимање ће почети одмах после кликтања на справицу или на ставку менија, прескакајући дијалог потврде.</string>
<string name="customize_route_line">Прилагоди линију руте</string>
<string name="route_line_use_map_style_appearance">Линија руте ће користити %1$s одабран на означеном стилу карте: %2$s.</string>
<string name="shared_string_route_line">Линија руте</string>
<string name="specify_color_for_map_mode">Одаберите боју за режим карте: %1$s.</string>
<string name="no_purchases">Немате ниједну куповину</string>
<string name="new_device_account">Нови уређај / нови налог</string>
<string name="contact_support_description">Ако имате икаквих питања, контактирајте нас на %1$s.</string>
<string name="empty_purchases_description">Ако се Ваша куповина не појави овде, кликните на „%1$s” или контактирајте нашу подршку.</string>
<string name="contact_support">Контактирајте подршку</string>
<string name="troubleshooting">Решавање проблема</string>
<string name="troubleshooting_description">Пратите ову везу ако имате икаквих проблема са куповином.</string>
<string name="osmand_live">OsmAnd уживо</string>
<string name="renew_subscription">Обнови чланарину</string>
<string name="annual_subscription">Годишња чланарина</string>
<string name="monthly_subscription">Месечна чланарина</string>
<string name="three_months_subscription">Тромесечна чланарина</string>
<string name="next_billing_date">Следећи датум наплате: %1$s</string>
<string name="osmand_live_cancelled">Отказано</string>
<string name="in_grace_period">У грејс периоду</string>
<string name="on_hold">На чекању</string>
<string name="expired">Истекло</string>
<string name="update_all_maps_added">Ажурирај све карте додате на %1$s\?</string>
<string name="exit_number">Број излаза</string>
<string name="announce_when_exceeded">Објави када се премаши</string>
<string name="user_points">Кориснички поени</string>
<string name="output">Излаз</string>
<string name="open_place_reviews_plugin_description">OpenPlaceReviews је пројакат покретан од стране заједнице о јавним местима, као што су ресторани, хотели, пролазне тачке. Пројекат сакупља јавне информације о њима, као што су слике, рецензије, везе ка другим местима као OpenStreetMap или Википедија.
\n
\nСви подаци на OpenPlaceReview су отворени и доступни свима: http://openplacereviews.org/data.
\n
\nМожете прочитати више на: http://openplacereviews.org</string>
<string name="release_4_0_beta">• Ажурирања OsmAnd уживо су премештена у „Преузимања &gt; Ажурирања”
\n
\n • Путање се сада могу обојити по висини, брзини или нагибу.
\n
\n • Додата опција да се измени изглед линије која се приказује приликом навођења
\n
\n • Ажуриран дијалог за „Снимање пута”
\n
\n</string>
<string name="copy_address">Копирај адресу</string>
<string name="voice_prompts_timetable">Времена гласовних навођења</string>
<string name="profile_type_osmand_string">OsmAnd профил</string>
<string name="profile_type_user_string">Кориснички профил</string>
<string name="reverse_all_points">Обрни све тачке</string>
<string name="profile_by_default_description">Одаберите профил које ће се користити по покретању апликације.</string>
<string name="shared_string_last_used">Последње коришћено</string>
</resources>

View file

@ -3926,4 +3926,6 @@
<string name="poi_hoops">Ringar</string>
<string name="poi_office_diplomatic">Diplomatiskt kontor</string>
<string name="poi_bay_filter">Typ av vik</string>
<string name="poi_plateau">Platå</string>
<string name="poi_club_social">Social klubb</string>
</resources>

View file

@ -470,7 +470,7 @@
<string name="indexing_map">Indexerar kartan …</string>
<string name="indexing_poi">Indexerar Intressepunkter …</string>
<string name="indexing_transport">Indexerar transport …</string>
<string name="shared_string_io_error">Ett I/O-fel har inträffat</string>
<string name="shared_string_io_error">I/O-fel</string>
<string name="km">km</string>
<string name="km_h">km/h</string>
<string name="m">m</string>
@ -736,7 +736,7 @@
<string name="favourites_remove_dialog_success">Favoritpunkten {0} togs bort utan problem.</string>
<string name="osb_comment_dialog_message">Meddelande</string>
<string name="osb_comment_dialog_author">Författarnamn</string>
<string name="osb_comment_dialog_success">Kommentaren lades till utan problem</string>
<string name="osb_comment_dialog_success">Kommentaren tillagd</string>
<string name="osb_comment_dialog_error">Det gick inte att lägga till kommentar.</string>
<string name="poi_edit_title">Redigera POI</string>
<string name="poi_create_title">Skapa POI</string>
@ -759,7 +759,7 @@
<string name="osmand_srtm_short_description_80_chars">OsmAnd-modul för höjdkurvor offline</string>
<string name="map_widget_distancemeasurement">Avståndsmätning</string>
<string name="map_widget_audionotes">Ljudanteckningar</string>
<string name="audionotes_plugin_description">Denna modul för ljud- och videoanteckningar erbjuder möjlighet att skapa ljud-/foto-/videoanteckningar under en resa, antingen med hjälp av en knapp på kartskärmen eller direkt i kontextmenyn för en position på kartan.</string>
<string name="audionotes_plugin_description">Gör ljud-/foto-/videoanteckningar under en resa, med antingen en kartknapp eller platsens snabbmeny.</string>
<string name="audionotes_plugin_name">Ljud-/Videoanteckningar</string>
<string name="index_srtm_parts">delar</string>
<string name="index_srtm_ele">Höjdkurvor</string>
@ -1259,7 +1259,10 @@
<string name="fav_point_emoticons_message">Vi ändrade namnet på din favoritpunkt till %1$s för att underlätta din smiley i filnamnet.</string>
<string name="speed_limit_exceed_message">Välj hur mycket hastighetsgränsen måste överskridas för att du ska få ett röstmeddelande.</string>
<string name="speed_limit_exceed">Tolerans för hastighetsgräns</string>
<string name="anonymous_user_hint">En anonym användare kan inte:\n- skapa grupper;\n- synkronisera grupper och enheter med servern;\n- hantera grupper och enheter på ett personligt ställe på webbplatsen.</string>
<string name="anonymous_user_hint">Anonyma användare kan inte:
\n- Skapa grupper;
\n- Synkronisera grupper och enheter med servern;
\n- Hantera grupper och enheter i en personlig instrumentpanel på webbplatsen.</string>
<string name="anonymous_user">Anonym användare</string>
<string name="logged_as">Inloggad som %1$s</string>
<string name="configure_map">Konfigurera kartan</string>
@ -1357,11 +1360,11 @@
<string name="notes">Anteckningar</string>
<string name="online_map">Online-karta</string>
<string name="share_note">Dela anteckning</string>
<string name="plugin_nautical_descr">Om du aktiverar denna vy ändras kartstilen till Nautisk och visar alla sjömärken och sjökortssymboler.
<string name="plugin_nautical_descr">Detta plugin berikar OsmAnds kart- och navigationsapp för att också producera nautiska kartor för båtliv, segling och andra typer av vattensporter.
\n
\nEn kartfil som innehåller alla nautiska symboler globalt finns tillgänglig som en enda nedladdning med namnet \'World seamarks\'.
\nEtt speciellt karttillägg för OsmAnd kommer att tillhandahålla alla nautiska navigationsmärken och kartsymboler, både för inland och för närliggande navigering. Beskrivningen av varje navigeringsmärke innehåller de detaljer som behövs för att identifiera dem och deras betydelse (kategori, form, färg, sekvens, referens etc.).
\n
\nDenna vy kan ändras genom att antingen inaktivera den här igen eller genom att ändra kartstilen under Konfigurera kartor.</string>
\nFör att återgå till en av OsmAnds konventionella kartstilar, helt enkelt avaktivera detta plugin igen, eller ändra \'Kartstil\' under \'Konfigurera karta\' efter önskemål.</string>
<string name="plugin_ski_descr">Detta plugin för OsmAnd ger dig detaljer om globala utförsåkning, längdskidspår, alpina skidvägar, linbanor och skidliftar. Rutter och pister visas färgkodade av svårigheter och avbildas i en speciell \"vinter\" -stil som liknar ett snöfärgat vinterlandskap.
\n
\nOm du aktiverar den här vyn ändras kartstilen till \"Vinter och skidor\" och visar alla landskapsfunktioner under vinterförhållanden. Denna vy kan återställas genom att antingen avaktivera den igen här, eller genom att ändra \'Kartstil\' under \'Konfigurera karta\' efter önskemål.</string>
@ -1415,12 +1418,12 @@
<string name="shared_string_more">Mer…</string>
<string name="shared_string_more_actions">Fler åtgärder</string>
<string name="shared_string_do_not_show_again">Visa inte nästa gång</string>
<string name="shared_string_remember_my_choice">Kom ihåg mitt val</string>
<string name="shared_string_remember_my_choice">Kom ihåg valet</string>
<string name="shared_string_refresh">Uppdatera</string>
<string name="shared_string_download">Hämta</string>
<string name="shared_string_downloading">Laddar ner…</string>
<string name="shared_string_download_successful">Hämtningen lyckades</string>
<string name="shared_string_unexpected_error">Ett oväntat fel uppstod</string>
<string name="shared_string_download_successful">Nedladdat</string>
<string name="shared_string_unexpected_error">Oväntat fel</string>
<string name="shared_string_action_template">Åtgärd {0}</string>
<string name="shared_string_close">Stäng</string>
<string name="shared_string_exit">Utgång</string>
@ -1430,10 +1433,10 @@
<string name="shared_string_map">Karta</string>
<string name="shared_string_favorite">Favorit</string>
<string name="shared_string_favorites">Favoriter</string>
<string name="shared_string_add_to_favorites">Lägg till i Favoriter</string>
<string name="shared_string_add_to_favorites">Lägg till i \'Favoriter\'</string>
<string name="shared_string_my_location">Min position</string>
<string name="shared_string_my_places">Mina platser</string>
<string name="shared_string_my_favorites">Mina favoriter</string>
<string name="shared_string_my_favorites">Favoriter</string>
<string name="shared_string_tracks">Mina spår</string>
<string name="shared_string_currently_recording_track">Spelar för tillfället in spår</string>
<string name="shared_string_audio">Ljud</string>
@ -1459,21 +1462,21 @@
<string name="your_edits">Dina redigeringar</string>
<string name="osmand_parking_overdue">över tiden</string>
<string name="delay_to_start_navigation_descr">Ange väntetid att stanna kvar på ruttplaneringsskärmen.</string>
<string name="delay_to_start_navigation">Börja sväng-efter-sväng-navigering efter …</string>
<string name="delay_to_start_navigation">Starta sväng-för-sväng-vägledning efter …</string>
<string name="shared_string_go">Kör</string>
<string name="local_osm_changes_upload_all_confirm">Du håller på att skicka %1$d ändring(ar) till OSM. Är du säker?</string>
<string name="confirmation_to_clear_history">Vill du tömma historiken?</string>
<string name="local_osm_changes_upload_all_confirm">Är du säker på att du vill ladda upp %1$d ändringar till OSM\?</string>
<string name="confirmation_to_clear_history">Rensa historik\?</string>
<string name="current_route">Aktuell rutt</string>
<string name="osm_changes_added_to_local_edits">OSM-ändringar lades till i lokala ändringar</string>
<string name="mark_to_delete">Markera för att ta bort</string>
<string name="confirm_usage_speed_cameras">I många länder (Tyskland, Frankrike, Italien och andra) är det inte tillåtet att använda varningar för hastighetskameror. OsmAnd tar inget ansvar om du bryter mot lagen. Tryck på Ja endast om du får använda denna funktion.</string>
<string name="confirm_usage_speed_cameras">I många länder (Tyskland, Frankrike, Italien och andra) är användning av hastighetskameravarningar olaglig. OsmAnd tar inget ansvar om du bryter mot lagen. Klicka bara på \'Ja\' om du är berättigad att använda den här funktionen.</string>
<string name="welmode_download_maps">Hämta kartor</string>
<string name="welcome_select_region">För att avspegla dina trafiksignaler och -förordningar på ett korrekt sätt, välj den region du kör i:</string>
<string name="welcome_text">OsmAnd erbjuder global frånkopplad kartsurfning och frånkopplad navigering.</string>
<string name="welcome_header">Välkommen</string>
<string name="agps_info">A-GPS-info</string>
<string name="shared_string_message">Meddelande</string>
<string name="agps_data_last_downloaded">A-GPS-data senast nedladdade: %1$s</string>
<string name="agps_data_last_downloaded">A-GPS-data har laddats ner: %1$s</string>
<string name="shared_string_do_not_use">Använd inte</string>
<string name="shared_string_address">Adress</string>
<string name="shared_string_show_description">Visa beskrivning.</string>
@ -1488,9 +1491,9 @@
<string name="index_name_netherlands">Europa - Nederländerna</string>
<string name="rendering_value_highContrastRoads_name">Högkontrastvägar</string>
<string name="rendering_value__name">Standard</string>
<string name="application_dir_change_warning3">Kopiera OsmAnds datafiler till den nya destinationen?</string>
<string name="application_dir_change_warning3">Flytta OsmAnds datafiler till den nya destinationen\?</string>
<string name="specified_directiory_not_writeable">Kunde inte skapa kartor i den angivna mappen</string>
<string name="copying_osmand_file_failed">Kopieringen misslyckades</string>
<string name="copying_osmand_file_failed">Det gick inte att flytta filer</string>
<string name="storage_directory_external">Extern lagring</string>
<string name="storage_directory_multiuser">Lagring för flera användare</string>
<string name="storage_directory_internal_app">Internt appminne</string>
@ -1512,16 +1515,16 @@
<string name="shared_string_wikipedia">Wikipedia</string>
<string name="local_indexes_cat_wiki">Wikipedia</string>
<string name="shared_string_show_details">Visa detaljer</string>
<string name="local_recordings_delete_all_confirm">Du håller på att ta bort %1$d anteckningar. Är du säker?</string>
<string name="local_recordings_delete_all_confirm">Är du säker på att du vill ta bort %1$d anteckningar\?</string>
<string name="download_wikipedia_maps">Wikipedia</string>
<string name="shared_string_import2osmand">Importera till OsmAnd</string>
<string name="gps_network_not_enabled">Platstjänsten är av. Vill du slå på den\?</string>
<string name="archive_wikipedia_data">Du har gamla och inkompatibla data från Wikipedia. Vill du arkivera dem?</string>
<string name="download_wikipedia_files">Hämta ytterligare data från Wikipedia (%1$s MB)?</string>
<string name="download_wikipedia_files">Hämta ytterligare data från Wikipedia (%1$s MB)\?</string>
<string name="lang_vo">Volapük</string>
<string name="lang_th">Thai</string>
<string name="lang_te">Telugu</string>
<string name="lang_nn">Norska (nynorska)</string>
<string name="lang_nn">Norska (Nynorska)</string>
<string name="lang_new">Newar/Nepal Bhasa</string>
<string name="lang_ms">Malajiska</string>
<string name="lang_ht">Haitiska</string>
@ -1565,7 +1568,7 @@
<string name="rendering_value_translucent_blue_name">Genomskinlig blå</string>
<string name="rendering_value_purple_name">Purpur</string>
<string name="rendering_value_translucent_purple_name">Genomskinlig purpur</string>
<string name="restart_is_required">Starta om appen manuellt för att ändringarna ska börja gälla.</string>
<string name="restart_is_required">En omstart krävs för att tillämpa ändringen.</string>
<string name="rendering_attr_currentTrackColor_name">GPX-färg</string>
<string name="rendering_value_yellow_name">Gul</string>
<string name="rendering_value_default13_name">Standard (13)</string>
@ -1589,8 +1592,8 @@
<string name="shared_string_undo">ÅNGRA</string>
<string name="shared_string_skip">Hoppa över</string>
<string name="app_name_osmand">OsmAnd</string>
<string name="routing_attr_avoid_shuttle_train_name">Undvik pendeltåg</string>
<string name="routing_attr_avoid_shuttle_train_description">Undvik att använda pendeltåg</string>
<string name="routing_attr_avoid_shuttle_train_name">Inget pendeltåg</string>
<string name="routing_attr_avoid_shuttle_train_description">Undviker att använda pendeltåg</string>
<string name="plugin_settings">Insticksprogram</string>
<string name="traffic_warning_hazard">Varning</string>
<string name="tab_title_basic">Grundläggande</string>
@ -1600,7 +1603,7 @@
<string name="opening_at">Öppnar</string>
<string name="closing_at">Stänger</string>
<string name="av_locations">Platser</string>
<string name="av_locations_descr">GPX-fil med anteckningar om platser.</string>
<string name="av_locations_descr">GPX-fil med platser.</string>
<string name="poi_dialog_poi_type">Typ av POI</string>
<string name="add_opening_hours">Lägg till öppettider</string>
<string name="contact_info">Kontaktinformation</string>
@ -1620,7 +1623,7 @@
<string name="simulate_your_location_stop_descr">Sluta simulera din plats.</string>
<string name="simulate_your_location_descr">Simulera din plats med en beräknad rutt eller med ett inspelat GPX-spår.</string>
<string name="downloads_left_template">%1$s nedladdningar kvar</string>
<string name="favourites_edit_dialog_title">Information om favoriter</string>
<string name="favourites_edit_dialog_title">Favoritinformation</string>
<string name="roads">Vägar</string>
<string name="favourites_context_menu_add">Lägg till favorit</string>
<string name="default_speed_system_descr">Ange enhet för hastighet.</string>
@ -1634,7 +1637,7 @@
<string name="si_nm_h">Sjömil per timme (knop)</string>
<string name="shared_string_trip_recording">Inspelning av resa</string>
<string name="shared_string_navigation">Navigering</string>
<string name="osmand_running_in_background">Körs i bakgrunden</string>
<string name="osmand_running_in_background">Kör i bakgrunden</string>
<string name="favorite_category_add_new">Lägg till ny</string>
<string name="favorite_category_select">Välj kategori</string>
<string name="count_of_lines">Antal rader</string>
@ -1653,7 +1656,7 @@
<string name="activate_srtm_plugin">Aktivera modulen SRTM</string>
<string name="later">Senare</string>
<string name="get_full_version">Fullversionen</string>
<string name="favorite_category_dublicate_message">Det angivna kategorinamnet finns redan. Ange ett annat namn.</string>
<string name="favorite_category_dublicate_message">Använd ett kategorinamn som inte redan finns.</string>
<string name="favorite_category_name">Kategorinamn</string>
<string name="favorite_category_add_new_title">Lägg till en ny kategori</string>
<string name="file_size_in_mb">%.1f MB</string>
@ -1668,9 +1671,9 @@
<string name="share_menu_location">Dela platsen</string>
<string name="shared_string_send">Sänd</string>
<string name="hillshade_layer_disabled">Skuggad relief-lager inaktiverat</string>
<string name="show_on_start_description">\'Av\' startar kartskärmen direkt.</string>
<string name="show_on_start_description">\'Av\' startar kartan direkt.</string>
<string name="map_downloaded">Karta hämtad</string>
<string name="map_downloaded_descr">Kartan över %1$s har hämtats, och du kan nu börja använda den.</string>
<string name="map_downloaded_descr">%1$s -kartan är redo att användas.</string>
<string name="go_to_map">Visa kartan</string>
<string name="shared_string_qr_code">QR-kod</string>
<string name="enter_country_name">Ange land</string>
@ -1693,7 +1696,7 @@
<string name="versions_item">Versioner</string>
<string name="contact_us">Kontakta oss</string>
<string name="osm_edit_created_poi">Skapat en OSM POI</string>
<string name="world_map_download_descr">Baskarta över världen (täcker hela världen med låg zoomningsgrad) saknas eller är gammal. Hämta gärna denna karta för en global översikt.</string>
<string name="world_map_download_descr">Världskarta (täcker hela världen vid låg zoomnivå) saknas eller är föråldrad. Överväg att ladda ner den för en global översikt.</string>
<string name="shared_string_upload">Skicka</string>
<string name="map_legend">Teckenförklaring</string>
<string name="shared_string_update">Uppdatering</string>
@ -1721,9 +1724,9 @@
<string name="osn_comment_dialog_title">Lägg till kommentar</string>
<string name="osn_reopen_dialog_title">Öppna anteckning igen</string>
<string name="osn_close_dialog_title">Stäng anteckning</string>
<string name="osn_add_dialog_success">En anteckning har skapats utan problem</string>
<string name="osn_add_dialog_success">Anteckningen har skapats</string>
<string name="osn_add_dialog_error">Det gick inte att skapa anteckningen.</string>
<string name="osn_close_dialog_success">Anteckningen stängdes utan problem</string>
<string name="osn_close_dialog_success">Anteckningen stängd</string>
<string name="osn_close_dialog_error">Det gick inte att stänga anteckningen.</string>
<string name="context_menu_item_delete_waypoint">Ta bort GPX-waypoint?</string>
<string name="context_menu_item_edit_waypoint">Redigera GPX-waypoint</string>
@ -1767,8 +1770,8 @@
<string name="route_duration">Tid:</string>
<string name="missing_write_external_storage_permission">Appen har inte tillåtelse att använda SD-kortet</string>
<string name="no_location_permission">Ge platsåtkomst.</string>
<string name="no_camera_permission">Appen har inte tillräckliga behörigheter för att komma åt kameran.</string>
<string name="no_microphone_permission">Appen har inte tillräckliga behörigheter för att komma åt mikrofonen.</string>
<string name="no_camera_permission">Ge kameraåtkomst.</string>
<string name="no_microphone_permission">Ge mikrofonåtkomst.</string>
<string name="select_voice_provider">Välj röstvägledning</string>
<string name="select_voice_provider_descr">Välj eller hämta röstvägledning för ditt språk.</string>
<string name="impassable_road_desc">Välj de vägar du vill undvika under navigering.</string>
@ -1790,7 +1793,7 @@
<string name="starting_point">Startpunkt</string>
<string name="item_removed">Post borttagen</string>
<string name="n_items_removed">poster raderade</string>
<string name="shared_string_undo_all">ÅNGRA ALLA</string>
<string name="shared_string_undo_all">Ångra allt</string>
<string name="rendering_attr_hideIcons_name">POI-ikoner</string>
<string name="switch_start_finish">Skifta startpunkt och destination</string>
<string name="number_of_contributors">Antal bidragsgivare</string>
@ -1798,10 +1801,10 @@
<string name="reports_for">Rapport för</string>
<string name="shared_string_select">Välj</string>
<string name="shared_string_remove">Ta bort</string>
<string name="clear_updates_proposition_message">Du kan ta bort hämtade uppdateringar och få tillbaka originalkartan</string>
<string name="clear_updates_proposition_message">Ta bort hämtade uppdateringar och få tillbaka originalkartan</string>
<string name="add_time_span">Lägg till tidsspann</string>
<string name="road_blocked">Blockerad väg</string>
<string name="data_is_not_available">Inga data tillgängliga</string>
<string name="data_is_not_available">Ingen data tillgänglig</string>
<string name="rendering_attr_hideUnderground_name">Underjordiska objekt</string>
<string name="shared_string_read_more">Läs mer</string>
<string name="rec_split_storage_size">Lagringsutrymme</string>
@ -1810,18 +1813,18 @@
<string name="shared_string_save_changes">Spara ändringar</string>
<string name="find_parking">Hitta en parkeringsplats</string>
<string name="show_polygons">Visa polygoner</string>
<string name="rendering_attr_showMtbRoutes_name">Visa MTB-rutter</string>
<string name="rendering_attr_showMtbRoutes_name">Visa mountainbike spår</string>
<string name="select_map_markers">Välj kartmarkörer</string>
<string name="shared_string_reverse_order">Omvänd ordning</string>
<string name="show_map_markers_description">Aktivera kartmarkörerna.</string>
<string name="clear_active_markers_q">Vill du ta bort alla aktiva markörer?</string>
<string name="clear_markers_history_q">Vill du radera kartmarkörshistoriken?</string>
<string name="clear_active_markers_q">Ta bort alla aktiva markörer\?</string>
<string name="clear_markers_history_q">Radera kartmarkörshistoriken\?</string>
<string name="active_markers">Aktiva markörer</string>
<string name="map_markers">Kartmarkörer</string>
<string name="map_marker">Kartmarkör</string>
<string name="add_points_to_map_markers_q">Vill du lägga till alla punkter i Kartmarkörer?</string>
<string name="add_points_to_map_markers_q">Lägg till alla punkter som kartmarkörer\?</string>
<string name="shared_string_add_to_map_markers">Lägg till i Kartmarkörer</string>
<string name="consider_turning_polygons_off">Rekommendationen är att slå av rendering av polygoner.</string>
<string name="consider_turning_polygons_off">Det är rekommenderat att slå av rendering av polygoner.</string>
<string name="map_marker_1st">Första kartmarkör</string>
<string name="map_marker_2nd">Andra kartmarkör</string>
<string name="shared_string_toolbar">Verktygsfält</string>
@ -1839,34 +1842,34 @@
<string name="donations">Donationer</string>
<string name="number_of_recipients">Antal mottagare</string>
<string name="osm_user_stat">Redigeringar %1$s, rang %2$s, redigeringar totalt %3$s</string>
<string name="osm_editors_ranking">Ranglista OSM-redigerare</string>
<string name="osm_editors_ranking">OSM Editor rankning</string>
<string name="osm_live_subscription">OsmAnd Live-prenumeration</string>
<string name="osm_live_subscribe_btn">Prenumerera</string>
<string name="osm_live_email_desc">Krävs för att ge er information om bidrag.</string>
<string name="osm_live_user_public_name">Publikt namn</string>
<string name="osm_live_email_desc">Behövs för att uppdatera dig om dina bidrag.</string>
<string name="osm_live_user_public_name">Offentligt namn</string>
<string name="osm_live_hide_user_name">Visa inte mitt namn i rapporter</string>
<string name="osm_live_month_cost">Månadskostnad</string>
<string name="osm_live_month_cost">Kostnad per månad</string>
<string name="osm_live_month_cost_desc">Månadsbetalning</string>
<string name="osm_live_active">Aktiv</string>
<string name="osm_live_not_active">Inaktiv</string>
<string name="osm_live_enter_email">Ange en giltig e-postadress</string>
<string name="osm_live_enter_user_name">Ange publikt namn</string>
<string name="osm_live_enter_user_name">Ange ett offentligt namn</string>
<string name="osm_live_thanks">Tack för att du stödjer OsmAnd!
\nFör att aktivera alla nya funktioner behöver du starta om OsmAnd.</string>
<string name="osm_live_region_desc">Delar av din donation kommer att skickas till OSM-användare som skickar in kartändringar i det området.</string>
<string name="osm_live_subscription_settings">Prenumerationsinställningar</string>
<string name="osm_live_ask_for_purchase">Köp en OsmAnd Live-prenumeration först</string>
<string name="osm_live_ask_for_purchase">Köp först ett abonnemang på OsmAnd Live</string>
<string name="show_transparency_seekbar">Visa transparent sökfält</string>
<string name="recalculate_route">Beräkna om rutten</string>
<string name="shared_string_topbar">Toppfält</string>
<string name="storage_directory_shared">Delat minne</string>
<string name="avoid_road">Undvik väg</string>
<string name="storage_directory_readonly_desc">Den för tillfället valda datalagringsmappen är skrivskyddad. Lagringsmappen har tillfälligt ändrats till internminnet. Välj en giltig datalagringsmapp.</string>
<string name="shared_string_move_up">Flytta upp</string>
<string name="shared_string_move_down">Flytta ned</string>
<string name="storage_directory_readonly_desc">Växlade till internminnet eftersom den valda datalagringsmappen är skrivskyddad. Välj en skrivbar lagringskatalog.</string>
<string name="shared_string_move_up">Flytta </string>
<string name="shared_string_move_down">Flytta </string>
<string name="finish_navigation">Avsluta navigeringen</string>
<string name="full_report">Fullständig rapport</string>
<string name="open_street_map_login_and_pass">OpenStreetMap inloggning och lösenord</string>
<string name="open_street_map_login_and_pass">OSM-användarnamn och lösenord</string>
<string name="no_map_markers_found">Lägg till kartmarkörer via kartan</string>
<string name="no_waypoints_found">Hittar inga waypoints</string>
<string name="map_widget_bearing">Relativ bäring</string>
@ -1897,12 +1900,12 @@
<string name="rendering_value_medium_name">Mellan</string>
<string name="rendering_value_bold_name">Tjock</string>
<string name="report">Rapporter</string>
<string name="storage_permission_restart_is_required">Nu har appen tillåtelse att skriva till extern lagringsplats. En manuell omstart av appen krävs.</string>
<string name="storage_permission_restart_is_required">Appen får nu skriva till extern lagring, men måste startas igen för att göra det.</string>
<string name="osm_live_support_region">Stödregion</string>
<string name="osm_live_header">Denna prenumeration aktiverar uppdateringar varje timme av kartor runt omkring i världen.
\nEn del av inkomsterna går tillbaka till OSM-gemenskapen och betalas ut för varje OSM-bidrag.
\nOm du tycker om OsmAnd och OSM och vill stödja och stödjas av dem så är detta ett utmärkt sätt att göra det på.</string>
<string name="access_no_destination">Destinationen är inte fastställd</string>
<string name="access_no_destination">Tillgänglighetsplugin: Ingen destination inställd</string>
<string name="map_widget_magnetic_bearing">Magnetisk bäring</string>
<string name="rec_split_clip_length">Klipplängd</string>
<string name="file_name_containes_illegal_char">Filnamnet innehåller ogiltiga tecken</string>
@ -1968,7 +1971,7 @@
<string name="no_inet_connection_desc_map">Krävs för att hämta kartor.</string>
<string name="search_location">Söker efter plats…</string>
<string name="storage_free_space">Oanvänt utrymme</string>
<string name="storage_place_description">OsmAnds lagringsplats för data (för kartor, GPX-filer med mera): %1$s.</string>
<string name="storage_place_description">OsmAnds lagringsplats för data (för kartor, spårfiler med mera): %1$s.</string>
<string name="give_permission">Bevilja tillstånd</string>
<string name="allow_access_location">Tillåt platsåtkomst</string>
<string name="update_all_maps_now">Uppdatera alla kartor nu\?</string>
@ -1978,7 +1981,7 @@
<string name="replace_favorite_confirmation">Är du säker på att du vill ersätta favoriten %1$s?</string>
<string name="clear_tile_data">Rensa alla rutor</string>
<string name="search_hint">Ange stad, adress och POI-namn</string>
<string name="donation_to_osm">Donation till OpenStreetMap-gemenskapen</string>
<string name="donation_to_osm">Donation till OSM-communityn</string>
<string name="get_it">Skaffa det</string>
<string name="get_for">Skaffa för %1$s</string>
<string name="skip_map_downloading_desc">Du har inte några offline-kartor installerade. Du kan välja en karta från listan eller hämta kartor senare via \'Meny - %1$s\'.</string>
@ -1993,7 +1996,7 @@
<string name="save_track_precision">Minsta loggningsprecision</string>
<string name="save_track_precision_descr">Filter: Ingen loggning om inte denna noggrannhet uppnås.</string>
<string name="christmas_poi">Jul-POI</string>
<string name="christmas_desc_q">Visa Jul-POI?</string>
<string name="christmas_desc_q">Visa POI:er för julhelgen\?</string>
<string name="rendering_value_light_brown_name">Ljusbrun</string>
<string name="rendering_value_dark_brown_name">Mörkbrun</string>
<string name="rendering_attr_contourColorScheme_name">Färgschema för konturer</string>
@ -2004,26 +2007,26 @@
<string name="shared_string_recorded">Inspelat</string>
<string name="shared_string_record">Spela in</string>
<string name="gpx_logging_no_data">Inga data</string>
<string name="trip_rec_notification_settings_desc">Visa en systemavisering som gör att du kan starta trippinspelning.</string>
<string name="routing_attr_allow_motorway_name">Tillåt motorvägar</string>
<string name="routing_attr_allow_motorway_description">Tillåt motorvägar.</string>
<string name="trip_rec_notification_settings_desc">Visa ett systemmeddelande som gör det möjligt att starta trippinspelning.</string>
<string name="routing_attr_allow_motorway_name">Använd motorvägar</string>
<string name="routing_attr_allow_motorway_description">Tillåter motorvägar.</string>
<string name="wiki_around">Närliggande Wikipedia-artiklar</string>
<string name="search_map_hint">Sök stad eller region</string>
<string name="search_map_hint">Stad eller region</string>
<string name="route_roundabout_short">Tag den %1$d avfarten och kör</string>
<string name="upload_poi">Ladda upp POI</string>
<string name="route_calculation">Ruttberäkning</string>
<string name="gpx_no_tracks_title">Du har inga GPX-filer ännu</string>
<string name="gpx_no_tracks_title_folder">Du kan också lägga till GPX-filer i mappen</string>
<string name="gpx_no_tracks_title">Du har inga spårfiler än</string>
<string name="gpx_no_tracks_title_folder">Du kan också lägga till spårfiler i mappen</string>
<string name="gpx_add_track">Lägg till mer…</string>
<string name="shared_string_appearance">Utseende</string>
<string name="trip_rec_notification_settings">Aktivera snabbstart av inspelning</string>
<string name="christmas_desc">Med tanke på den kommande julen och nyåret så kan du välja att visa POI som har med julen att göra: julgranar, julmarknader med mera.</string>
<string name="trip_rec_notification_settings">Aktivera snabbinspelning</string>
<string name="christmas_desc">Förutse jul- och nyårsferier kan du välja att visa tillhörande intressepunkter som julgranar och marknader etc.</string>
<string name="rendering_attr_contourWidth_name">Bredd på konturlinjen</string>
<string name="rendering_attr_hideWaterPolygons_description">Vatten</string>
<string name="osm_live_payment_desc">Prenumerationsavgiften faktureras varje månad. Avbryt den när som helst i Google Play.</string>
<string name="donation_to_osm_desc">En del av din donation skickas till OSM-användare som skickar in ändringar till OpenStreetMap. Kostnaden för abonnemanget förblir densamma.</string>
<string name="osm_live_payment_desc">Prenumerationen debiteras per vald period. Avbryt det på Google Play när som helst.</string>
<string name="donation_to_osm_desc">En del av din donation skickas till OSM-bidragsgivare. Prenumerationskostnaden förblir densamma.</string>
<string name="osm_live_subscription_desc">En prenumeration aktiverar uppdateringar varje timme, dag eller vecka och obegränsade nedladdningar av alla kartor globalt.</string>
<string name="osm_live_banner_desc">Erhåll obegränsade karthämtningar och kartuppdateringar oftare än en gång i månaden: varje vecka, dagligen eller varje timme.</string>
<string name="osm_live_banner_desc">Få obegränsad nedladdning av kartor, lägg till uppdateringar varje vecka, dagligen eller till och med varje timme.</string>
<string name="rendering_value_low_name">Låg</string>
<string name="rendering_attr_contourWidth_description">Bredd på konturlinjen</string>
<string name="rendering_value_high_name">Hög</string>
@ -2069,7 +2072,7 @@
\n</string>
<string name="navigate_point_olc_info_short">Kort OLC
\nVänligen tillhandahåll fullständig kod</string>
<string name="file_can_not_be_moved">Filen kan inte flyttas.</string>
<string name="file_can_not_be_moved">Det gick inte att flytta filen.</string>
<string name="shared_string_move">Flytta</string>
<string name="shared_string_gpx_tracks">Spår</string>
<string name="routing_attr_driving_style_name">Körstil</string>
@ -2104,7 +2107,7 @@
<string name="quick_action_add_marker_descr">Tryck på åtgärdsknappen sätter en kartmarkör i centrum av skärmen.</string>
<string name="add_new_folder">Lägg till ny mapp</string>
<string name="points_delete_multiple_succesful">Punkt(er) togs bort.</string>
<string name="points_delete_multiple">Du håller på att ta bort %1$d punkt(er). Är du säker?</string>
<string name="points_delete_multiple">Är du säker på att du vill ta bort %1$d punkt(er)\?</string>
<string name="route_points_category_name">Kurvor att passera längs rutten</string>
<string name="track_points_category_name">Vägpunkter, sevärdheter, namngivna funktioner</string>
<string name="shared_string_gpx_track">Spår</string>
@ -2135,11 +2138,11 @@
<string name="select_street">Välj gator</string>
<string name="shared_string_in_name">i %1$s</string>
<string name="type_address">Ange adress</string>
<string name="type_city_town">Ange stad</string>
<string name="type_city_town">Skriv stad/samhälle/ort</string>
<string name="type_postcode">Ange postnummer</string>
<string name="nearest_cities">Närmaste städer</string>
<string name="select_city">Välj stad</string>
<string name="select_postcode">Välj postnummer</string>
<string name="select_postcode">Postnummer sökning</string>
<string name="quick_action_auto_zoom">Autozoomning på/av</string>
<string name="quick_action_showhide_osmbugs_descr">Knapp för att visa eller dölja OSM-anteckningar på kartan.</string>
<string name="restart_search">Starta om sökningen</string>
@ -2153,7 +2156,7 @@
<string name="favorite_group_name">Gruppnamn</string>
<string name="change_color">Ändra färg</string>
<string name="edit_name">Redigera namn</string>
<string name="quick_action_add_destination">Lägg till destination</string>
<string name="quick_action_add_destination">Ange destination</string>
<string name="quick_action_replace_destination">Ersätt destination</string>
<string name="no_overlay">Inget överlägg</string>
<string name="no_underlay">Inget underlägg</string>
@ -2212,7 +2215,7 @@
<string name="mapillary_menu_title_dates">Datum</string>
<string name="mapillary_menu_edit_text_hint">Ange användarnamn</string>
<string name="mapillary_menu_title_username">Användarnamn</string>
<string name="animate_my_location">Animera min plats</string>
<string name="animate_my_location">Animera din egen position</string>
<string name="analyze_on_map">Analysera på kartan</string>
<string name="restore_purchases">Återställ köp</string>
<string name="shared_string_paused">Pausad</string>
@ -2396,15 +2399,15 @@
<string name="routing_attr_allow_private_name">Tillåt privat åtkomst</string>
<string name="routing_attr_allow_private_description">Tillåta åtkomst till privata områden.</string>
<string name="display_zoom_level">Visa zoom-nivå: %1$s</string>
<string name="animate_my_location_desc">Aktivera kartpanoreringsanimation av \'Min Position\' under navigering.</string>
<string name="animate_my_location_desc">Aktivera animerad kartpanning av \"Min position\" under navigering.</string>
<string name="shared_string_overview">Översikt</string>
<string name="quick_action_auto_zoom_desc">Ett tryck på den här åtgärdsknappen kommer att slå på/av automatisk zoomkarta enligt din hastighet.</string>
<string name="quick_action_auto_zoom_on">Aktivera autozoom karta</string>
<string name="quick_action_auto_zoom_off">Inaktivera autozoom karta</string>
<string name="quick_action_auto_zoom_desc">Knapp för att slå på eller av hastighetsstyrd automatisk zoom.</string>
<string name="quick_action_auto_zoom_on">Aktivera autozoom</string>
<string name="quick_action_auto_zoom_off">Inaktivera autozoom</string>
<string name="quick_action_add_first_intermediate">Lägg till första mellanliggande</string>
<string name="quick_action_add_destination_desc">Genom att trycka på den här åtgärdsknappen blir skärmens mittpunkt resmålet, alla tidigare valda mål blir den senaste mellanliggande destinationen.</string>
<string name="quick_action_replace_destination_desc">Genom att trycka på den här åtgärdsknappen kan skärmen centrera den nya ruttdestinationen och ersätta den tidigare valda destinationen (om någon).</string>
<string name="quick_action_add_first_intermediate_desc">Genom att trycka på denna åtgärdsknapp kommer skärmens mittpunkt att bli den första mellanliggande destinationen.</string>
<string name="quick_action_add_destination_desc">En knapp för att göra skärmen centrerad till ruttdestinationen, en tidigare vald destination skulle bli den sista mellandestinationen.</string>
<string name="quick_action_replace_destination_desc">En knapp för att göra skärmen centrerad till den nya ruttdestinationen och ersätta den tidigare valda destinationen (om någon).</string>
<string name="quick_action_add_first_intermediate_desc">En knapp för att göra skärmens centrum till den första mellanliggande destinationen.</string>
<string name="subscribe_email_desc">Anmäl dig till vår e-postlista om apprabatter och få 3 extra kartnedladdningar!</string>
<string name="depth_contour_descr">Havsdjupskonturer och sjömärken.</string>
<string name="sea_depth_thanks">Tack för att du köpt \"Nautiska djupkonturer\"</string>
@ -3358,4 +3361,50 @@
<string name="renew_subscription">Förnya prenumerationen</string>
<string name="in_grace_period">I nådeperioden</string>
<string name="on_hold">Pausad</string>
<string name="shared_string_night_map">Nattkarta</string>
<string name="add_online_source">Lägg till onlinekälla</string>
<string name="clear_tiles_warning">Om du använder dessa ändringar raderas cachade data för denna kakelkälla</string>
<string name="vessel_height_warning_link">Ställ in fartygets höjd</string>
<string name="vessel_height_warning">Du kan ställa in fartygets höjd för att undvika låga broar. Tänk på att om bron är rörlig kommer vi att använda dess höjd i öppet tillstånd.</string>
<string name="vessel_height_limit_description">Ställ in fartygets höjd för att undvika låga broar. Tänk på att om bron är rörlig kommer vi att använda dess höjd i öppet tillstånd.</string>
<string name="vessel_width_limit_description">Ställ in fartygets bredd för att undvika smala broar</string>
<string name="quick_action_showhide_mapillary_descr">En växling för att visa eller dölja Mapillary-lagret på kartan.</string>
<string name="routing_attr_length_description">Ange tillåten fordonslängd på rutter.</string>
<string name="routing_attr_length_name">Längdsgräns</string>
<string name="shared_string_bearing">Bäring</string>
<string name="item_deleted">%1$s har tagits bort</string>
<string name="speed_cameras_restart_descr">Starta om appen för att radera all hastighetskameradata.</string>
<string name="shared_string_uninstall_and_restart">Avinstallera och starta om</string>
<string name="speed_cameras_removed_descr">Den här enheten har inte hastighetskameror.</string>
<string name="app_mode_inline_skates">Rullskridskor</string>
<string name="quick_action_remove_next_destination">Ta bort närmaste destination</string>
<string name="use_volume_buttons_as_zoom_descr">Kontrollera zoomningsnivån för kartan med volymknapparna på enheten.</string>
<string name="use_volume_buttons_as_zoom">Volymknappar som zoom</string>
<string name="please_provide_point_name_error">Ange ett namn för punkten</string>
<string name="quick_action_remove_next_destination_descr">Raderar nästa destination på din rutt. Om det är den slutliga destinationen kommer navigationen att stoppas.</string>
<string name="add_hidden_group_info">Den tillagda punkten kommer inte att synas på kartan, eftersom den valda gruppen är dold kan du hitta den i \"%s\".</string>
<string name="app_mode_enduro_motorcycle">Enduro motorcykel</string>
<string name="app_mode_motor_scooter">Skoter</string>
<string name="app_mode_wheelchair">Rullstol</string>
<string name="app_mode_wheelchair_forward">Rullstol framåt</string>
<string name="show_start_dialog">Visa startdialogrutan</string>
<string name="trip_recording_show_start_dialog_setting">Om den är inaktiverad startar inspelningen direkt efter att du har tryckt på widgeten eller menyalternativet och hoppat över bekräftelsedialogrutan.</string>
<string name="customize_route_line">Anpassa ruttlinjen</string>
<string name="shared_string_route_line">Ruttlinje</string>
<string name="route_line_use_map_style_appearance">Ruttlinje skulle användas %1$s som anges i vald kartstil: %2$s.</string>
<string name="expired">Upphörd</string>
<string name="release_4_0_beta">• OsmAnd Live-uppdateringar flyttade till \"Nedladdningar&gt; Uppdateringar\"
\n
\n• Spår kan nu färga efter höjd, hastighet eller lutning.
\n
\n• Lagt till alternativ för att ändra utseendet på navigeringslinjen
\n
\n• Uppdaterad \"Trip recording\" -dialog
\n
\n</string>
<string name="update_all_maps_added">Uppdatera alla kartor som lagts till i %1$s\?</string>
<string name="exit_number">Utgångsnummer</string>
<string name="announce_when_exceeded">Meddela när den överskrids</string>
<string name="user_points">Användarpunkter</string>
<string name="output">Utgång</string>
</resources>

View file

@ -3926,4 +3926,6 @@
<string name="poi_karate">Карате</string>
<string name="poi_office_diplomatic">Дипломатичне відомство</string>
<string name="poi_bay_filter">Тип затоки</string>
<string name="poi_plateau">Плато</string>
<string name="poi_club_social">Суспільний клуб</string>
</resources>

View file

@ -3926,4 +3926,6 @@
<string name="poi_hoops">籃圈</string>
<string name="poi_office_diplomatic">外交部</string>
<string name="poi_bay_filter">海灣類型</string>
<string name="poi_plateau">高原</string>
<string name="poi_club_social">社交俱樂部</string>
</resources>

View file

@ -4381,4 +4381,8 @@
<string name="poi_office_diplomatic">Diplomatic office</string>
<string name="poi_plateau">Plateau</string>
<string name="poi_club_social">Social club</string>
</resources>

View file

@ -21,8 +21,14 @@
<string name="user_points">User points</string>
<string name="announce_when_exceeded">Announce when exceeded</string>
<string name="exit_number">Exit number</string>
<string name="srtm_download_single_help_message">Please select the needed format. You will need to re-download the file to change the format.</string>
<string name="srtm_download_list_help_message">OsmAnd provides contour lines data in meters and feet. You will need to re-download the file to change the format.</string>
<string name="srtm_unit_format">Contour lines unit format</string>
<string name="shared_string_feet">feet</string>
<string name="update_all_maps_added">Update all maps added to %1$s?</string>
<string name="release_4_0_beta">
• Added option to download Contour lines in feet\n\n
• Plan Route landscape: added tabs to switch between points or graphs\n\n
• OsmAnd Live updates moved to \"Downloads > Updates\"\n\n
• Tracks now could be colorizing by altitude, speed, or slope.\n\n
• Added option to change the appearance of the navigation route line\n\n

View file

@ -18,11 +18,12 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.inapp.InAppPurchases.InAppPurchase;
import net.osmand.plus.inapp.InAppPurchases.InAppPurchase.PurchaseState;
import net.osmand.plus.inapp.InAppPurchases.InAppSubscription;
import net.osmand.plus.inapp.InAppPurchases.InAppSubscription.SubscriptionState;
import net.osmand.plus.inapp.InAppPurchases.PurchaseInfo;
import net.osmand.plus.inapp.InAppPurchasesImpl.InAppPurchaseLiveUpdatesOldSubscription;
import net.osmand.plus.inapp.util.BillingManager;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.srtmplugin.SRTMPlugin;
import net.osmand.util.Algorithms;
@ -174,7 +175,8 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
});
}
for (Purchase purchase : purchases) {
if (!purchase.isAcknowledged()) {
InAppSubscription subscription = getLiveUpdates().getSubscriptionBySku(purchase.getSku());
if (!purchase.isAcknowledged() || (subscription != null && !subscription.isPurchased())) {
onPurchaseFinished(purchase);
}
}
@ -310,8 +312,8 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
}
}
}
for (Entry<String, SubscriptionState> entry : subscriptionStateMap.entrySet()) {
SubscriptionState state = entry.getValue();
for (Entry<String, SubscriptionStateHolder> entry : subscriptionStateMap.entrySet()) {
SubscriptionState state = entry.getValue().state;
if (state == SubscriptionState.PAUSED || state == SubscriptionState.ON_HOLD) {
String sku = entry.getKey();
if (!result.contains(sku)) {
@ -492,15 +494,17 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
}
private PurchaseInfo getPurchaseInfo(Purchase purchase) {
return new PurchaseInfo(purchase.getSku(), purchase.getOrderId(), purchase.getPurchaseToken());
return new PurchaseInfo(purchase.getSku(), purchase.getOrderId(), purchase.getPurchaseToken(),
purchase.getPurchaseTime(), purchase.getPurchaseState(), purchase.isAcknowledged(), purchase.isAutoRenewing());
}
private void fetchInAppPurchase(@NonNull InAppPurchase inAppPurchase, @NonNull SkuDetails skuDetails, @Nullable Purchase purchase) {
if (purchase != null) {
inAppPurchase.setPurchaseState(InAppPurchase.PurchaseState.PURCHASED);
inAppPurchase.setPurchaseTime(purchase.getPurchaseTime());
inAppPurchase.setPurchaseState(PurchaseState.PURCHASED);
inAppPurchase.setPurchaseInfo(ctx, getPurchaseInfo(purchase));
} else {
inAppPurchase.setPurchaseState(InAppPurchase.PurchaseState.NOT_PURCHASED);
inAppPurchase.setPurchaseState(PurchaseState.NOT_PURCHASED);
inAppPurchase.restorePurchaseInfo(ctx);
}
inAppPurchase.setPrice(skuDetails.getPrice());
inAppPurchase.setPriceCurrencyCode(skuDetails.getPriceCurrencyCode());
@ -519,18 +523,17 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
}
if (inAppPurchase instanceof InAppSubscription) {
InAppSubscription s = (InAppSubscription) inAppPurchase;
SubscriptionState state = subscriptionStateMap.get(inAppPurchase.getSku());
s.setState(state == null ? SubscriptionState.UNDEFINED : state);
CommonPreference<String> statePref = ctx.getSettings().registerStringPreference(
s.getSku() + "_state", SubscriptionState.UNDEFINED.getStateStr()).makeGlobal();
s.setPrevState(SubscriptionState.getByStateStr(statePref.get()));
statePref.set(s.getState().getStateStr());
s.restoreState(ctx);
s.restoreExpireTime(ctx);
SubscriptionStateHolder stateHolder = subscriptionStateMap.get(s.getSku());
if (stateHolder != null) {
s.setState(ctx, stateHolder.state);
s.setExpireTime(ctx, stateHolder.expireTime);
}
if (s.getState().isGone() && s.hasStateChanged()) {
ctx.getSettings().LIVE_UPDATES_EXPIRED_FIRST_DLG_SHOWN_TIME.set(0L);
ctx.getSettings().LIVE_UPDATES_EXPIRED_SECOND_DLG_SHOWN_TIME.set(0L);
}
String introductoryPrice = skuDetails.getIntroductoryPrice();
String introductoryPricePeriod = skuDetails.getIntroductoryPricePeriod();
int introductoryPriceCycles = skuDetails.getIntroductoryPriceCycles();

View file

@ -29,6 +29,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.inapp.InAppPurchases.InAppPurchase;
import net.osmand.plus.inapp.InAppPurchases.InAppSubscription;
import net.osmand.plus.inapp.InAppPurchases.InAppSubscriptionIntroductoryInfo;
import net.osmand.plus.inapp.InAppPurchases.PurchaseInfo;
import net.osmand.plus.inapp.InAppPurchasesImpl.InAppPurchaseLiveUpdatesOldSubscription;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.util.Algorithms;
@ -48,7 +49,7 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
private List<ProductInfo> productInfos;
private OwnedPurchasesResult ownedSubscriptions;
private List<OwnedPurchasesResult> ownedInApps = new ArrayList<>();
private final List<OwnedPurchasesResult> ownedInApps = new ArrayList<>();
public InAppPurchaseHelperImpl(OsmandApplication ctx) {
super(ctx);
@ -233,15 +234,18 @@ public class InAppPurchaseHelperImpl extends InAppPurchaseHelper {
}
private PurchaseInfo getPurchaseInfo(InAppPurchaseData purchase) {
return new PurchaseInfo(purchase.getProductId(), purchase.getSubscriptionId(), purchase.getPurchaseToken());
return new PurchaseInfo(purchase.getProductId(), purchase.getSubscriptionId(), purchase.getPurchaseToken(),
purchase.getPurchaseTime(), purchase.getPurchaseState(), true, purchase.isAutoRenewing());
}
private void fetchInAppPurchase(@NonNull InAppPurchase inAppPurchase, @NonNull ProductInfo productInfo, @Nullable InAppPurchaseData purchaseData) {
if (purchaseData != null) {
inAppPurchase.setPurchaseState(InAppPurchase.PurchaseState.PURCHASED);
inAppPurchase.setPurchaseTime(purchaseData.getPurchaseTime());
inAppPurchase.setPurchaseInfo(ctx, getPurchaseInfo(purchaseData));
} else {
inAppPurchase.setPurchaseState(InAppPurchase.PurchaseState.NOT_PURCHASED);
inAppPurchase.restorePurchaseInfo(ctx);
}
inAppPurchase.setPrice(productInfo.getPrice());
inAppPurchase.setPriceCurrencyCode(productInfo.getCurrency());

View file

@ -22,6 +22,8 @@ import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.StateListDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.StatFs;
@ -264,6 +266,11 @@ public class AndroidUtils {
return "";
}
public static String getFreeSpace(Context ctx, File dir) {
long size = AndroidUtils.getAvailableSpace(dir);
return AndroidUtils.formatSize(ctx, size);
}
public static View findParentViewById(View view, int id) {
ViewParent viewParent = view.getParent();
@ -856,11 +863,39 @@ public class AndroidUtils {
return result;
}
public static long getAvailableSpace(@NonNull OsmandApplication app) {
return getAvailableSpace(app.getAppPath(null));
}
public static long getTotalSpace(@NonNull OsmandApplication app) {
return getTotalSpace(app.getAppPath(null));
}
public static long getAvailableSpace(@Nullable File dir) {
if (dir != null && dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath());
return fs.getAvailableBlocksLong() * fs.getBlockSize();
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2) {
return fs.getAvailableBlocksLong() * fs.getBlockSizeLong();
} else {
return fs.getAvailableBlocks() * fs.getBlockSize();
}
} catch (IllegalArgumentException e) {
LOG.error(e);
}
}
return -1;
}
public static long getTotalSpace(@Nullable File dir) {
if (dir != null && dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath());
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2) {
return fs.getBlockCountLong() * fs.getBlockSizeLong();
} else {
return fs.getBlockCount() * fs.getBlockSize();
}
} catch (IllegalArgumentException e) {
LOG.error(e);
}
@ -887,13 +922,6 @@ public class AndroidUtils {
return -1;
}
public static float getUsedSpaceGb(File dir) {
if (dir.canRead()) {
return getTotalSpaceGb(dir) - getFreeSpaceGb(dir);
}
return -1;
}
public static CharSequence getStyledString(CharSequence baseString, CharSequence stringToInsertAndStyle,
CharacterStyle baseStyle, CharacterStyle replaceStyle) {
int indexOfPlaceholder = baseString.toString().indexOf(STRING_PLACEHOLDER);

View file

@ -291,10 +291,12 @@ public class GpxSelectionHelper {
return group;
}
private String getGroupName(GPXFile g) {
public String getGroupName(GPXFile g) {
String name = g.path;
if (g.showCurrentTrack) {
name = getString(R.string.shared_string_currently_recording_track);
} else if (Algorithms.isEmpty(name)) {
name = getString(R.string.current_route);
} else {
int i = name.lastIndexOf('/');
if (i >= 0) {

View file

@ -442,15 +442,14 @@ public class UiUtilities {
} catch (Throwable e) { }
}
public static void rotateImageByLayoutDirection(ImageView image, int layoutDirection) {
public static void rotateImageByLayoutDirection(ImageView image) {
if (image == null) {
return;
}
int rotation = layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL ? 180 : 0;
int rotation = AndroidUtils.getLayoutDirection(image.getContext()) == ViewCompat.LAYOUT_DIRECTION_RTL ? 180 : 0;
image.setRotationY(rotation);
}
public static void updateCustomRadioButtons(Context app, View buttonsView, boolean nightMode,
CustomRadioButtonType buttonType) {
int activeColor = ContextCompat.getColor(app, nightMode

View file

@ -13,6 +13,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.SQLiteTileSource;
import net.osmand.plus.Version;
import net.osmand.plus.download.SrtmDownloadItem;
import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
import net.osmand.plus.voice.JSMediaCommandPlayerImpl;
import net.osmand.plus.voice.JSTTSCommandPlayerImpl;
@ -143,8 +144,6 @@ public class LocalIndexHelper {
return null;
}
public List<LocalIndexInfo> getLocalIndexInfos(String downloadName) {
List<LocalIndexInfo> list = new ArrayList<>();
LocalIndexInfo info = getLocalIndexInfo(LocalIndexType.MAP_DATA, downloadName, false, false);
@ -313,7 +312,7 @@ public class LocalIndexHelper {
}
}
}
private void loadTravelData(File mapPath, List<LocalIndexInfo> result, AbstractLoadLocalIndexTask loadTask) {
if (mapPath.canRead()) {
for (File mapFile : listFilesSorted(mapPath)) {
@ -333,14 +332,15 @@ public class LocalIndexHelper {
if (mapPath.canRead()) {
for (File mapFile : listFilesSorted(mapPath)) {
if (mapFile.isFile() && mapFile.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) {
String fileName = mapFile.getName();
LocalIndexType lt = LocalIndexType.MAP_DATA;
if (mapFile.getName().endsWith(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)) {
if (SrtmDownloadItem.isSrtmFile(fileName)) {
lt = LocalIndexType.SRTM_DATA;
} else if (mapFile.getName().endsWith(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT)) {
} else if (fileName.endsWith(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT)) {
lt = LocalIndexType.WIKI_DATA;
}
LocalIndexInfo info = new LocalIndexInfo(lt, mapFile, backup, app);
if (loadedMaps.containsKey(mapFile.getName()) && !backup) {
if (loadedMaps.containsKey(fileName) && !backup) {
info.setLoaded(true);
}
updateDescription(info);
@ -403,7 +403,7 @@ public class LocalIndexHelper {
if (fileName.endsWith(IndexConstants.SQLITE_EXT)) {
return fileName.substring(0, fileName.length() - IndexConstants.SQLITE_EXT.length());
}
if (localIndexInfo.getType() == TRAVEL_DATA &&
if (localIndexInfo.getType() == TRAVEL_DATA &&
fileName.endsWith(IndexConstants.BINARY_WIKIVOYAGE_MAP_INDEX_EXT)) {
return fileName.substring(0, fileName.length() - IndexConstants.BINARY_WIKIVOYAGE_MAP_INDEX_EXT.length());
}
@ -430,5 +430,4 @@ public class LocalIndexHelper {
return fileName;
}
}
}

View file

@ -94,6 +94,12 @@ public class MapActivityKeyListener implements KeyEvent.Callback {
mapActivity.getMapViewTrackingUtilities().backToLocationImpl();
} else if (keyCode == KeyEvent.KEYCODE_D) {
mapActivity.getMapViewTrackingUtilities().switchRotateMapMode();
} else if (keyCode == KeyEvent.KEYCODE_MINUS) {
mapActivity.changeZoom(-1);
return true;
} else if (keyCode == KeyEvent.KEYCODE_PLUS || keyCode == KeyEvent.KEYCODE_EQUALS) {
mapActivity.changeZoom(1);
return true;
} else if (mapScrollHelper.isAvailableKeyCode(keyCode)) {
return mapScrollHelper.onKeyUp(keyCode, event);
} else if (settings.EXTERNAL_INPUT_DEVICE.get() == PARROT_EXTERNAL_DEVICE) {
@ -121,13 +127,7 @@ public class MapActivityKeyListener implements KeyEvent.Callback {
return true;
}
} else if (settings.EXTERNAL_INPUT_DEVICE.get() == GENERIC_EXTERNAL_DEVICE) {
if (keyCode == KeyEvent.KEYCODE_MINUS) {
mapActivity.changeZoom(-1);
return true;
} else if (keyCode == KeyEvent.KEYCODE_PLUS || keyCode == KeyEvent.KEYCODE_EQUALS) {
mapActivity.changeZoom(1);
return true;
}
// currently doesn't process specific commands
} else if (OsmandPlugin.onMapActivityKeyUp(mapActivity, keyCode)) {
return true;
}

View file

@ -109,7 +109,7 @@ public class PluginInfoFragment extends BaseOsmAndFragment implements PluginStat
}
}
});
UiUtilities.rotateImageByLayoutDirection(closeButton, AndroidUtils.getLayoutDirection(app));
UiUtilities.rotateImageByLayoutDirection(closeButton);
Drawable pluginImage = plugin.getAssetResourceImage();
if (pluginImage != null) {

View file

@ -101,7 +101,7 @@ public class PluginsFragment extends BaseOsmAndFragment implements PluginStateLi
}
}
});
UiUtilities.rotateImageByLayoutDirection(closeButton, AndroidUtils.getLayoutDirection(app));
UiUtilities.rotateImageByLayoutDirection(closeButton);
adapter = new PluginsListAdapter(requireContext());

View file

@ -22,7 +22,6 @@ import android.media.MediaRecorder;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Build;
import android.os.StatFs;
import android.provider.MediaStore;
import android.view.Display;
import android.view.KeyEvent;
@ -1607,13 +1606,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
double bitrate = (((p.videoBitRate + p.audioBitRate) / 8f) * 60f) / (1 << 30); // gigabytes per minute
double clipSpace = bitrate * AV_RS_CLIP_LENGTH.get();
double storageSize = AV_RS_STORAGE_SIZE.get();
double availableSpace = storageSize;
File dir = app.getAppPath("").getParentFile();
if (dir.canRead()) {
StatFs fs = new StatFs(dir.getAbsolutePath());
availableSpace = (double) (fs.getAvailableBlocks()) * fs.getBlockSize() / (1 << 30) - clipSpace;
}
double availableSpace = (double) AndroidUtils.getAvailableSpace(app) / (1 << 30) - clipSpace;
if (usedSpace + clipSpace > storageSize || clipSpace > availableSpace) {
Arrays.sort(files, new Comparator<File>() {

View file

@ -11,7 +11,6 @@ import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.os.StatFs;
import android.text.SpannableString;
import android.view.LayoutInflater;
import android.view.View;
@ -42,7 +41,6 @@ import net.osmand.plus.widgets.style.CustomTypefaceSpan;
import org.apache.commons.logging.Log;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@ -381,16 +379,7 @@ public class MultimediaNotesFragment extends BaseSettingsFragment implements Cop
private void setupStorageSizePref(AudioVideoNotesPlugin plugin) {
ListPreferenceEx storageSize = (ListPreferenceEx) findPreference(plugin.AV_RS_STORAGE_SIZE.getId());
File dir = app.getAppPath("").getParentFile();
long size = 0;
if (dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath());
size = ((long) fs.getBlockSize() * (long) fs.getBlockCount()) / (1 << 30);
} catch (IllegalArgumentException e) {
log.error(e);
}
}
long size = AndroidUtils.getTotalSpace(app) / (1 << 30);
if (size > 0) {
int value = 1;
ArrayList<Integer> gbList = new ArrayList<>();

View file

@ -0,0 +1,80 @@
package net.osmand.plus.base;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils;
import net.osmand.plus.R;
import net.osmand.plus.widgets.multistatetoggle.RadioItem;
import java.util.Collections;
import java.util.List;
public class ModeSelectionBottomSheet extends SelectionBottomSheet {
public static final String TAG = ModeSelectionBottomSheet.class.getSimpleName();
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
showElements(primaryDescription, toggleContainer);
hideElements(checkBox, checkBoxTitle, titleDescription,
secondaryDescription, selectedSize, selectAllButton);
}
@Override
protected void updateItemView(SelectableItem item, View view) {
ImageView ivIcon = view.findViewById(R.id.icon);
TextView tvTitle = view.findViewById(R.id.title);
TextView tvDescr = view.findViewById(R.id.description);
Drawable icon = uiUtilities.getIcon(item.getIconId(), activeColorRes);
ivIcon.setImageDrawable(icon);
tvTitle.setText(item.getTitle());
tvDescr.setText(item.getDescription());
tvDescr.setTextColor(ContextCompat.getColor(app, AndroidUtils.getSecondaryTextColorId(nightMode)));
}
@Override
protected int getItemLayoutId() {
return R.layout.bottom_sheet_item_with_descr_56dp;
}
public void setItem(SelectableItem item) {
setItems(Collections.singletonList(item));
}
@NonNull
@Override
public List<SelectableItem> getSelectedItems() {
return allItems;
}
@Override
protected boolean shouldShowDivider() {
return false;
}
public static ModeSelectionBottomSheet showInstance(@NonNull AppCompatActivity activity,
@NonNull SelectableItem previewItem,
@NonNull List<RadioItem> radioItems,
boolean usedOnMap) {
ModeSelectionBottomSheet fragment = new ModeSelectionBottomSheet();
fragment.setUsedOnMap(usedOnMap);
fragment.setModes(radioItems);
fragment.setItems(Collections.singletonList(previewItem));
FragmentManager fm = activity.getSupportFragmentManager();
fragment.show(fm, TAG);
return fragment;
}
}

View file

@ -0,0 +1,180 @@
package net.osmand.plus.base;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.core.widget.CompoundButtonCompat;
import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils;
import net.osmand.plus.R;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.util.Algorithms;
import java.util.ArrayList;
import java.util.List;
import static net.osmand.view.ThreeStateCheckbox.State.CHECKED;
import static net.osmand.view.ThreeStateCheckbox.State.MISC;
import static net.osmand.view.ThreeStateCheckbox.State.UNCHECKED;
public class MultipleSelectionBottomSheet extends SelectionBottomSheet {
public static final String TAG = MultipleSelectionBottomSheet.class.getSimpleName();
private final List<SelectableItem> selectedItems = new ArrayList<>();
private SelectionUpdateListener selectionUpdateListener;
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
selectAllButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkBox.performClick();
boolean checked = checkBox.getState() == CHECKED;
if (checked) {
selectedItems.addAll(allItems);
} else {
selectedItems.clear();
}
onSelectedItemsChanged();
updateItemsSelection(checked);
}
});
}
@Override
protected boolean shouldShowDivider() {
return true;
}
@Override
protected void updateItemView(final SelectableItem item, View view) {
boolean checked = selectedItems.contains(item);
ImageView imageView = view.findViewById(R.id.icon);
TextView title = view.findViewById(R.id.title);
TextView description = view.findViewById(R.id.description);
final CheckBox checkBox = view.findViewById(R.id.compound_button);
AndroidUiHelper.setVisibility(View.VISIBLE, imageView, title, description, checkBox);
checkBox.setChecked(checked);
CompoundButtonCompat.setButtonTintList(checkBox, AndroidUtils.createCheckedColorStateList(app, secondaryColorRes, activeColorRes));
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
boolean checked = !checkBox.isChecked();
checkBox.setChecked(checked);
if (checked) {
selectedItems.add(item);
} else {
selectedItems.remove(item);
}
onSelectedItemsChanged();
}
});
title.setText(item.getTitle());
description.setText(item.getDescription());
imageView.setImageDrawable(uiUtilities.getIcon(item.getIconId(), activeColorRes));
}
@Override
protected int getItemLayoutId() {
return R.layout.bottom_sheet_item_with_descr_and_checkbox_56dp;
}
@Override
protected void notifyUiInitialized() {
onSelectedItemsChanged();
super.notifyUiInitialized();
}
private void onSelectedItemsChanged() {
updateSelectAllButton();
updateSelectedSizeView();
updateApplyButtonEnable();
if (selectionUpdateListener != null) {
selectionUpdateListener.onSelectionUpdate();
}
}
private void updateSelectAllButton() {
String checkBoxTitle;
if (Algorithms.isEmpty(selectedItems)) {
checkBox.setState(UNCHECKED);
checkBoxTitle = getString(R.string.shared_string_select_all);
} else {
checkBox.setState(selectedItems.containsAll(allItems) ? CHECKED : MISC);
checkBoxTitle = getString(R.string.shared_string_deselect_all);
}
int checkBoxColor = checkBox.getState() == UNCHECKED ? secondaryColorRes : activeColorRes;
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, checkBoxColor)));
this.checkBoxTitle.setText(checkBoxTitle);
}
private void updateSelectedSizeView() {
String selected = String.valueOf(selectedItems.size());
String all = String.valueOf(allItems.size());
selectedSize.setText(getString(R.string.ltr_or_rtl_combine_via_slash, selected, all));
}
private void updateApplyButtonEnable() {
boolean noEmptySelection = !Algorithms.isEmpty(selectedItems);
rightButton.setEnabled(noEmptySelection);
}
private void updateItemsSelection(boolean checked) {
for (SelectableItem item : allItems) {
View v = listViews.get(item);
CheckBox checkBox = v != null ? (CheckBox) v.findViewById(R.id.compound_button) : null;
if (checkBox != null) {
checkBox.setChecked(checked);
}
}
}
protected void setSelectedItems(List<SelectableItem> selected) {
selectedItems.clear();
if (!Algorithms.isEmpty(selected)) {
selectedItems.addAll(selected);
}
}
@NonNull
@Override
public List<SelectableItem> getSelectedItems() {
return selectedItems;
}
public void setSelectionUpdateListener(SelectionUpdateListener selectionUpdateListener) {
this.selectionUpdateListener = selectionUpdateListener;
}
public static MultipleSelectionBottomSheet showInstance(@NonNull AppCompatActivity activity,
@NonNull List<SelectableItem> items,
@Nullable List<SelectableItem> selected,
boolean usedOnMap) {
MultipleSelectionBottomSheet fragment = new MultipleSelectionBottomSheet();
fragment.setUsedOnMap(usedOnMap);
fragment.setItems(items);
fragment.setSelectedItems(selected);
FragmentManager fm = activity.getSupportFragmentManager();
fragment.show(fm, TAG);
return fragment;
}
public interface SelectionUpdateListener {
void onSelectionUpdate();
}
}

View file

@ -0,0 +1,41 @@
package net.osmand.plus.base;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import net.osmand.plus.widgets.multistatetoggle.RadioItem;
import java.util.List;
public class MultipleSelectionWithModeBottomSheet extends MultipleSelectionBottomSheet {
public static final String TAG = MultipleSelectionWithModeBottomSheet.class.getSimpleName();
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
showElements(secondaryDescription, toggleContainer, checkBox,
checkBoxTitle, titleDescription, selectedSize, selectAllButton);
}
public static MultipleSelectionWithModeBottomSheet showInstance(@NonNull AppCompatActivity activity,
@NonNull List<SelectableItem> items,
@Nullable List<SelectableItem> selected,
@NonNull List<RadioItem> modes,
boolean usedOnMap) {
MultipleSelectionWithModeBottomSheet fragment = new MultipleSelectionWithModeBottomSheet();
fragment.setUsedOnMap(usedOnMap);
fragment.setItems(items);
fragment.setSelectedItems(selected);
fragment.setModes(modes);
FragmentManager fm = activity.getSupportFragmentManager();
fragment.show(fm, TAG);
return fragment;
}
}

View file

@ -1,301 +0,0 @@
package net.osmand.plus.base;
import android.content.res.ColorStateList;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.core.widget.CompoundButtonCompat;
import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton;
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithCompoundButton.Builder;
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.SimpleDividerItem;
import net.osmand.util.Algorithms;
import net.osmand.view.ThreeStateCheckbox;
import java.util.ArrayList;
import java.util.List;
import static net.osmand.view.ThreeStateCheckbox.State.CHECKED;
import static net.osmand.view.ThreeStateCheckbox.State.MISC;
import static net.osmand.view.ThreeStateCheckbox.State.UNCHECKED;
public class SelectMultipleItemsBottomSheet extends MenuBottomSheetDialogFragment {
private OsmandApplication app;
private UiUtilities uiUtilities;
private TextView title;
private TextView description;
private TextView applyButtonTitle;
private TextView checkBoxTitle;
private TextView selectedSize;
private ThreeStateCheckbox checkBox;
private int activeColorRes;
private int secondaryColorRes;
private final List<SelectableItem> allItems = new ArrayList<>();
private final List<SelectableItem> selectedItems = new ArrayList<>();
private SelectionUpdateListener selectionUpdateListener;
private OnApplySelectionListener onApplySelectionListener;
public static final String TAG = SelectMultipleItemsBottomSheet.class.getSimpleName();
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View mainView = super.onCreateView(inflater, parent, savedInstanceState);
onSelectedItemsChanged();
return mainView;
}
@Override
public void createMenuItems(Bundle savedInstanceState) {
app = requiredMyApplication();
uiUtilities = app.getUIUtilities();
activeColorRes = nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light;
secondaryColorRes = nightMode ? R.color.icon_color_secondary_dark : R.color.icon_color_secondary_light;
items.add(createTitleItem());
items.add(new SimpleDividerItem(app));
createListItems();
}
private BaseBottomSheetItem createTitleItem() {
LayoutInflater themedInflater = UiUtilities.getInflater(requireContext(), nightMode);
View view = themedInflater.inflate(R.layout.settings_group_title, null);
checkBox = view.findViewById(R.id.check_box);
checkBoxTitle = view.findViewById(R.id.check_box_title);
description = view.findViewById(R.id.description);
selectedSize = view.findViewById(R.id.selected_size);
title = view.findViewById(R.id.title);
View selectAllButton = view.findViewById(R.id.select_all_button);
selectAllButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkBox.performClick();
boolean checked = checkBox.getState() == CHECKED;
if (checked) {
selectedItems.addAll(allItems);
} else {
selectedItems.clear();
}
onSelectedItemsChanged();
updateItems(checked);
}
});
return new SimpleBottomSheetItem.Builder().setCustomView(view).create();
}
private void createListItems() {
for (final SelectableItem item : allItems) {
boolean checked = selectedItems.contains(item);
final BottomSheetItemWithCompoundButton[] uiItem = new BottomSheetItemWithCompoundButton[1];
final Builder builder = (BottomSheetItemWithCompoundButton.Builder) new Builder();
builder.setChecked(checked)
.setButtonTintList(AndroidUtils.createCheckedColorStateList(app, secondaryColorRes, activeColorRes))
.setLayoutId(R.layout.bottom_sheet_item_with_descr_and_checkbox_56dp)
.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean checked = !uiItem[0].isChecked();
uiItem[0].setChecked(checked);
SelectableItem tag = (SelectableItem) uiItem[0].getTag();
if (checked) {
selectedItems.add(tag);
} else {
selectedItems.remove(tag);
}
onSelectedItemsChanged();
}
})
.setTag(item);
setupListItem(builder, item);
uiItem[0] = builder.create();
items.add(uiItem[0]);
}
}
@Override
protected void setupRightButton() {
super.setupRightButton();
applyButtonTitle = rightButton.findViewById(R.id.button_text);
}
@Override
protected void onRightBottomButtonClick() {
if (onApplySelectionListener != null) {
onApplySelectionListener.onSelectionApplied(selectedItems);
}
dismiss();
}
private void onSelectedItemsChanged() {
updateSelectAllButton();
updateSelectedSizeView();
updateApplyButtonEnable();
if (selectionUpdateListener != null) {
selectionUpdateListener.onSelectionUpdate();
}
}
@Override
protected int getRightBottomButtonTextId() {
return R.string.shared_string_apply;
}
@Override
protected boolean useVerticalButtons() {
return true;
}
private void setupListItem(Builder builder, SelectableItem item) {
builder.setTitle(item.title);
builder.setDescription(item.description);
builder.setIcon(uiUtilities.getIcon(item.iconId, activeColorRes));
}
private void updateSelectAllButton() {
String checkBoxTitle;
if (Algorithms.isEmpty(selectedItems)) {
checkBox.setState(UNCHECKED);
checkBoxTitle = getString(R.string.shared_string_select_all);
} else {
checkBox.setState(selectedItems.containsAll(allItems) ? CHECKED : MISC);
checkBoxTitle = getString(R.string.shared_string_deselect_all);
}
int checkBoxColor = checkBox.getState() == UNCHECKED ? secondaryColorRes : activeColorRes;
CompoundButtonCompat.setButtonTintList(checkBox, ColorStateList.valueOf(ContextCompat.getColor(app, checkBoxColor)));
this.checkBoxTitle.setText(checkBoxTitle);
}
private void updateSelectedSizeView() {
String selected = String.valueOf(selectedItems.size());
String all = String.valueOf(allItems.size());
selectedSize.setText(getString(R.string.ltr_or_rtl_combine_via_slash, selected, all));
}
private void updateApplyButtonEnable() {
if (Algorithms.isEmpty(selectedItems)) {
rightButton.setEnabled(false);
} else {
rightButton.setEnabled(true);
}
}
private void updateItems(boolean checked) {
for (BaseBottomSheetItem item : items) {
if (item instanceof BottomSheetItemWithCompoundButton) {
((BottomSheetItemWithCompoundButton) item).setChecked(checked);
}
}
}
public void setTitle(@NonNull String title) {
this.title.setText(title);
}
public void setDescription(@NonNull String description) {
this.description.setText(description);
}
public void setConfirmButtonTitle(@NonNull String confirmButtonTitle) {
applyButtonTitle.setText(confirmButtonTitle);
}
private void setItems(List<SelectableItem> allItems) {
if (!Algorithms.isEmpty(allItems)) {
this.allItems.addAll(allItems);
}
}
private void setSelectedItems(List<SelectableItem> selected) {
if (!Algorithms.isEmpty(selected)) {
this.selectedItems.addAll(selected);
}
}
public List<SelectableItem> getSelectedItems() {
return selectedItems;
}
@Override
public void onPause() {
super.onPause();
if (requireActivity().isChangingConfigurations()) {
dismiss();
}
}
public static SelectMultipleItemsBottomSheet showInstance(@NonNull AppCompatActivity activity,
@NonNull List<SelectableItem> items,
@Nullable List<SelectableItem> selected,
boolean usedOnMap) {
SelectMultipleItemsBottomSheet fragment = new SelectMultipleItemsBottomSheet();
fragment.setUsedOnMap(usedOnMap);
fragment.setItems(items);
fragment.setSelectedItems(selected);
FragmentManager fm = activity.getSupportFragmentManager();
fragment.show(fm, TAG);
return fragment;
}
public void setSelectionUpdateListener(SelectionUpdateListener selectionUpdateListener) {
this.selectionUpdateListener = selectionUpdateListener;
}
public void setOnApplySelectionListener(OnApplySelectionListener onApplySelectionListener) {
this.onApplySelectionListener = onApplySelectionListener;
}
public interface SelectionUpdateListener {
void onSelectionUpdate();
}
public interface OnApplySelectionListener {
void onSelectionApplied(List<SelectableItem> selectedItems);
}
public static class SelectableItem {
private String title;
private String description;
private int iconId;
private Object object;
public void setTitle(String title) {
this.title = title;
}
public void setDescription(String description) {
this.description = description;
}
public void setIconId(int iconId) {
this.iconId = iconId;
}
public void setObject(Object object) {
this.object = object;
}
public Object getObject() {
return object;
}
}
}

View file

@ -0,0 +1,290 @@
package net.osmand.plus.base;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.SimpleBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.SimpleDividerItem;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.widgets.multistatetoggle.MultiStateToggleButton;
import net.osmand.plus.widgets.multistatetoggle.RadioItem;
import net.osmand.plus.widgets.multistatetoggle.TextToggleButton;
import net.osmand.util.Algorithms;
import net.osmand.view.ThreeStateCheckbox;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class SelectionBottomSheet extends MenuBottomSheetDialogFragment {
protected OsmandApplication app;
protected LayoutInflater inflater;
protected UiUtilities uiUtilities;
protected TextView title;
protected TextView titleDescription;
protected TextView primaryDescription;
protected TextView secondaryDescription;
protected TextView selectedSize;
protected LinearLayout toggleContainer;
protected MultiStateToggleButton radioGroup;
protected View selectAllButton;
protected TextView checkBoxTitle;
protected ThreeStateCheckbox checkBox;
protected LinearLayout listContainer;
protected TextView applyButtonTitle;
protected int activeColorRes;
protected int secondaryColorRes;
private OnUiInitializedAdapter onUiInitializedAdapter;
private OnApplySelectionListener onApplySelectionListener;
protected List<SelectableItem> allItems = new ArrayList<>();
protected Map<SelectableItem, View> listViews = new HashMap<>();
private List<RadioItem> modes;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View mainView = super.onCreateView(inflater, parent, savedInstanceState);
createSelectionListIfPossible();
notifyUiInitialized();
return mainView;
}
@Override
public void createMenuItems(Bundle savedInstanceState) {
app = requiredMyApplication();
uiUtilities = app.getUIUtilities();
inflater = UiUtilities.getInflater(requireContext(), nightMode);
activeColorRes = nightMode ? R.color.icon_color_active_dark : R.color.icon_color_active_light;
secondaryColorRes = nightMode ? R.color.icon_color_secondary_dark : R.color.icon_color_secondary_light;
items.add(createHeaderView());
if (shouldShowDivider()) {
items.add(new SimpleDividerItem(app));
}
items.add(createSelectionView());
}
private BaseBottomSheetItem createHeaderView() {
View view = inflater.inflate(R.layout.settings_group_title, null);
title = view.findViewById(R.id.title);
titleDescription = view.findViewById(R.id.title_description);
primaryDescription = view.findViewById(R.id.primary_description);
secondaryDescription = view.findViewById(R.id.secondary_description);
selectedSize = view.findViewById(R.id.selected_size);
toggleContainer = view.findViewById(R.id.custom_radio_buttons);
radioGroup = new TextToggleButton(app, toggleContainer, nightMode);
selectAllButton = view.findViewById(R.id.select_all_button);
checkBoxTitle = view.findViewById(R.id.check_box_title);
checkBox = view.findViewById(R.id.check_box);
if (modes != null) {
radioGroup.setItems(modes);
}
return new SimpleBottomSheetItem.Builder().setCustomView(view).create();
}
private BaseBottomSheetItem createSelectionView() {
Context themedCtx = UiUtilities.getThemedContext(requireContext(), nightMode);
listContainer = new LinearLayout(themedCtx);
listContainer.setLayoutParams(new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
listContainer.setOrientation(LinearLayout.VERTICAL);
return new SimpleBottomSheetItem.Builder().setCustomView(listContainer).create();
}
public void setTitle(@NonNull String title) {
this.title.setText(title);
}
public void setTitleDescription(@NonNull String description) {
titleDescription.setText(description);
}
public void setPrimaryDescription(@NonNull String description) {
primaryDescription.setText(description);
}
public void setSecondaryDescription(@NonNull String description) {
secondaryDescription.setText(description);
}
public void setApplyButtonTitle(@NonNull String title) {
applyButtonTitle.setText(title);
}
public void setModes(@NonNull List<RadioItem> modes) {
this.modes = modes;
if (radioGroup != null) {
radioGroup.setItems(modes);
}
}
public void setSelectedMode(@NonNull RadioItem mode) {
radioGroup.setSelectedItem(mode);
}
public void setItems(List<SelectableItem> allItems) {
this.allItems.clear();
if (!Algorithms.isEmpty(allItems)) {
this.allItems.addAll(allItems);
createSelectionListIfPossible();
}
}
public void setOnUiInitializedAdapter(OnUiInitializedAdapter onUiInitializedAdapter) {
this.onUiInitializedAdapter = onUiInitializedAdapter;
}
public void setOnApplySelectionListener(OnApplySelectionListener onApplySelectionListener) {
this.onApplySelectionListener = onApplySelectionListener;
}
private void createSelectionListIfPossible() {
if (listContainer != null && allItems != null) {
recreateList();
}
}
private void recreateList() {
listViews.clear();
listContainer.removeAllViews();
for (SelectableItem item : allItems) {
setupItemView(item, inflater.inflate(getItemLayoutId(), null));
}
}
private void setupItemView(SelectableItem item, View view) {
updateItemView(item, view);
listViews.put(item, view);
listContainer.addView(view);
}
public List<SelectableItem> getAllItems() {
return allItems;
}
@NonNull
public abstract List<SelectableItem> getSelectedItems();
protected abstract void updateItemView(SelectableItem item, View view);
protected abstract int getItemLayoutId();
protected abstract boolean shouldShowDivider();
protected void notifyUiInitialized() {
if (onUiInitializedAdapter != null) {
onUiInitializedAdapter.onUiInitialized();
}
}
protected void showElements(View... views) {
AndroidUiHelper.setVisibility(View.VISIBLE, views);
}
protected void hideElements(View... views) {
AndroidUiHelper.setVisibility(View.GONE, views);
}
@Override
protected void setupRightButton() {
super.setupRightButton();
applyButtonTitle = rightButton.findViewById(R.id.button_text);
}
@Override
protected void onRightBottomButtonClick() {
if (onApplySelectionListener != null) {
onApplySelectionListener.onSelectionApplied(getSelectedItems());
}
dismiss();
}
@Override
protected int getRightBottomButtonTextId() {
return R.string.shared_string_apply;
}
@Override
protected boolean useVerticalButtons() {
return true;
}
@Override
public void onPause() {
super.onPause();
if (requireActivity().isChangingConfigurations()) {
dismiss();
}
}
public interface OnUiInitializedAdapter {
void onUiInitialized();
}
public interface OnApplySelectionListener {
void onSelectionApplied(List<SelectableItem> selectedItems);
}
public static class SelectableItem {
private String title;
private String description;
private int iconId;
private Object object;
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
public int getIconId() {
return iconId;
}
public Object getObject() {
return object;
}
public void setTitle(String title) {
this.title = title;
}
public void setDescription(String description) {
this.description = description;
}
public void setIconId(int iconId) {
this.iconId = iconId;
}
public void setObject(Object object) {
this.object = object;
}
}
}

View file

@ -32,6 +32,10 @@ public class BaseBottomSheetItem {
return tag;
}
public void setTag(Object tag) {
this.tag = tag;
}
public BaseBottomSheetItem(View view,
@LayoutRes int layoutId,
Object tag,

View file

@ -11,7 +11,6 @@ import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.StatFs;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@ -34,10 +33,10 @@ import net.osmand.FileUtils;
import net.osmand.PlatformUtil;
import net.osmand.ValueHolder;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.ProgressImplementation;
import net.osmand.plus.R;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
@ -93,18 +92,6 @@ public class DashChooseAppDirFragment {
selectePathTemp = null;
}
private String getFreeSpace(File dir) {
if (dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath());
return AndroidUtils.formatSize(activity, (long) fs.getAvailableBlocks() * fs.getBlockSize());
} catch (IllegalArgumentException e) {
LOG.error(e);
}
}
return "";
}
public void updateView() {
if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_INTERNAL_FILE) {
locationPath.setText(R.string.storage_directory_internal_app);
@ -117,7 +104,7 @@ public class DashChooseAppDirFragment {
} else if (type == OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED) {
locationPath.setText(R.string.storage_directory_manual);
}
locationDesc.setText(selectedFile.getAbsolutePath() + " \u2022 " + getFreeSpace(selectedFile));
locationDesc.setText(selectedFile.getAbsolutePath() + " \u2022 " + AndroidUtils.getFreeSpace(activity, selectedFile));
boolean copyFiles = !currentAppFile.getAbsolutePath().equals(selectedFile.getAbsolutePath()) && !mapsCopied;
warningReadonly.setVisibility(copyFiles ? View.VISIBLE : View.GONE);
if (copyFiles) {

View file

@ -530,7 +530,7 @@ public class ConfigureMapMenu {
TextView switchText = (TextView) v.findViewById(R.id.switchText);
switchText.setText(activity.getString(R.string.translit_name_if_miss, txtValues[position]));
SwitchCompat check = (SwitchCompat) v.findViewById(R.id.check);
check.setChecked(settings.MAP_TRANSLITERATE_NAMES.isSet() ? transliterateNames : txtIds[position].equals("en"));
check.setChecked(transliterateNames);
check.setOnCheckedChangeListener(translitChangdListener);
UiUtilities.setupCompoundButton(nightMode, selectedProfileColor, check);
} else {
@ -548,6 +548,7 @@ public class ConfigureMapMenu {
@Override
public void onClick(DialogInterface dialog, int which) {
selectedLanguageIndex = which;
transliterateNames = settings.MAP_TRANSLITERATE_NAMES.isSet() ? transliterateNames : txtIds[which].equals("en");
((AlertDialog) dialog).getListView().setSelection(which);
singleChoiceAdapter.notifyDataSetChanged();
}

View file

@ -652,7 +652,7 @@ public class DownloadActivity extends AbstractDownloadActivity implements Downlo
TextView messageTextView = (TextView) view.findViewById(R.id.leftTextView);
ProgressBar sizeProgress = (ProgressBar) view.findViewById(R.id.progressBar);
File dir = activity.getMyApplication().getAppPath("").getParentFile();
File dir = activity.getMyApplication().getAppPath(null);
String size = "";
int percent = 0;
if (dir.canRead()) {

View file

@ -10,6 +10,7 @@ import net.osmand.map.OsmandRegions;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.util.Algorithms;
@ -27,11 +28,12 @@ import java.util.Locale;
import java.util.Map;
import static net.osmand.IndexConstants.BINARY_MAP_INDEX_EXT;
import static net.osmand.plus.activities.LocalIndexHelper.LocalIndexType.SRTM_DATA;
public class DownloadActivityType {
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy", Locale.US);
private static Map<String, DownloadActivityType> byTag = new HashMap<>();
public static final DownloadActivityType NORMAL_FILE =
new DownloadActivityType(R.string.download_regular_maps, "map", 10);
public static final DownloadActivityType VOICE_FILE =
@ -83,7 +85,7 @@ public class DownloadActivityType {
iconResource = R.drawable.ic_map;
}
public int getStringResource(){
public int getStringResource() {
return stringResource;
}
@ -101,7 +103,7 @@ public class DownloadActivityType {
public static boolean isCountedInDownloads(IndexItem es) {
DownloadActivityType tp = es.getType();
if(tp == NORMAL_FILE || tp == ROADS_FILE){
if (tp == NORMAL_FILE || tp == ROADS_FILE) {
if (!es.extra) {
return true;
}
@ -120,17 +122,17 @@ public class DownloadActivityType {
public static Collection<DownloadActivityType> values() {
return byTag.values();
}
protected static String addVersionToExt(String ext, int version) {
return "_" + version + ext;
}
public boolean isAccepted(String fileName) {
if(NORMAL_FILE == this) {
return fileName.endsWith(addVersionToExt(IndexConstants.BINARY_MAP_INDEX_EXT_ZIP, IndexConstants.BINARY_MAP_VERSION))
if (NORMAL_FILE == this) {
return fileName.endsWith(addVersionToExt(IndexConstants.BINARY_MAP_INDEX_EXT_ZIP, IndexConstants.BINARY_MAP_VERSION))
|| fileName.endsWith(IndexConstants.EXTRA_ZIP_EXT)
|| fileName.endsWith(IndexConstants.SQLITE_EXT);
} else if(ROADS_FILE == this) {
} else if (ROADS_FILE == this) {
return fileName.endsWith(addVersionToExt(IndexConstants.BINARY_ROAD_MAP_INDEX_EXT_ZIP, IndexConstants.BINARY_MAP_VERSION));
} else if (VOICE_FILE == this) {
return fileName.endsWith(addVersionToExt(IndexConstants.VOICE_INDEX_EXT_ZIP, IndexConstants.VOICE_VERSION));
@ -145,8 +147,9 @@ public class DownloadActivityType {
return fileName.endsWith(addVersionToExt(IndexConstants.BINARY_TRAVEL_GUIDE_MAP_INDEX_EXT_ZIP,
IndexConstants.BINARY_MAP_VERSION));
} else if (SRTM_COUNTRY_FILE == this) {
return fileName.endsWith(addVersionToExt(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT_ZIP,
IndexConstants.BINARY_MAP_VERSION));
boolean srtm = fileName.endsWith(addVersionToExt(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT_ZIP, IndexConstants.BINARY_MAP_VERSION));
boolean srtmf = fileName.endsWith(addVersionToExt(IndexConstants.BINARY_SRTM_FEET_MAP_INDEX_EXT_ZIP, IndexConstants.BINARY_MAP_VERSION));
return srtm || srtmf;
} else if (HILLSHADE_FILE == this) {
return fileName.endsWith(IndexConstants.SQLITE_EXT);
} else if (SLOPE_FILE == this) {
@ -160,7 +163,7 @@ public class DownloadActivityType {
}
return false;
}
public File getDownloadFolder(OsmandApplication ctx, IndexItem indexItem) {
if (NORMAL_FILE == this) {
if (indexItem.fileName.endsWith(IndexConstants.SQLITE_EXT)) {
@ -196,17 +199,17 @@ public class DownloadActivityType {
}
public boolean isZipStream(OsmandApplication ctx, IndexItem indexItem) {
return HILLSHADE_FILE != this && SLOPE_FILE != this && SQLITE_FILE != this && WIKIVOYAGE_FILE != this && GPX_FILE != this;
return HILLSHADE_FILE != this && SLOPE_FILE != this && SQLITE_FILE != this && WIKIVOYAGE_FILE != this && GPX_FILE != this;
}
public boolean isZipFolder(OsmandApplication ctx, IndexItem indexItem) {
return this == VOICE_FILE;
}
public boolean preventMediaIndexing(OsmandApplication ctx, IndexItem indexItem) {
return this == VOICE_FILE && indexItem.fileName.endsWith(IndexConstants.VOICE_INDEX_EXT_ZIP);
}
public String getUnzipExtension(OsmandApplication ctx, IndexItem indexItem) {
if (NORMAL_FILE == this) {
if (indexItem.fileName.endsWith(IndexConstants.BINARY_MAP_INDEX_EXT_ZIP)) {
@ -217,7 +220,7 @@ public class DownloadActivityType {
return IndexConstants.EXTRA_EXT;
} else if (indexItem.fileName.endsWith(IndexConstants.SQLITE_EXT)) {
return IndexConstants.SQLITE_EXT;
} else if (indexItem.fileName.endsWith(IndexConstants.ANYVOICE_INDEX_EXT_ZIP)){
} else if (indexItem.fileName.endsWith(IndexConstants.ANYVOICE_INDEX_EXT_ZIP)) {
return "";
}
} else if (ROADS_FILE == this) {
@ -227,7 +230,7 @@ public class DownloadActivityType {
} else if (FONT_FILE == this) {
return IndexConstants.FONT_INDEX_EXT;
} else if (SRTM_COUNTRY_FILE == this) {
return IndexConstants.BINARY_SRTM_MAP_INDEX_EXT;
return SrtmDownloadItem.getExtension(indexItem);
} else if (WIKIPEDIA_FILE == this) {
return IndexConstants.BINARY_WIKI_MAP_INDEX_EXT;
} else if (WIKIVOYAGE_FILE == this) {
@ -249,9 +252,9 @@ public class DownloadActivityType {
}
throw new UnsupportedOperationException();
}
public String getUrlSuffix(OsmandApplication ctx) {
if (this== ROADS_FILE) {
if (this == ROADS_FILE) {
return "&road=yes";
} else if (this == LIVE_UPDATES_FILE) {
return "&aosmc=yes";
@ -280,7 +283,7 @@ public class DownloadActivityType {
public String getBaseUrl(OsmandApplication ctx, String fileName) {
String url = "https://" + IndexConstants.INDEX_DOWNLOAD_DOMAIN + "/download?event=2&"
+ Version.getVersionAsURLParam(ctx) + "&file=" + encode(fileName);
if(this == LIVE_UPDATES_FILE && fileName.length() > 16) {
if (this == LIVE_UPDATES_FILE && fileName.length() > 16) {
// DATE_AND_EXT_STR_LEN = "_18_06_02.obf.gz".length()
String region = fileName.substring(0, fileName.length() - 16).toLowerCase();
url += "&region=" + encode(region);
@ -343,7 +346,7 @@ public class DownloadActivityType {
}
return "";
}
public String getVisibleName(DownloadItem downloadItem, Context ctx, OsmandRegions osmandRegions, boolean includingParent) {
if (this == VOICE_FILE) {
String fileName = downloadItem.getFileName();
@ -361,6 +364,9 @@ public class DownloadActivityType {
if (basename.endsWith(FileNameTranslationHelper.WIKI_NAME)) {
return FileNameTranslationHelper.getWikiName(ctx, basename);
}
if (basename.endsWith(FileNameTranslationHelper.WIKIVOYAGE_NAME)) {
return FileNameTranslationHelper.getWikivoyageName(ctx, basename);
}
// if (this == HILLSHADE_FILE){
// return FileNameTranslationHelper.getHillShadeName(ctx, osmandRegions, bn);
// }
@ -383,7 +389,7 @@ public class DownloadActivityType {
return osmandRegions.getLocaleName(basename, includingParent);
}
public String getTargetFileName(IndexItem item) {
String fileName = item.fileName;
// if(fileName.endsWith(IndexConstants.VOICE_INDEX_EXT_ZIP) ||
@ -423,7 +429,7 @@ public class DownloadActivityType {
}
String baseNameWithoutVersion = fileName.substring(0, l);
if (this == SRTM_COUNTRY_FILE) {
return baseNameWithoutVersion + IndexConstants.BINARY_SRTM_MAP_INDEX_EXT;
return baseNameWithoutVersion + SrtmDownloadItem.getExtension(item);
}
if (this == WIKIPEDIA_FILE) {
return baseNameWithoutVersion + IndexConstants.BINARY_WIKI_MAP_INDEX_EXT;
@ -487,7 +493,7 @@ public class DownloadActivityType {
return fileName.substring(0, l);
}
if (this == LIVE_UPDATES_FILE) {
if(fileName.indexOf('.') > 0){
if (fileName.indexOf('.') > 0) {
return fileName.substring(0, fileName.indexOf('.'));
}
return fileName;
@ -495,10 +501,10 @@ public class DownloadActivityType {
int ls = fileName.lastIndexOf('_');
if (ls >= 0) {
return fileName.substring(0, ls);
} else if(fileName.indexOf('.') > 0){
} else if (fileName.indexOf('.') > 0) {
return fileName.substring(0, fileName.indexOf('.'));
}
return fileName;
}
}
}

View file

@ -9,7 +9,6 @@ import android.net.TrafficStats;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.os.StatFs;
import android.view.View;
import android.widget.Toast;
@ -17,13 +16,12 @@ import androidx.annotation.UiThread;
import androidx.appcompat.app.AlertDialog;
import net.osmand.AndroidNetworkUtils;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.map.WorldRegion;
import net.osmand.map.WorldRegion.RegionParams;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.OsmandPreference;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.base.BasicProgressAsyncTask;
@ -31,6 +29,8 @@ import net.osmand.plus.download.DownloadFileHelper.DownloadFileShowWarning;
import net.osmand.plus.helpers.DatabaseHelper;
import net.osmand.plus.notifications.OsmandNotification;
import net.osmand.plus.resources.ResourceManager;
import net.osmand.plus.settings.backend.OsmandPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
@ -240,9 +240,12 @@ public class DownloadIndexesThread {
}
public void cancelDownload(DownloadItem item) {
if (item instanceof MultipleIndexItem) {
MultipleIndexItem multipleIndexItem = (MultipleIndexItem) item;
cancelDownload(multipleIndexItem.getAllIndexes());
if (item instanceof MultipleDownloadItem) {
MultipleDownloadItem multipleDownloadItem = (MultipleDownloadItem) item;
cancelDownload(multipleDownloadItem.getAllIndexes());
} else if (item instanceof SrtmDownloadItem) {
IndexItem indexItem = ((SrtmDownloadItem) item).getIndexItem();
cancelDownload(indexItem);
} else if (item instanceof IndexItem) {
IndexItem indexItem = (IndexItem) item;
cancelDownload(indexItem);
@ -299,19 +302,8 @@ public class DownloadIndexesThread {
return null;
}
@SuppressWarnings("deprecation")
public double getAvailableSpace() {
File dir = app.getAppPath("").getParentFile();
double asz = -1;
if (dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath());
asz = (((long) fs.getAvailableBlocks()) * fs.getBlockSize()) / (1 << 20);
} catch (IllegalArgumentException e) {
LOG.error(e);
}
}
return asz;
return AndroidUtils.getAvailableSpace(app) / (1 << 20);
}
/// PRIVATE IMPL

View file

@ -3,12 +3,14 @@ package net.osmand.plus.download;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.map.OsmandRegions;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import java.io.File;
import java.text.DateFormat;
import java.util.List;
import java.util.Locale;
@ -55,6 +57,12 @@ public abstract class DownloadItem {
return type.getBasename(this);
}
@NonNull
public abstract List<File> getDownloadedFiles(@NonNull OsmandApplication app);
@Nullable
public abstract String getAdditionalDescription(Context ctx);
protected abstract double getSizeToDownloadInMb();
public abstract double getArchiveSizeMB();
@ -69,8 +77,7 @@ public abstract class DownloadItem {
public abstract String getFileName();
@NonNull
public abstract List<File> getDownloadedFiles(@NonNull OsmandApplication app);
public abstract String getDate(@NonNull DateFormat dateFormat, boolean remote);
@NonNull
public static String getFormattedMb(@NonNull Context ctx, double sizeInMb) {

View file

@ -1,5 +1,26 @@
package net.osmand.plus.download;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.provider.Settings.Secure;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@ -11,29 +32,9 @@ import java.util.Comparator;
import java.util.List;
import java.util.zip.GZIPInputStream;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings;
import org.apache.commons.logging.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetManager;
import android.provider.Settings.Secure;
public class DownloadOsmandIndexesHelper {
private final static Log log = PlatformUtil.getLog(DownloadOsmandIndexesHelper.class);
public static class IndexFileList implements Serializable {
private static final long serialVersionUID = 1L;
@ -41,29 +42,29 @@ public class DownloadOsmandIndexesHelper {
IndexItem basemap;
ArrayList<IndexItem> indexFiles = new ArrayList<IndexItem>();
private String mapversion;
private Comparator<IndexItem> comparator = new Comparator<IndexItem>(){
private Comparator<IndexItem> comparator = new Comparator<IndexItem>() {
@Override
public int compare(IndexItem o1, IndexItem o2) {
String object1 = o1.getFileName();
String object2 = o2.getFileName();
if(object1.endsWith(IndexConstants.ANYVOICE_INDEX_EXT_ZIP)){
if(object2.endsWith(IndexConstants.ANYVOICE_INDEX_EXT_ZIP)){
if (object1.endsWith(IndexConstants.ANYVOICE_INDEX_EXT_ZIP)) {
if (object2.endsWith(IndexConstants.ANYVOICE_INDEX_EXT_ZIP)) {
return object1.compareTo(object2);
} else {
return -1;
}
} else if(object2.endsWith(IndexConstants.ANYVOICE_INDEX_EXT_ZIP)){
} else if (object2.endsWith(IndexConstants.ANYVOICE_INDEX_EXT_ZIP)) {
return 1;
}
return object1.compareTo(object2);
}
};
public void setDownloadedFromInternet(boolean downloadedFromInternet) {
this.downloadedFromInternet = downloadedFromInternet;
}
public boolean isDownloadedFromInternet() {
return downloadedFromInternet;
}
@ -75,12 +76,12 @@ public class DownloadOsmandIndexesHelper {
@SuppressLint("DefaultLocale")
public void add(IndexItem indexItem) {
indexFiles.add(indexItem);
if(indexItem.getFileName().toLowerCase().startsWith("world_basemap")) {
if (indexItem.getFileName().toLowerCase().startsWith("world_basemap")) {
basemap = indexItem;
}
}
public void sort(){
public void sort() {
Collections.sort(indexFiles, comparator);
}
@ -91,7 +92,7 @@ public class DownloadOsmandIndexesHelper {
public List<IndexItem> getIndexFiles() {
return indexFiles;
}
public IndexItem getBasemap() {
return basemap;
}
@ -106,7 +107,7 @@ public class DownloadOsmandIndexesHelper {
return false;
}
}
}
public static IndexFileList getIndexesList(OsmandApplication app) {
PackageManager pm = app.getPackageManager();
@ -141,16 +142,16 @@ public class DownloadOsmandIndexesHelper {
}
private static void listVoiceAssets(IndexFileList result, AssetManager amanager, PackageManager pm,
OsmandSettings settings) {
OsmandSettings settings) {
try {
File voicePath = settings.getContext().getAppPath(IndexConstants.VOICE_INDEX_DIR);
File voicePath = settings.getContext().getAppPath(IndexConstants.VOICE_INDEX_DIR);
// list = amanager.list("voice");
String date = "";
long dateModified = System.currentTimeMillis();
try {
OsmandApplication app = settings.getContext();
ApplicationInfo appInfo = pm.getApplicationInfo(app.getPackageName(), 0);
dateModified = new File(appInfo.sourceDir).lastModified();
dateModified = new File(appInfo.sourceDir).lastModified();
date = AndroidUtils.formatDate((Context) settings.getContext(), dateModified);
} catch (NameNotFoundException e) {
log.error(e);
@ -177,17 +178,17 @@ public class DownloadOsmandIndexesHelper {
log.error("Error while loading tts files from assets", e); //$NON-NLS-1$
}
}
private static IndexFileList downloadIndexesListFromInternet(OsmandApplication ctx){
private static IndexFileList downloadIndexesListFromInternet(OsmandApplication ctx) {
try {
IndexFileList result = new IndexFileList();
log.debug("Start loading list of index files"); //$NON-NLS-1$
try {
String strUrl = ctx.getAppCustomization().getIndexesUrl();
long nd = ctx.getAppInitializer().getFirstInstalledDays();
if(nd > 0) {
strUrl += "&nd=" + nd;
if (nd > 0) {
strUrl += "&nd=" + nd;
}
strUrl += "&ns=" + ctx.getAppInitializer().getNumberOfStarts();
try {
@ -202,12 +203,12 @@ public class DownloadOsmandIndexesHelper {
GZIPInputStream gzin = new GZIPInputStream(in);
parser.setInput(gzin, "UTF-8"); //$NON-NLS-1$
int next;
while((next = parser.next()) != XmlPullParser.END_DOCUMENT) {
while ((next = parser.next()) != XmlPullParser.END_DOCUMENT) {
if (next == XmlPullParser.START_TAG) {
DownloadActivityType tp = DownloadActivityType.getIndexType(parser.getAttributeValue(null, "type"));
if (tp != null) {
IndexItem it = tp.parseIndexItem(ctx, parser);
if(it != null) {
if (it != null) {
result.add(it);
}
} else if ("osmand_regions".equals(parser.getName())) {
@ -226,7 +227,7 @@ public class DownloadOsmandIndexesHelper {
log.error("Error while loading indexes from repository", e); //$NON-NLS-1$
return null;
}
if (result.isAcceptable()) {
return result;
} else {
@ -239,19 +240,19 @@ public class DownloadOsmandIndexesHelper {
}
public static class AssetIndexItem extends IndexItem {
private final String assetName;
private final String destFile;
private final long dateModified;
public AssetIndexItem(String fileName, String description, String date,
long dateModified, String size, long sizeL, String assetName, String destFile, DownloadActivityType type) {
long dateModified, String size, long sizeL, String assetName, String destFile, DownloadActivityType type) {
super(fileName, description, dateModified, size, sizeL, sizeL, type);
this.dateModified = dateModified;
this.assetName = assetName;
this.destFile = destFile;
}
public long getDateModified() {
return dateModified;
}
@ -261,7 +262,7 @@ public class DownloadOsmandIndexesHelper {
return new DownloadEntry(assetName, destFile, dateModified);
}
public String getDestFile(){
public String getDestFile() {
return destFile;
}
}

View file

@ -25,12 +25,11 @@ import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static net.osmand.plus.download.DownloadResourceGroup.DownloadResourceGroupType.REGION_MAPS;
@ -117,6 +116,16 @@ public class DownloadResources extends DownloadResourceGroup {
return res;
}
@NonNull
public List<DownloadItem> getDownloadItems(WorldRegion region) {
DownloadResourceGroup group = getRegionMapsGroup(region);
if (group != null) {
return group.getIndividualDownloadItems();
}
return Collections.emptyList();
}
@NonNull
public List<IndexItem> getIndexItems(WorldRegion region) {
if (groupByRegion != null) {
List<IndexItem> res = groupByRegion.get(region);
@ -124,7 +133,7 @@ public class DownloadResources extends DownloadResourceGroup {
return res;
}
}
return new LinkedList<>();
return Collections.emptyList();
}
public void updateLoadedFiles() {
@ -471,30 +480,60 @@ public class DownloadResources extends DownloadResourceGroup {
addGroup(otherGroup);
createHillshadeSRTMGroups();
collectMultipleIndexesItems();
replaceIndividualSrtmWithGroups(region);
createMultipleDownloadItems(region);
trimEmptyGroups();
updateLoadedFiles();
return true;
}
private void collectMultipleIndexesItems() {
collectMultipleIndexesItems(region);
private void replaceIndividualSrtmWithGroups(@NonNull WorldRegion region) {
DownloadResourceGroup group = getRegionMapsGroup(region);
if (group != null) {
boolean useMetersByDefault = SrtmDownloadItem.shouldUseMetersByDefault(app);
boolean listModified = false;
DownloadActivityType srtmType = DownloadActivityType.SRTM_COUNTRY_FILE;
List<DownloadItem> individualItems = group.getIndividualDownloadItems();
if (isListContainsType(individualItems, srtmType)) {
List<IndexItem> srtmIndexes = new ArrayList<>();
for (DownloadItem item : individualItems) {
if (item.getType() == srtmType && item instanceof IndexItem) {
srtmIndexes.add((IndexItem) item);
}
}
if (srtmIndexes.size() > 1) {
individualItems.removeAll(srtmIndexes);
group.addItem(new SrtmDownloadItem(srtmIndexes, useMetersByDefault));
}
listModified = true;
}
if (listModified) {
sortDownloadItems(individualItems);
}
}
List<WorldRegion> subRegions = region.getSubregions();
if (!Algorithms.isEmpty(subRegions)) {
for (WorldRegion subRegion : subRegions) {
replaceIndividualSrtmWithGroups(subRegion);
}
}
}
private void collectMultipleIndexesItems(@NonNull WorldRegion region) {
private void createMultipleDownloadItems(@NonNull WorldRegion region) {
List<WorldRegion> subRegions = region.getSubregions();
if (Algorithms.isEmpty(subRegions)) return;
DownloadResourceGroup group = getRegionMapsGroup(region);
if (group != null) {
boolean listModified = false;
List<IndexItem> indexesList = group.getIndividualResources();
List<WorldRegion> regionsToCollect = removeDuplicateRegions(subRegions);
List<DownloadItem> downloadItems = group.getIndividualDownloadItems();
List<WorldRegion> uniqueSubRegions = WorldRegion.removeDuplicates(subRegions);
for (DownloadActivityType type : DownloadActivityType.values()) {
if (!doesListContainIndexWithType(indexesList, type)) {
List<IndexItem> indexesFromSubRegions = collectIndexesOfType(regionsToCollect, type);
if (indexesFromSubRegions != null) {
group.addItem(new MultipleIndexItem(region, indexesFromSubRegions, type));
if (!isListContainsType(downloadItems, type)) {
List<DownloadItem> itemsFromSubRegions = collectItemsOfType(uniqueSubRegions, type);
if (itemsFromSubRegions != null) {
group.addItem(new MultipleDownloadItem(region, itemsFromSubRegions, type));
listModified = true;
}
}
@ -504,7 +543,7 @@ public class DownloadResources extends DownloadResourceGroup {
}
}
for (WorldRegion subRegion : subRegions) {
collectMultipleIndexesItems(subRegion);
createMultipleDownloadItems(subRegion);
}
}
@ -517,43 +556,21 @@ public class DownloadResources extends DownloadResourceGroup {
}
@Nullable
private List<IndexItem> collectIndexesOfType(@NonNull List<WorldRegion> regions,
@NonNull DownloadActivityType type) {
List<IndexItem> collectedIndexes = new ArrayList<>();
private List<DownloadItem> collectItemsOfType(@NonNull List<WorldRegion> regions,
@NonNull DownloadActivityType type) {
List<DownloadItem> collectedItems = new ArrayList<>();
for (WorldRegion region : regions) {
List<IndexItem> regionIndexes = getIndexItems(region);
boolean found = false;
if (regionIndexes != null) {
for (IndexItem index : regionIndexes) {
if (index.getType() == type) {
found = true;
collectedIndexes.add(index);
break;
}
for (DownloadItem item : getDownloadItems(region)) {
if (item.getType() == type) {
found = true;
collectedItems.add(item);
break;
}
}
if (!found) return null;
}
return collectedIndexes;
}
private List<WorldRegion> removeDuplicateRegions(List<WorldRegion> regions) {
Set<WorldRegion> duplicates = new HashSet<>();
for (int i = 0; i < regions.size() - 1; i++) {
WorldRegion r1 = regions.get(i);
for (int j = i + 1; j < regions.size(); j++) {
WorldRegion r2 = regions.get(j);
if (r1.containsRegion(r2)) {
duplicates.add(r2);
} else if (r2.containsRegion(r1)) {
duplicates.add(r1);
}
}
}
for (WorldRegion region : duplicates) {
regions.remove(region);
}
return regions;
return collectedItems;
}
private void buildRegionsGroups(WorldRegion region, DownloadResourceGroup group) {
@ -688,11 +705,11 @@ public class DownloadResources extends DownloadResourceGroup {
&& isIndexItemDownloaded(downloadThread, type, downloadRegion.getSuperregion(), res);
}
private boolean doesListContainIndexWithType(List<IndexItem> indexItems,
DownloadActivityType type) {
if (indexItems != null) {
for (IndexItem indexItem : indexItems) {
if (indexItem.getType() == type) {
private boolean isListContainsType(List<DownloadItem> items,
DownloadActivityType type) {
if (items != null) {
for (DownloadItem item : items) {
if (item.getType() == type) {
return true;
}
}

View file

@ -1,6 +1,9 @@
package net.osmand.plus.download;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
@ -19,6 +22,7 @@ import java.util.Date;
import java.util.List;
public class IndexItem extends DownloadItem implements Comparable<IndexItem> {
private static final Log log = PlatformUtil.getLog(IndexItem.class);
String description;
@ -225,6 +229,12 @@ public class IndexItem extends DownloadItem implements Comparable<IndexItem> {
public String getDate(java.text.DateFormat format) {
return format.format(new Date(timestamp));
}
@Nullable
@Override
public String getAdditionalDescription(Context ctx) {
return null;
}
public static class DownloadEntry {
public long dateModified;
@ -254,5 +264,4 @@ public class IndexItem extends DownloadItem implements Comparable<IndexItem> {
}
}
}

View file

@ -1,32 +1,47 @@
package net.osmand.plus.download;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.map.WorldRegion;
import net.osmand.plus.OsmandApplication;
import java.io.File;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;
public class MultipleIndexItem extends DownloadItem {
public class MultipleDownloadItem extends DownloadItem {
private final List<IndexItem> items;
private final List<DownloadItem> items;
public MultipleIndexItem(@NonNull WorldRegion region,
@NonNull List<IndexItem> items,
@NonNull DownloadActivityType type) {
public MultipleDownloadItem(@NonNull WorldRegion region,
@NonNull List<DownloadItem> items,
@NonNull DownloadActivityType type) {
super(type);
this.items = items;
}
public List<IndexItem> getAllIndexes() {
List<IndexItem> indexes = new ArrayList<>();
for (DownloadItem item : items) {
IndexItem index = getIndexItem(item);
if (index != null) {
indexes.add(index);
}
}
return indexes;
}
public List<DownloadItem> getAllItems() {
return items;
}
@Override
public boolean isOutdated() {
for (IndexItem item : items) {
for (DownloadItem item : items) {
if (item.isOutdated()) {
return true;
}
@ -36,7 +51,7 @@ public class MultipleIndexItem extends DownloadItem {
@Override
public boolean isDownloaded() {
for (IndexItem item : items) {
for (DownloadItem item : items) {
if (item.isDownloaded()) {
return true;
}
@ -46,8 +61,8 @@ public class MultipleIndexItem extends DownloadItem {
@Override
public boolean isDownloading(@NonNull DownloadIndexesThread thread) {
for (IndexItem item : items) {
if (thread.isDownloading(item)) {
for (DownloadItem item : items) {
if (item.isDownloading(thread)) {
return true;
}
}
@ -78,31 +93,31 @@ public class MultipleIndexItem extends DownloadItem {
@Override
public List<File> getDownloadedFiles(@NonNull OsmandApplication app) {
List<File> result = new ArrayList<>();
for (IndexItem item : items) {
for (DownloadItem item : items) {
result.addAll(item.getDownloadedFiles(app));
}
return result;
}
public List<IndexItem> getIndexesToDownload() {
List<IndexItem> indexesToDownload = new ArrayList<>();
for (IndexItem item : items) {
public List<DownloadItem> getItemsToDownload() {
List<DownloadItem> itemsToDownload = new ArrayList<>();
for (DownloadItem item : getAllItems()) {
if (item.hasActualDataToDownload()) {
indexesToDownload.add(item);
itemsToDownload.add(item);
}
}
return indexesToDownload;
return itemsToDownload;
}
@Override
public boolean hasActualDataToDownload() {
return getIndexesToDownload().size() > 0;
return getItemsToDownload().size() > 0;
}
@Override
public double getSizeToDownloadInMb() {
double totalSizeMb = 0.0d;
for (IndexItem item : items) {
for (DownloadItem item : items) {
if (item.hasActualDataToDownload()) {
totalSizeMb += item.getSizeToDownloadInMb();
}
@ -113,10 +128,33 @@ public class MultipleIndexItem extends DownloadItem {
@Override
public double getArchiveSizeMB() {
double result = 0.0d;
for (IndexItem item : items) {
for (DownloadItem item : items) {
result += item.getArchiveSizeMB();
}
return result;
}
@Nullable
public static IndexItem getIndexItem(@NonNull DownloadItem obj) {
if (obj instanceof IndexItem) {
return (IndexItem) obj;
} else if (obj instanceof SrtmDownloadItem) {
return ((SrtmDownloadItem) obj).getIndexItem();
}
return null;
}
@Nullable
@Override
public String getAdditionalDescription(Context ctx) {
for (DownloadItem item : items) {
return item.getAdditionalDescription(ctx);
}
return null;
}
@Override
public String getDate(@NonNull DateFormat dateFormat, boolean remote) {
return "";
}
}

View file

@ -1,113 +0,0 @@
package net.osmand.plus.download;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import net.osmand.map.OsmandRegions;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.base.SelectMultipleItemsBottomSheet;
import net.osmand.plus.base.SelectMultipleItemsBottomSheet.OnApplySelectionListener;
import net.osmand.plus.base.SelectMultipleItemsBottomSheet.SelectableItem;
import net.osmand.plus.base.SelectMultipleItemsBottomSheet.SelectionUpdateListener;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;
public class MultipleIndexesUiHelper {
public static void showDialog(@NonNull MultipleIndexItem multipleIndexItem,
@NonNull AppCompatActivity activity,
@NonNull final OsmandApplication app,
@NonNull DateFormat dateFormat,
boolean showRemoteDate,
@NonNull final SelectItemsToDownloadListener listener) {
List<IndexItem> indexesToDownload = getIndexesToDownload(multipleIndexItem);
List<SelectableItem> allItems = new ArrayList<>();
List<SelectableItem> selectedItems = new ArrayList<>();
OsmandRegions osmandRegions = app.getRegions();
for (IndexItem indexItem : multipleIndexItem.getAllIndexes()) {
SelectableItem selectableItem = new SelectableItem();
selectableItem.setTitle(indexItem.getVisibleName(app, osmandRegions, false));
String size = indexItem.getSizeDescription(app);
String date = indexItem.getDate(dateFormat, showRemoteDate);
String description = app.getString(R.string.ltr_or_rtl_combine_via_bold_point, size, date);
selectableItem.setDescription(description);
selectableItem.setIconId(indexItem.getType().getIconResource());
selectableItem.setObject(indexItem);
allItems.add(selectableItem);
if (indexesToDownload.contains(indexItem)) {
selectedItems.add(selectableItem);
}
}
final SelectMultipleItemsBottomSheet dialog =
SelectMultipleItemsBottomSheet.showInstance(activity, allItems, selectedItems, true);
dialog.setSelectionUpdateListener(new SelectionUpdateListener() {
@Override
public void onSelectionUpdate() {
dialog.setTitle(app.getString(R.string.welmode_download_maps));
String total = app.getString(R.string.shared_string_total);
double sizeToDownload = getDownloadSizeInMb(dialog.getSelectedItems());
String size = DownloadItem.getFormattedMb(app, sizeToDownload);
String description =
app.getString(R.string.ltr_or_rtl_combine_via_colon, total, size);
dialog.setDescription(description);
String btnTitle = app.getString(R.string.shared_string_download);
if (sizeToDownload > 0) {
btnTitle = app.getString(R.string.ltr_or_rtl_combine_via_dash, btnTitle, size);
}
dialog.setConfirmButtonTitle(btnTitle);
}
});
dialog.setOnApplySelectionListener(new OnApplySelectionListener() {
@Override
public void onSelectionApplied(List<SelectableItem> selectedItems) {
List<IndexItem> indexItems = new ArrayList<>();
for (SelectableItem item : selectedItems) {
Object obj = item.getObject();
if (obj instanceof IndexItem) {
indexItems.add((IndexItem) obj);
}
}
listener.onItemsToDownloadSelected(indexItems);
}
});
}
private static List<IndexItem> getIndexesToDownload(MultipleIndexItem multipleIndexItem) {
if (multipleIndexItem.hasActualDataToDownload()) {
// download left regions
return multipleIndexItem.getIndexesToDownload();
} else {
// download all regions again
return multipleIndexItem.getAllIndexes();
}
}
private static double getDownloadSizeInMb(@NonNull List<SelectableItem> selectableItems) {
List<IndexItem> indexItems = new ArrayList<>();
for (SelectableItem i : selectableItems) {
Object obj = i.getObject();
if (obj instanceof IndexItem) {
indexItems.add((IndexItem) obj);
}
}
double totalSizeMb = 0.0d;
for (IndexItem item : indexItems) {
totalSizeMb += item.getSizeToDownloadInMb();
}
return totalSizeMb;
}
public interface SelectItemsToDownloadListener {
void onItemsToDownloadSelected(List<IndexItem> items);
}
}

View file

@ -0,0 +1,281 @@
package net.osmand.plus.download;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.base.MultipleSelectionBottomSheet;
import net.osmand.plus.base.MultipleSelectionBottomSheet.SelectionUpdateListener;
import net.osmand.plus.base.ModeSelectionBottomSheet;
import net.osmand.plus.base.MultipleSelectionWithModeBottomSheet;
import net.osmand.plus.base.SelectionBottomSheet;
import net.osmand.plus.base.SelectionBottomSheet.OnApplySelectionListener;
import net.osmand.plus.base.SelectionBottomSheet.OnUiInitializedAdapter;
import net.osmand.plus.base.SelectionBottomSheet.SelectableItem;
import net.osmand.plus.widgets.multistatetoggle.RadioItem;
import net.osmand.plus.widgets.multistatetoggle.RadioItem.OnRadioItemClickListener;
import net.osmand.plus.widgets.multistatetoggle.TextToggleButton.TextRadioItem;
import net.osmand.util.Algorithms;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;
import static net.osmand.plus.download.MultipleDownloadItem.getIndexItem;
public class SelectIndexesUiHelper {
private final OsmandApplication app;
private final AppCompatActivity activity;
private final ItemsToDownloadSelectedListener listener;
private final DateFormat dateFormat;
private final boolean showRemoteDate;
private final DownloadItem downloadItem;
private SelectionBottomSheet dialog;
private SelectIndexesUiHelper(@NonNull DownloadItem downloadItem,
@NonNull AppCompatActivity activity,
@NonNull DateFormat dateFormat,
boolean showRemoteDate,
@NonNull ItemsToDownloadSelectedListener listener) {
this.app = (OsmandApplication) activity.getApplicationContext();
this.activity = activity;
this.downloadItem = downloadItem;
this.dateFormat = dateFormat;
this.showRemoteDate = showRemoteDate;
this.listener = listener;
}
public static void showDialog(@NonNull DownloadItem i,
@NonNull AppCompatActivity a,
@NonNull DateFormat df,
boolean showRemoteDate,
@NonNull ItemsToDownloadSelectedListener l) {
new SelectIndexesUiHelper(i, a, df, showRemoteDate, l).showDialogInternal();
}
private void showDialogInternal() {
if (downloadItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) {
if (downloadItem instanceof MultipleDownloadItem) {
showSrtmMultipleSelectionDialog();
} else {
showSrtmModeSelectionDialog();
}
} else if (downloadItem instanceof MultipleDownloadItem) {
showMultipleSelectionDialog();
}
}
private void showMultipleSelectionDialog() {
List<SelectableItem> allItems = new ArrayList<>();
List<SelectableItem> selectedItems = new ArrayList<>();
prepareItems(allItems, selectedItems);
MultipleSelectionBottomSheet msDialog = MultipleSelectionBottomSheet.showInstance(
activity, allItems, selectedItems, true);
this.dialog = msDialog;
msDialog.setOnUiInitializedAdapter(new OnUiInitializedAdapter() {
@Override
public void onUiInitialized() {
dialog.setTitle(app.getString(R.string.welmode_download_maps));
}
});
msDialog.setSelectionUpdateListener(new SelectionUpdateListener() {
@Override
public void onSelectionUpdate() {
updateSize();
}
});
msDialog.setOnApplySelectionListener(getOnApplySelectionListener(listener));
}
private void showSrtmMultipleSelectionDialog() {
List<SelectableItem> allItems = new ArrayList<>();
List<SelectableItem> selectedItems = new ArrayList<>();
prepareItems(allItems, selectedItems);
SrtmDownloadItem srtmItem = (SrtmDownloadItem) ((MultipleDownloadItem)downloadItem).getAllItems().get(0);
final int selectedModeOrder = srtmItem.isUseMetric() ? 0 : 1;
final List<RadioItem> radioItems = createSrtmRadioItems();
MultipleSelectionBottomSheet msDialog = MultipleSelectionWithModeBottomSheet.showInstance(
activity, allItems, selectedItems, radioItems, true);
this.dialog = msDialog;
msDialog.setOnUiInitializedAdapter(new OnUiInitializedAdapter() {
@Override
public void onUiInitialized() {
dialog.setTitle(app.getString(R.string.welmode_download_maps));
dialog.setSelectedMode(radioItems.get(selectedModeOrder));
dialog.setSecondaryDescription(app.getString(R.string.srtm_download_list_help_message));
}
});
msDialog.setSelectionUpdateListener(new SelectionUpdateListener() {
@Override
public void onSelectionUpdate() {
updateSize();
}
});
msDialog.setOnApplySelectionListener(getOnApplySelectionListener(listener));
}
private void showSrtmModeSelectionDialog() {
SrtmDownloadItem srtmItem = (SrtmDownloadItem) downloadItem;
final int selectedModeOrder = srtmItem.isUseMetric() ? 0 : 1;
final List<RadioItem> radioItems = createSrtmRadioItems();
SelectableItem preview = createSelectableItem(srtmItem);
dialog = ModeSelectionBottomSheet.showInstance(activity, preview, radioItems, true);
dialog.setOnUiInitializedAdapter(new OnUiInitializedAdapter() {
@Override
public void onUiInitialized() {
ModeSelectionBottomSheet dialog = (ModeSelectionBottomSheet) SelectIndexesUiHelper.this.dialog;
dialog.setTitle(app.getString(R.string.srtm_unit_format));
dialog.setPrimaryDescription(app.getString(R.string.srtm_download_single_help_message));
updateSize();
dialog.setSelectedMode(radioItems.get(selectedModeOrder));
}
});
dialog.setOnApplySelectionListener(getOnApplySelectionListener(listener));
}
private void prepareItems(List<SelectableItem> allItems,
List<SelectableItem> selectedItems) {
final MultipleDownloadItem multipleDownloadItem = (MultipleDownloadItem) downloadItem;
final List<DownloadItem> itemsToDownload = getItemsToDownload(multipleDownloadItem);
for (DownloadItem downloadItem : multipleDownloadItem.getAllItems()) {
SelectableItem selectableItem = createSelectableItem(downloadItem);
allItems.add(selectableItem);
if (itemsToDownload.contains(downloadItem)) {
selectedItems.add(selectableItem);
}
}
}
private List<RadioItem> createSrtmRadioItems() {
List<RadioItem> radioItems = new ArrayList<>();
radioItems.add(createSrtmRadioBtn(R.string.shared_string_meters, true));
radioItems.add(createSrtmRadioBtn(R.string.shared_string_feet, false));
return radioItems;
}
private RadioItem createSrtmRadioBtn(int titleId,
final boolean useMeters) {
String title = Algorithms.capitalizeFirstLetter(app.getString(titleId));
RadioItem radioItem = new TextRadioItem(title);
radioItem.setOnClickListener(new OnRadioItemClickListener() {
@Override
public boolean onRadioItemClick(RadioItem radioItem, View view) {
updateDialogListItems(useMeters);
updateSize();
return true;
}
});
return radioItem;
}
private void updateDialogListItems(boolean useMeters) {
List<SelectableItem> items = new ArrayList<>(dialog.getAllItems());
for (SelectableItem item : items) {
DownloadItem downloadItem = (DownloadItem) item.getObject();
if (downloadItem instanceof SrtmDownloadItem) {
((SrtmDownloadItem) downloadItem).setUseMetric(useMeters);
updateSelectableItem(item, downloadItem);
}
}
dialog.setItems(items);
}
private SelectableItem createSelectableItem(DownloadItem item) {
SelectableItem selectableItem = new SelectableItem();
updateSelectableItem(selectableItem, item);
return selectableItem;
}
private void updateSelectableItem(SelectableItem selectableItem,
DownloadItem downloadItem) {
selectableItem.setTitle(downloadItem.getVisibleName(app, app.getRegions(), false));
String size = downloadItem.getSizeDescription(app);
String addDescr = downloadItem.getAdditionalDescription(app);
if (addDescr != null) {
size += " " + addDescr;
}
String date = downloadItem.getDate(dateFormat, showRemoteDate);
String description = app.getString(R.string.ltr_or_rtl_combine_via_bold_point, size, date);
selectableItem.setDescription(description);
selectableItem.setIconId(downloadItem.getType().getIconResource());
selectableItem.setObject(downloadItem);
}
private OnApplySelectionListener getOnApplySelectionListener(final ItemsToDownloadSelectedListener listener) {
return new OnApplySelectionListener() {
@Override
public void onSelectionApplied(List<SelectableItem> selectedItems) {
List<IndexItem> indexes = new ArrayList<>();
for (SelectableItem item : selectedItems) {
IndexItem index = getIndexItem((DownloadItem) item.getObject());
if (index != null) {
indexes.add(index);
}
}
listener.onItemsToDownloadSelected(indexes);
}
};
}
private void updateSize() {
double sizeToDownload = getDownloadSizeInMb(dialog.getSelectedItems());
String size = DownloadItem.getFormattedMb(app, sizeToDownload);
String total = app.getString(R.string.shared_string_total);
String description = app.getString(R.string.ltr_or_rtl_combine_via_colon, total, size);
dialog.setTitleDescription(description);
String btnTitle = app.getString(R.string.shared_string_download);
if (sizeToDownload > 0) {
btnTitle = app.getString(R.string.ltr_or_rtl_combine_via_dash, btnTitle, size);
}
dialog.setApplyButtonTitle(btnTitle);
}
private double getDownloadSizeInMb(@NonNull List<SelectableItem> selectableItems) {
double totalSizeMb = 0.0d;
for (SelectableItem i : selectableItems) {
Object obj = i.getObject();
if (obj instanceof DownloadItem) {
totalSizeMb += ((DownloadItem) obj).getSizeToDownloadInMb();
}
}
return totalSizeMb;
}
private static List<DownloadItem> getItemsToDownload(MultipleDownloadItem md) {
if (md.hasActualDataToDownload()) {
// download left regions
return md.getItemsToDownload();
} else {
// download all regions again
return md.getAllItems();
}
}
public interface ItemsToDownloadSelectedListener {
void onItemsToDownloadSelected(List<IndexItem> items);
}
}

View file

@ -0,0 +1,191 @@
package net.osmand.plus.download;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.IndexConstants;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.helpers.enums.MetricsConstants;
import net.osmand.util.Algorithms;
import java.io.File;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.List;
import static net.osmand.IndexConstants.BINARY_SRTM_MAP_INDEX_EXT;
import static net.osmand.IndexConstants.BINARY_SRTM_MAP_INDEX_EXT_ZIP;
import static net.osmand.plus.activities.LocalIndexHelper.LocalIndexType.SRTM_DATA;
import static net.osmand.plus.download.DownloadActivityType.SRTM_COUNTRY_FILE;
public class SrtmDownloadItem extends DownloadItem {
private final List<IndexItem> indexes;
private boolean useMetric;
public SrtmDownloadItem(List<IndexItem> indexes, boolean useMetric) {
super(SRTM_COUNTRY_FILE);
this.indexes = indexes;
this.useMetric = useMetric;
}
public void setUseMetric(boolean useMetric) {
this.useMetric = useMetric;
}
public boolean isUseMetric() {
for (IndexItem index : indexes) {
if (index.isDownloaded()) {
return isMetricItem(index);
}
}
return useMetric;
}
@NonNull
public IndexItem getIndexItem() {
for (IndexItem index : indexes) {
if (index.isDownloaded()) {
return index;
}
}
for (IndexItem index : indexes) {
if (useMetric && isMetricItem(index) || !useMetric && !isMetricItem(index)) {
return index;
}
}
return indexes.get(0);
}
@Override
protected double getSizeToDownloadInMb() {
return getIndexItem().getSizeToDownloadInMb();
}
@Override
public double getArchiveSizeMB() {
return getIndexItem().getArchiveSizeMB();
}
@Override
public boolean isOutdated() {
for (DownloadItem item : indexes) {
if (item.isOutdated()) {
return true;
}
}
return false;
}
@Override
public boolean isDownloaded() {
for (DownloadItem item : indexes) {
if (item.isDownloaded()) {
return true;
}
}
return false;
}
@Override
public boolean hasActualDataToDownload() {
for (IndexItem item : indexes) {
if (!item.hasActualDataToDownload()) {
return false;
}
}
return true;
}
@Override
public boolean isDownloading(@NonNull DownloadIndexesThread thread) {
for (IndexItem item : indexes) {
if (thread.isDownloading(item)) {
return true;
}
}
return false;
}
@Override
public String getFileName() {
return getIndexItem().getFileName();
}
@NonNull
@Override
public List<File> getDownloadedFiles(@NonNull OsmandApplication app) {
List<File> result = new ArrayList<>();
for (IndexItem index : indexes) {
result.addAll(index.getDownloadedFiles(app));
}
return result;
}
public String getDate(@NonNull DateFormat dateFormat, boolean remote) {
return getIndexItem().getDate(dateFormat, remote);
}
@Override
public @Nullable String getAdditionalDescription(Context ctx) {
return getAbbreviationInScopes(ctx, this);
}
public static boolean shouldUseMetersByDefault(@NonNull OsmandApplication app) {
MetricsConstants metricSystem = app.getSettings().METRIC_SYSTEM.get();
return metricSystem != MetricsConstants.MILES_AND_FEET;
}
@NonNull
public static String getAbbreviationInScopes(Context ctx, Object obj) {
String abbreviation = ctx.getString(isMetricItem(obj) ? R.string.m : R.string.foot);
return "(" + abbreviation + ")";
}
public static boolean containsSrtmExtension(@NonNull String fileName) {
return fileName.contains(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)
|| fileName.contains(IndexConstants.BINARY_SRTM_FEET_MAP_INDEX_EXT);
}
public static boolean isSrtmFile(@NonNull String fileName) {
return fileName.endsWith(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)
|| fileName.endsWith(IndexConstants.BINARY_SRTM_FEET_MAP_INDEX_EXT);
}
@NonNull
public static String getExtension(IndexItem indexItem) {
return isMetricItem(indexItem) ?
IndexConstants.BINARY_SRTM_MAP_INDEX_EXT :
IndexConstants.BINARY_SRTM_FEET_MAP_INDEX_EXT;
}
public static boolean isSRTMItem(Object item) {
if (item instanceof DownloadItem) {
return ((DownloadItem) item).getType() == SRTM_COUNTRY_FILE;
} else if (item instanceof LocalIndexInfo) {
return ((LocalIndexInfo) item).getType() == SRTM_DATA;
}
return false;
}
private static boolean isMetricItem(Object item) {
if (item instanceof IndexItem) {
return ((IndexItem) item).getFileName().endsWith(BINARY_SRTM_MAP_INDEX_EXT_ZIP);
} else if (item instanceof LocalIndexInfo) {
return ((LocalIndexInfo) item).getFileName().endsWith(BINARY_SRTM_MAP_INDEX_EXT);
} else if (item instanceof SrtmDownloadItem) {
return isMetricItem(((SrtmDownloadItem) item).getIndexItem());
} else if (item instanceof MultipleDownloadItem) {
List<DownloadItem> items = ((MultipleDownloadItem) item).getAllItems();
if (!Algorithms.isEmpty(items)) {
return isMetricItem(items.get(0));
}
}
return false;
}
}

View file

@ -87,7 +87,7 @@ public class ActiveDownloadsDialogFragment extends DialogFragment implements Dow
}
ItemViewHolder viewHolder = (ItemViewHolder) convertView.getTag();
IndexItem item = getItem(position);
viewHolder.bindIndexItem(item);
viewHolder.bindDownloadItem(item);
return convertView;
}

View file

@ -5,7 +5,6 @@ import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.StatFs;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
@ -17,8 +16,6 @@ import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.ibm.icu.impl.IllegalIcuArgumentException;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentManager;
@ -28,12 +25,12 @@ import net.osmand.IProgress;
import net.osmand.PlatformUtil;
import net.osmand.plus.OnDismissDialogFragmentListener;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.dashboard.DashChooseAppDirFragment;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.settings.backend.OsmandSettings;
import org.apache.commons.logging.Log;
@ -119,7 +116,7 @@ public class DataStoragePlaceDialogFragment extends BottomSheetDialogFragment {
deviceStorageImageView.setImageDrawable(getContentIcon(R.drawable.ic_action_phone));
TextView deviceStorageDescription = (TextView) view.findViewById(R.id.deviceMemoryDescription);
deviceStorageDescription.setText(deviceStorageName);
deviceStorageDescription.setText(getFreeSpace(deviceStorage));
deviceStorageDescription.setText(AndroidUtils.getFreeSpace(activity, deviceStorage));
View sharedMemoryRow = view.findViewById(R.id.sharedMemoryRow);
if (hasExternalStoragePermission && sharedStorage != null) {
@ -127,7 +124,7 @@ public class DataStoragePlaceDialogFragment extends BottomSheetDialogFragment {
ImageView sharedMemoryImageView = (ImageView) view.findViewById(R.id.sharedMemoryImageView);
sharedMemoryImageView.setImageDrawable(getContentIcon(R.drawable.ic_action_phone));
TextView sharedMemoryDescription = (TextView) view.findViewById(R.id.sharedMemoryDescription);
sharedMemoryDescription.setText(getFreeSpace(sharedStorage));
sharedMemoryDescription.setText(AndroidUtils.getFreeSpace(activity, sharedStorage));
} else {
view.findViewById(R.id.divSharedStorage).setVisibility(View.GONE);
sharedMemoryRow.setVisibility(View.GONE);
@ -139,7 +136,7 @@ public class DataStoragePlaceDialogFragment extends BottomSheetDialogFragment {
ImageView memoryStickImageView = (ImageView) view.findViewById(R.id.memoryStickImageView);
memoryStickImageView.setImageDrawable(getContentIcon(R.drawable.ic_sdcard));
TextView memoryStickDescription = (TextView) view.findViewById(R.id.memoryStickDescription);
memoryStickDescription.setText(getFreeSpace(cardStorage));
memoryStickDescription.setText(AndroidUtils.getFreeSpace(activity, cardStorage));
} else {
view.findViewById(R.id.divExtStorage).setVisibility(View.GONE);
memoryStickRow.setVisibility(View.GONE);
@ -192,23 +189,6 @@ public class DataStoragePlaceDialogFragment extends BottomSheetDialogFragment {
.getDefaultInternalStorage();
}
private String getFreeSpace(File dir) {
String sz = "";
if (dir != null && dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath());
@SuppressWarnings("deprecation")
long size = (long) fs.getAvailableBlocks() * fs.getBlockSize();
if (size > 0) {
sz = AndroidUtils.formatSize(getActivity(), size);
}
} catch (IllegalIcuArgumentException e) {
LOG.error(e);
}
}
return sz;
}
private void checkAssets() {
getMyApplication().getResourceManager().checkAssets(IProgress.EMPTY_PROGRESS, true);
}

View file

@ -78,7 +78,7 @@ public class DownloadResourceGroupAdapter extends OsmandBaseExpandableListAdapte
} else {
viewHolder.setShowTypeInDesc(true);
}
viewHolder.bindIndexItem(item);
viewHolder.bindDownloadItem(item);
} else {
DownloadResourceGroup group = (DownloadResourceGroup) child;
DownloadGroupViewHolder viewHolder;

View file

@ -41,9 +41,9 @@ import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.DownloadResourceGroup;
import net.osmand.plus.download.DownloadResources;
import net.osmand.plus.download.IndexItem;
import net.osmand.plus.download.MultipleIndexesUiHelper;
import net.osmand.plus.download.MultipleIndexesUiHelper.SelectItemsToDownloadListener;
import net.osmand.plus.download.MultipleIndexItem;
import net.osmand.plus.download.SelectIndexesUiHelper;
import net.osmand.plus.download.SelectIndexesUiHelper.ItemsToDownloadSelectedListener;
import net.osmand.plus.download.MultipleDownloadItem;
import net.osmand.plus.download.ui.LocalIndexesFragment.LocalIndexOperationTask;
import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper;
@ -146,11 +146,11 @@ public class ItemViewHolder {
depthContoursPurchased = InAppPurchaseHelper.isDepthContoursPurchased(context.getMyApplication());
}
public void bindIndexItem(final DownloadItem downloadItem) {
bindIndexItem(downloadItem, null);
public void bindDownloadItem(final DownloadItem downloadItem) {
bindDownloadItem(downloadItem, null);
}
public void bindIndexItem(final DownloadItem downloadItem, final String cityName) {
public void bindDownloadItem(final DownloadItem downloadItem, final String cityName) {
initAppStatusVariables();
boolean isDownloading = downloadItem.isDownloading(context.getDownloadThread());
int progress = -1;
@ -160,20 +160,20 @@ public class ItemViewHolder {
boolean disabled = checkDisabledAndClickAction(downloadItem);
/// name and left item
String name;
if(showTypeInName) {
if (showTypeInName) {
name = downloadItem.getType().getString(context);
} else {
name = downloadItem.getVisibleName(context, context.getMyApplication().getRegions(), showParentRegionName);
}
String text = (!Algorithms.isEmpty(cityName) && !cityName.equals(name) ? cityName + "\n" : "") + name;
nameTextView.setText(text);
if(!disabled) {
if (!disabled) {
nameTextView.setTextColor(textColorPrimary);
} else {
nameTextView.setTextColor(textColorSecondary);
}
int color = textColorSecondary;
if(downloadItem.isDownloaded() && !isDownloading) {
if (downloadItem.isDownloaded() && !isDownloading) {
int colorId = downloadItem.isOutdated() ? R.color.color_distance : R.color.color_ok;
color = context.getResources().getColor(colorId);
}
@ -203,12 +203,12 @@ public class ItemViewHolder {
} else {
descrTextView.setText(downloadItem.getType().getString(context));
}
} else if (downloadItem instanceof MultipleIndexItem) {
MultipleIndexItem item = (MultipleIndexItem) downloadItem;
} else if (downloadItem instanceof MultipleDownloadItem) {
MultipleDownloadItem item = (MultipleDownloadItem) downloadItem;
String allRegionsHeader = context.getString(R.string.shared_strings_all_regions);
String regionsHeader = context.getString(R.string.regions);
String allRegionsCount = String.valueOf(item.getAllIndexes().size());
String leftToDownloadCount = String.valueOf(item.getIndexesToDownload().size());
String allRegionsCount = String.valueOf(item.getAllItems().size());
String leftToDownloadCount = String.valueOf(item.getItemsToDownload().size());
String header;
String count;
if (item.hasActualDataToDownload()) {
@ -226,8 +226,11 @@ public class ItemViewHolder {
header = allRegionsHeader;
count = allRegionsCount;
}
String fullDescription =
context.getString(R.string.ltr_or_rtl_combine_via_colon, header, count);
String fullDescription = context.getString(R.string.ltr_or_rtl_combine_via_colon, header, count);
String addDescr = item.getAdditionalDescription(context);
if (addDescr != null) {
fullDescription += " " + addDescr;
}
if (item.hasActualDataToDownload()) {
fullDescription = context.getString(
R.string.ltr_or_rtl_combine_via_bold_point, fullDescription,
@ -235,11 +238,14 @@ public class ItemViewHolder {
}
descrTextView.setText(fullDescription);
} else {
IndexItem item = (IndexItem) downloadItem;
String pattern = context.getString(R.string.ltr_or_rtl_combine_via_bold_point);
String type = item.getType().getString(context);
String size = item.getSizeDescription(context);
String date = item.getDate(dateFormat, showRemoteDate);
String type = downloadItem.getType().getString(context);
String size = downloadItem.getSizeDescription(context);
String addDescr = downloadItem.getAdditionalDescription(context);
if (addDescr != null) {
size += " " + addDescr;
}
String date = downloadItem.getDate(dateFormat, showRemoteDate);
String fullDescription = String.format(pattern, size, date);
if (showTypeInDesc) {
fullDescription = String.format(pattern, type, fullDescription);
@ -254,14 +260,14 @@ public class ItemViewHolder {
if (showProgressInDesc) {
double mb = downloadItem.getArchiveSizeMB();
String v ;
String v;
if (progress != -1) {
v = context.getString(R.string.value_downloaded_of_max, mb * progress / 100, mb);
} else {
v = context.getString(R.string.file_size_in_mb, mb);
}
String fullDescription = v;
if(showTypeInDesc && downloadItem.getType() == DownloadActivityType.ROADS_FILE) {
if (showTypeInDesc && downloadItem.getType() == DownloadActivityType.ROADS_FILE) {
fullDescription = context.getString(R.string.ltr_or_rtl_combine_via_bold_point,
downloadItem.getType().getString(context), fullDescription);
}
@ -274,9 +280,9 @@ public class ItemViewHolder {
}
}
public void bindIndexItem(final CityItem cityItem) {
public void bindDownloadItem(final CityItem cityItem) {
if (cityItem.getIndexItem() != null) {
bindIndexItem(cityItem.getIndexItem(), cityItem.getName());
bindDownloadItem(cityItem.getIndexItem(), cityItem.getName());
} else {
nameTextView.setText(cityItem.getName());
nameTextView.setTextColor(textColorPrimary);
@ -302,7 +308,7 @@ public class ItemViewHolder {
if (isDownloading) {
rightImageButton.setImageDrawable(getContentIcon(context, R.drawable.ic_action_remove_dark));
rightImageButton.setContentDescription(context.getString(R.string.shared_string_cancel));
} else if(!item.hasActualDataToDownload()) {
} else if (!item.hasActualDataToDownload()) {
rightImageButton.setImageDrawable(getContentIcon(context, R.drawable.ic_overflow_menu_white));
rightImageButton.setContentDescription(context.getString(R.string.shared_string_more));
} else {
@ -316,9 +322,9 @@ public class ItemViewHolder {
}
private int getDownloadActionIconId(@NonNull DownloadItem item) {
return item instanceof MultipleIndexItem ?
return item instanceof MultipleDownloadItem ?
R.drawable.ic_action_multi_download :
R.drawable.ic_action_import;
R.drawable.ic_action_gsave_dark;
}
@SuppressLint("DefaultLocale")
@ -389,13 +395,13 @@ public class ItemViewHolder {
return new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isDownloading) {
if(silentCancelDownload) {
if (isDownloading) {
if (silentCancelDownload) {
context.getDownloadThread().cancelDownload(item);
} else {
context.makeSureUserCancelDownload(item);
}
} else if(!item.hasActualDataToDownload()){
} else if (!item.hasActualDataToDownload()) {
showContextMenu(v, item, item.getRelatedGroup());
} else {
download(item, item.getRelatedGroup());
@ -406,8 +412,8 @@ public class ItemViewHolder {
}
protected void showContextMenu(View v,
final DownloadItem downloadItem,
final DownloadResourceGroup parentOptional) {
final DownloadItem downloadItem,
final DownloadResourceGroup parentOptional) {
OsmandApplication app = context.getMyApplication();
PopupMenu optionsMenu = new PopupMenu(context, v);
MenuItem item;
@ -455,10 +461,11 @@ public class ItemViewHolder {
}
}
}
if(!handled) {
if (!handled) {
startDownload(item);
}
}
private void confirmDownload(final DownloadItem item) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.are_you_sure);
@ -476,18 +483,17 @@ public class ItemViewHolder {
}
private void startDownload(DownloadItem item) {
if (item instanceof MultipleIndexItem) {
selectIndexesToDownload((MultipleIndexItem) item);
} else if (item instanceof IndexItem) {
if (item instanceof IndexItem) {
IndexItem indexItem = (IndexItem) item;
context.startDownload(indexItem);
} else {
selectIndexesToDownload(item);
}
}
private void selectIndexesToDownload(MultipleIndexItem item) {
OsmandApplication app = context.getMyApplication();
MultipleIndexesUiHelper.showDialog(item, context, app, dateFormat, showRemoteDate,
new SelectItemsToDownloadListener() {
private void selectIndexesToDownload(DownloadItem item) {
SelectIndexesUiHelper.showDialog(item, context, dateFormat, showRemoteDate,
new ItemsToDownloadSelectedListener() {
@Override
public void onItemsToDownloadSelected(List<IndexItem> indexes) {
IndexItem[] indexesArray = new IndexItem[indexes.size()];
@ -498,7 +504,7 @@ public class ItemViewHolder {
}
private void confirmRemove(@NonNull final DownloadItem downloadItem,
@NonNull final List<File> downloadedFiles) {
@NonNull final List<File> downloadedFiles) {
OsmandApplication app = context.getMyApplication();
AlertDialog.Builder confirm = new AlertDialog.Builder(context);
@ -526,7 +532,7 @@ public class ItemViewHolder {
}
private void remove(@NonNull LocalIndexType type,
@NonNull List<File> filesToDelete) {
@NonNull List<File> filesToDelete) {
OsmandApplication app = context.getMyApplication();
LocalIndexOperationTask removeTask = new LocalIndexOperationTask(
context,

View file

@ -55,6 +55,7 @@ import net.osmand.plus.dialogs.DirectionsDialogs;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import net.osmand.plus.download.IndexItem;
import net.osmand.plus.download.SrtmDownloadItem;
import net.osmand.plus.helpers.FileNameTranslationHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.mapsource.EditMapSourceDialogFragment.OnMapSourceUpdateListener;
@ -74,6 +75,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
public class LocalIndexesFragment extends OsmandExpandableListFragment implements DownloadEvents,
OnMapSourceUpdateListener, RenameCallback {
private LoadLocalIndexTask asyncLoader;
@ -351,10 +353,10 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
getMyApplication().getResourceManager().closeFile(info.getFileName());
File tShm = new File(f.getParentFile(), f.getName() + "-shm");
File tWal = new File(f.getParentFile(), f.getName() + "-wal");
if(tShm.exists()) {
if (tShm.exists()) {
Algorithms.removeAllFiles(tShm);
}
if(tWal.exists()) {
if (tWal.exists()) {
Algorithms.removeAllFiles(tWal);
}
}
@ -370,8 +372,8 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
getMyApplication().getResourceManager().closeFile(info.getFileName());
}
} else if (operation == CLEAR_TILES_OPERATION) {
ITileSource src = (ITileSource) info.getAttachedObject();
if(src != null) {
ITileSource src = (ITileSource) info.getAttachedObject();
if (src != null) {
src.deleteTiles(info.getPathToData());
}
}
@ -419,10 +421,10 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
@Override
protected void onPostExecute(String result) {
a.setProgressBarIndeterminateVisibility(false);
if(result != null && result.length() > 0) {
if (result != null && result.length() > 0) {
Toast.makeText(a, result, Toast.LENGTH_LONG).show();
}
if (operation == RESTORE_OPERATION || operation == BACKUP_OPERATION || operation == CLEAR_TILES_OPERATION) {
a.reloadLocalIndexes();
} else {
@ -507,7 +509,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
ItemClickListener listener = new ContextMenuAdapter.ItemClickListener() {
@Override
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter,
int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
localOptionsMenu(itemId);
return true;
}
@ -608,7 +610,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
}
private void openSelectionMode(final int actionResId, final int actionIconId,
final DialogInterface.OnClickListener listener) {
final DialogInterface.OnClickListener listener) {
final int colorResId = getMyApplication().getSettings().isLightContent() ? R.color.active_buttons_and_links_text_light : R.color.active_buttons_and_links_text_dark;
String value = getString(actionResId);
if (value.endsWith("...")) {
@ -709,7 +711,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
}
public void openSelectionMode(int stringRes, int darkIcon, DialogInterface.OnClickListener listener,
EnumSet<LocalIndexType> filter) {
EnumSet<LocalIndexType> filter) {
if (filter != null) {
listAdapter.filterCategories(filter);
}
@ -860,7 +862,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
@Override
public View getChildView(final int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
boolean isLastChild, View convertView, ViewGroup parent) {
LocalIndexInfoViewHolder viewHolder;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(ctx);
@ -878,8 +880,8 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
private String getNameToDisplay(LocalIndexInfo child) {
return child.getType() == LocalIndexType.VOICE_DATA ? FileNameTranslationHelper.getVoiceName(ctx, child.getFileName()) :
FileNameTranslationHelper.getFileName(ctx,
ctx.getMyApplication().getResourceManager().getOsmandRegions(),
child.getFileName());
ctx.getMyApplication().getResourceManager().getOsmandRegions(),
child.getFileName());
}
@Override
@ -963,7 +965,7 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
return ctx.getString(R.string.download_roads_only_item);
} else if (child.isBackupedData() && child.getFileName().endsWith(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT)) {
return ctx.getString(R.string.download_wikipedia_maps);
} else if (child.isBackupedData() && child.getFileName().endsWith(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)) {
} else if (child.isBackupedData() && (SrtmDownloadItem.isSrtmFile(child.getFileName()))) {
return ctx.getString(R.string.download_srtm_maps);
}
return "";
@ -1029,6 +1031,10 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
builder.append(AndroidUtils.formatSize(ctx, child.getSize() * 1024l));
}
if (SrtmDownloadItem.isSRTMItem(child)) {
builder.append(" ").append(SrtmDownloadItem.getAbbreviationInScopes(ctx, child));
}
if (!Algorithms.isEmpty(child.getDescription())) {
if (builder.length() > 0) {
builder.append("");
@ -1150,5 +1156,4 @@ public class LocalIndexesFragment extends OsmandExpandableListFragment implement
private DownloadActivity getDownloadActivity() {
return (DownloadActivity) getActivity();
}
}

View file

@ -382,10 +382,10 @@ public class SearchDialogFragment extends DialogFragment implements DownloadEven
if (obj instanceof IndexItem) {
IndexItem item = (IndexItem) obj;
viewHolder.setShowTypeInDesc(true);
viewHolder.bindIndexItem(item);
viewHolder.bindDownloadItem(item);
} else {
CityItem item = (CityItem) obj;
viewHolder.bindIndexItem(item);
viewHolder.bindDownloadItem(item);
if (item.getIndexItem() == null) {
new IndexItemResolverTask(viewHolder, item).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@ -461,7 +461,7 @@ public class SearchDialogFragment extends DialogFragment implements DownloadEven
if (viewHolder != null) {
if (indexItem != null) {
cityItem.setIndexItem(indexItem);
viewHolder.bindIndexItem(indexItem, cityItem.getName());
viewHolder.bindDownloadItem(indexItem, cityItem.getName());
}
}
}

View file

@ -410,7 +410,7 @@ public class UpdatesIndexFragment extends OsmAndListFragment implements Download
holder.setShowRemoteDate(true);
holder.setShowTypeInDesc(true);
holder.setShowParentRegionName(true);
holder.bindIndexItem(getItem(position));
holder.bindDownloadItem(getItem(position));
}
return view;
}

View file

@ -5,7 +5,6 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StatFs;
import android.provider.Settings.Secure;
import android.util.Log;
import android.view.LayoutInflater;
@ -37,7 +36,6 @@ import net.osmand.plus.AppInitializer.AppInitializeListener;
import net.osmand.plus.OsmAndLocationProvider;
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.activities.MapActivity;
@ -51,12 +49,12 @@ import net.osmand.plus.download.IndexItem;
import net.osmand.plus.download.ui.DataStoragePlaceDialogFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.resources.ResourceManager;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
@ -331,7 +329,7 @@ public class FirstUsageWizardFragment extends BaseOsmAndFragment implements OsmA
FragmentActivity activity = getActivity();
if (!OsmAndLocationProvider.isLocationPermissionAvailable(activity)) {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
new String[] {Manifest.permission.ACCESS_FINE_LOCATION},
FIRST_USAGE_LOCATION_PERMISSION);
} else {
app.getLocationProvider().addLocationListener(this);
@ -387,13 +385,13 @@ public class FirstUsageWizardFragment extends BaseOsmAndFragment implements OsmA
@Override
public void onResume() {
super.onResume();
((MapActivity)getActivity()).disableDrawer();
((MapActivity) getActivity()).disableDrawer();
}
@Override
public void onPause() {
super.onPause();
((MapActivity)getActivity()).enableDrawer();
((MapActivity) getActivity()).enableDrawer();
}
@Override
@ -697,7 +695,7 @@ public class FirstUsageWizardFragment extends BaseOsmAndFragment implements OsmA
TextView freeSpaceValue = (TextView) storageView.findViewById(R.id.storage_free_space_value);
String freeSpaceStr = getString(R.string.storage_free_space) + ": ";
freeSpace.setText(freeSpaceStr);
freeSpaceValue.setText(getFreeSpace(settings.getExternalStorageDirectory()));
freeSpaceValue.setText(AndroidUtils.getFreeSpace(storageView.getContext(), settings.getExternalStorageDirectory()));
AppCompatButton changeStorageButton = (AppCompatButton) storageView.findViewById(R.id.storage_change_button);
if (wizardType == WizardType.MAP_DOWNLOAD) {
@ -709,7 +707,7 @@ public class FirstUsageWizardFragment extends BaseOsmAndFragment implements OsmA
public void onClick(View v) {
if (!DownloadActivity.hasPermissionToWriteExternalStorage(getContext())) {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
FIRST_USAGE_REQUEST_WRITE_EXTERNAL_STORAGE_PERMISSION);
} else {
@ -737,18 +735,6 @@ public class FirstUsageWizardFragment extends BaseOsmAndFragment implements OsmA
}
}
private String getFreeSpace(File dir) {
if (dir.canRead()) {
try {
StatFs fs = new StatFs(dir.getAbsolutePath());
return AndroidUtils.formatSize(getActivity(), (long) fs.getAvailableBlocks() * fs.getBlockSize());
} catch (IllegalArgumentException e) {
LOG.error(e);
}
}
return "";
}
public static void showSearchLocationFragment(FragmentActivity activity, boolean searchByIp) {
Fragment fragment = new FirstUsageWizardFragment();
Bundle args = new Bundle();

View file

@ -1,9 +1,11 @@
package net.osmand.plus.helpers;
import android.content.Context;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.map.OsmandRegions;
import net.osmand.map.WorldRegion;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.download.DownloadResources;
@ -19,6 +21,7 @@ import java.lang.reflect.Field;
public class FileNameTranslationHelper {
private static final Log LOG = PlatformUtil.getLog(FileNameTranslationHelper.class);
public static final String WIKI_NAME = "_wiki";
public static final String WIKIVOYAGE_NAME = "_wikivoyage";
public static final String HILL_SHADE = "Hillshade";
public static final String SLOPE = "Slope";
public static final String SEA_DEPTH = "Depth_";
@ -31,6 +34,8 @@ public class FileNameTranslationHelper {
String basename = getBasename(fileName);
if (basename.endsWith(WIKI_NAME)) { //wiki files
return getWikiName(ctx, basename);
} else if (basename.endsWith(WIKIVOYAGE_NAME)) {
return getWikivoyageName(ctx, basename);
} else if (fileName.endsWith("tts")) { //tts files
return getVoiceName(ctx, fileName);
} else if (fileName.endsWith(IndexConstants.FONT_INDEX_EXT)) { //otf files
@ -75,10 +80,10 @@ public class FileNameTranslationHelper {
return ctx.getString(R.string.ltr_or_rtl_combine_via_space, locName, "(" + terrain + ")");
}
public static String getWikiName(Context ctx, String basename){
public static String getWikiName(Context ctx, String basename) {
String cutted = basename.substring(0, basename.indexOf("_wiki"));
String wikiName = getStandardLangName(ctx, cutted);
if (wikiName == null){
if (wikiName == null) {
wikiName = cutted;
}
String wikiWord = ctx.getString(R.string.amenity_type_osmwiki);
@ -87,7 +92,18 @@ public class FileNameTranslationHelper {
//removing word in "()" from recourse file
return wikiName + " " + wikiWord.substring(0, index).trim();
}
return wikiName + " " + ctx.getString(R.string.amenity_type_osmwiki);
return wikiName + " " + ctx.getString(R.string.amenity_type_osmwiki);
}
public static String getWikivoyageName(Context ctx, String basename) {
String formattedName = basename.substring(0, basename.indexOf(WIKIVOYAGE_NAME)).replaceAll("-", "").replaceAll("all", "");
String wikiVoyageName = getSuggestedWikivoyageMaps(ctx, formattedName);
if (wikiVoyageName == null) {
wikiVoyageName = formattedName;
}
String wikiVoyageWord = ctx.getString(R.string.shared_string_wikivoyage);
return ctx.getString(R.string.ltr_or_rtl_combine_via_space, wikiVoyageName, wikiVoyageWord);
}
public static String getVoiceName(Context ctx, String fileName) {
@ -196,8 +212,8 @@ public class FileNameTranslationHelper {
return ctx.getString(R.string.lang_pl);
} else if (filename.equalsIgnoreCase("Portuguese")) {
return ctx.getString(R.string.lang_pt);
//} else if (filename.equalsIgnoreCase("Portuguese")) {
// return ctx.getString(R.string.lang_pt_br);
//} else if (filename.equalsIgnoreCase("Portuguese")) {
// return ctx.getString(R.string.lang_pt_br);
} else if (filename.equalsIgnoreCase("Romanian")) {
return ctx.getString(R.string.lang_ro);
} else if (filename.equalsIgnoreCase("Russian")) {
@ -227,11 +243,11 @@ public class FileNameTranslationHelper {
return ctx.getString(R.string.index_item_world_altitude_correction);
} else if (basename.equals("world_basemap")) {
return ctx.getString(R.string.index_item_world_basemap);
} else if (basename.equals("world_basemap_detailed")){
} else if (basename.equals("world_basemap_detailed")) {
return ctx.getString(R.string.index_item_world_basemap_detailed);
} else if (basename.equals("world_bitcoin_payments")) {
return ctx.getString(R.string.index_item_world_bitcoin_payments);
} else if (basename.equals(DownloadResources.WORLD_SEAMARKS_KEY) ||
} else if (basename.equals(DownloadResources.WORLD_SEAMARKS_KEY) ||
basename.equals(DownloadResources.WORLD_SEAMARKS_OLD_KEY)) {
return ctx.getString(R.string.index_item_world_seamarks);
} else if (basename.equals("world_wikivoyage")) {
@ -245,4 +261,27 @@ public class FileNameTranslationHelper {
}
return null;
}
private static String getSuggestedWikivoyageMaps(Context ctx, String filename) {
if (WorldRegion.AFRICA_REGION_ID.equalsIgnoreCase(filename)) {
return ctx.getString(R.string.index_name_africa);
} else if (WorldRegion.AUSTRALIA_AND_OCEANIA_REGION_ID.replaceAll("-", "").equalsIgnoreCase(filename)) {
return ctx.getString(R.string.index_name_oceania);
} else if (WorldRegion.ASIA_REGION_ID.equalsIgnoreCase(filename)) {
return ctx.getString(R.string.index_name_asia);
} else if (WorldRegion.CENTRAL_AMERICA_REGION_ID.equalsIgnoreCase(filename)) {
return ctx.getString(R.string.index_name_central_america);
} else if (WorldRegion.EUROPE_REGION_ID.equalsIgnoreCase(filename)) {
return ctx.getString(R.string.index_name_europe);
} else if (WorldRegion.RUSSIA_REGION_ID.equalsIgnoreCase(filename)) {
return ctx.getString(R.string.index_name_russia);
} else if (WorldRegion.NORTH_AMERICA_REGION_ID.equalsIgnoreCase(filename)) {
return ctx.getString(R.string.index_name_north_america);
} else if (WorldRegion.SOUTH_AMERICA_REGION_ID.equalsIgnoreCase(filename)) {
return ctx.getString(R.string.index_name_south_america);
} else if (WorldRegion.ANTARCTICA_REGION_ID.equalsIgnoreCase(filename)) {
return ctx.getString(R.string.index_name_antarctica);
}
return null;
}
}

View file

@ -79,6 +79,7 @@ import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.GPXDatabase.GpxDataItem;
import net.osmand.plus.GpxDbHelper;
import net.osmand.plus.GpxDbHelper.GpxDataItemCallback;
import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
@ -2228,17 +2229,18 @@ public class GpxUiHelper {
return dataSet;
}
public static GpxDisplayItem makeGpxDisplayItem(OsmandApplication app, GPXUtilities.GPXFile gpx) {
GpxDisplayItem gpxItem = null;
String groupName = app.getString(R.string.current_route);
GpxDisplayGroup group = app.getSelectedGpxHelper().buildGpxDisplayGroup(gpx, 0, groupName);
public static GpxDisplayItem makeGpxDisplayItem(OsmandApplication app, GPXFile gpxFile) {
GpxSelectionHelper helper = app.getSelectedGpxHelper();
String groupName = helper.getGroupName(gpxFile);
GpxDisplayGroup group = helper.buildGpxDisplayGroup(gpxFile, 0, groupName);
if (group != null && group.getModifiableList().size() > 0) {
gpxItem = group.getModifiableList().get(0);
GpxDisplayItem gpxItem = group.getModifiableList().get(0);
if (gpxItem != null) {
gpxItem.route = true;
}
return gpxItem;
}
return gpxItem;
return null;
}
public static void saveAndShareGpx(@NonNull final Context context, @NonNull final GPXFile gpxFile) {

View file

@ -21,6 +21,7 @@ import net.osmand.plus.inapp.InAppPurchases.InAppPurchase.PurchaseState;
import net.osmand.plus.inapp.InAppPurchases.InAppSubscription;
import net.osmand.plus.inapp.InAppPurchases.InAppSubscription.SubscriptionState;
import net.osmand.plus.inapp.InAppPurchases.InAppSubscriptionList;
import net.osmand.plus.inapp.InAppPurchases.PurchaseInfo;
import net.osmand.plus.liveupdates.CountrySelectionFragment;
import net.osmand.plus.liveupdates.CountrySelectionFragment.CountryItem;
import net.osmand.plus.settings.backend.OsmandSettings;
@ -52,7 +53,7 @@ public abstract class InAppPurchaseHelper {
protected InAppPurchases purchases;
protected long lastValidationCheckTime;
protected boolean inventoryRequested;
protected Map<String, SubscriptionState> subscriptionStateMap = new HashMap<>();
protected Map<String, SubscriptionStateHolder> subscriptionStateMap = new HashMap<>();
private static final long PURCHASE_VALIDATION_PERIOD_MSEC = 1000 * 60 * 60 * 24; // daily
@ -85,6 +86,11 @@ public abstract class InAppPurchaseHelper {
void onFail();
}
static class SubscriptionStateHolder {
SubscriptionState state = SubscriptionState.UNDEFINED;
long expireTime = 0;
}
public enum InAppPurchaseTaskType {
REQUEST_INVENTORY,
PURCHASE_FULL_VERSION,
@ -112,30 +118,6 @@ public abstract class InAppPurchaseHelper {
void onCommandDone(@NonNull InAppCommand command);
}
public static class PurchaseInfo {
private String sku;
private String orderId;
private String purchaseToken;
public PurchaseInfo(String sku, String orderId, String purchaseToken) {
this.sku = sku;
this.orderId = orderId;
this.purchaseToken = purchaseToken;
}
public String getSku() {
return sku;
}
public String getOrderId() {
return orderId;
}
public String getPurchaseToken() {
return purchaseToken;
}
}
public String getToken() {
return token;
}
@ -193,6 +175,11 @@ public abstract class InAppPurchaseHelper {
return purchases.getPurchasedMonthlyLiveUpdates();
}
@Nullable
public InAppSubscription getAnyPurchasedSubscription() {
return purchases.getAnyPurchasedSubscription();
}
public InAppPurchaseHelper(OsmandApplication ctx) {
this.ctx = ctx;
isDeveloperVersion = Version.isDeveloperVersion(ctx);
@ -202,8 +189,7 @@ public abstract class InAppPurchaseHelper {
public List<InAppSubscription> getEverMadeSubscriptions() {
List<InAppSubscription> subscriptions = new ArrayList<>();
for (InAppSubscription subscription : getLiveUpdates().getVisibleSubscriptions()) {
SubscriptionState state = subscription.getState();
if (state != SubscriptionState.UNDEFINED) {
if (subscription.isPurchased() || subscription.getState() != SubscriptionState.UNDEFINED) {
subscriptions.add(subscription);
}
}
@ -448,15 +434,22 @@ public abstract class InAppPurchaseHelper {
}
if (subscriptionsStateJson != null) {
inventoryRequested = true;
Map<String, SubscriptionState> subscriptionStateMap = new HashMap<>();
Map<String, SubscriptionStateHolder> subscriptionStateMap = new HashMap<>();
try {
JSONArray subArrJson = new JSONArray(subscriptionsStateJson);
for (int i = 0; i < subArrJson.length(); i++) {
JSONObject subObj = subArrJson.getJSONObject(i);
String sku = subObj.getString("sku");
String state = subObj.getString("state");
long expireTime = 0;
if (subObj.has("expire_time")) {
expireTime = subObj.getLong("expire_time");
}
if (!Algorithms.isEmpty(sku) && !Algorithms.isEmpty(state)) {
subscriptionStateMap.put(sku, SubscriptionState.getByStateStr(state));
SubscriptionStateHolder stateHolder = new SubscriptionStateHolder();
stateHolder.state = SubscriptionState.getByStateStr(state);
stateHolder.expireTime = expireTime;
subscriptionStateMap.put(sku, stateHolder);
}
}
} catch (JSONException e) {
@ -500,12 +493,14 @@ public abstract class InAppPurchaseHelper {
protected void onPurchaseDone(PurchaseInfo info) {
logDebug("Purchase successful.");
InAppPurchase liveUpdatesPurchase = getLiveUpdates().getSubscriptionBySku(info.getSku());
InAppSubscription liveUpdatesPurchase = getLiveUpdates().getSubscriptionBySku(info.getSku());
if (liveUpdatesPurchase != null) {
// bought live updates
logDebug("Live updates subscription purchased.");
final String sku = liveUpdatesPurchase.getSku();
liveUpdatesPurchase.setPurchaseState(PurchaseState.PURCHASED);
liveUpdatesPurchase.setPurchaseInfo(ctx, info);
liveUpdatesPurchase.setState(ctx, SubscriptionState.UNDEFINED);
sendTokens(Collections.singletonList(info), new OnRequestResultListener() {
@Override
public void onResult(String result) {
@ -525,6 +520,7 @@ public abstract class InAppPurchaseHelper {
} else if (info.getSku().equals(getFullVersion().getSku())) {
// bought full version
getFullVersion().setPurchaseState(PurchaseState.PURCHASED);
getFullVersion().setPurchaseInfo(ctx, info);
logDebug("Full version purchased.");
showToast(ctx.getString(R.string.full_version_thanks));
ctx.getSettings().FULL_VERSION_PURCHASED.set(true);
@ -536,6 +532,7 @@ public abstract class InAppPurchaseHelper {
} else if (info.getSku().equals(getDepthContours().getSku())) {
// bought sea depth contours
getDepthContours().setPurchaseState(PurchaseState.PURCHASED);
getDepthContours().setPurchaseInfo(ctx, info);
logDebug("Sea depth contours purchased.");
showToast(ctx.getString(R.string.sea_depth_thanks));
ctx.getSettings().DEPTH_CONTOURS_PURCHASED.set(true);
@ -548,6 +545,7 @@ public abstract class InAppPurchaseHelper {
} else if (info.getSku().equals(getContourLines().getSku())) {
// bought contour lines
getContourLines().setPurchaseState(PurchaseState.PURCHASED);
getContourLines().setPurchaseInfo(ctx, info);
logDebug("Contours lines purchased.");
showToast(ctx.getString(R.string.contour_lines_thanks));
ctx.getSettings().CONTOUR_LINES_PURCHASED.set(true);

View file

@ -7,33 +7,41 @@ import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import net.osmand.AndroidUtils;
import net.osmand.Period;
import net.osmand.Period.PeriodUnit;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.widgets.style.CustomTypefaceSpan;
import net.osmand.util.Algorithms;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Currency;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import androidx.annotation.ColorInt;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
public abstract class InAppPurchases {
protected InAppPurchase fullVersion;
@ -47,6 +55,10 @@ public abstract class InAppPurchases {
protected InAppPurchases(OsmandApplication ctx) {
}
private static OsmandSettings getSettings(@NonNull Context ctx) {
return ((OsmandApplication) ctx.getApplicationContext()).getSettings();
}
public InAppPurchase getFullVersion() {
return fullVersion;
}
@ -83,6 +95,17 @@ public abstract class InAppPurchases {
return null;
}
@Nullable
public InAppSubscription getAnyPurchasedSubscription() {
List<InAppSubscription> allSubscriptions = liveUpdates.getAllSubscriptions();
for (InAppSubscription subscription : allSubscriptions) {
if (subscription.isAnyPurchased()) {
return subscription;
}
}
return null;
}
public InAppSubscriptionList getLiveUpdates() {
return liveUpdates;
}
@ -231,7 +254,7 @@ public abstract class InAppPurchases {
private double priceValue;
private String priceCurrencyCode;
private PurchaseState purchaseState = PurchaseState.UNKNOWN;
private long purchaseTime;
private PurchaseInfo purchaseInfo;
double monthlyPriceValue;
boolean donationSupported = false;
@ -253,6 +276,37 @@ public abstract class InAppPurchases {
return sku;
}
@Nullable
public String getOrderId() {
return purchaseInfo != null ? purchaseInfo.getOrderId() : null;
}
private CommonPreference<String> getPurchaseInfoPref(@NonNull Context ctx) {
return getSettings(ctx).registerStringPreference(sku + "_purchase_info", "").makeGlobal();
}
public boolean storePurchaseInfo(@NonNull Context ctx) {
PurchaseInfo purchaseInfo = this.purchaseInfo;
if (purchaseInfo != null) {
getPurchaseInfoPref(ctx).set(purchaseInfo.toJson());
return true;
}
return false;
}
public boolean restorePurchaseInfo(@NonNull Context ctx) {
String json = getPurchaseInfoPref(ctx).get();
if (!Algorithms.isEmpty(json)) {
try {
purchaseInfo = new PurchaseInfo(json);
} catch (JSONException e) {
// ignore
}
return true;
}
return false;
}
public String getPrice(Context ctx) {
if (!Algorithms.isEmpty(price)) {
return price;
@ -266,11 +320,16 @@ public abstract class InAppPurchases {
}
public long getPurchaseTime() {
return purchaseTime;
return purchaseInfo != null ? purchaseInfo.getPurchaseTime() : 0;
}
public void setPurchaseTime(long purchaseTime) {
this.purchaseTime = purchaseTime;
public PurchaseInfo getPurchaseInfo() {
return purchaseInfo;
}
void setPurchaseInfo(@NonNull Context ctx, PurchaseInfo purchaseInfo) {
this.purchaseInfo = purchaseInfo;
storePurchaseInfo(ctx);
}
public String getDefaultPrice(Context ctx) {
@ -571,35 +630,33 @@ public abstract class InAppPurchases {
public static abstract class InAppSubscription extends InAppPurchase {
private Map<String, InAppSubscription> upgrades = new ConcurrentHashMap<>();
private String skuNoVersion;
private final Map<String, InAppSubscription> upgrades = new ConcurrentHashMap<>();
private final String skuNoVersion;
private String subscriptionPeriodString;
private Period subscriptionPeriod;
private boolean upgrade = false;
private SubscriptionState state = SubscriptionState.UNDEFINED;
private SubscriptionState prevState = SubscriptionState.UNDEFINED;
private SubscriptionState previousState = SubscriptionState.UNDEFINED;
private long expireTime = 0;
private InAppSubscriptionIntroductoryInfo introductoryInfo;
public enum SubscriptionState {
UNDEFINED("undefined", 0, 0),
ACTIVE("active", R.string.osm_live_active, R.drawable.bg_osmand_live_active),
CANCELLED("cancelled", R.string.osmand_live_cancelled, R.drawable.bg_osmand_live_cancelled),
IN_GRACE_PERIOD("in_grace_period", R.string.in_grace_period, R.drawable.bg_osmand_live_active),
ON_HOLD("on_hold", R.string.on_hold, R.drawable.bg_osmand_live_cancelled),
PAUSED("paused", R.string.shared_string_paused, R.drawable.bg_osmand_live_cancelled),
EXPIRED("expired", R.string.expired, R.drawable.bg_osmand_live_cancelled);
UNDEFINED("undefined", R.string.shared_string_undefined),
ACTIVE("active", R.string.osm_live_active),
CANCELLED("cancelled", R.string.osmand_live_cancelled),
IN_GRACE_PERIOD("in_grace_period", R.string.in_grace_period),
ON_HOLD("on_hold", R.string.on_hold),
PAUSED("paused", R.string.shared_string_paused),
EXPIRED("expired", R.string.expired);
private final String stateStr;
@StringRes
private final int stringRes;
@DrawableRes
private final int backgroundRes;
SubscriptionState(@NonNull String stateStr, @StringRes int stringRes, @DrawableRes int backgroundRes) {
SubscriptionState(@NonNull String stateStr, @StringRes int stringRes) {
this.stateStr = stateStr;
this.stringRes = stringRes;
this.backgroundRes = backgroundRes;
}
public String getStateStr() {
@ -611,11 +668,6 @@ public abstract class InAppPurchases {
return stringRes;
}
@DrawableRes
public int getBackgroundRes() {
return backgroundRes;
}
@NonNull
public static SubscriptionState getByStateStr(@NonNull String stateStr) {
for (SubscriptionState state : SubscriptionState.values()) {
@ -678,21 +730,76 @@ public abstract class InAppPurchases {
return state;
}
public void setState(@NonNull SubscriptionState state) {
public void setState(@NonNull Context ctx, @NonNull SubscriptionState state) {
this.state = state;
storeState(ctx, state);
}
@NonNull
public SubscriptionState getPrevState() {
return prevState;
}
public void setPrevState(@NonNull SubscriptionState prevState) {
this.prevState = prevState;
public SubscriptionState getPreviousState() {
return previousState;
}
public boolean hasStateChanged() {
return state != prevState;
return state != previousState;
}
private CommonPreference<String> getStatePref(@NonNull Context ctx) {
return getSettings(ctx).registerStringPreference(getSku() + "_state", "").makeGlobal();
}
void storeState(@NonNull Context ctx, @NonNull SubscriptionState state) {
getStatePref(ctx).set(state.getStateStr());
}
boolean restoreState(@NonNull Context ctx) {
String stateStr = getStatePref(ctx).get();
if (!Algorithms.isEmpty(stateStr)) {
SubscriptionState state = SubscriptionState.getByStateStr(stateStr);
this.previousState = state;
this.state = state;
return true;
}
return false;
}
public long getCalculatedExpiredTime() {
long purchaseTime = getPurchaseTime();
Period period = getSubscriptionPeriod();
if (purchaseTime == 0 || period == null || period.getUnit() == null) {
return 0;
}
Date date = new Date(purchaseTime);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(period.getUnit().getCalendarIdx(), period.getNumberOfUnits());
return calendar.getTimeInMillis();
}
public long getExpireTime() {
return expireTime;
}
public void setExpireTime(@NonNull Context ctx, long expireTime) {
this.expireTime = expireTime;
storeExpireTime(ctx, expireTime);
}
private CommonPreference<Long> getExpireTimePref(@NonNull Context ctx) {
return getSettings(ctx).registerLongPreference(getSku() + "_expire_time", 0L).makeGlobal();
}
boolean restoreExpireTime(@NonNull Context ctx) {
Long expireTime = getExpireTimePref(ctx).get();
if (expireTime != null) {
this.expireTime = expireTime;
return true;
}
return false;
}
void storeExpireTime(@NonNull Context ctx, long expireTime) {
getExpireTimePref(ctx).set(expireTime);
}
public boolean isAnyPurchased() {
@ -999,5 +1106,95 @@ public abstract class InAppPurchases {
return null;
}
}
public static class PurchaseInfo {
private String sku;
private String orderId;
private String purchaseToken;
private long purchaseTime;
private int purchaseState;
private boolean acknowledged;
private boolean autoRenewing;
PurchaseInfo(String sku, String orderId, String purchaseToken, long purchaseTime,
int purchaseState, boolean acknowledged, boolean autoRenewing) {
this.sku = sku;
this.orderId = orderId;
this.purchaseToken = purchaseToken;
this.purchaseTime = purchaseTime;
this.purchaseState = purchaseState;
this.acknowledged = acknowledged;
this.autoRenewing = autoRenewing;
}
PurchaseInfo(@NonNull String json) throws JSONException {
parseJson(json);
}
public String getSku() {
return sku;
}
public String getOrderId() {
return orderId;
}
public String getPurchaseToken() {
return purchaseToken;
}
public long getPurchaseTime() {
return purchaseTime;
}
public int getPurchaseState() {
return purchaseState;
}
public boolean isAcknowledged() {
return acknowledged;
}
public boolean isAutoRenewing() {
return autoRenewing;
}
public String toJson() {
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("sku", sku);
jsonMap.put("orderId", orderId);
jsonMap.put("purchaseToken", purchaseToken);
jsonMap.put("purchaseTime", purchaseTime);
jsonMap.put("purchaseState", purchaseState);
jsonMap.put("acknowledged", acknowledged);
jsonMap.put("autoRenewing", autoRenewing);
return new JSONObject(jsonMap).toString();
}
public void parseJson(@NonNull String json) throws JSONException {
JSONObject jsonObj = new JSONObject(json);
if (jsonObj.has("sku")) {
this.sku = jsonObj.getString("sku");
}
if (jsonObj.has("orderId")) {
this.orderId = jsonObj.getString("orderId");
}
if (jsonObj.has("purchaseToken")) {
this.purchaseToken = jsonObj.getString("purchaseToken");
}
if (jsonObj.has("purchaseTime")) {
this.purchaseTime = jsonObj.getLong("purchaseTime");
}
if (jsonObj.has("purchaseState")) {
this.purchaseState = jsonObj.getInt("purchaseState");
}
if (jsonObj.has("acknowledged")) {
this.acknowledged = jsonObj.getBoolean("acknowledged");
}
if (jsonObj.has("autoRenewing")) {
this.autoRenewing = jsonObj.getBoolean("autoRenewing");
}
}
}
}

View file

@ -282,6 +282,9 @@ public class LiveUpdatesFragment extends BaseOsmAndDialogFragment implements OnL
dismiss();
}
});
if (closeButton instanceof ImageView) {
UiUtilities.rotateImageByLayoutDirection((ImageView) closeButton);
}
FrameLayout iconHelpContainer = toolbar.findViewById(R.id.action_button);
int iconColorResId = nightMode ? R.color.active_buttons_and_links_text_dark : R.color.active_buttons_and_links_text_light;

View file

@ -42,9 +42,10 @@ import net.osmand.plus.liveupdates.LiveUpdatesHelper.UpdateFrequency;
import net.osmand.plus.resources.IncrementalChangesManager;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.widgets.MultiStateToggleButton;
import net.osmand.plus.widgets.MultiStateToggleButton.OnRadioItemClickListener;
import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem;
import net.osmand.plus.widgets.multistatetoggle.RadioItem;
import net.osmand.plus.widgets.multistatetoggle.RadioItem.OnRadioItemClickListener;
import net.osmand.plus.widgets.multistatetoggle.TextToggleButton;
import net.osmand.plus.widgets.multistatetoggle.TextToggleButton.TextRadioItem;
import net.osmand.plus.widgets.TextViewEx;
import net.osmand.plus.widgets.style.CustomTypefaceSpan;
import net.osmand.util.Algorithms;
@ -83,8 +84,8 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen
private BaseBottomSheetItem itemFrequencyHelpMessage;
private BaseBottomSheetItem itemClear;
private BaseBottomSheetItem itemViaWiFi;
private MultiStateToggleButton frequencyToggleButton;
private MultiStateToggleButton timeOfDayToggleButton;
private TextToggleButton frequencyToggleButton;
private TextToggleButton timeOfDayToggleButton;
private String fileName;
private OnLiveUpdatesForLocalChange onLiveUpdatesForLocalChange;
@ -195,9 +196,9 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen
String morning = getString(R.string.morning);
String night = getString(R.string.night);
RadioItem morningButton = new RadioItem(morning);
RadioItem nightButton = new RadioItem(night);
timeOfDayToggleButton = new MultiStateToggleButton(app, itemTimeOfDayButtons, nightMode);
TextRadioItem morningButton = new TextRadioItem(morning);
TextRadioItem nightButton = new TextRadioItem(night);
timeOfDayToggleButton = new TextToggleButton(app, itemTimeOfDayButtons, nightMode);
timeOfDayToggleButton.setItems(morningButton, nightButton);
setSelectedRadioItem(timeOfDayToggleButton, timeOfDayPreference.get(), morningButton, nightButton);
timeOfDayToggleButton.updateView(localUpdatePreference.get());
@ -231,10 +232,10 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen
String hourly = getString(R.string.hourly);
String daily = getString(R.string.daily);
String weekly = getString(R.string.weekly);
RadioItem hourlyButton = new RadioItem(hourly);
RadioItem dailyButton = new RadioItem(daily);
RadioItem weeklyButton = new RadioItem(weekly);
frequencyToggleButton = new MultiStateToggleButton(app, itemFrequencyButtons, nightMode);
TextRadioItem hourlyButton = new TextRadioItem(hourly);
TextRadioItem dailyButton = new TextRadioItem(daily);
TextRadioItem weeklyButton = new TextRadioItem(weekly);
frequencyToggleButton = new TextToggleButton(app, itemFrequencyButtons, nightMode);
frequencyToggleButton.setItems(hourlyButton, dailyButton, weeklyButton);
setSelectedRadioItem(frequencyToggleButton, frequencyPreference.get(), hourlyButton, dailyButton, weeklyButton);
frequencyToggleButton.updateView(localUpdatePreference.get());
@ -467,7 +468,7 @@ public class LiveUpdatesSettingsBottomSheet extends MenuBottomSheetDialogFragmen
return dividerItem;
}
private void setSelectedRadioItem(MultiStateToggleButton toggleButton, int position, RadioItem... buttons) {
private void setSelectedRadioItem(TextToggleButton toggleButton, int position, TextRadioItem... buttons) {
toggleButton.setSelectedItem(buttons[position]);
}

View file

@ -7,12 +7,13 @@ import android.os.AsyncTask;
import androidx.annotation.NonNull;
import net.osmand.AndroidUtils;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.plus.GpxSelectionHelper;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayGroup;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
@ -24,7 +25,6 @@ import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.track.TrackMenuFragment;
import net.osmand.util.Algorithms;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
@ -93,27 +93,14 @@ public class SelectedGpxMenuController extends MenuController {
@Override
protected GpxSelectionHelper.GpxDisplayItem doInBackground(Void... voids) {
GpxSelectionHelper.GpxDisplayGroup gpxDisplayGroup = null;
GPXUtilities.GPXFile gpxFile = null;
GPXUtilities.Track generalTrack = null;
if (selectedGpxFile.getGpxFile().path != null) {
gpxFile = GPXUtilities.loadGPXFile(new File(selectedGpxFile.getGpxFile().path));
}
if (gpxFile != null) {
generalTrack = gpxFile.getGeneralTrack();
}
if (generalTrack != null) {
gpxFile.addGeneralTrack();
gpxDisplayGroup = app.getSelectedGpxHelper().buildGeneralGpxDisplayGroup(gpxFile, generalTrack);
} else if (gpxFile != null && gpxFile.tracks.size() > 0) {
gpxDisplayGroup = app.getSelectedGpxHelper().buildGeneralGpxDisplayGroup(gpxFile, gpxFile.tracks.get(0));
}
List<GpxSelectionHelper.GpxDisplayItem> items = null;
if (gpxDisplayGroup != null) {
items = gpxDisplayGroup.getModifiableList();
}
if (items != null && items.size() > 0) {
return items.get(0);
GPXFile gpxFile = selectedGpxFile.getGpxFile();
if (gpxFile.tracks.size() > 0) {
GpxDisplayGroup gpxDisplayGroup = app.getSelectedGpxHelper().buildGeneralGpxDisplayGroup(gpxFile, gpxFile.tracks.get(0));
List<GpxDisplayItem> items = gpxDisplayGroup.getModifiableList();
if (!Algorithms.isEmpty(items)) {
return items.get(0);
}
}
return null;
}

View file

@ -24,6 +24,7 @@ import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.LineGraphType;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter;
@ -109,9 +110,16 @@ public class GraphsCard extends BaseCard implements OnUpdateInfoListener {
GraphAdapterHelper.bindGraphAdapters(commonGraphAdapter, Collections.singletonList((BaseGraphAdapter) customGraphAdapter), (ViewGroup) view);
refreshMapCallback = GraphAdapterHelper.bindToMap(commonGraphAdapter, mapActivity, trackDetailsMenu);
updateTopPadding();
fullUpdate();
}
private void updateTopPadding() {
int topPadding = AndroidUiHelper.isOrientationPortrait(mapActivity) ?
0 : app.getResources().getDimensionPixelSize(R.dimen.content_padding_small);
view.setPadding(0, topPadding, 0, 0);
}
@Override
public int getCardLayoutId() {
return R.layout.measurement_tool_graph_card;

View file

@ -11,6 +11,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
@ -82,9 +83,13 @@ import net.osmand.plus.views.layers.MapControlsLayer.MapControlsThemeInfoProvide
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarView;
import net.osmand.plus.widgets.MultiStateToggleButton;
import net.osmand.plus.widgets.MultiStateToggleButton.OnRadioItemClickListener;
import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem;
import net.osmand.plus.widgets.multistatetoggle.IconToggleButton;
import net.osmand.plus.widgets.multistatetoggle.IconToggleButton.IconRadioItem;
import net.osmand.plus.widgets.multistatetoggle.MultiStateToggleButton;
import net.osmand.plus.widgets.multistatetoggle.RadioItem;
import net.osmand.plus.widgets.multistatetoggle.RadioItem.OnRadioItemClickListener;
import net.osmand.plus.widgets.multistatetoggle.TextToggleButton;
import net.osmand.plus.widgets.multistatetoggle.TextToggleButton.TextRadioItem;
import net.osmand.router.RoutePlannerFrontEnd.GpxRouteApproximation;
import net.osmand.util.Algorithms;
@ -130,6 +135,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private RadioItem graphBtn;
private View mainView;
private View bottomMapControls;
private View topMapControls;
private ImageView upDownBtn;
private ImageView undoBtn;
private ImageView redoBtn;
@ -251,7 +257,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public void showProgressBar() {
MeasurementToolFragment.this.showProgressBar();
updateInfoView();
updateCardContainerSize();
updateInfoViewAppearance();
}
@Override
@ -261,10 +267,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override
public void hideProgressBar() {
((ProgressBar) mainView.findViewById(R.id.snap_to_road_progress_bar)).setVisibility(View.GONE);
((ProgressBar) mainView.findViewById(R.id.snap_to_road_progress_bar)).setVisibility(View.INVISIBLE);
progressBarVisible = false;
updateInfoView();
updateCardContainerSize();
updateInfoViewAppearance();
}
@Override
@ -287,32 +293,38 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
.inflate(R.layout.fragment_measurement_tool, container, false);
mainView = view.findViewById(R.id.main_view);
AndroidUtils.setBackground(mapActivity, mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
detailsMenu = new GraphDetailsMenu();
LinearLayout infoButtonsContainer = mainView.findViewById(R.id.custom_radio_buttons);
if (portrait) {
cardsContainer = mainView.findViewById(R.id.cards_container);
infoTypeBtn = new TextToggleButton(app, infoButtonsContainer, nightMode);
String pointsBtnTitle = getString(R.string.shared_string_gpx_points);
pointsBtn = new RadioItem(pointsBtnTitle);
pointsBtn.setOnClickListener(getInfoTypeBtnListener(InfoType.POINTS));
pointsBtn = new TextRadioItem(pointsBtnTitle);
String graphBtnTitle = getString(R.string.shared_string_graph);
graphBtn = new RadioItem(graphBtnTitle);
graphBtn.setOnClickListener(getInfoTypeBtnListener(InfoType.GRAPH));
graphBtn = new TextRadioItem(graphBtnTitle);
LinearLayout infoButtonsContainer = mainView.findViewById(R.id.custom_radio_buttons);
infoTypeBtn = new MultiStateToggleButton(app, infoButtonsContainer, nightMode);
infoTypeBtn.setItems(pointsBtn, graphBtn);
} else {
cardsContainer = mapActivity.findViewById(R.id.left_side_menu);
bottomMapControls = mapActivity.findViewById(R.id.bottom_controls_container);
topMapControls = mapActivity.findViewById(R.id.top_controls_container);
infoTypeBtn = new IconToggleButton(app, infoButtonsContainer, nightMode);
pointsBtn = new IconRadioItem(R.drawable.ic_action_plan_route_point_colored, true);
graphBtn = new IconRadioItem(R.drawable.ic_action_analyze_intervals);
ScrollUtils.addOnGlobalLayoutListener(mainView, new Runnable() {
@Override
public void run() {
updateCardContainerSize();
updateInfoViewAppearance();
}
});
}
pointsBtn.setOnClickListener(getInfoTypeBtnListener(InfoType.POINTS));
graphBtn.setOnClickListener(getInfoTypeBtnListener(InfoType.GRAPH));
infoTypeBtn.setItems(pointsBtn, graphBtn);
pointsCard = new PointsCard(mapActivity, this);
graphsCard = new GraphsCard(mapActivity, detailsMenu, this);
@ -348,7 +360,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public void onClick(View v) {
if (infoExpanded) {
collapseInfoView();
} else if (setInfoType(InfoType.POINTS) && portrait) {
} else if (setInfoType(InfoType.POINTS)) {
infoTypeBtn.setSelectedItem(pointsBtn);
}
}
@ -626,7 +638,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (portrait) {
setMapPosition(OsmandSettings.MIDDLE_TOP_CONSTANT);
} else {
shiftBottomMapControls(false);
shiftMapControls(false);
setMapPosition(OsmandSettings.LANDSCAPE_MIDDLE_RIGHT_CONSTANT);
}
cardsContainer.setVisibility(View.VISIBLE);
@ -640,15 +652,14 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
private void collapseInfoView() {
cardsContainer.setVisibility(View.GONE);
if (portrait) {
infoTypeBtn.setSelectedItem(null);
} else {
shiftBottomMapControls(true);
}
infoExpanded = false;
currentInfoType = null;
setDefaultMapPosition();
cardsContainer.setVisibility(View.GONE);
if (!portrait) {
shiftMapControls(true);
}
infoTypeBtn.setSelectedItem(null);
moveMapToDefaultPosition();
updateUpDownBtn();
}
@ -676,37 +687,37 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
}
private void updateCardContainerSize() {
if (portrait) {
return;
private void updateInfoViewAppearance() {
if (portrait) return;
View toolsPanel = mainView.findViewById(R.id.measure_mode_controls);
View snapToRoadProgress = mainView.findViewById(R.id.snap_to_road_progress_bar);
int infoViewWidth = mainView.getWidth() - toolsPanel.getWidth();
int bottomMargin = toolsPanel.getHeight();
if (progressBarVisible) {
bottomMargin += snapToRoadProgress.getHeight();
}
View measureModeControls = mainView.findViewById(R.id.measure_mode_controls);
int width = mainView.getWidth() - measureModeControls.getWidth();
int bottomMargin = measureModeControls.getHeight();
bottomMargin = progressBarVisible ? bottomMargin + mainView.findViewById(R.id.snap_to_road_progress_bar).getHeight() : bottomMargin;
ViewGroup.MarginLayoutParams params = null;
if (mainView.getParent() instanceof FrameLayout) {
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, -1);
params.setMargins(0, 0, 0, bottomMargin);
cardsContainer.setLayoutParams(params);
params = new FrameLayout.LayoutParams(infoViewWidth, -1);
} else if (mainView.getParent() instanceof LinearLayout) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width, -1);
params.setMargins(0, 0, 0, bottomMargin);
params = new LinearLayout.LayoutParams(infoViewWidth, -1);
}
if (params != null) {
AndroidUtils.setMargins(params, 0, 0, 0, bottomMargin);
cardsContainer.setLayoutParams(params);
}
}
private void shiftBottomMapControls(boolean toInitialPosition) {
if (portrait) {
return;
}
int leftMargin = toInitialPosition ? 0 : cardsContainer.getWidth();
if (bottomMapControls.getParent() instanceof LinearLayout) {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) bottomMapControls.getLayoutParams();
params.setMargins(leftMargin, 0, 0, 0);
} else if (bottomMapControls.getParent() instanceof FrameLayout) {
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) bottomMapControls.getLayoutParams();
params.setMargins(leftMargin, 0, 0, 0);
}
private void shiftMapControls(boolean toInitialPosition) {
boolean isLayoutRtl = AndroidUtils.isLayoutRtl(getContext());
int shiftPosition = toInitialPosition ? 0 : cardsContainer.getWidth();
int start = isLayoutRtl ? 0 : shiftPosition;
int end = isLayoutRtl ? shiftPosition : 0;
AndroidUtils.setMargins((MarginLayoutParams) bottomMapControls.getLayoutParams(), start, 0, end, 0);
AndroidUtils.setMargins((MarginLayoutParams) topMapControls.getLayoutParams(), start, 0, end, 0);
}
public boolean isInEditMode() {
@ -772,7 +783,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
mapActivity.getMapLayers().getMapControlsLayer().addThemeInfoProviderTag(TAG);
mapActivity.getMapLayers().getMapControlsLayer().showMapControlsIfHidden();
cachedMapPosition = mapActivity.getMapView().getMapPosition();
setDefaultMapPosition();
moveMapToDefaultPosition();
addInitialPoint();
}
}
@ -1196,7 +1207,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override
public void onCloseMenu() {
setDefaultMapPosition();
moveMapToDefaultPosition();
}
@Override
@ -1390,7 +1401,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
editingCtx.cancelSnapToRoad();
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
mainView.findViewById(R.id.snap_to_road_progress_bar).setVisibility(View.GONE);
mainView.findViewById(R.id.snap_to_road_progress_bar).setVisibility(View.INVISIBLE);
mapActivity.refreshMap();
}
}
@ -1641,7 +1652,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
updateInfoView();
}
private void setDefaultMapPosition() {
private void moveMapToDefaultPosition() {
setMapPosition(OsmandSettings.CENTER_CONSTANT);
}

View file

@ -83,7 +83,7 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl
public static final String UPDATE_DYNAMIC_ITEMS = "update_dynamic_items";
private static final int GPS_UPDATE_INTERVAL = 1000;
public static final GPXTabItemType[] INIT_TAB_ITEMS =
new GPXTabItemType[]{GPX_TAB_ITEM_GENERAL, GPX_TAB_ITEM_ALTITUDE, GPX_TAB_ITEM_SPEED};
new GPXTabItemType[] {GPX_TAB_ITEM_GENERAL, GPX_TAB_ITEM_ALTITUDE, GPX_TAB_ITEM_SPEED};
private OsmandApplication app;
private OsmandSettings settings;
@ -651,7 +651,7 @@ public class TripRecordingBottomSheet extends MenuBottomSheetDialogFragment impl
}
@Override
public void openAnalyzeOnMap(GpxDisplayItem gpxItem) {
public void openAnalyzeOnMap(@NonNull GpxDisplayItem gpxItem) {
}
public interface DismissTargetFragment {

View file

@ -2,6 +2,8 @@ package net.osmand.plus.myplaces;
import android.view.View;
import androidx.annotation.NonNull;
import net.osmand.GPXUtilities.TrkSegment;
import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem;
@ -19,5 +21,5 @@ public interface SegmentActionsListener {
void showOptionsPopupMenu(View view, TrkSegment trkSegment, boolean confirmDeletion, GpxDisplayItem gpxItem);
void openAnalyzeOnMap(GpxDisplayItem gpxItem);
void openAnalyzeOnMap(@NonNull GpxDisplayItem gpxItem);
}

View file

@ -292,7 +292,7 @@ public class TrackSegmentFragment extends OsmAndListFragment implements TrackBit
}
@Override
public void openAnalyzeOnMap(GpxDisplayItem gpxItem) {
public void openAnalyzeOnMap(@NonNull GpxDisplayItem gpxItem) {
OsmandSettings settings = app.getSettings();
settings.setMapLocationToShow(gpxItem.locationOnMap.lat, gpxItem.locationOnMap.lon,
settings.getLastKnownMapZoom(),

View file

@ -1,12 +1,11 @@
package net.osmand.plus.resources;
import android.view.LayoutInflater;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.R;
import net.osmand.plus.download.SrtmDownloadItem;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
@ -33,12 +32,11 @@ public class IncrementalChangesManager {
private static final org.apache.commons.logging.Log log = PlatformUtil.getLog(IncrementalChangesManager.class);
private ResourceManager resourceManager;
private final Map<String, RegionUpdateFiles> regions = new ConcurrentHashMap<String, IncrementalChangesManager.RegionUpdateFiles>();
public IncrementalChangesManager(ResourceManager resourceManager) {
this.resourceManager = resourceManager;
}
public List<File> collectChangesFiles(File dir, String ext, List<File> files) {
if (dir.exists() && dir.canRead()) {
File[] lf = dir.listFiles();
@ -47,8 +45,8 @@ public class IncrementalChangesManager {
}
Set<String> existingFiles = new HashSet<String>();
for (File f : files) {
if(!f.getName().endsWith(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT) &&
!f.getName().endsWith(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)) {
if (!f.getName().endsWith(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT) &&
!SrtmDownloadItem.isSrtmFile(f.getName())) {
existingFiles.add(Algorithms.getFileNameWithoutExtension(f));
}
}
@ -71,7 +69,7 @@ public class IncrementalChangesManager {
public synchronized void indexMainMap(File f, long dateCreated) {
String nm = Algorithms.getFileNameWithoutExtension(f).toLowerCase();
RegionUpdateFiles regionUpdateFiles = regions.get(nm);
if(regionUpdateFiles == null) {
if (regionUpdateFiles == null) {
regionUpdateFiles = new RegionUpdateFiles(nm);
regions.put(nm, regionUpdateFiles);
}
@ -98,7 +96,7 @@ public class IncrementalChangesManager {
RegionUpdate monthRu = regionUpdateFiles.monthUpdates.get(month);
while (it.hasNext()) {
RegionUpdate ru = it.next();
if(ru == null) {
if (ru == null) {
continue;
}
if (ru.obfCreated <= dateCreated ||
@ -114,58 +112,58 @@ public class IncrementalChangesManager {
}
}
}
public synchronized boolean index(File f, long dateCreated, BinaryMapIndexReader mapReader) {
String index = Algorithms.getFileNameWithoutExtension(f).toLowerCase();
if(index.length() <= 9 || index.charAt(index.length() - 9) != '_'){
if (index.length() <= 9 || index.charAt(index.length() - 9) != '_') {
return false;
}
String nm = index.substring(0, index.length() - 9);
String date = index.substring(index.length() - 9 + 1);
RegionUpdateFiles regionUpdateFiles = regions.get(nm);
if(regionUpdateFiles == null) {
if (regionUpdateFiles == null) {
regionUpdateFiles = new RegionUpdateFiles(nm);
regions.put(nm, regionUpdateFiles);
}
return regionUpdateFiles.addUpdate(date, f, dateCreated);
}
protected static String formatSize(long vl) {
return (vl * 1000 / (1 << 20l)) / 1000.0f + "";
}
public static long calculateSize(List<IncrementalUpdate> list) {
long l = 0;
for(IncrementalUpdate iu : list) {
for (IncrementalUpdate iu : list) {
l += iu.containerSize;
}
return l;
}
}
protected class RegionUpdate {
protected File file;
protected String date;
protected long obfCreated;
protected long obfCreated;
}
protected class RegionUpdateFiles {
protected String nm;
protected File mainFile;
protected long mainFileInit;
TreeMap<String, List<RegionUpdate>> dayUpdates = new TreeMap<String, List<RegionUpdate>>();
TreeMap<String, RegionUpdate> monthUpdates = new TreeMap<String, RegionUpdate>();
public RegionUpdateFiles(String nm) {
this.nm = nm;
}
public boolean addUpdate(String date, File file, long dateCreated) {
String monthYear = date.substring(0, 5);
RegionUpdate ru = new RegionUpdate();
ru.date = date;
ru.file = file;
ru.obfCreated = dateCreated;
if(date.endsWith("00")) {
if (date.endsWith("00")) {
monthUpdates.put(monthYear, ru);
} else {
List<RegionUpdate> list = dayUpdates.get(monthYear);
@ -179,22 +177,21 @@ public class IncrementalChangesManager {
}
}
public class IncrementalUpdateList {
public TreeMap<String, IncrementalUpdateGroupByMonth> updateByMonth =
public TreeMap<String, IncrementalUpdateGroupByMonth> updateByMonth =
new TreeMap<String, IncrementalUpdateGroupByMonth>();
public String errorMessage;
public RegionUpdateFiles updateFiles;
public boolean isPreferrableLimitForDayUpdates(String monthYearPart, List<IncrementalUpdate> dayUpdates) {
List<RegionUpdate> lst = updateFiles.dayUpdates.get(monthYearPart);
if(lst == null || lst.size() < 10) {
if (lst == null || lst.size() < 10) {
return true;
}
return false;
}
public List<IncrementalUpdate> getItemsForUpdate() {
Iterator<IncrementalUpdateGroupByMonth> it = updateByMonth.values().iterator();
List<IncrementalUpdate> ll = new ArrayList<IncrementalUpdate>();
@ -208,7 +205,7 @@ public class IncrementalChangesManager {
} else {
// it causes problem when person doesn't restart application for 10 days so updates stop working
// && isPreferrableLimitForDayUpdates(n.monthYearPart, n.getDayUpdates())
if (n.isDayUpdateApplicable() ) {
if (n.isDayUpdateApplicable()) {
ll.addAll(n.getDayUpdates());
} else if (n.isMonthUpdateApplicable()) {
ll.addAll(n.getMonthUpdate());
@ -234,51 +231,51 @@ public class IncrementalChangesManager {
}
}
}
protected static class IncrementalUpdateGroupByMonth {
public final String monthYearPart ;
public final String monthYearPart;
public List<IncrementalUpdate> dayUpdates = new ArrayList<IncrementalUpdate>();
public IncrementalUpdate monthUpdate;
public long calculateSizeMonthUpdates() {
return calculateSize(getMonthUpdate());
}
public long calculateSizeDayUpdates() {
return calculateSize(getDayUpdates());
}
public boolean isMonthUpdateApplicable() {
return monthUpdate != null;
}
public boolean isDayUpdateApplicable() {
boolean inLimits = dayUpdates.size() > 0 && dayUpdates.size() < 4;
if(!inLimits) {
if (!inLimits) {
return false;
}
return true;
}
public List<IncrementalUpdate> getMonthUpdate() {
List<IncrementalUpdate> ll = new ArrayList<IncrementalUpdate>();
if(monthUpdate == null) {
if (monthUpdate == null) {
return ll;
}
ll.add(monthUpdate);
for(IncrementalUpdate iu : dayUpdates) {
if(iu.timestamp > monthUpdate.timestamp) {
for (IncrementalUpdate iu : dayUpdates) {
if (iu.timestamp > monthUpdate.timestamp) {
ll.add(iu);
}
}
return ll;
}
public List<IncrementalUpdate> getDayUpdates() {
return dayUpdates;
}
public IncrementalUpdateGroupByMonth(String monthYearPart ) {
public IncrementalUpdateGroupByMonth(String monthYearPart) {
this.monthYearPart = monthYearPart;
}
}
@ -300,7 +297,7 @@ public class IncrementalChangesManager {
return "Update " + fileName + " " + sizeText + " MB " + date + ", timestamp: " + timestamp;
}
}
private List<IncrementalUpdate> getIncrementalUpdates(String file, long timestamp) throws IOException,
XmlPullParserException {
String url = URL + "?aosmc=true&timestamp=" + timestamp + "&file=" + URLEncoder.encode(file);
@ -314,7 +311,7 @@ public class IncrementalChangesManager {
int elements = 0;
while (parser.next() != XmlPullParser.END_DOCUMENT) {
if (parser.getEventType() == XmlPullParser.START_TAG) {
elements ++;
elements++;
if (parser.getName().equals("update")) {
IncrementalUpdate dt = new IncrementalUpdate();
dt.date = parser.getAttributeValue("", "updateDate");
@ -332,21 +329,19 @@ public class IncrementalChangesManager {
conn.disconnect();
return lst;
}
public IncrementalUpdateList getUpdatesByMonth(String fileName) {
IncrementalUpdateList iul = new IncrementalUpdateList();
RegionUpdateFiles ruf = regions.get(fileName.toLowerCase());
iul.updateFiles = ruf;
if(ruf == null) {
if (ruf == null) {
iul.errorMessage = resourceManager.getContext().getString(R.string.no_updates_available);
return iul;
}
long timestamp = getTimestamp(ruf);
try {
List<IncrementalUpdate> lst = getIncrementalUpdates(fileName, timestamp);
for(IncrementalUpdate iu : lst) {
for (IncrementalUpdate iu : lst) {
iul.addUpdate(iu);
}
} catch (Exception e) {
@ -357,9 +352,9 @@ public class IncrementalChangesManager {
return iul;
}
public long getUpdatesSize(String fileName){
public long getUpdatesSize(String fileName) {
RegionUpdateFiles ruf = regions.get(fileName.toLowerCase());
if(ruf == null) {
if (ruf == null) {
return 0;
}
long size = 0;
@ -374,9 +369,9 @@ public class IncrementalChangesManager {
return size;
}
public void deleteUpdates(String fileName){
public void deleteUpdates(String fileName) {
RegionUpdateFiles ruf = regions.get(fileName.toLowerCase());
if(ruf == null) {
if (ruf == null) {
return;
}
for (List<RegionUpdate> regionUpdates : ruf.dayUpdates.values()) {
@ -399,7 +394,7 @@ public class IncrementalChangesManager {
public long getTimestamp(String fileName) {
RegionUpdateFiles ruf = regions.get(fileName.toLowerCase());
if(ruf == null) {
if (ruf == null) {
return System.currentTimeMillis();
}
return getTimestamp(ruf);
@ -407,7 +402,7 @@ public class IncrementalChangesManager {
public long getMapTimestamp(String fileName) {
RegionUpdateFiles ruf = regions.get(fileName.toLowerCase());
if(ruf == null) {
if (ruf == null) {
return System.currentTimeMillis();
}
return ruf.mainFileInit;

View file

@ -41,6 +41,7 @@ import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.download.DownloadOsmandIndexesHelper;
import net.osmand.plus.download.DownloadOsmandIndexesHelper.AssetEntry;
import net.osmand.plus.download.SrtmDownloadItem;
import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.render.MapRenderRepositories;
import net.osmand.plus.render.NativeOsmandLibrary;
@ -78,11 +79,11 @@ import java.util.concurrent.ConcurrentHashMap;
import static net.osmand.IndexConstants.VOICE_INDEX_DIR;
/**
* Resource manager is responsible to work with all resources
* Resource manager is responsible to work with all resources
* that could consume memory (especially with file resources).
* Such as indexes, tiles.
* Also it is responsible to create cache for that resources if they
* can't be loaded fully into memory & clear them on request.
* can't be loaded fully into memory & clear them on request.
*/
public class ResourceManager {
@ -91,10 +92,10 @@ public class ResourceManager {
public static final String DEFAULT_WIKIVOYAGE_TRAVEL_OBF = "Default_wikivoyage.travel.obf";
private static final Log log = PlatformUtil.getLog(ResourceManager.class);
protected static ResourceManager manager = null;
protected File dirWithTiles ;
protected File dirWithTiles;
private List<TilesCache> tilesCacheList = new ArrayList<>();
private BitmapTilesCache bitmapTilesCache;
@ -115,21 +116,22 @@ public class ResourceManager {
STREET_LOOKUP,
TRANSPORT,
ADDRESS,
QUICK_SEARCH,
QUICK_SEARCH,
ROUTING,
TRANSPORT_ROUTING
}
public static class BinaryMapReaderResource {
private BinaryMapIndexReader initialReader;
private File filename;
private List<BinaryMapIndexReader> readers = new ArrayList<>(BinaryMapReaderResourceType.values().length);
private boolean useForRouting;
private boolean useForPublicTransport;
public BinaryMapReaderResource(File f, BinaryMapIndexReader initialReader) {
this.filename = f;
this.initialReader = initialReader;
while(readers.size() < BinaryMapReaderResourceType.values().length) {
while (readers.size() < BinaryMapReaderResourceType.values().length) {
readers.add(null);
}
}
@ -173,7 +175,7 @@ public class ResourceManager {
}
initialReader = null;
}
public boolean isClosed() {
return initialReader == null;
}
@ -189,7 +191,7 @@ public class ResourceManager {
public void setUseForRouting(boolean useForRouting) {
this.useForRouting = useForRouting;
}
public boolean isUseForRouting() {
return useForRouting;
}
@ -202,34 +204,32 @@ public class ResourceManager {
this.useForPublicTransport = useForPublicTransport;
}
}
protected final Map<String, BinaryMapReaderResource> fileReaders = new ConcurrentHashMap<String, BinaryMapReaderResource>();
private final Map<String, RegionAddressRepository> addressMap = new ConcurrentHashMap<String, RegionAddressRepository>();
protected final Map<String, AmenityIndexRepository> amenityRepositories = new ConcurrentHashMap<String, AmenityIndexRepository>();
// protected final Map<String, BinaryMapIndexReader> routingMapFiles = new ConcurrentHashMap<String, BinaryMapIndexReader>();
protected final Map<String, AmenityIndexRepository> amenityRepositories = new ConcurrentHashMap<String, AmenityIndexRepository>();
// protected final Map<String, BinaryMapIndexReader> routingMapFiles = new ConcurrentHashMap<String, BinaryMapIndexReader>();
protected final Map<String, BinaryMapReaderResource> transportRepositories = new ConcurrentHashMap<String, BinaryMapReaderResource>();
protected final Map<String, BinaryMapReaderResource> travelRepositories = new ConcurrentHashMap<String, BinaryMapReaderResource>();
protected final Map<String, String> indexFileNames = new ConcurrentHashMap<String, String>();
protected final Map<String, String> basemapFileNames = new ConcurrentHashMap<String, String>();
protected final IncrementalChangesManager changesManager = new IncrementalChangesManager(this);
protected final MapRenderRepositories renderer;
protected final MapTileDownloader tileDownloader;
public final AsyncLoadingThread asyncLoadingThread = new AsyncLoadingThread(this);
private HandlerThread renderingBufferImageThread;
protected boolean internetIsNotAccessible = false;
private boolean depthContours;
public ResourceManager(OsmandApplication context) {
this.context = context;
this.renderer = new MapRenderRepositories(context);
@ -271,7 +271,7 @@ public class ResourceManager {
public MapTileDownloader getMapTileDownloader() {
return tileDownloader;
}
public HandlerThread getRenderingBufferImageThread() {
return renderingBufferImageThread;
}
@ -293,17 +293,17 @@ public class ResourceManager {
// ".nomedia" indicates there are no pictures and no music to list in this dir for the Gallery app
try {
context.getAppPath(".nomedia").createNewFile(); //$NON-NLS-1$
} catch( Exception e ) {
} catch (Exception e) {
}
for (TilesCache tilesCache : tilesCacheList) {
tilesCache.setDirWithTiles(dirWithTiles);
}
}
public java.text.DateFormat getDateFormat() {
return DateFormat.getDateFormat(context);
}
public OsmandApplication getContext() {
return context;
}
@ -323,7 +323,7 @@ public class ResourceManager {
return null;
}
public synchronized void tileDownloaded(DownloadRequest request){
public synchronized void tileDownloaded(DownloadRequest request) {
if (request instanceof TileLoadDownloadRequest) {
TileLoadDownloadRequest req = ((TileLoadDownloadRequest) request);
TilesCache cache = getTilesCache(req.tileSource);
@ -332,13 +332,13 @@ public class ResourceManager {
}
}
}
public synchronized boolean tileExistOnFileSystem(String file, ITileSource map, int x, int y, int zoom) {
TilesCache cache = getTilesCache(map);
return cache != null && cache.tileExistOnFileSystem(file, map, x, y, zoom);
}
public void clearTileForMap(String file, ITileSource map, int x, int y, int zoom){
public void clearTileForMap(String file, ITileSource map, int x, int y, int zoom) {
TilesCache cache = getTilesCache(map);
if (cache != null) {
cache.getTileForMap(file, map, x, y, zoom, true, false, true, true);
@ -376,7 +376,7 @@ public class ResourceManager {
////////////////////////////////////////////// Working with indexes ////////////////////////////////////////////////
public List<String> reloadIndexesOnStart(AppInitializer progress, List<String> warnings){
public List<String> reloadIndexesOnStart(AppInitializer progress, List<String> warnings) {
close();
// check we have some assets to copy to sdcard
warnings.addAll(checkAssets(progress, false));
@ -429,7 +429,7 @@ public class ResourceManager {
return warnings;
}
public List<String> indexFontFiles(IProgress progress){
public List<String> indexFontFiles(IProgress progress) {
File file = context.getAppPath(IndexConstants.FONT_INDEX_DIR);
file.mkdirs();
List<String> warnings = new ArrayList<String>();
@ -473,10 +473,10 @@ public class ResourceManager {
log.error("Error while loading tts files from assets", e);
}
}
public List<String> checkAssets(IProgress progress, boolean forceUpdate) {
String fv = Version.getFullVersion(context);
if(context.getAppInitializer().isAppVersionChanged()) {
if (context.getAppInitializer().isAppVersionChanged()) {
copyMissingJSAssets();
}
if (!fv.equalsIgnoreCase(context.getSettings().PREVIOUS_INSTALLED_VERSION.get()) || forceUpdate) {
@ -509,7 +509,7 @@ public class ResourceManager {
}
return Collections.emptyList();
}
private void copyRegionsBoundaries() {
try {
File file = context.getAppPath("regions.ocbf");
@ -522,7 +522,7 @@ public class ResourceManager {
log.error(e.getMessage(), e);
}
}
private void copyPoiTypes() {
try {
File file = context.getAppPath(IndexConstants.SETTINGS_DIR + "poi_types.xml");
@ -540,6 +540,7 @@ public class ResourceManager {
private final static String ASSET_COPY_MODE__overwriteOnlyIfExists = "overwriteOnlyIfExists";
private final static String ASSET_COPY_MODE__alwaysOverwriteOrCopy = "alwaysOverwriteOrCopy";
private final static String ASSET_COPY_MODE__copyOnlyIfDoesNotExist = "copyOnlyIfDoesNotExist";
private void unpackBundledAssets(AssetManager assetManager, File appDataDir, IProgress progress, boolean isFirstInstall) throws IOException, XmlPullParserException {
List<AssetEntry> assetEntries = DownloadOsmandIndexesHelper.getBundledAssets(assetManager);
for (AssetEntry asset : assetEntries) {
@ -581,7 +582,7 @@ public class ResourceManager {
}
public static void copyAssets(AssetManager assetManager, String assetName, File file) throws IOException {
if(file.exists()){
if (file.exists()) {
Algorithms.removeAllFiles(file);
}
file.getParentFile().mkdirs();
@ -593,9 +594,9 @@ public class ResourceManager {
}
private List<File> collectFiles(File dir, String ext, List<File> files) {
if(dir.exists() && dir.canRead()) {
if (dir.exists() && dir.canRead()) {
File[] lf = dir.listFiles();
if(lf == null || lf.length == 0) {
if (lf == null || lf.length == 0) {
return files;
}
for (File f : lf) {
@ -606,12 +607,10 @@ public class ResourceManager {
}
return files;
}
private void renameRoadsFiles(ArrayList<File> files, File roadsPath) {
Iterator<File> it = files.iterator();
while(it.hasNext()) {
while (it.hasNext()) {
File f = it.next();
if (f.getName().endsWith("-roads" + IndexConstants.BINARY_MAP_INDEX_EXT)) {
f.renameTo(new File(roadsPath, f.getName().replace("-roads" + IndexConstants.BINARY_MAP_INDEX_EXT,
@ -632,7 +631,7 @@ public class ResourceManager {
File appPath = context.getAppPath(null);
File roadsPath = context.getAppPath(IndexConstants.ROADS_INDEX_DIR);
roadsPath.mkdirs();
collectFiles(appPath, IndexConstants.BINARY_MAP_INDEX_EXT, files);
renameRoadsFiles(files, roadsPath);
collectFiles(roadsPath, IndexConstants.BINARY_MAP_INDEX_EXT, files);
@ -645,7 +644,7 @@ public class ResourceManager {
if (OsmandPlugin.getEnabledPlugin(SRTMPlugin.class) != null || InAppPurchaseHelper.isContourLinesPurchased(context)) {
collectFiles(context.getAppPath(IndexConstants.SRTM_INDEX_DIR), IndexConstants.BINARY_MAP_INDEX_EXT, files);
}
changesManager.collectChangesFiles(context.getAppPath(IndexConstants.LIVE_INDEX_DIR), IndexConstants.BINARY_MAP_INDEX_EXT, files);
Collections.sort(files, Algorithms.getFileVersionComparator());
@ -703,7 +702,7 @@ public class ResourceManager {
log.error(String.format("File %s could not be read", f.getName()), e);
}
boolean wikiMap = (f.getName().contains("_wiki") || f.getName().contains(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT));
boolean srtmMap = f.getName().contains(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT);
boolean srtmMap = SrtmDownloadItem.containsSrtmExtension(f.getName());
if (mapReader == null || (!Version.isPaidVersion(context) && wikiMap && !f.getName().equals(DEFAULT_WIKIVOYAGE_TRAVEL_OBF))) {
warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$
} else {
@ -714,9 +713,9 @@ public class ResourceManager {
if (dateCreated == 0) {
dateCreated = f.lastModified();
}
if(f.getParentFile().getName().equals(liveDir.getName())) {
if (f.getParentFile().getName().equals(liveDir.getName())) {
boolean toUse = changesManager.index(f, dateCreated, mapReader);
if(!toUse) {
if (!toUse) {
try {
mapReader.close();
} catch (IOException e) {
@ -724,7 +723,7 @@ public class ResourceManager {
}
continue;
}
} else if(!wikiMap && !srtmMap) {
} else if (!wikiMap && !srtmMap) {
changesManager.indexMainMap(f, dateCreated);
}
indexFileNames.put(f.getName(), dateFormat.format(dateCreated)); //$NON-NLS-1$
@ -733,7 +732,7 @@ public class ResourceManager {
}
renderer.initializeNewResource(progress, f, mapReader);
BinaryMapReaderResource resource = new BinaryMapReaderResource(f, mapReader);
if (collectTravelFiles(resource)){
if (collectTravelFiles(resource)) {
//travel files are indexed
continue;
}
@ -746,7 +745,7 @@ public class ResourceManager {
transportRepositories.put(f.getName(), resource);
}
// disable osmc for routing temporarily due to some bugs
if (mapReader.containsRouteData() && (!f.getParentFile().equals(liveDir) ||
if (mapReader.containsRouteData() && (!f.getParentFile().equals(liveDir) ||
context.getSettings().USE_OSM_LIVE_FOR_ROUTING.get())) {
resource.setUseForRouting(true);
}
@ -789,7 +788,7 @@ public class ResourceManager {
}
}
Iterator<Entry<PoiCategory, Map<String, PoiType>>> it = toAddPoiTypes.entrySet().iterator();
while(it.hasNext()) {
while (it.hasNext()) {
Entry<PoiCategory, Map<String, PoiType>> next = it.next();
PoiCategory category = next.getKey();
category.addExtraPoiTypes(next.getValue());
@ -839,7 +838,7 @@ public class ResourceManager {
}
private boolean collectTravelFiles(BinaryMapReaderResource resource) {
if (resource.getFileName().contains(IndexConstants.BINARY_TRAVEL_GUIDE_MAP_INDEX_EXT)){
if (resource.getFileName().contains(IndexConstants.BINARY_TRAVEL_GUIDE_MAP_INDEX_EXT)) {
travelRepositories.put(resource.getFileName(), resource);
return true;
}
@ -855,7 +854,7 @@ public class ResourceManager {
}
}
}
////////////////////////////////////////////// Working with amenities ////////////////////////////////////////////////
public List<AmenityIndexRepository> getAmenityRepositories() {
@ -872,7 +871,7 @@ public class ResourceManager {
}
public List<Amenity> searchAmenities(SearchPoiTypeFilter filter,
double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, final ResultMatcher<Amenity> matcher) {
double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, final ResultMatcher<Amenity> matcher) {
final List<Amenity> amenities = new ArrayList<Amenity>();
searchAmenitiesInProgress = true;
try {
@ -901,8 +900,8 @@ public class ResourceManager {
return amenities;
}
public List<Amenity> searchAmenitiesOnThePath(List<Location> locations, double radius, SearchPoiTypeFilter filter,
ResultMatcher<Amenity> matcher) {
public List<Amenity> searchAmenitiesOnThePath(List<Location> locations, double radius, SearchPoiTypeFilter filter,
ResultMatcher<Amenity> matcher) {
searchAmenitiesInProgress = true;
final List<Amenity> amenities = new ArrayList<Amenity>();
try {
@ -921,9 +920,9 @@ public class ResourceManager {
if (!filter.isEmpty()) {
for (AmenityIndexRepository index : getAmenityRepositories()) {
if (index.checkContainsInt(
MapUtils.get31TileNumberY(topLatitude),
MapUtils.get31TileNumberX(leftLongitude),
MapUtils.get31TileNumberY(bottomLatitude),
MapUtils.get31TileNumberY(topLatitude),
MapUtils.get31TileNumberX(leftLongitude),
MapUtils.get31TileNumberY(bottomLatitude),
MapUtils.get31TileNumberX(rightLongitude))) {
repos.add(index);
}
@ -931,7 +930,7 @@ public class ResourceManager {
if (!repos.isEmpty()) {
for (AmenityIndexRepository r : repos) {
List<Amenity> res = r.searchAmenitiesOnThePath(locations, radius, filter, matcher);
if(res != null) {
if (res != null) {
amenities.addAll(res);
}
}
@ -943,12 +942,11 @@ public class ResourceManager {
}
return amenities;
}
public boolean containsAmenityRepositoryToSearch(boolean searchByName){
public boolean containsAmenityRepositoryToSearch(boolean searchByName) {
for (AmenityIndexRepository index : getAmenityRepositories()) {
if(searchByName){
if(index instanceof AmenityIndexRepositoryBinary){
if (searchByName) {
if (index instanceof AmenityIndexRepositoryBinary) {
return true;
}
} else {
@ -957,10 +955,10 @@ public class ResourceManager {
}
return false;
}
public List<Amenity> searchAmenitiesByName(String searchQuery,
double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude,
double lat, double lon, ResultMatcher<Amenity> matcher) {
double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude,
double lat, double lon, ResultMatcher<Amenity> matcher) {
List<Amenity> amenities = new ArrayList<Amenity>();
List<AmenityIndexRepositoryBinary> list = new ArrayList<AmenityIndexRepositoryBinary>();
int left = MapUtils.get31TileNumberX(leftLongitude);
@ -973,16 +971,16 @@ public class ResourceManager {
}
if (index instanceof AmenityIndexRepositoryBinary) {
if (index.checkContainsInt(top, left, bottom, right)) {
if(index.checkContains(lat, lon)){
if (index.checkContains(lat, lon)) {
list.add(0, (AmenityIndexRepositoryBinary) index);
} else {
list.add((AmenityIndexRepositoryBinary) index);
}
}
}
}
// Not using boundares results in very slow initial search if user has many maps installed
// int left = 0;
// int top = 0;
@ -1000,7 +998,7 @@ public class ResourceManager {
return amenities;
}
public Map<PoiCategory, List<String>> searchAmenityCategoriesByName(String searchQuery, double lat, double lon) {
Map<PoiCategory, List<String>> map = new LinkedHashMap<PoiCategory, List<String>>();
for (AmenityIndexRepository index : getAmenityRepositories()) {
@ -1016,17 +1014,17 @@ public class ResourceManager {
public AmenityIndexRepositoryBinary getAmenityRepositoryByFileName(String filename) {
return (AmenityIndexRepositoryBinary) amenityRepositories.get(filename);
}
////////////////////////////////////////////// Working with address ///////////////////////////////////////////
public RegionAddressRepository getRegionRepository(String name){
public RegionAddressRepository getRegionRepository(String name) {
return addressMap.get(name);
}
public Collection<RegionAddressRepository> getAddressRepositories(){
public Collection<RegionAddressRepository> getAddressRepositories() {
return addressMap.values();
}
public Collection<BinaryMapReaderResource> getFileReaders() {
List<String> fileNames = new ArrayList<>(fileReaders.keySet());
Collections.sort(fileNames, Algorithms.getStringVersionComparator());
@ -1039,8 +1037,7 @@ public class ResourceManager {
}
return res;
}
////////////////////////////////////////////// Working with transport ////////////////////////////////////////////////
private List<BinaryMapIndexReader> getTransportRepositories(double topLat, double leftLon, double bottomLat, double rightLon) {
@ -1059,7 +1056,7 @@ public class ResourceManager {
public List<TransportStop> searchTransportSync(double topLat, double leftLon, double bottomLat, double rightLon,
ResultMatcher<TransportStop> matcher) throws IOException {
ResultMatcher<TransportStop> matcher) throws IOException {
TransportStopsRouteReader readers =
new TransportStopsRouteReader(getTransportRepositories(topLat, leftLon, bottomLat, rightLon));
List<TransportStop> stops = new ArrayList<>();
@ -1076,7 +1073,7 @@ public class ResourceManager {
public List<TransportRoute> getRoutesForStop(TransportStop stop) {
List<TransportRoute> rts = stop.getRoutes();
if(rts != null) {
if (rts != null) {
return rts;
}
return Collections.emptyList();
@ -1086,26 +1083,26 @@ public class ResourceManager {
public boolean updateRenderedMapNeeded(RotatedTileBox rotatedTileBox, DrawSettings drawSettings) {
return renderer.updateMapIsNeeded(rotatedTileBox, drawSettings);
}
public void updateRendererMap(RotatedTileBox rotatedTileBox, OnMapLoadedListener mapLoadedListener){
public void updateRendererMap(RotatedTileBox rotatedTileBox, OnMapLoadedListener mapLoadedListener) {
renderer.interruptLoadingMap();
asyncLoadingThread.requestToLoadMap(new MapLoadRequest(rotatedTileBox, mapLoadedListener));
}
public void interruptRendering(){
public void interruptRendering() {
renderer.interruptLoadingMap();
}
public boolean isSearchAmenitiesInProgress() {
return searchAmenitiesInProgress;
}
public MapRenderRepositories getRenderer() {
return renderer;
}
////////////////////////////////////////////// Closing methods ////////////////////////////////////////////////
public void closeFile(String fileName) {
amenityRepositories.remove(fileName);
addressMap.remove(fileName);
@ -1114,12 +1111,12 @@ public class ResourceManager {
travelRepositories.remove(fileName);
renderer.closeConnection(fileName);
BinaryMapReaderResource resource = fileReaders.remove(fileName);
if(resource != null) {
if (resource != null) {
resource.close();
}
}
}
public synchronized void close(){
public synchronized void close() {
for (TilesCache tc : tilesCacheList) {
tc.close();
}
@ -1130,7 +1127,7 @@ public class ResourceManager {
travelRepositories.clear();
addressMap.clear();
amenityRepositories.clear();
for(BinaryMapReaderResource res : fileReaders.values()) {
for (BinaryMapReaderResource res : fileReaders.values()) {
res.close();
}
fileReaders.clear();
@ -1154,7 +1151,7 @@ public class ResourceManager {
Collection<BinaryMapReaderResource> fileReaders = getFileReaders();
List<BinaryMapIndexReader> readers = new ArrayList<>(fileReaders.size());
for (BinaryMapReaderResource r : fileReaders) {
if (r.isUseForPublicTransport()) {
if (r.isUseForPublicTransport()) {
BinaryMapIndexReader reader = r.getReader(BinaryMapReaderResourceType.TRANSPORT_ROUTING);
if (reader != null) {
readers.add(reader);
@ -1182,9 +1179,8 @@ public class ResourceManager {
public Map<String, String> getIndexFileNames() {
return new LinkedHashMap<String, String>(indexFileNames);
}
public boolean containsBasemap(){
public boolean containsBasemap() {
return !basemapFileNames.isEmpty();
}
@ -1218,13 +1214,13 @@ public class ResourceManager {
}
return map;
}
public synchronized void reloadTilesFromFS() {
for (TilesCache tc : tilesCacheList) {
tc.tilesOnFS.clear();
}
}
/// On low memory method ///
public void onLowMemory() {
log.info("On low memory");
@ -1233,10 +1229,10 @@ public class ResourceManager {
r.clearCache();
}
renderer.clearCache();
System.gc();
}
public GeoidAltitudeCorrection getGeoidAltitudeCorrection() {
return geoidAltitudeCorrection;
}
@ -1251,7 +1247,7 @@ public class ResourceManager {
tc.clearTiles();
}
}
public IncrementalChangesManager getChangesManager() {
return changesManager;
}

View file

@ -32,9 +32,10 @@ import net.osmand.plus.settings.fragments.HeaderUiAdapter;
import net.osmand.plus.track.AppearanceViewHolder;
import net.osmand.plus.track.ColorsCard;
import net.osmand.plus.track.CustomColorBottomSheet.ColorPickerListener;
import net.osmand.plus.widgets.MultiStateToggleButton;
import net.osmand.plus.widgets.MultiStateToggleButton.OnRadioItemClickListener;
import net.osmand.plus.widgets.MultiStateToggleButton.RadioItem;
import net.osmand.plus.widgets.multistatetoggle.RadioItem;
import net.osmand.plus.widgets.multistatetoggle.RadioItem.OnRadioItemClickListener;
import net.osmand.plus.widgets.multistatetoggle.TextToggleButton;
import net.osmand.plus.widgets.multistatetoggle.TextToggleButton.TextRadioItem;
import java.util.ArrayList;
import java.util.Arrays;
@ -134,17 +135,17 @@ public class RouteLineColorCard extends BaseCard implements CardListener, ColorP
}
private void setupRadioGroup(LinearLayout buttonsContainer) {
RadioItem day = createMapThemeButton(false);
RadioItem night = createMapThemeButton(true);
TextRadioItem day = createMapThemeButton(false);
TextRadioItem night = createMapThemeButton(true);
MultiStateToggleButton radioGroup = new MultiStateToggleButton(app, buttonsContainer, nightMode);
TextToggleButton radioGroup = new TextToggleButton(app, buttonsContainer, nightMode);
radioGroup.setItems(day, night);
radioGroup.setSelectedItem(!isNightMap() ? day : night);
}
private RadioItem createMapThemeButton(final boolean isNight) {
RadioItem item = new RadioItem(app.getString(!isNight ? DAY_TITLE_ID : NIGHT_TITLE_ID));
private TextRadioItem createMapThemeButton(final boolean isNight) {
TextRadioItem item = new TextRadioItem(app.getString(!isNight ? DAY_TITLE_ID : NIGHT_TITLE_ID));
item.setOnClickListener(new OnRadioItemClickListener() {
@Override
public boolean onRadioItemClick(RadioItem radioItem, View view) {

View file

@ -542,7 +542,8 @@ public class QuickSearchCustomPoiFragment extends DialogFragment implements OnFi
titleView.setText(textString);
Set<String> subtypes = filter.getAcceptedSubtypes(category);
if (categorySelected) {
if (subtypes == null) {
LinkedHashSet<String> poiTypes = filter.getAcceptedTypes().get(category);
if (subtypes == null || (poiTypes != null && category.getPoiTypes().size() == poiTypes.size())) {
descView.setText(getString(R.string.shared_string_all));
} else {
StringBuilder sb = new StringBuilder();

View file

@ -101,7 +101,7 @@ public class QuickSearchSubCategoriesFragment extends BaseOsmAndDialogFragment {
updateAddBtnVisibility();
}
});
if (selectAll || acceptedCategories == null) {
if (selectAll || acceptedCategories == null || poiCategory.getPoiTypes().size() == acceptedCategories.size()) {
adapter.setSelectedItems(poiTypeList);
selectAll = true;
} else {

View file

@ -7,6 +7,7 @@ import androidx.annotation.Nullable;
import net.osmand.IndexConstants;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.download.SrtmDownloadItem;
import net.osmand.util.Algorithms;
import org.json.JSONException;
@ -92,7 +93,7 @@ public class FileSettingsItem extends StreamSettingsItem {
case OTHER:
break;
case SRTM_MAP:
if (name.endsWith(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)) {
if (SrtmDownloadItem.isSrtmFile(name)) {
return subtype;
}
break;
@ -257,6 +258,8 @@ public class FileSettingsItem extends StreamSettingsItem {
prefix = oldPath.substring(0, oldPath.lastIndexOf(IndexConstants.BINARY_WIKI_MAP_INDEX_EXT));
} else if (oldPath.endsWith(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)) {
prefix = oldPath.substring(0, oldPath.lastIndexOf(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT));
} else if (oldPath.endsWith(IndexConstants.BINARY_SRTM_FEET_MAP_INDEX_EXT)) {
prefix = oldPath.substring(0, oldPath.lastIndexOf(IndexConstants.BINARY_SRTM_FEET_MAP_INDEX_EXT));
} else if (oldPath.endsWith(IndexConstants.BINARY_ROAD_MAP_INDEX_EXT)) {
prefix = oldPath.substring(0, oldPath.lastIndexOf(IndexConstants.BINARY_ROAD_MAP_INDEX_EXT));
} else {

View file

@ -10,6 +10,7 @@ import com.google.gson.reflect.TypeToken;
import net.osmand.osm.MapPoiTypes;
import net.osmand.osm.PoiCategory;
import net.osmand.osm.PoiType;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.poi.PoiUIFilter;
@ -148,7 +149,21 @@ public class PoiUiFiltersSettingsItem extends CollectionSettingsItem<PoiUIFilter
JSONObject jsonObject = new JSONObject();
jsonObject.put("name", filter.getName());
jsonObject.put("filterId", filter.getFilterId());
jsonObject.put("acceptedTypes", gson.toJson(filter.getAcceptedTypes(), type));
Map<PoiCategory, LinkedHashSet<String>> acceptedTypes = filter.getAcceptedTypes();
for (PoiCategory category : acceptedTypes.keySet()) {
LinkedHashSet<String> poiTypes = acceptedTypes.get(category);
if (poiTypes == null) {
poiTypes = new LinkedHashSet<>();
List<PoiType> types = category.getPoiTypes();
for (PoiType poiType : types) {
poiTypes.add(poiType.getKeyName());
}
acceptedTypes.put(category, poiTypes);
}
}
jsonObject.put("acceptedTypes", gson.toJson(acceptedTypes, type));
jsonArray.put(jsonObject);
}
json.put("items", jsonArray);

View file

@ -200,7 +200,7 @@ public class DataStorageHelper {
terrainMemory = MemoryItem.builder()
.setKey(TERRAIN_MEMORY)
.setExtensions(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)
.setExtensions(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT, IndexConstants.BINARY_SRTM_FEET_MAP_INDEX_EXT)
.setDirectories(
createDirectory(SRTM_INDEX_DIR, true, EXTENSIONS, true),
createDirectory(TILES_INDEX_DIR, false, PREFIX, false))
@ -323,7 +323,7 @@ public class DataStorageHelper {
public interface UpdateMemoryInfoUIAdapter {
void onMemoryInfoUpdate();
void onFinishUpdating(String tag);
}

Some files were not shown because too many files have changed in this diff Show more