Merge branch 'master' into refactor_plan_route_approx

This commit is contained in:
max-klaus 2020-10-25 18:46:31 +03:00 committed by GitHub
commit 80f3101ba9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
156 changed files with 6730 additions and 5850 deletions

View file

@ -873,4 +873,14 @@ interface IOsmAndAidlInterface {
boolean setMapMargins(in MapMarginsParams params);
boolean exportProfile(in ExportProfileParams params);
/**
* Is any fragment open.
*/
boolean isFragmentOpen();
/**
* Is contect menu open.
*/
boolean isMenuOpen();
}

View file

@ -3,18 +3,31 @@ package net.osmand.aidlapi.customization;
import android.os.Bundle;
import android.os.Parcel;
import androidx.annotation.Nullable;
import net.osmand.aidlapi.AidlParams;
import java.util.ArrayList;
import java.util.List;
public class MapMarginsParams extends AidlParams {
private String appModeKey;
public static final String LEFT_MARGIN_KEY = "leftMargin";
public static final String TOP_MARGIN_KEY = "topMargin";
public static final String RIGHT_MARGIN_KEY = "rightMargin";
public static final String BOTTOM_MARGIN_KEY = "bottomMargin";
public static final String APP_MODES_KEYS_KEY = "appModesKeys";
private ArrayList<String> appModesKeys = new ArrayList<>();
private int leftMargin;
private int topMargin;
private int rightMargin;
private int bottomMargin;
public MapMarginsParams(String appModeKey, int leftMargin, int topMargin, int rightMargin, int bottomMargin) {
this.appModeKey = appModeKey;
public MapMarginsParams(int leftMargin, int topMargin, int rightMargin, int bottomMargin,
@Nullable List<String> appModesKeys) {
if (appModesKeys != null) {
this.appModesKeys.addAll(appModesKeys);
}
this.leftMargin = leftMargin;
this.topMargin = topMargin;
this.rightMargin = rightMargin;
@ -37,8 +50,8 @@ public class MapMarginsParams extends AidlParams {
}
};
public String getAppModeKey() {
return appModeKey;
public List<String> getAppModesKeys() {
return appModesKeys;
}
public int getLeftMargin() {
@ -59,19 +72,19 @@ public class MapMarginsParams extends AidlParams {
@Override
public void writeToBundle(Bundle bundle) {
bundle.putString("appModeKey", appModeKey);
bundle.putInt("leftMargin", leftMargin);
bundle.putInt("topMargin", topMargin);
bundle.putInt("rightMargin", rightMargin);
bundle.putInt("bottomMargin", bottomMargin);
bundle.putInt(LEFT_MARGIN_KEY, leftMargin);
bundle.putInt(TOP_MARGIN_KEY, topMargin);
bundle.putInt(RIGHT_MARGIN_KEY, rightMargin);
bundle.putInt(BOTTOM_MARGIN_KEY, bottomMargin);
bundle.putStringArrayList(APP_MODES_KEYS_KEY, appModesKeys);
}
@Override
protected void readFromBundle(Bundle bundle) {
appModeKey = bundle.getString("appModeKey");
leftMargin = bundle.getInt("leftMargin");
topMargin = bundle.getInt("topMargin");
rightMargin = bundle.getInt("rightMargin");
bottomMargin = bundle.getInt("bottomMargin");
leftMargin = bundle.getInt(LEFT_MARGIN_KEY);
topMargin = bundle.getInt(TOP_MARGIN_KEY);
rightMargin = bundle.getInt(RIGHT_MARGIN_KEY);
bottomMargin = bundle.getInt(BOTTOM_MARGIN_KEY);
appModesKeys = bundle.getStringArrayList(APP_MODES_KEYS_KEY);
}
}

View file

@ -45,7 +45,7 @@ public interface IProgress {
public boolean isInterrupted() {return false;}
@Override
public boolean isIndeterminate() {return false;}
public boolean isIndeterminate() {return true;}
@Override
public void finishTask() {}

View file

@ -823,7 +823,7 @@ public class MapPoiTypes {
}
String name = keyName;
name = name.replace('_', ' ');
return Algorithms.capitalizeFirstLetterAndLowercase(name);
return Algorithms.capitalizeFirstLetter(name);
}
public boolean isRegisteredType(PoiCategory t) {

View file

@ -41,7 +41,7 @@ public class RenderingRule {
public void init(Map<String, String> attributes) {
ArrayList<RenderingRuleProperty> props = new ArrayList<RenderingRuleProperty>(attributes.size());
intProperties = new int[attributes.size()];
floatProperties = null;
floatProperties = new float[attributes.size()];
attributesRef = null;
int i = 0;
Iterator<Entry<String, String>> it = attributes.entrySet().iterator();
@ -58,14 +58,13 @@ public class RenderingRule {
attributesRef[i] = storage.getRenderingAttributeRule(vl.substring(1));
} else if (property.isString()) {
intProperties[i] = storage.getDictionaryValue(vl);
} else if (property.isFloat()) {
if (floatProperties == null) {
// lazy creates
floatProperties = new float[attributes.size()];
}
floatProperties[i] = property.parseFloatValue(vl);
intProperties[i] = property.parseIntValue(vl);
} else {
float floatVal = property.parseFloatValue(vl);
// if (floatProperties == null && floatVal != 0) {
// // lazy creates
// floatProperties = new float[attributes.size()];
floatProperties[i] = floatVal;
// }
intProperties[i] = property.parseIntValue(vl);
}
i++;
@ -95,7 +94,7 @@ public class RenderingRule {
public float getFloatPropertyValue(String property) {
int i = getPropertyIndex(property);
if(i >= 0 && floatProperties != null){
if (i >= 0) {
return floatProperties[i];
}
return 0;

View file

@ -155,12 +155,7 @@ public class RenderingRuleProperty {
try {
int colon = value.indexOf(':');
if(colon != -1) {
int c = 0;
if(colon > 0) {
c += (int) Float.parseFloat(value.substring(0, colon));
}
c += (int) Float.parseFloat(value.substring(colon + 1));
return c;
return (int) Float.parseFloat(value.substring(colon + 1));
}
return (int) Float.parseFloat(value);
} catch (NumberFormatException e) {
@ -190,30 +185,35 @@ public class RenderingRuleProperty {
} catch (NumberFormatException e) {
log.error("Rendering parse " + value + " in " + attrName);
}
return -1;
return 0;
} else {
return -1;
}
}
public float parseFloatValue(String value){
if(type == FLOAT_TYPE){
try {
public float parseFloatValue(String value) {
try {
if (type == FLOAT_TYPE) {
int colon = value.indexOf(':');
if(colon != -1) {
if(colon > 0) {
if (colon != -1) {
if (colon > 0) {
return Float.parseFloat(value.substring(0, colon));
}
}
return 0;
}
return Float.parseFloat(value);
} catch (NumberFormatException e) {
log.error("Rendering parse " + value + " in " + attrName);
} else if (type == INT_TYPE) {
int colon = value.indexOf(':');
if (colon != -1 && colon > 0) {
return Float.parseFloat(value.substring(0, colon));
}
return 0;
}
return -1;
} else {
return -1;
} catch (NumberFormatException e) {
log.error("Rendering parse " + value + " in " + attrName);
}
return 0;
}

View file

@ -244,8 +244,6 @@ public class RenderingRuleStorageProperties {
R_TEXT_HALO_COLOR = registerRuleInternal(RenderingRuleProperty.createOutputColorProperty(TEXT_HALO_COLOR));
R_TEXT_SIZE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(TEXT_SIZE));
R_TEXT_ORDER = registerRuleInternal(RenderingRuleProperty.createOutputIntProperty(TEXT_ORDER));
R_ICON_ORDER = registerRuleInternal(RenderingRuleProperty.createOutputIntProperty(ICON_ORDER));
R_ICON_VISIBLE_SIZE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(ICON_VISIBLE_SIZE));
R_TEXT_MIN_DISTANCE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(TEXT_MIN_DISTANCE));
R_TEXT_SHIELD = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty(TEXT_SHIELD));
@ -265,7 +263,9 @@ public class RenderingRuleStorageProperties {
R_ICON_3 = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty("icon_3"));
R_ICON_4 = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty("icon_4"));
R_ICON_5 = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty("icon_5"));
R_ICON_ORDER = registerRuleInternal(RenderingRuleProperty.createOutputIntProperty(ICON_ORDER));
R_SHIELD = registerRuleInternal(RenderingRuleProperty.createOutputStringProperty(SHIELD));
R_ICON_VISIBLE_SIZE = registerRuleInternal(RenderingRuleProperty.createOutputFloatProperty(ICON_VISIBLE_SIZE));
// polygon/way
R_COLOR = registerRuleInternal(RenderingRuleProperty.createOutputColorProperty(COLOR));

View file

@ -267,4 +267,8 @@
<string name="last_response_duration">Апошні адказ: %1$s таму</string>
<string name="duration_ago">%1$s таму</string>
<string name="shared_string_error_short">ERR</string>
<string name="send_report">Даслаць справаздачу</string>
<string name="shared_string_export">Экспартаваць</string>
<string name="logcat_buffer">Буфер logcat</string>
<string name="logcat_buffer_descr">Праверце і падзяліцеся падрабязнымі журналамі праграмы</string>
</resources>

View file

@ -269,4 +269,8 @@
<string name="last_response_duration">Sidste svar: %1$s siden</string>
<string name="duration_ago">%1$s siden</string>
<string name="shared_string_error_short">ERR</string>
<string name="shared_string_export">Eksporter</string>
<string name="logcat_buffer">Logcat-buffer</string>
<string name="logcat_buffer_descr">Kontroller og del detaljerede logfiler for programmet</string>
<string name="send_report">Send rapport</string>
</resources>

View file

@ -233,7 +233,7 @@
<string name="osmand_service_descr">OsmAnd Tracker, ekran kapalıyken arka planda çalışır.</string>
<string name="share_location">Konumu paylaş</string>
<string name="sharing_location">Konum paylaşılıyor</string>
<string name="process_service">OsmAnd Tracker servisi</string>
<string name="process_service">OsmAnd Tracker hizmeti</string>
<string name="osmand_logo">OsmAnd logosu</string>
<string name="install_osmand_dialog_message">Önce OsmAnd\'ın ücretsiz veya ücretli sürümünü yüklemeniz gerekmektedir</string>
<string name="install_osmand">OsmAnd\'ı yükle</string>

View file

@ -53,7 +53,8 @@
android:icon="@mipmap/icon" android:label="@string/app_name"
android:name="net.osmand.plus.OsmandApplication" android:configChanges="locale"
android:theme="@style/OsmandDarkTheme" android:restoreAnyVersion="true" android:largeHeap="true"
android:supportsRtl="true" android:usesCleartextTraffic="true">
android:supportsRtl="true" android:usesCleartextTraffic="true"
android:hasFragileUserData="true" android:requestLegacyExternalStorage="true">
<meta-data android:name="com.google.android.backup.api_key" android:value="AEdPqrEAAAAIqF3tNGT66etVBn_vgzpfAY1wmIzKV1Ss6Ku-2A" />
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
@ -246,6 +247,7 @@
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="content"/>
<data android:scheme="file"/>
<data android:host="*"/>
<data android:pathPattern=".*\\.obf" />
@ -261,6 +263,7 @@
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="content"/>
<data android:scheme="file"/>
<data android:host="*"/>
<data android:mimeType="*/*"/>
@ -465,6 +468,13 @@
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="osmand-oauth" />
</intent-filter>
</activity>
<receiver android:name="net.osmand.plus.audionotes.MediaRemoteControlReceiver">
@ -477,28 +487,11 @@
<activity android:name="net.osmand.plus.activities.SettingsActivity" android:label="@string/shared_string_settings" android:configChanges="keyboardHidden|orientation" />
<activity android:name="net.osmand.plus.activities.SettingsGeneralActivity" android:configChanges="keyboardHidden|orientation" />
<activity android:name="net.osmand.plus.activities.SettingsNavigationActivity" android:configChanges="keyboardHidden|orientation" />
<activity android:name="net.osmand.plus.monitoring.SettingsMonitoringActivity" android:configChanges="keyboardHidden|orientation" />
<activity android:name="net.osmand.plus.osmedit.SettingsOsmEditingActivity"
android:launchMode="singleInstance"
android:configChanges="keyboardHidden|orientation">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="osmand-oauth" />
</intent-filter>
</activity>
<activity android:name="net.osmand.plus.development.SettingsDevelopmentActivity" android:configChanges="keyboardHidden|orientation" />
<activity android:name="net.osmand.plus.audionotes.SettingsAudioVideoActivity" android:configChanges="keyboardHidden|orientation" />
<activity android:name="net.osmand.access.SettingsAccessibilityActivity" android:configChanges="keyboardHidden|orientation" />
<activity android:name="net.osmand.plus.activities.search.SearchActivity" android:label="@string/search_activity" />
<activity android:name="net.osmand.plus.activities.FavoritesListActivity" android:label="@string/favourites_list_activity" />
<activity android:name=".myplaces.FavoritesActivity" android:windowSoftInputMode="adjustPan" />
<activity android:name="net.osmand.plus.activities.TrackActivity"/>
<activity android:name="net.osmand.plus.activities.PluginsActivity" />
<activity android:name="net.osmand.plus.activities.PluginActivity" />
<activity android:name="net.osmand.plus.activities.ContributionVersionActivity" android:configChanges="keyboardHidden|orientation" android:label="@string/contribution_activity" />

View file

@ -53,7 +53,7 @@ android {
defaultConfig {
minSdkVersion System.getenv("MIN_SDK_VERSION") ? System.getenv("MIN_SDK_VERSION").toInteger() : 15
targetSdkVersion 28
targetSdkVersion 29
versionCode 390
versionCode System.getenv("APK_NUMBER_VERSION") ? System.getenv("APK_NUMBER_VERSION").toInteger() : versionCode
multiDexEnabled true
@ -331,6 +331,9 @@ task collectHelpContentsAssets(type: Copy) {
from("../../help/website/feature_articles") {
include "*.html"
}
from("../../help/website/blog_articles") {
include "osmand-3-8-released.html"
}
into "assets/feature_articles"
}

View file

@ -130,33 +130,25 @@
tools:text="@string/add_point_after"/>
</RelativeLayout>
<View
<LinearLayout
android:id="@+id/additional_info_container"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone" >
<FrameLayout
android:id="@+id/points_list_container"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_points_list_container_height"
android:background="@color/activity_background_color_dark"
android:visibility="gone">
<include layout="@layout/custom_radio_buttons" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/measure_points_recycler_view"
<View
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="@dimen/content_padding_small" />
<include layout="@layout/card_bottom_divider"/>
<androidx.appcompat.widget.AppCompatImageView
<FrameLayout
android:id="@+id/cards_container"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_gravity="bottom"
android:alpha="0.5"
android:scaleType="fitXY"
osmand:srcCompat="@drawable/bg_shadow_onmap"/>
</FrameLayout>
android:layout_height="wrap_content" />
</LinearLayout>
<LinearLayout
android:id="@+id/measure_mode_controls"

View file

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
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:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/graph_types_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/content_padding_small"
android:clipToPadding="false"
android:orientation="horizontal"
android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
tools:itemCount="3"
tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/point_editor_icon_category_item"
tools:orientation="horizontal" />
<LinearLayout
android:id="@+id/common_graphs_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible"
android:orientation="vertical">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/line_chart"
android:layout_width="match_parent"
android:layout_height="@dimen/route_info_line_chart_height"
android:layout_gravity="center_vertical" />
</LinearLayout>
<LinearLayout
android:id="@+id/custom_graphs_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
tools:visibility="visible"
android:orientation="vertical">
<com.github.mikephil.charting.charts.HorizontalBarChart
android:id="@+id/horizontal_chart"
android:layout_width="match_parent"
android:layout_height="@dimen/route_info_chart_height" />
<LinearLayout
android:id="@+id/route_items"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="@dimen/route_info_legend_padding"
android:paddingBottom="@dimen/route_info_legend_padding" />
</LinearLayout>
<LinearLayout
android:id="@+id/message_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding_small"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding_small"
android:visibility="gone"
tools:visibility="visible"
android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/message_icon"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:tint="?attr/default_icon_color"
tools:src="@drawable/ic_action_info_dark" />
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="@dimen/card_button_progress_size"
android:layout_height="@dimen/card_button_progress_size"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:indeterminate="true"
android:visibility="gone" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/message_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="start|center_vertical"
android:layout_weight="1"
android:letterSpacing="@dimen/description_letter_spacing"
android:lineSpacingMultiplier="@dimen/bottom_sheet_text_spacing_multiplier"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="Altitude data available only on the roads, you need to calculate a route using “Route between points” to get it." />
</LinearLayout>
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_gravity="bottom"
android:alpha="0.5"
android:scaleType="fitXY"
osmand:srcCompat="@drawable/bg_shadow_onmap" />
</LinearLayout>

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:id="@+id/points_list_container"
android:layout_width="match_parent"
android:layout_height="@dimen/measurement_tool_points_list_container_height"
android:background="?attr/activity_background_color">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/measure_points_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include layout="@layout/card_bottom_divider" />
<androidx.appcompat.widget.AppCompatImageView
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_gravity="bottom"
android:alpha="0.5"
android:scaleType="fitXY"
osmand:srcCompat="@drawable/bg_shadow_onmap" />
</FrameLayout>

View file

@ -1,186 +1,204 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/bg_color"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color"
android:orientation="vertical"
tools:context=".activities.PluginActivity">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<FrameLayout
<include layout="@layout/global_preference_toolbar" />
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:orientation="vertical" >
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/plugin_image_placeholder"
android:layout_width="360dp"
android:layout_height="144dp"
android:layout_gravity="center"
android:scaleType="center"
android:background="@color/osmand_orange"
osmand:srcCompat="@drawable/ic_extension_dark"
android:visibility="gone"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/plugin_image"
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/plugin_image_placeholder"
android:layout_width="360dp"
android:layout_height="144dp"
android:layout_gravity="center"
android:background="@color/osmand_orange"
android:scaleType="center"
android:visibility="gone"
osmand:srcCompat="@drawable/ic_extension_dark" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/plugin_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"
android:maxWidth="360dp"
android:maxHeight="200dp"
android:scaleType="fitCenter" />
</FrameLayout>
<FrameLayout
android:id="@+id/plugin_header"
android:layout_width="match_parent"
android:layout_height="66dp"
android:background="?attr/expandable_list_item_background"
android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"
android:paddingRight="@dimen/content_padding">
<net.osmand.plus.widgets.ButtonEx
android:id="@+id/plugin_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
android:layout_marginTop="9dp"
android:layout_marginBottom="9dp"
android:background="?attr/expandable_list_item_background"
android:drawablePadding="10dp"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:paddingStart="0dp"
android:paddingLeft="0dp"
android:paddingEnd="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:text="@string/shared_string_settings"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_sub_text_size"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium" />
<FrameLayout
android:layout_width="139dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:layout_marginTop="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding">
<net.osmand.plus.widgets.SwitchEx
android:id="@+id/plugin_enable_disable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/switch_ex_background"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:paddingStart="9.5dp"
android:paddingLeft="9.5dp"
android:paddingTop="8dp"
android:paddingEnd="9.5dp"
android:paddingRight="9.5dp"
android:paddingBottom="8dp"
android:textColor="?attr/switch_ex_text_color"
android:textOff="@string/shared_string_off"
android:textOn="@string/shared_string_on"
android:textSize="@dimen/default_sub_text_size"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium" />
<net.osmand.plus.widgets.ButtonEx
android:id="@+id/plugin_get"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/get_button_background"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:paddingStart="9.5dp"
android:paddingLeft="9.5dp"
android:paddingTop="8dp"
android:paddingEnd="9.5dp"
android:paddingRight="9.5dp"
android:paddingBottom="8dp"
android:text="@string/get_plugin"
android:textColor="@color/color_white"
android:textSize="@dimen/default_sub_text_size"
android:visibility="gone"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium" />
</FrameLayout>
</FrameLayout>
<LinearLayout
android:id="@+id/plugin_install_header"
android:layout_width="match_parent"
android:layout_height="66dp"
android:background="?attr/plugin_details_install_header_bg"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:visibility="gone"
tools:visibility="visible">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/ic_world_globe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:background="@drawable/ic_world_globe_dark" />
<net.osmand.plus.widgets.TextViewEx
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="@dimen/content_padding"
android:paddingLeft="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:text="@string/plugin_install_needs_network"
android:textColor="?android:textColorSecondary"
osmand:typeface="@string/font_roboto_regular" />
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:adjustViewBounds="true"
android:maxWidth="360dp"
android:maxHeight="200dp"
android:scaleType="fitCenter" />
android:layout_marginStart="@dimen/content_padding"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:text="@string/shared_string_description"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium" />
</FrameLayout>
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/plugin_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginTop="14dp"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="@string/lorem_ipsum" />
<FrameLayout
android:id="@+id/plugin_header"
android:layout_width="match_parent"
android:layout_height="66dp"
android:background="?attr/expandable_list_item_background"
android:paddingLeft="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding"
android:paddingStart="@dimen/content_padding">
</LinearLayout>
<net.osmand.plus.widgets.ButtonEx
android:id="@+id/plugin_settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
android:layout_marginBottom="9dp"
android:layout_marginTop="9dp"
android:background="?attr/expandable_list_item_background"
android:drawablePadding="10dp"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:paddingLeft="0dp"
android:paddingRight="@dimen/content_padding"
android:text="@string/shared_string_settings"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_sub_text_size"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"
android:paddingEnd="@dimen/content_padding"
android:paddingStart="0dp" />
</ScrollView>
<FrameLayout
android:layout_width="139dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|end"
android:layout_marginBottom="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding">
<net.osmand.plus.widgets.SwitchEx
android:id="@+id/plugin_enable_disable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/switch_ex_background"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:paddingBottom="8dp"
android:paddingLeft="9.5dp"
android:paddingRight="9.5dp"
android:paddingTop="8dp"
android:textColor="?attr/switch_ex_text_color"
android:textOff="@string/shared_string_off"
android:textOn="@string/shared_string_on"
android:textSize="@dimen/default_sub_text_size"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"
android:paddingStart="9.5dp"
android:paddingEnd="9.5dp" />
<net.osmand.plus.widgets.ButtonEx
android:id="@+id/plugin_get"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/get_button_background"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
android:paddingBottom="8dp"
android:paddingLeft="9.5dp"
android:paddingRight="9.5dp"
android:paddingTop="8dp"
android:text="@string/get_plugin"
android:textColor="@color/color_white"
android:textSize="@dimen/default_sub_text_size"
android:visibility="gone"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"
android:paddingStart="9.5dp"
android:paddingEnd="9.5dp" />
</FrameLayout>
</FrameLayout>
<LinearLayout
android:id="@+id/plugin_install_header"
android:layout_width="match_parent"
android:layout_height="66dp"
android:background="?attr/plugin_details_install_header_bg"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:visibility="gone"
tools:visibility="visible"
android:paddingEnd="@dimen/content_padding"
android:paddingStart="@dimen/content_padding">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/ic_world_globe"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:background="@drawable/ic_world_globe_dark"/>
<net.osmand.plus.widgets.TextViewEx
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/content_padding"
android:paddingRight="@dimen/content_padding"
android:text="@string/plugin_install_needs_network"
android:textColor="?android:textColorSecondary"
osmand:typeface="@string/font_roboto_regular"
android:paddingStart="@dimen/content_padding"
android:paddingEnd="@dimen/content_padding" />
</LinearLayout>
<net.osmand.plus.widgets.TextViewEx
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding"
android:text="@string/shared_string_description"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"
osmand:textAllCapsCompat="true"
osmand:typeface="@string/font_roboto_medium"
android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/plugin_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/content_padding"
android:layout_marginRight="@dimen/content_padding"
android:layout_marginTop="14dp"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
osmand:typeface="@string/font_roboto_regular"
tools:text="@string/lorem_ipsum"
android:layout_marginEnd="@dimen/content_padding"
android:layout_marginStart="@dimen/content_padding" />
</LinearLayout>
</ScrollView>
</LinearLayout>

View file

@ -1,14 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/bg_color"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/global_preference_toolbar" />
</com.google.android.material.appbar.AppBarLayout>
<ListView
android:id="@android:id/list"
android:id="@+id/plugins_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/plugins_list_item"/>
</LinearLayout>
android:dividerHeight="1dp"
android:drawSelectorOnTop="true" />
</LinearLayout>

View file

@ -52,6 +52,7 @@
android:ellipsize="end"
android:lines="2"
android:maxLines="2"
android:scrollbars="none"
android:text="@string/lorem_ipsum"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"

View file

@ -17,13 +17,12 @@
android:layout_marginEnd="@dimen/content_padding">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
style="@style/Widget.MaterialComponents.AutoCompleteTextView.FilledBox"
android:id="@+id/tagEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="@dimen/wpt_list_item_height"
android:hint="@string/hint_tag"
android:gravity="bottom"
android:paddingBottom="@dimen/text_margin_small"
tools:text="Tag text"/>
</com.google.android.material.textfield.TextInputLayout>
@ -34,12 +33,11 @@
android:layout_weight="1">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
style="@style/Widget.MaterialComponents.AutoCompleteTextView.FilledBox"
android:id="@+id/valueEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="@dimen/wpt_list_item_height"
android:gravity="bottom"
android:paddingBottom="@dimen/text_margin_small"
android:hint="@string/hint_value"
tools:text="Value text"/>

View file

@ -64,6 +64,13 @@
tools:text="Some description" />
</LinearLayout>
<include
layout="@layout/profile_button_small"
android:layout_width="@dimen/list_header_height"
android:layout_height="@dimen/list_header_height"
android:layout_marginLeft="@dimen/content_padding_half"
android:layout_marginRight="@dimen/content_padding_half" />
</LinearLayout>
</androidx.appcompat.widget.Toolbar>

View file

@ -3901,4 +3901,23 @@
\nيمكنك إدارة وإلغاء الاشتراكات الخاصة بك عن طريق الانتقال إلى إعدادات AppGallery.</string>
<string name="routing_attr_avoid_footways_description">تجنب الممرات</string>
<string name="routing_attr_avoid_footways_name">تجنب الممرات</string>
<string name="what_is_new">ما الجديد</string>
<string name="development">تطوير</string>
<string name="use_live_public_transport">بيانات أوسماند لايف</string>
<string name="use_live_routing">بيانات أوسماند لايف</string>
<string name="use_complex_routing">التوجيه المركب</string>
<string name="complex_routing_descr">التوجيه على مرحلتين لملاحة السيارة.</string>
<string name="use_native_pt">تطوير النقل العام المحلي</string>
<string name="use_native_pt_desc">قم بالتبديل إلى Java (الآمن) حساب توجيه النقل العام</string>
<string name="perform_oauth_authorization_description">قم بإجراء تسجيل دخول إلى OAuth لاستخدام ميزات osmedit</string>
<string name="perform_oauth_authorization">تسجيل الدخول عبر OAuth</string>
<string name="clear_osm_token">مسح رمز OpenStreetMap OAuth</string>
<string name="osm_edit_logout_success">تسجيل الخروج بنجاح</string>
<string name="file_already_imported">تم استيراد الملف بالفعل في أوسماند</string>
<string name="use_two_phase_routing">استخدام خوارزمية توجيه من مرحلتين A*</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="snowmobile_render_descr">للقيادة على الجليد مع طرق ومسارات مخصصة.</string>
<string name="shared_string_graph">رسم بياني</string>
</resources>

View file

@ -3844,4 +3844,5 @@
<string name="poi_recycling_small_electrical_appliances">Маленькія электрапрыборы</string>
<string name="poi_beehive">Вулей</string>
<string name="poi_nuts">Крама арэхаў</string>
<string name="poi_fuel_lng"></string>
</resources>

View file

@ -1576,7 +1576,7 @@
<string name="routing_attr_height_name">Абмежаванне па вышыні</string>
<string name="routing_attr_height_description">Пазначыць вышыню транспартнага сродку для разліку маршруту.</string>
<string name="use_fast_recalculation">Разумны пераразлік маршруту</string>
<string name="use_fast_recalculation_desc">Пераразлічваць толькі пачатак маршруту для доўгіх паездак.</string>
<string name="use_fast_recalculation_desc">Пераразлічваць толькі пачатак маршруту. Падыходзіць для доўгіх паездак.</string>
<string name="shared_string_logoff">Выйсці</string>
<string name="rendering_value_disabled_name">Выключана</string>
<string name="rendering_value_walkingRoutesOSMC_name">Афарбоўка па пешаходнаму сімвалу OSMC</string>
@ -3957,4 +3957,27 @@
<string name="sort_last_modified">Апошняя змена</string>
<string name="sort_name_descending">Назва: Я — А</string>
<string name="sort_name_ascending">Назва: А — Я</string>
<string name="what_is_new">Што новага</string>
<string name="contour_lines_thanks">Дзякуй за набыццё ўбудовы «Контурныя лініі»</string>
<string name="osm_live_payment_desc_hw">Плата за падпіску спаганяецца за абраны перыяд. Скасаваць яе на AppGallery можна у любы момант.</string>
<string name="osm_live_payment_subscription_management_hw">Пры пацвярджэнні пакупкі аплата будзе спаганяцца з рахунка, звязанага з вашым акаўнтам AppGallery.
\n
\nПадпіска аўтаматычна працягваецца, калі вы не скасуеце яе да даты працягу. З вашага рахунка будзе адзін раз спаганяцца аплата за перыяд працягу (месяц/тры месяцы/год).
\n
\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="complex_routing_descr">Дзвюхфазная аўтанавігацыя.</string>
<string name="use_native_pt">Натыўны грамадскі транспарт (у распрацоўцы)</string>
<string name="perform_oauth_authorization">Увайсці праз OAuth</string>
<string name="use_two_phase_routing">Выкарыстоўваць 2-фазны алгарытм маршрутызацыі A *</string>
<string name="use_native_pt_desc">Перайсці на разлік маршруту грамадскага транспарту на Java (бяспечны)</string>
<string name="file_already_imported">Файл ужо імпартаваны ў OsmAnd</string>
<string name="start_finish_icons">Значкі старту і фінішу</string>
<string name="perform_oauth_authorization_description">Увайдзіце праз OAuth, каб выкарыстоўваць функцыі osmedit</string>
<string name="clear_osm_token">Ачысціць токен OpenStreetMap OAuth</string>
<string name="osm_edit_logout_success">Выхад выкананы</string>
<string name="use_live_public_transport">Даныя OsmAnd Live</string>
<string name="use_live_routing">Даныя OsmAnd Live</string>
</resources>

View file

@ -3925,4 +3925,8 @@
<string name="complex_routing_descr">Zwei-Phasen-Routenberechnung für die Autonavigation.</string>
<string name="use_native_pt">Native ÖPNV Entwicklung</string>
<string name="use_native_pt_desc">Wechseln zu Java (sicher) Berechnung des ÖPNV-Routings</string>
<string name="osm_edit_logout_success">Abmeldung erfolgreich</string>
<string name="file_already_imported">Datei wurde bereits in OsmAnd importiert</string>
<string name="perform_oauth_authorization">Anmelden über OAuth</string>
<string name="clear_osm_token">OpenStreetMap OAuth-Token löschen</string>
</resources>

View file

@ -3837,4 +3837,5 @@
<string name="poi_departures_board_delay">prokrasto</string>
<string name="poi_departures_board">Tabulo de forveturoj</string>
<string name="poi_drinking_water_refill">Plenigi per trinkebla akvo</string>
<string name="poi_fuel_lng">tergaso likva (LNG)</string>
</resources>

View file

@ -73,7 +73,7 @@
<string name="lang_vo">Volapuko</string>
<string name="osmand_play_title_30_chars">OsmAnd Mapoj kaj Navigado</string>
<string name="shared_string_reverse_order">Inversa ordigo</string>
<string name="switch_start_finish">Anstataŭigi komencpunkton per finpunkto</string>
<string name="switch_start_finish">Anstataŭigi komencpunkton per celo</string>
<string name="rendering_attr_hideIcons_name">Emblemoj de interesejoj</string>
<string name="item_removed">Elemento forigita</string>
<string name="n_items_removed">elementoj forigitaj</string>
@ -742,7 +742,7 @@
<string name="osmo_edit_color">Vidiga koloro</string>
<string name="int_days">tagoj</string>
<string name="osmo_connect_menu">Konekti</string>
<string name="use_points_as_intermediates">Prikalkuli kurson inter punktojn</string>
<string name="use_points_as_intermediates">Kalkuli kurson inter punktoj</string>
<string name="always_center_position_on_map">Ĉiam montri centrigitan pozicion</string>
<string name="localization_pref_title">Loko</string>
<string name="index_item_nation_addresses">adresoj tutmondaj</string>
@ -1853,7 +1853,7 @@
<string name="navigation_intent_invalid">Erara formo: %s</string>
<string name="plugin_install_needs_network">Vi devas esti konektita al la interreto por instali tiun ĉi kromprogramon.</string>
<string name="use_fast_recalculation">Inteligenta rekalkulado de kurso</string>
<string name="use_fast_recalculation_desc">Por longaj vojaĝoj, rekalkuli nur komencan parton de kurso.</string>
<string name="use_fast_recalculation_desc">Rekalkuli nur komencan parton de kurso. Uzebla por longaj kursoj.</string>
<string name="rate_this_app">Taksi tiun ĉi aplikaĵon</string>
<string name="we_really_care_about_your_opinion">Via opinio estas grava por ni.</string>
<string name="rate_this_app_long">Bonvolu taksi OsmAnd ĉe Google Play</string>
@ -1890,7 +1890,7 @@
<string name="unsaved_changes_will_be_lost">Ĉiuj nekonservitaj ŝanĝoj estos forigitaj. Ĉu pluigi?</string>
<string name="downloads_left_template">ankoraŭ %1$s elŝutoj</string>
<string name="roads">Vojoj</string>
<string name="downloading_number_of_files">Elŝutado - %1$s dosiero</string>
<string name="downloading_number_of_files">Elŝutado %1$d dosiero</string>
<string name="show_free_version_banner">Montri reklamaĵon de senpaga versio</string>
<string name="show_free_version_banner_description">Montri reklamaĵon de senpaga versio, eĉ se vi havas pagan version.</string>
<string name="activate_seamarks_plugin">Bonvolu aktivigi la kromprogramon “mara map-vido”</string>
@ -2832,13 +2832,13 @@
<string name="osm_live_payment_3_months_title">Ĉiu-3-monate</string>
<string name="osm_live_payment_annual_title">Ĉiujare</string>
<string name="osm_live_payment_month_cost_descr">%1$s / monato</string>
<string name="osm_live_payment_month_cost_descr_ex">%1$,2f %2$s / monato</string>
<string name="osm_live_payment_month_cost_descr_ex">%1$.2f %2$s / monato</string>
<string name="osm_live_payment_discount_descr">Ŝparu %1$s</string>
<string name="osm_live_payment_current_subscription">Nuna kotizo</string>
<string name="osm_live_payment_renews_monthly">Reaboni ĉiumonate</string>
<string name="osm_live_payment_renews_quarterly">Reaboni ĉiukvaronjare</string>
<string name="osm_live_payment_renews_annually">Reaboni ĉiujare</string>
<string name="default_price_currency_format">%1$,2f %2$s</string>
<string name="default_price_currency_format">%1$.2f %2$s</string>
<string name="osm_live_payment_header">Intertempo de pagoj:</string>
<string name="osm_live_payment_contribute_descr">Donacoj helpos fondi kartografion de OSM.</string>
<string name="powered_by_osmand">De OsmAnd</string>
@ -3357,7 +3357,7 @@
<string name="file_import_error">Eraro dum enporti %1$s: %2$s</string>
<string name="file_imported_successfully">%1$s enportita.</string>
<string name="rendering_value_white_name">Blanka</string>
<string name="swap_two_places">Anstataŭigi %1$s per %2$s</string>
<string name="swap_two_places">Anstataŭigi: %1$s ⇄ %2$s</string>
<string name="route_start_point">Komencpunkto</string>
<string name="swap_start_and_destination">Anstataŭigi komencpunkton per celo</string>
<string name="simulate_your_location_gpx_descr">Simuli vian pozicion uzante registritan GPXkurson.</string>
@ -3651,7 +3651,7 @@
<string name="ltr_or_rtl_combine_via_slash_with_space">%1$s / %2$s</string>
<string name="osm_live_payment_subscription_management">La pago estos prenita el via konto Google Play post konfirmi aĉeton.
\n
\n La abono aŭtomate renoviĝos escepte se ĝi estos nuligita antaŭ la dato de renoviĝo. La pago estos prenita por la renoviĝa periodo (monato/tri monatoj/jaro) nur je la data de renoviĝo.
\n La abono aŭtomate renoviĝos escepte se ĝi estos nuligita antaŭ la dato de renoviĝo. La pago estos prenita por la renoviĝa periodo (monato/tri monatoj/jaro) nur je la dato de renoviĝo.
\n
\n Vi povas administri kaj rezigni viajn abonojn per agordoj de Google Play.</string>
<string name="search_poi_types_descr">Miksi specojn de interesejoj el diversaj kategorioj. Frapetu ŝaltilon por elekti la tutan kategorion, frapetu ĉe maldekstre por elekti detala(j)n objekto(j)n el la kategorio.</string>
@ -3894,7 +3894,7 @@
<string name="simplified_track">Simpligita spuro</string>
<string name="simplified_track_description">Nur la linio de kurso estos konservita, la navigadpunktoj estos forigitaj.</string>
<string name="shared_string_file_name">Dosiernomo</string>
<string name="number_of_gpx_files_selected_pattern">%d dosieroj de spuroj elektitaj</string>
<string name="number_of_gpx_files_selected_pattern">%s dosieroj de spuroj elektitaj</string>
<string name="disable_recording_once_app_killed_descrp">Paŭzigos registri spuron je halto de la aplikaĵo (per la menuo de lastaj aplikaĵoj). (Fona emblemo de OsmAnd malaperos de la androida sciiga zono.)</string>
<string name="gpx_monitoring_stop">Paŭzigi registri spuron</string>
<string name="gpx_monitoring_start">Daŭrigi registri spuron</string>
@ -3903,4 +3903,33 @@
<string name="previous_segment">Antaŭa segmento</string>
<string name="all_previous_segments">Ĉiuj antaŭaj segmentoj</string>
<string name="only_selected_segment_recalc">Nur la elektita segmento estos rekalkulita uzante la elektitan profilon.</string>
<string name="what_is_new">Kio estas nova</string>
<string name="osm_live_payment_subscription_management_hw">La pago estos prenita el via konto AppGallery post konfirmi aĉeton.
\n
\n La abono aŭtomate renoviĝos escepte se ĝi estos nuligita antaŭ la dato de renoviĝo. La pago estos prenita por la renoviĝa periodo (monato/tri monatoj/jaro) nur je la dato de renoviĝo.
\n
\n Vi povas administri kaj rezigni viajn abonojn per la agordoj de AppGallery.</string>
<string name="start_finish_icons">Emblemoj komenco/fino</string>
<string name="contour_lines_thanks">Dankon al vi por aĉeti la kromprogramon “nivelkurboj”</string>
<string name="osm_live_payment_desc_hw">Abonpago prenita por la elektita periodo. VI ĉiam povas rezigni abonon ĉe AppGallery.</string>
<string name="routing_attr_avoid_footways_description">Eviti irejojn</string>
<string name="routing_attr_avoid_footways_name">Sen trotuaroj</string>
<string name="development">Programado</string>
<string name="use_live_public_transport">Datumoj OsmAnd Live</string>
<string name="use_live_routing">Datumoj OsmAnd Live</string>
<string name="use_complex_routing">Komplika kurs-difinado</string>
<string name="complex_routing_descr">Du-faza difinado de kurso por aŭtomobila navigo.</string>
<string name="use_native_pt">Indiĝena metodo de publik-transporta navigo</string>
<string name="use_native_pt_desc">Aktivigi (sekuran) metodon por kalkuli kursojn de publika transporto uzante programlingvon Java</string>
<string name="perform_oauth_authorization_description">Ensaluti uzante OAuth por redakti la mapon OSM</string>
<string name="perform_oauth_authorization">Ensaluti per OAuth</string>
<string name="clear_osm_token">Forigi ĵetonon OpenStreetMap OAuth</string>
<string name="osm_edit_logout_success">Sukcese elsalutinta</string>
<string name="snowmobile_render_descr">Por veturi per motorsledo sur dediĉitaj vojoj.</string>
<string name="file_already_imported">Dosiero jam estas enportita al OsmAnd</string>
<string name="use_two_phase_routing">Uzi 2-fazan A* algoritmon de navigo</string>
<string name="shared_string_graph">Diagramo</string>
<string name="message_need_calculate_route_before_show_graph">Datumoj de %1$s estas disponeblaj nur por vojoj, vi devas kalkuli la kurson uzante “kalkuli kurson inter punktoj” por akiri ĝin.</string>
<string name="message_graph_will_be_available_after_recalculation">Atendado ĝis la kurso estos rekalkulita.
\nDiagramo estos videbla post rekalkulado.</string>
</resources>

View file

@ -3568,8 +3568,8 @@
<string name="poi_health_specialty_radiotheraphy_yes">Radioterapia</string>
<string name="poi_hazard">Advertencia de peligro</string>
<string name="poi_rtsa_scale_filter">Categoría de dificultad</string>
<string name="poi_rtsa_scale_nc">н/к (sin categoría)</string>
<string name="poi_rtsa_scale_nc_asterisk">н/к* (sin categoría, posible peligro)</string>
<string name="poi_rtsa_scale_nc">s/c (sin categoría)</string>
<string name="poi_rtsa_scale_nc_asterisk">s/c* (sin categoría, posible peligro)</string>
<string name="poi_rtsa_scale_1a">1A</string>
<string name="poi_rtsa_scale_1a_asterisk">1A*</string>
<string name="poi_rtsa_scale_1b">1B</string>

View file

@ -3929,4 +3929,11 @@
<string name="perform_oauth_authorization">Ingresar a través de OAuth</string>
<string name="clear_osm_token">Vaciar llave OAuth de OpenStreetMap</string>
<string name="osm_edit_logout_success">Sesión finalizada</string>
<string name="snowmobile_render_descr">Para caminos y senderos exclusivos de motos de nieve.</string>
<string name="file_already_imported">El archivo ya fue importado en OsmAnd</string>
<string name="use_two_phase_routing">Usar el algoritmo de enrutamiento A* de 2 fases</string>
<string name="shared_string_graph">Gráfico</string>
<string name="message_need_calculate_route_before_show_graph">%1$s datos disponibles sólo en los caminos, necesitas calcular una ruta usando «Ruta entre puntos» para obtenerla.</string>
<string name="message_graph_will_be_available_after_recalculation">Espera el recálculo de la ruta.
\nEl gráfico estará disponible después del recálculo.</string>
</resources>

View file

@ -3559,20 +3559,20 @@
<string name="poi_payment_coins_0_5">$0.5 mündid</string>
<string name="poi_charging_station">Laadimisjaam</string>
<string name="poi_hazard">Oht</string>
<string name="poi_rtsa_scale_nc">н/к</string>
<string name="poi_rtsa_scale_nc_asterisk">н/к*</string>
<string name="poi_rtsa_scale_1a">1А</string>
<string name="poi_rtsa_scale_1a_asterisk">1А*</string>
<string name="poi_rtsa_scale_1b">1Б</string>
<string name="poi_rtsa_scale_1b_asterisk">1Б*</string>
<string name="poi_rtsa_scale_2a">2А</string>
<string name="poi_rtsa_scale_2a_asterisk">2А*</string>
<string name="poi_rtsa_scale_2b">2Б</string>
<string name="poi_rtsa_scale_2b_asterisk">2Б*</string>
<string name="poi_rtsa_scale_3a">3А</string>
<string name="poi_rtsa_scale_3a_asterisk">3А*</string>
<string name="poi_rtsa_scale_3b">3Б</string>
<string name="poi_rtsa_scale_3b_asterisk">3Б*</string>
<string name="poi_rtsa_scale_nc">k/p</string>
<string name="poi_rtsa_scale_nc_asterisk">k/p*</string>
<string name="poi_rtsa_scale_1a">1A</string>
<string name="poi_rtsa_scale_1a_asterisk">1A*</string>
<string name="poi_rtsa_scale_1b">1B</string>
<string name="poi_rtsa_scale_1b_asterisk">1B*</string>
<string name="poi_rtsa_scale_2a">2A</string>
<string name="poi_rtsa_scale_2a_asterisk">2A*</string>
<string name="poi_rtsa_scale_2b">2B</string>
<string name="poi_rtsa_scale_2b_asterisk">2B*</string>
<string name="poi_rtsa_scale_3a">3A</string>
<string name="poi_rtsa_scale_3a_asterisk">3A*</string>
<string name="poi_rtsa_scale_3b">3B</string>
<string name="poi_rtsa_scale_3b_asterisk">3B*</string>
<string name="poi_flare">Gaasi põletamine;Hõõglamp</string>
<string name="poi_change_delete">Kustutatud objekt</string>
<string name="poi_health_specialty_radiotherapy_yes">Kiiritusravi</string>

View file

@ -3593,7 +3593,7 @@
<string name="height_limit_description">Kuna mõnedel marsruutidel võidakse kohaldada sõidukite kõrguspiiranguid, siis palun märkige oma sõiduki kõrgus.</string>
<string name="lenght_limit_description">Kuna mõnedel marsruutidel võidakse kohaldada piiranguid pikkade sõidukite suhtes, siis palun märkige oma sõiduki pikkus.</string>
<string name="weight_limit_description">Kuna mõnedel marsruutidel võidakse kohaldada sõidukite kaalupiiranguid, siis palun märkige oma sõiduki kaal.</string>
<string name="gpx_parse_error">OsmAnd GPX faili vorming pole korrektne. Täpsemaks uurimiseks palun suhtle meie tugimeeskonnaga.</string>
<string name="gpx_parse_error">OsmAnd GPX-andmestiku vorming on vigane. Täpsemaks uurimiseks palun võta ühendust meie kasutajatoega.</string>
<string name="sort_by_category">Sorteeri kategooria järgi</string>
<string name="shared_string_resume">Jätka</string>
<string name="import_profile_dialog_description">Imporditavas profiilis leidub täiendavaid andmeid. Vajutades „Impordi“ imporditakse vaid profiili andmed, täiendavate andmete jaoks pead märkima vastava valiku.</string>
@ -3775,4 +3775,11 @@
<string name="osm_live_payment_desc_hw">Arveldame tellimuse eest valitud ajavahemiku alusel. Seda saad sa vabalt valitud ajal tühistada AppGallery\'s.</string>
<string name="use_complex_routing">Keeruka teekonna koostamine</string>
<string name="osm_edit_logout_success">Väljalogimine õnnestus</string>
<string name="development">Arendus</string>
<string name="clear_osm_token">Kustuta OpenStreetMap\'i OAuth\'i pääsuluba</string>
<string name="perform_oauth_authorization">Logi sisse OAuth abil</string>
<string name="perform_oauth_authorization_description">Kui sa soovid kasutada kaardi muutmise võimalusi, siis palun logi sisse OAuth abil</string>
<string name="what_is_new">Meie uudised</string>
<string name="use_two_phase_routing">Kasuta kahefaasilist A-klassi teekonna koostamise algoritmi</string>
<string name="file_already_imported">See fail on juba OsmAnd\'i imporditud</string>
</resources>

View file

@ -3900,4 +3900,16 @@
<string name="perform_oauth_authorization">Connectez-vous avec OAuth</string>
<string name="clear_osm_token">Supprimer le jeton OAuth d\'OpenStreetMap</string>
<string name="osm_edit_logout_success">Déconnexion réussie</string>
<string name="file_already_imported">Le fichier est déjà importé dans OsmAnd</string>
<string name="use_two_phase_routing">Utiliser un algorithme de routage A* à 2 phases</string>
<string name="osm_live_payment_subscription_management_hw">Le paiement sera débité de votre compte AppGallery dès confirmation de l\'achat.
\n
\nA moins qu\'il ne soit annulé avant sa date de renouvellement, l\'abonnement sera automatiquement débité à chaque échéance (mensuelle / trimestrielle / annuelle).
\n
\nVous pouvez gérer et annuler vos abonnements dans vos paramètres AppGallery.</string>
<string name="message_need_calculate_route_before_show_graph">Seulement %1$s données disponibles sur les routes. Vous devez calculer l\'itinéraire via \"Itinéraire entre 2 points\".</string>
<string name="message_graph_will_be_available_after_recalculation">Recalcul de l\'itinéraire en cours.
\nLe graphique sera disponible à l\'issue du calcul.</string>
<string name="snowmobile_render_descr">Pour la conduite en motoneige avec des routes et des pistes dédiées.</string>
<string name="shared_string_graph">Graphique</string>
</resources>

View file

@ -65,7 +65,7 @@
<string name="poi_traffic_calming_bump">Lomba pequena de velocidade</string>
<string name="poi_service_tyres">Rodas</string>
<string name="poi_vehicle_inspection">Inspección técnica de vehículos</string>
<string name="poi_car_wash">Lavadura de automóbiles</string>
<string name="poi_car_wash">Lavado de automóbiles</string>
<string name="poi_fuel">Gasolineira;Estación de combustíbel;Estación de servizo</string>
<string name="poi_compressed_air">Ar comprimido</string>
<string name="poi_parking">Aparcadoiro</string>

View file

@ -3675,7 +3675,7 @@ Lon %2$s</string>
<string name="ltr_or_rtl_combine_via_slash_with_space">%1$s / %2$s</string>
<string name="osm_live_payment_subscription_management">"O pagamento será cobrado na túa conta da Google Play na confirmación da compra.
\n
\n A subscrición é renovada de xeito automático, a menos que sexa desbotada antes da data de renovación. A túa conta será cobrada polo período de renovación (més/trimestre/ano) soamente na data de renovación.
\n A subscrición é renovada de xeito automático, a menos que sexa desbotada antes da data de renovación. A túa conta será cobrada polo período de renovación (mes/trimestre/ano) soamente na data de renovación.
\n
\n Podes xestionar e desbotar as túas subscricións entrando nos axustes da Google Play."</string>
<string name="search_poi_types">Procurar tipos de PDI</string>
@ -3945,4 +3945,9 @@ Lon %2$s</string>
<string name="complex_routing_descr">Enrutamento de dúas fases para a navegación de automóbil</string>
<string name="use_native_pt">Desenvolvemento do transporte público nativo</string>
<string name="use_native_pt_desc">Activar cálculo de enrutamento de transporte público do Java (seguro)</string>
<string name="what_is_new">Novidades</string>
<string name="perform_oauth_authorization_description">Inicia sesión co OAuth para empregar as funcións de edición do OSM</string>
<string name="perform_oauth_authorization">Entrar polo OAuth</string>
<string name="clear_osm_token">Limpar token do OpenStreetMap OAuth</string>
<string name="osm_edit_logout_success">Sesión rematada</string>
</resources>

View file

@ -3553,20 +3553,20 @@
<string name="poi_health_specialty_radiotheraphy_yes">Sugárkezelés</string>
<string name="poi_hazard">Veszély</string>
<string name="poi_rtsa_scale_filter">Nehézségi fok (az Orosz Túrasportszövetség skáláján)</string>
<string name="poi_rtsa_scale_nc">н/к</string>
<string name="poi_rtsa_scale_nc_asterisk">н/к*</string>
<string name="poi_rtsa_scale_1a">1А</string>
<string name="poi_rtsa_scale_1a_asterisk">1А*</string>
<string name="poi_rtsa_scale_1b">1Б</string>
<string name="poi_rtsa_scale_1b_asterisk">1Б*</string>
<string name="poi_rtsa_scale_2a">2А</string>
<string name="poi_rtsa_scale_2a_asterisk">2А*</string>
<string name="poi_rtsa_scale_2b">2Б</string>
<string name="poi_rtsa_scale_2b_asterisk">2Б*</string>
<string name="poi_rtsa_scale_3a">3А</string>
<string name="poi_rtsa_scale_3a_asterisk">3А*</string>
<string name="poi_rtsa_scale_3b">3Б</string>
<string name="poi_rtsa_scale_3b_asterisk">3Б*</string>
<string name="poi_rtsa_scale_nc">N/A</string>
<string name="poi_rtsa_scale_nc_asterisk">N/A*</string>
<string name="poi_rtsa_scale_1a">1A</string>
<string name="poi_rtsa_scale_1a_asterisk">1A*</string>
<string name="poi_rtsa_scale_1b">1B</string>
<string name="poi_rtsa_scale_1b_asterisk">1B*</string>
<string name="poi_rtsa_scale_2a">2A</string>
<string name="poi_rtsa_scale_2a_asterisk">2A*</string>
<string name="poi_rtsa_scale_2b">2B</string>
<string name="poi_rtsa_scale_2b_asterisk">2B*</string>
<string name="poi_rtsa_scale_3a">3A</string>
<string name="poi_rtsa_scale_3a_asterisk">3A*</string>
<string name="poi_rtsa_scale_3b">3B</string>
<string name="poi_rtsa_scale_3b_asterisk">3B*</string>
<string name="poi_flare">Gázfáklya</string>
<string name="poi_change_delete">Törölt objektum</string>
<string name="poi_health_specialty_radiotherapy_yes">Sugárkezelés</string>

View file

@ -3739,11 +3739,11 @@
<string name="shared_string_include_data">Kiegészítő adatok átvétele</string>
<string name="import_profile_dialog_description">Az importált profil kiegészítő adatokat is tartalmaz. Koppintson az \"Importál\" gombra kizálólag a profiladatok importálásához vagy válassza a kiegészítő adatokat.</string>
<string name="import_complete_description">Összes adat importálva innen: %1$s, az alábbi gombokkal megnyithatja az alkalmazás megfelelő részét az adatok kezeléséhez.</string>
<string name="osm_live_payment_subscription_management">A fizetés a Google Play fiókhoz lesz felszámítva a vásárlás megerősítésekor.
<string name="osm_live_payment_subscription_management">A fizetést a vásárlás visszaigazolásakor a Google Play számlájára terheljük.
\n
\nAz előfizetés automatikusan megújul, kivéve ha a meghosszabbítás napja előtt lemondásra kerül. A fókjához az új időszak (hónap/három hónap/év) díja kizárólag a meghosszabítás napján lesz felszámolva.
\nAz előfizetés automatikusan megújul, kivéve, ha azt a megújítási dátum előtt lemondja. A megújítási időszakra (hónap / 3 hónap / év) vonatkozóan a számláját csak a megújítás napján terheljük meg.
\n
\nAz előfizetéseit a Google Play beállításainál tudja kezelni és lemondani.</string>
\nAz előfizetéseket a Google Play beállításai között kezelheti és törölheti.</string>
<string name="quick_action_remove_next_destination_descr">Törli az útvonal soron következő célpontját. Amennyiben ez a végző célpont, a navigáció megáll.</string>
<string name="plugin_wikipedia_description">Tudjon meg többet az érdekes pontokról a Wikipédiából. Ez az Ön offline zsebútikönyve egyszerűen kapcsolja be a Wikipédia-bővítményt, és élvezze az Ön körüli objektumokról szóló cikkeket.</string>
<string name="app_mode_enduro_motorcycle">Salakmotor</string>
@ -3918,4 +3918,6 @@
<string name="perform_oauth_authorization">Bejelentkezés OAuth segítségével</string>
<string name="clear_osm_token">OpenStreetMap OAuth token törlése</string>
<string name="osm_edit_logout_success">Sikeresen kijelentkezett</string>
<string name="use_two_phase_routing">Kétszakaszos A* útvonaltervezési algoritmus használata</string>
<string name="file_already_imported">A fájl már importálva van az OsmAndba</string>
</resources>

View file

@ -3827,4 +3827,7 @@
<string name="poi_elevator">Lyfta</string>
<string name="poi_recycling_small_electrical_appliances">Smærri raftæki</string>
<string name="poi_drinking_water_refill">Áfylling drykkjarvatns</string>
<string name="poi_fuel_lng">LNG</string>
<string name="poi_departures_board_no">Brottfaratafla: nei</string>
<string name="poi_departures_board">Brottfaratafla</string>
</resources>

View file

@ -530,7 +530,7 @@
<string name="global_settings">Víðværar stillingar</string>
<string name="general_settings">Almennt</string>
<string name="osmand_service">Bakgrunnshamur</string>
<string name="delete_confirmation_msg">Eyða \'%s\'?</string>
<string name="delete_confirmation_msg">Eyða %1$s\?</string>
<string name="city_type_suburb">Úthverfi</string>
<string name="city_type_hamlet">Byggðakjarni</string>
<string name="city_type_village">Þorp</string>
@ -709,8 +709,8 @@
<string name="routing_attr_allow_motorway_description">Leyfa hraðbrautir.</string>
<string name="wiki_around">Wikipedia-greinar í nágrenninu</string>
<string name="route_calculation">Útreikningur leiðar</string>
<string name="gpx_no_tracks_title">Þú ert ekki með neina GPX-ferla ennþá</string>
<string name="gpx_no_tracks_title_folder">Þú getur líka bætt GPX-skrám í möppuna</string>
<string name="gpx_no_tracks_title">Þú ert ekki ennþá með neina ferla</string>
<string name="gpx_no_tracks_title_folder">Þú getur líka bætt ferilskrám í möppuna</string>
<string name="trip_rec_notification_settings">Virkja hraðskráningu ferðar</string>
<string name="shared_string_trip">Ferð</string>
<string name="shared_string_recorded">Skráð</string>
@ -723,7 +723,7 @@
<string name="no_inet_connection">Engin internettenging</string>
<string name="no_inet_connection_desc_map">Nauðsynleg til að sækja kort.</string>
<string name="search_location">Leita að stað…</string>
<string name="storage_place_description">Gagnageymsla OsmAnd (fyrir kort, GPX-ferla, o.s.frv.): %1$s.</string>
<string name="storage_place_description">Gagnageymsla OsmAnd (fyrir kort, ferilskrár, o.s.frv.): %1$s.</string>
<string name="give_permission">Gefa heimild</string>
<string name="no_update_info">Ekki sýna nýjar útgáfur</string>
<string name="get_started">Komast í gang</string>
@ -1718,7 +1718,7 @@
<string name="map_text_size_descr">Stærð leturs fyrir nöfn á kortinu:</string>
<string name="trace_rendering">Aflúsunarupplýsingar myndgerðar</string>
<string name="trace_rendering_descr">Birta afköst myndgerðar.</string>
<string name="gpx_option_reverse_route">Snúa við stefnu GPX</string>
<string name="gpx_option_reverse_route">Snúa við stefnu ferils</string>
<string name="choose_audio_stream">Frálag raddleiðsagnar</string>
<string name="voice_stream_music">Hljóð í margmiðlun/tónlist</string>
<string name="level_to_switch_vector_raster_descr">Nota rastakort fyrir allt undir þessu aðdráttarstigi.</string>
@ -1746,7 +1746,7 @@
<string name="incremental_search_building">Stigvaxandi leit byggingar</string>
<string name="poi_error_info_not_loaded">Upplýsingum um hnút var ekki hlaðið inn</string>
<string name="use_fast_recalculation">Snjöll endurreiknun leiðar</string>
<string name="use_fast_recalculation_desc">Einungis endurreikna upphafshluta leiðar fyrir langar ferðir.</string>
<string name="use_fast_recalculation_desc">Endurreiknar aðeins upphafshluta leiðar. Má nota fyrir langar ferðir.</string>
<string name="confirm_download_roadmaps">Kortið sem eingöngu er með vegum er ekki nauðsynlegt, þar sem þú ert þegar með staðlaða (fulla útgáfu) kortsins. Sækja það samt?</string>
<string name="rendering_attr_depthContours_description">Birta dýptarlínur og punkta.</string>
<string name="rendering_attr_depthContours_name">Dýptarlínur sjávar</string>
@ -2116,7 +2116,7 @@
<string name="import_gpx_failed_descr">Gat ekki flutt skrána inn. Vinsamlegast athugið hvort OsmAnd hafi réttindi til að lesa skrána þar sem hún er.</string>
<string name="open_mapillary">Opna Mapillary</string>
<string name="mapillary_widget">Mapillary græja</string>
<string name="mapillary">Götumyndir</string>
<string name="mapillary">Mapillary götumyndir</string>
<string name="mapillary_image">Mapillary-mynd</string>
<string name="map_widget_ruler_control">Mælistika út frá miðju hrings</string>
<string name="shared_string_permissions">Heimildir</string>
@ -2904,10 +2904,10 @@
<string name="routeInfo_road_types_name">Gerðir vega</string>
<string name="exit_at">Fara útaf við</string>
<string name="sit_on_the_stop">Fara um borð við stöðvunina</string>
<string name="quick_action_show_hide_gpx_tracks">Birta/Fela GPX-ferla</string>
<string name="quick_action_show_hide_gpx_tracks_descr">Hnappur til að birta eða fela valda GPX-ferla á kortinu.</string>
<string name="quick_action_gpx_tracks_hide">Fela GPX-ferla</string>
<string name="quick_action_gpx_tracks_show">Birta GPX-ferla</string>
<string name="quick_action_show_hide_gpx_tracks">Birta/Fela ferla</string>
<string name="quick_action_show_hide_gpx_tracks_descr">Hnappur til að birta eða fela valda ferla á kortinu.</string>
<string name="quick_action_gpx_tracks_hide">Fela ferla</string>
<string name="quick_action_gpx_tracks_show">Birta ferla</string>
<string name="release_3_3">• Nýr skjár fyrir \'Leiðir\': Birtir leiðarhnappa fyrir \'Heim\' og \'Vinna\', flýtileið á fyrri leið, listi yfir virka GPX-ferla og merki, leitarferill
\n
\n • Viðbótarupplýsingar undir \'Nánar um leið\': gerð vegar, yfirborð, bratti, áferð
@ -3766,7 +3766,7 @@
<string name="quick_action_showhide_mapillary_descr">Víxlhnappur til að birta eða fela Mapillary-lagið á kortinu.</string>
<string name="shared_string_bearing">Stefna</string>
<string name="item_deleted">%1$s eytt</string>
<string name="speed_cameras_restart_descr">Endurræsing er nauðsynleg til að geta fjarlægt alveg gögn um hraðamyndavélar.</string>
<string name="speed_cameras_restart_descr">Endurræstu forritið til að fjarlægja öll gögn um hraðamyndavélar.</string>
<string name="shared_string_uninstall_and_restart">Fjarlægja og endurræsa</string>
<string name="shared_string_uninstall">Fjarlægja</string>
<string name="speed_cameras_legal_descr">Aðvaranir vegna hraðamyndavéla eru bannaðar með lögum í sumum löndum.
@ -3777,19 +3777,19 @@
\n
\nVeldu %2$s: öllum gögnum sem tengjast hraðamyndavélum; t.d. aðvaranir, tilkynningar, staðsetningar o.fl. verður eytt þar til OsmAnd er sett inn aftur frá grunni.</string>
<string name="route_between_points_add_track_desc">Veldu ferilskrá þar sem nýjum bút verður bætt inn.</string>
<string name="route_between_points_desc">Veldu hvernig eigi að tengja punkta; með beinni línu eða reikna leið milli þeirra með þessu sniði.</string>
<string name="route_between_points_desc">Veldu hvernig eigi að tengja punkta; með beinni línu eða reikna leið milli þeirra eins og tiltekið er hér að neðan.</string>
<string name="route_between_points_whole_track_button_desc">Allur ferillinn verður endurreiknaður með völdu sniði.</string>
<string name="osm_edit_closed_note">Lokaður OSM-minnispunktur</string>
<string name="whole_track">Allur ferillinn</string>
<string name="track_show_start_finish_icons">Sýna tákn fyrir upphaf/enda</string>
<string name="track_show_start_finish_icons">Sýna tákn fyrir upphaf og enda</string>
<string name="speed_cameras_removed_descr">Þetta tæki er ekki með hraðamyndavélar.</string>
<string name="app_mode_go_cart">Gókart</string>
<string name="set_working_days_to_continue">Þú verður að skilgreina virka daga til að halda áfram</string>
<string name="set_working_days_to_continue">Skilgreindu virka daga til að halda áfram</string>
<string name="quick_action_remove_next_destination">Eyða næsta markpunkti</string>
<string name="navigation_profile">Leiðsagnarsnið</string>
<string name="app_mode_wheelchair_forward">Hjólastóll áfram</string>
<string name="plugin_wikipedia_description">Náðu í upplýsingar um merka staði frá Wikipedia. Þetta er þá orðið að vasaleiðsögn án nettengingar - bara virkjaðu Wikipedia-viðbótina og njóttu þess að geta lesið um hlutina í kringum þig.</string>
<string name="use_volume_buttons_as_zoom_descr">Virkja þetta til að hægt sé að stýra aðdráttarstigi korts með hljóðstyrkshnöppum.</string>
<string name="use_volume_buttons_as_zoom_descr">Stýrðu aðdráttarstigi korts með hljóðstyrkshnöppum tækisins.</string>
<string name="routing_attr_length_description">Tilgreindu lengd farartækis sem leyfð er á leiðum.</string>
<string name="in_case_of_reverse_direction">Ef stefna er öfug</string>
<string name="route_between_points_next_segment_button_desc">Aðeins næsti bútur verður endurreiknaður með völdu sniði.</string>
@ -3840,7 +3840,7 @@
\n</string>
<string name="gpx_split_interval_descr">Veldu bilið þar sem merki með tíma eða vegalengd á ferlinum verða birt.</string>
<string name="attach_to_the_roads">Tengja við vegina</string>
<string name="plan_route_exit_dialog_descr">Ertu viss um að þú viljir loka leiðaskipulagningu án þess að vista\? Þú munt tapa öllum breytingum.</string>
<string name="plan_route_exit_dialog_descr">Ertu viss um að þú viljir loka leiðaskipulagningu án þess að vista\?</string>
<string name="marker_save_as_track">Vista sem ferilskrá</string>
<string name="threshold_distance">Þolvik vegalengdar</string>
<string name="save_track_to_gpx_globally">Skrifa feril í GPX-skrá</string>
@ -3856,11 +3856,9 @@
<string name="start_of_the_track">Upphaf ferils</string>
<string name="shared_string_gpx_files">Ferlar</string>
<string name="access_hint_enter_address">Settu inn heimilisfang</string>
<string name="import_track_descr">Veldu ferilskrá til að fylgja eða flyttu inn úr tæki.</string>
<string name="import_track_descr">Veldu ferilskrá til að fylgja eða flyttu hana inn úr tækinu þínu.</string>
<string name="add_segment_to_the_track">Bæta í ferilskrá</string>
<string name="route_between_points_warning_desc">Til að nota þennan valkost þarf OsmAnd að festa ferilinn þinn við vegi á kortinu.
\n
\nÍ næsta skrefi þarftu að velja leiðsagnarsnið svo hægt sé að finna hvaða vegir séu leyfilegir og hvaða þolvik vegalengdar eigi að miða við til að nálga ferilinn þinn við fyrirliggjandi vegi.</string>
<string name="route_between_points_warning_desc">Í næsta skrefi þarftu að velja leiðsagnarsnið svo hægt sé að finna hvaða vegir séu leyfilegir og hvaða þolvik vegalengdar eigi að miða við til að nálga ferilinn þinn við fyrirliggjandi vegi.</string>
<string name="empty_state_my_tracks">Bæta við ferilskrám</string>
<string name="app_mode_inline_skates">Línuskautar</string>
<string name="add_address">Bæta við heimilisfangi</string>
@ -3868,7 +3866,7 @@
<string name="map_widget_monitoring">Skráning ferðar</string>
<string name="nearest_point">Næsti punktur</string>
<string name="show_gpx">Ferlar</string>
<string name="monitoring_control_start">GPX</string>
<string name="monitoring_control_start">REC</string>
<string name="plan_route_trim_before">Klippa á undan</string>
<string name="context_menu_item_add_waypoint">Bæta við leiðarpunkti í feril</string>
<string name="plan_route_change_route_type_after">Skipta um gerð leiðar eftir</string>
@ -3879,4 +3877,41 @@
<string name="shared_string_gpx_route">Skrá leið í feril</string>
<string name="select_another_track">Velja annan feril</string>
<string name="save_track_to_gpx">Skrifa feril sjálfkrafa í GPX-skrá á meðan leiðsögn stendur</string>
<string name="what_is_new">Nýjungar</string>
<string name="simplified_track">Einfaldaður ferill</string>
<string name="simplified_track_description">Aðeins leiðarlínan verður vistuð, ferilpunktunum verður eytt.</string>
<string name="shared_string_file_name">Skráarheiti</string>
<string name="system_default_theme">Sjálfgefið í kerfinu</string>
<string name="all_next_segments">Allir bútar í kjölfarið</string>
<string name="previous_segment">Fyrri bútur</string>
<string name="all_previous_segments">Allir fyrri bútar</string>
<string name="only_selected_segment_recalc">Aðeins valinn bútur verður endurreiknaður með völdu sniði.</string>
<string name="all_next_segments_will_be_recalc">Allir bútar sem á eftir fylgja verða endurreiknaðir með völdu sniði.</string>
<string name="all_previous_segments_will_be_recalc">Allir fyrri bútar verða endurreiknaðir með völdu sniði.</string>
<string name="open_saved_track">Opna vistaðan feril</string>
<string name="shared_string_is_saved">er vistað</string>
<string name="one_point_error">Bættu við a.m.k. tveimur punktum.</string>
<string name="shared_string_redo">Endurtaka</string>
<string name="sort_last_modified">Síðast breytt</string>
<string name="sort_name_descending">Nafn: Ö A</string>
<string name="sort_name_ascending">Nafn: A Ö</string>
<string name="start_finish_icons">Tákn við upphaf/enda</string>
<string name="routing_attr_avoid_footways_description">Forðast gangstéttir</string>
<string name="routing_attr_avoid_footways_name">Forðast gangstéttir</string>
<string name="development">Þróun</string>
<string name="use_live_public_transport">OsmAnd Live gögn</string>
<string name="use_live_routing">OsmAnd Live gögn</string>
<string name="use_complex_routing">Flókin leiðagerð</string>
<string name="complex_routing_descr">Tveggja-þátta leiðagerð fyrir bílaleiðsögn.</string>
<string name="use_native_pt">Innbyggð þróun almenningssamgangna</string>
<string name="use_native_pt_desc">Skipta yfir í Java (öruggt) útreikning fyrir almenningssamgöngur</string>
<string name="perform_oauth_authorization_description">Framkvæma OAuth-innskráningu til að nota osmedit-eiginleika</string>
<string name="perform_oauth_authorization">Skrá inn í gegnum OAuth</string>
<string name="clear_osm_token">Hreinsa OAuth-teikn OpenStreetMap</string>
<string name="osm_edit_logout_success">Útskráning tókst</string>
<string name="number_of_gpx_files_selected_pattern">%s GPX-skrár valdar</string>
<string name="disable_recording_once_app_killed_descrp">Mun setja GPX-skráningu í bið þegar forritið er drepið (slökkt á því í gegnum skjáinn fyrir nýleg forrit - bakgrunnsvísir OsmAnd hverfur þar með úr tilkynningastiku Android-kerfisins.)</string>
<string name="save_global_track_interval_descr">Veldu millibil skráninga í almenna leiðarskráningu (virkjað með viðmótshlutanum fyrir GPX-skráningu á kortinu).</string>
<string name="gpx_monitoring_stop">Setja skráningu í bið</string>
<string name="gpx_monitoring_start">Halda áfram með skráningu</string>
</resources>

View file

@ -3931,4 +3931,11 @@
<string name="perform_oauth_authorization">להיכנס דרך OAuth</string>
<string name="clear_osm_token">למחוק את אסימון ה־OAuth של OpenStreetMap</string>
<string name="osm_edit_logout_success">היציאה הצליחה</string>
<string name="file_already_imported">הקובץ כבר ייובא אל OsmAnd</string>
<string name="use_two_phase_routing">להשתמש באלגוריתם חישוב מסלול דו־שלבי A*</string>
<string name="snowmobile_render_descr">לנהיגה ברכבי שלג עם דרכים ומסלולים יעודיים.</string>
<string name="message_need_calculate_route_before_show_graph">הנתונים של %1$s זמינים בדרכים בלבד, עליך לחשב מסלול באמצעות „מסלול בין נקודות” כדי לקבל אותם.</string>
<string name="shared_string_graph">תרשים</string>
<string name="message_graph_will_be_available_after_recalculation">נא להמתין לחישוב המסלול מחדש.
\nהתרשים יהיה זמין לאחר החישוב מחדש.</string>
</resources>

View file

@ -50,8 +50,8 @@
<string name="poi_internet_access">インターネット有り</string>
<string name="poi_entertainment">レジャー</string>
<string name="poi_club">クラブ</string>
<string name="poi_sustenance">食堂</string>
<string name="poi_cafe_and_restaurant">軽食</string>
<string name="poi_sustenance">飲食店</string>
<string name="poi_cafe_and_restaurant">カフェ・レストラン</string>
<string name="poi_service">サービス</string>
<string name="poi_craft">工芸</string>
<string name="poi_finance">金融機関</string>
@ -568,9 +568,9 @@
<string name="poi_park">公園</string>
<string name="poi_recreation_ground">レクリエーション広場</string>
<string name="poi_village_green">共有地</string>
<string name="poi_cafe">喫茶店・カフェ</string>
<string name="poi_cafe">カフェ</string>
<string name="poi_biergarten">ビアガーデン</string>
<string name="poi_restaurant">レストラン・食堂</string>
<string name="poi_restaurant">レストラン</string>
<string name="poi_fast_food">ファーストフード</string>
<string name="poi_bar">バー・立ち呑み屋</string>
<string name="poi_food_court">フードコート</string>
@ -1012,7 +1012,7 @@
<string name="poi_entrance_main">正面玄関</string>
<string name="poi_entrance">入り口</string>
<string name="poi_entrance_exit">出口</string>
<string name="poi_highway_crossing">高速道路の横断歩道</string>
<string name="poi_highway_crossing">横断歩道</string>
<string name="poi_opening_hours">営業時間</string>
<string name="poi_collection_times">収集時間</string>
<string name="poi_description">詳細</string>
@ -3834,4 +3834,5 @@
<string name="poi_borough">行政区</string>
<string name="poi_give_box">ギブボックス(提供品置場)</string>
<string name="poi_fire_hydrant_type_pipe">簡易給水栓</string>
<string name="poi_fuel_lng">液化天然ガス</string>
</resources>

View file

@ -927,10 +927,10 @@ POIの更新は利用できません</string>
<string name="free_version_message">このOsmAnd 無料版はダウンロード数が%1$s個に制限されており、オフラインでのWikipedia記事利用もサポートしていません。</string>
<string name="free_version_title">無料版</string>
<string name="poi_context_menu_showdescription">POIの説明文を表示</string>
<string name="index_name_north_america"></string>
<string name="index_name_north_america">アメリカ</string>
<string name="index_name_us">アメリカ合衆国</string>
<string name="index_name_central_america"></string>
<string name="index_name_south_america"></string>
<string name="index_name_central_america">央アメリカ</string>
<string name="index_name_south_america">アメリカ</string>
<string name="index_name_europe">ヨーロッパ</string>
<string name="index_name_france">ヨーロッパ - フランス</string>
<string name="index_name_germany">ヨーロッパ - ドイツ</string>
@ -1553,7 +1553,7 @@ POIの更新は利用できません</string>
<string name="routing_attr_height_name">高さ制限</string>
<string name="routing_attr_height_description">ルート上で通行可能な車両の高さを指定します。</string>
<string name="use_fast_recalculation">スマートなルート再計算</string>
<string name="use_fast_recalculation_desc">経路が長い場合、最初の部分のみ再計算します。</string>
<string name="use_fast_recalculation_desc">ルートの最初の部分のみを再計算します。旅程(設定ルート)がとても長い場合に効果的です。</string>
<string name="light_theme">明色</string>
<string name="dark_theme">暗色</string>
<string name="lang_pms">ピエモンテ語</string>
@ -1936,7 +1936,7 @@ POIの更新は利用できません</string>
<string name="app_mode_bus">バス</string>
<string name="app_mode_train">鉄道</string>
<string name="current_track">現在の経路</string>
<string name="map_widget_battery">バッテリーレベル</string>
<string name="map_widget_battery">バッテリー残量</string>
<string name="change_markers_position">マーカーの位置を変更</string>
<string name="move_marker_bottom_sheet_title">マップ画面のドラッグでマーカー位置を調整できます</string>
<!-- string name="lat_lon_pattern">"緯度:%1$.5f 経度:%2$.5f"</string -->
@ -3307,7 +3307,7 @@ POIの更新は利用できません</string>
<string name="osmand_settings_descr">アプリ全体に反映されます</string>
<string name="osmand_settings">OsmAnd設定</string>
<string name="copy_from_other_profile">他のプロファイルからコピー</string>
<string name="turn_screen_on">画面表示機能</string>
<string name="turn_screen_on">画面の復帰設定</string>
<string name="map_during_navigation_info">ナビゲーション中のマップ表示</string>
<string name="map_during_navigation">ナビゲーション中のマップ表示</string>
<string name="shared_string_other">その他</string>
@ -3705,7 +3705,7 @@ POIの更新は利用できません</string>
<string name="lang_gu">グジャラート語</string>
<string name="lang_cv">チュヴァシ語</string>
<string name="gpx_parse_error">OsmAnd GPXの形式が正しくありません。サポートチームに連絡しての調査をおすすめします。</string>
<string name="screen_timeout">画面のタイムアウト</string>
<string name="screen_timeout">画面の消灯設定</string>
<string name="turn_screen_on_descr">画面復帰オプションを選択します(端末設定でロックされる場合は、OsmAndがバックグラウンド動作でないことを確認してください):</string>
<string name="system_screen_timeout_descr">端末側の画面オフ(省電力)設定に従って画面を消灯します。</string>
<string name="system_screen_timeout">端末側の画面オフ設定を使用</string>
@ -3760,7 +3760,7 @@ POIの更新は利用できません</string>
<string name="weight_limit_description">車両の重量を入力してください。一部のルートにおいては、大型車両では通行できない場合があります。</string>
<string name="lenght_limit_description">車の長さを入力してください。一部のルートにおいては、長い車両では通行できない場合があります。</string>
<string name="shared_string_always">常に</string>
<string name="screen_control">画面制御</string>
<string name="screen_control">画面制御</string>
<string name="turn_screen_on_power_button_disabled">現在無効。 \'画面を表示する時間\'の下にある\'画面を常に表示\'への設定が必要です。</string>
<string name="keep_screen_off">画面オフを維持</string>
<string name="pseudo_mercator_projection">疑似メルカトル図法</string>
@ -3801,7 +3801,7 @@ POIの更新は利用できません</string>
<string name="shared_string_uninstall">アンインストール</string>
<string name="speed_cameras_alert">一部の国では、スピードカメラの事前警告は法律で禁止されています。</string>
<string name="screen_timeout_descr">\"%1$s\"がオンの場合、設定された動作時間はそちらに依存します。</string>
<string name="default_screen_timeout">デフォルトの画面タイムアウト時間</string>
<string name="default_screen_timeout">端末設定の画面スリープ時間に従う</string>
<string name="shared_string_tones">トーン</string>
<string name="shared_string_meters">メートル</string>
<string name="details_dialog_decr">追加マップの詳細を表示または非表示にします</string>
@ -3900,4 +3900,18 @@ POIの更新は利用できません</string>
<string name="sort_last_modified">最終更新日</string>
<string name="sort_name_descending">名称: 降順(Z-A)</string>
<string name="sort_name_ascending">名称: 昇順(A-Z)</string>
<string name="use_native_pt_desc">Java(セーフモード)での公共交通機関ルーティング計算に切り替えます</string>
<string name="perform_oauth_authorization_description">OsmEdit機能を利用するには、OAuthでのログインが必要です。</string>
<string name="perform_oauth_authorization">OAuthでログイン</string>
<string name="clear_osm_token">OpenStreetMapOAuthトークンを消去する</string>
<string name="osm_edit_logout_success">ログアウトしました</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">OsmAnd Liveデータ</string>
<string name="use_live_routing">OsmAnd Liveデータ</string>
<string name="use_complex_routing">複雑なルート計算</string>
<string name="complex_routing_descr">カーナビゲーション向けの2段階ルート計算です。</string>
<string name="use_two_phase_routing">2段階 A*ルーティングアルゴリズムを使用</string>
<string name="file_already_imported">ファイルはすでにOsmAndにインポートされています</string>
</resources>

View file

@ -3866,4 +3866,6 @@
<string name="perform_oauth_authorization">Logg inn via OAuth</string>
<string name="what_is_new">Hva er nytt</string>
<string name="osm_edit_logout_success">Utlogget</string>
<string name="use_two_phase_routing">Bruk 2-stegs A*-rutingsalgoritme</string>
<string name="file_already_imported">Filen er allerede importert i OsmAnd</string>
</resources>

View file

@ -3561,14 +3561,14 @@
<string name="poi_health_specialty_radiotheraphy_yes">Radioterapia</string>
<string name="poi_hazard">Perigo</string>
<string name="poi_rtsa_scale_filter">Categoria de dificuldade</string>
<string name="poi_rtsa_scale_nc">н/к</string>
<string name="poi_rtsa_scale_nc_asterisk">н/к*</string>
<string name="poi_rtsa_scale_1a">1А</string>
<string name="poi_rtsa_scale_1a_asterisk">1А*</string>
<string name="poi_rtsa_scale_nc">n/c</string>
<string name="poi_rtsa_scale_nc_asterisk">n/c*</string>
<string name="poi_rtsa_scale_1a">1A</string>
<string name="poi_rtsa_scale_1a_asterisk">1A*</string>
<string name="poi_rtsa_scale_1b">1B</string>
<string name="poi_rtsa_scale_1b_asterisk">1B*</string>
<string name="poi_rtsa_scale_2a">2А</string>
<string name="poi_rtsa_scale_2a_asterisk">2А*</string>
<string name="poi_rtsa_scale_2a_asterisk">2A*</string>
<string name="poi_rtsa_scale_2b">2B</string>
<string name="poi_rtsa_scale_2b_asterisk">2B*</string>
<string name="poi_rtsa_scale_3a">3А</string>

View file

@ -2821,7 +2821,7 @@
<string name="osm_live_payment_renews_annually">Renova anualmente</string>
<string name="osm_live_payment_renews_quarterly">Renova trimestralmente</string>
<string name="powered_by_osmand">Por OsmAnd</string>
<string name="default_price_currency_format">%1$,2f %2$s</string>
<string name="default_price_currency_format">%1$.2f %2$s</string>
<string name="osm_live_payment_header">Período de pagamento:</string>
<string name="osm_live_payment_contribute_descr">As doações ajudam a financiar a cartografia no OSM.</string>
<string name="release_3_1">• Navegação: Corrige barra de progresso, inversão rápida de início e fim de rota
@ -3921,4 +3921,11 @@
<string name="perform_oauth_authorization">Entrar via OAuth</string>
<string name="clear_osm_token">Limpar token do OpenStreetMap OAuth</string>
<string name="osm_edit_logout_success">Saída bem sucedida</string>
<string name="file_already_imported">O arquivo já foi importado para OsmAnd</string>
<string name="use_two_phase_routing">Use o algoritmo de roteamento 2-phase A *</string>
<string name="snowmobile_render_descr">Para dirigir em motos de neve com estradas e trilhas exclusivas.</string>
<string name="shared_string_graph">Gráfico</string>
<string name="message_need_calculate_route_before_show_graph">Dados de %1$s disponíveis apenas nas estradas, você precisa calcular uma rota usando “Rota entre pontos” para obtê-la.</string>
<string name="message_graph_will_be_available_after_recalculation">Aguarde o recálculo da rota.
\nO gráfico estará disponível após o recálculo.</string>
</resources>

View file

@ -3548,18 +3548,18 @@
<string name="poi_park_ride_tram">Bonde</string>
<string name="poi_park_ride_ferry">Balsa</string>
<string name="poi_generator_source_biomass">Fonte de energia: biomassa</string>
<string name="poi_rtsa_scale_nc">н/к</string>
<string name="poi_rtsa_scale_nc_asterisk">н/к*</string>
<string name="poi_rtsa_scale_1a">1А</string>
<string name="poi_rtsa_scale_1a_asterisk">1А*</string>
<string name="poi_rtsa_scale_nc">n/c</string>
<string name="poi_rtsa_scale_nc_asterisk">n/c*</string>
<string name="poi_rtsa_scale_1a">1A</string>
<string name="poi_rtsa_scale_1a_asterisk">1A*</string>
<string name="poi_rtsa_scale_1b">1B</string>
<string name="poi_rtsa_scale_1b_asterisk">1B*</string>
<string name="poi_rtsa_scale_2a">2А</string>
<string name="poi_rtsa_scale_2a_asterisk">2А*</string>
<string name="poi_rtsa_scale_2a">2A</string>
<string name="poi_rtsa_scale_2a_asterisk">2A*</string>
<string name="poi_rtsa_scale_2b">2B</string>
<string name="poi_rtsa_scale_2b_asterisk">2B*</string>
<string name="poi_rtsa_scale_3a">3А</string>
<string name="poi_rtsa_scale_3a_asterisk">3А*</string>
<string name="poi_rtsa_scale_3a">3A</string>
<string name="poi_rtsa_scale_3a_asterisk">3A*</string>
<string name="poi_rtsa_scale_3b">3B</string>
<string name="poi_rtsa_scale_3b_asterisk">3B*</string>
<string name="poi_flare">Explosão de gás;Queimador de gás</string>

View file

@ -3928,4 +3928,11 @@
<string name="perform_oauth_authorization">Fazer login via OAuth</string>
<string name="clear_osm_token">Limpar token do OpenStreetMap OAuth</string>
<string name="osm_edit_logout_success">Logout bem sucedido</string>
<string name="file_already_imported">O ficheiro já é importado em OsmAnd</string>
<string name="use_two_phase_routing">Usar algoritmo de roteamento de 2 fases A*</string>
<string name="snowmobile_render_descr">Para a condução de motos de neve com estradas e pistas dedicadas.</string>
<string name="shared_string_graph">Gráfico</string>
<string name="message_need_calculate_route_before_show_graph">%1$s dados disponíveis apenas nas estradas, precisa calcular uma rota a usar \"Rota entre pontos\" para obtê-la.</string>
<string name="message_graph_will_be_available_after_recalculation">Espere pelo recalculo da rota.
\nO gráfico estará disponível após o recalculo.</string>
</resources>

View file

@ -1737,7 +1737,7 @@
<string name="poi_animal_boarding_cat">Тип приюта: для кошек</string>
<string name="poi_animal_boarding_dog_cat">Тип приюта: для собак и кошек</string>
<string name="poi_animal_boarding_horse">Тип приюта: для лошадей</string>
<string name="poi_historic_aircraft">Исторический самолёт</string>
<string name="poi_historic_aircraft">Историческое воздушное судно</string>
<string name="poi_honey">Мёд</string>
<string name="poi_elevator_yes">С лифтом</string>
<string name="poi_elevator_no">Без лифта</string>

View file

@ -1336,7 +1336,7 @@
<string name="local_index_tile_data_name">Данные о тайлах: %1$s</string>
<string name="base_world_map">Обзорная карта мира</string>
<string name="edit_tilesource_expiration_time">Время действия (в минутах)</string>
<string name="app_mode_aircraft">Самолёт</string>
<string name="app_mode_aircraft">Воздушное судно</string>
<string name="app_mode_boat">Лодка</string>
<string name="app_mode_hiking">Пеший туризм</string>
<string name="app_mode_motorcycle">Мотоцикл</string>
@ -2269,7 +2269,7 @@
<string name="quick_actions_delete">Удалить действие</string>
<string name="quick_actions_delete_text">Вы уверены, что хотите удалить действие «%s»\?</string>
<string name="quick_action_favorites_show">Показать избранные</string>
<string name="quick_action_favorites_hide">Скрыть сохранённые</string>
<string name="quick_action_favorites_hide">Скрыть избранные</string>
<string name="quick_action_showhide_poi_title">Показать/скрыть POI</string>
<string name="quick_action_poi_show">Показать %1$s</string>
<string name="quick_action_poi_hide">Скрыть %1$s</string>
@ -3242,8 +3242,8 @@
<string name="logcat_buffer">Буфер Logcat</string>
<string name="plugins_settings">Настройки плагинов</string>
<string name="language_and_output">Язык и вывод</string>
<string name="change_data_storage_full_description">Переместить файлы данных OsmAnd в новое место назначения\?
\n%1$s &gt; %2$s</string>
<string name="change_data_storage_full_description">Переместить файлы данных OsmAnd в новое место назначения\?
\n%1$s %2$s</string>
<string name="shared_string_by_default">По умолчанию</string>
<string name="data_storage_preference_summary">%1$s • %2$s</string>
<string name="data_storage_space_description">%1$s ГБ свободно (из %2$s ГБ)</string>
@ -3349,7 +3349,7 @@
<string name="select_color">Выберите цвет</string>
<string name="edit_profiles_descr">Вы не можете удалить стандартные профили OsmAnd, но вы можете отключить их на предыдущем экране или переместить вниз.</string>
<string name="edit_profiles">Редактировать профили</string>
<string name="select_nav_profile_dialog_message">Режим навигации определяет правила расчета маршрутов.</string>
<string name="select_nav_profile_dialog_message">Режим навигации определяет правила расчёта маршрутов.</string>
<string name="profile_appearance">Внешний вид профиля</string>
<string name="choose_icon_color_name">Значок, цвет и имя</string>
<string name="reorder_profiles">Редактировать список профилей</string>
@ -3580,7 +3580,7 @@
<string name="monitoring_min_speed_descr_remark">Примечание: проверка скорости &gt; 0: большинство модулей GPS сообщают значение скорости только в том случае, если алгоритм определяет, что вы движетесь, и ничего, если вы не перемещаетесь. Следовательно, использование параметра &gt; 0 в этом фильтре в некотором смысле приводит к обнаружению факта перемещения модуля GPS. Но даже если мы не производим данную фильтрацию во время записи, то всё равно эта функция используется при анализе GPX для определения скорректированного расстояния, то есть значение, отображаемое в этом поле, является расстоянием, записанным во время движения.</string>
<string name="multimedia_rec_split_title">Разделение записи</string>
<string name="live_monitoring_adress_descr">Укажите веб-адрес со следующими параметрами: lat={0}, lon={1}, timestamp={2}, hdop={3}, altitude={4}, speed={5}, bearing={6}.</string>
<string name="monitoring_min_accuracy_descr">"Будут записываться только точки, отвечающие по показателю минимальной точности (в метрах или футах — зависит от настроек системы). Точность — это близость измерений к истинному положению, и она не связана напрямую с точностью, которая представляет собой разброс повторных измерений."</string>
<string name="monitoring_min_accuracy_descr">Будут записываться только точки, отвечающие по показателю минимальной точности (в метрах или футах — зависит от настроек системы). Точность — это близость измерений к истинному положению, и она не связана напрямую с точностью, которая представляет собой разброс повторных измерений.</string>
<string name="monitoring_min_speed_descr_recommendation">Рекомендация: попробуйте сначала воспользоваться детектором движения через фильтр минимального смещения (B), что может дать лучшие результаты и вы потеряете меньше данных. Если треки остаются шумными на низких скоростях, попробуйте использовать ненулевые значения. Обратите внимание, что некоторые измерения могут вообще не указывать значения скорости (некоторые сетевые методы), и в этом случае ничего не будет записываться.</string>
<string name="slope_description">Для визуализации крутизны рельефа используются цвета.</string>
<string name="slope_read_more">Подробнее об уклонах можно прочитать в %1$s.</string>
@ -3882,7 +3882,7 @@
<string name="disable_recording_once_app_killed_descrp">Остановка записи GPX при принудительном закрытии (через последние приложения). (Из панели уведомлений Android исчезнет значок фонового режима.)</string>
<string name="shared_string_is_saved">сохранен</string>
<string name="one_point_error">Добавьте хотя бы две точки.</string>
<string name="shared_string_redo">ПОВТОРИТЬ</string>
<string name="shared_string_redo">Повторить</string>
<string name="release_3_8">• Обновлённая функция планирования маршрута позволяет применять к сегментам разные режимы навигации и настраивать привязку к дорогам
\n
\n • Новые настройки вида треков: выбор цвета и толщины линии, указатели направления, метки начала и конца маршрута
@ -3906,9 +3906,9 @@
<string name="routing_attr_avoid_footways_description">Избегать пешеходных дорожек</string>
<string name="routing_attr_avoid_footways_name">Избегать пешеходных дорожек</string>
<string name="osm_live_payment_desc_hw">Подписка взимается за выбранный период. Отмените её в AppGallery в любое время.</string>
<string name="osm_live_payment_subscription_management_hw">Оплата будет снята с вашей учетной записи AppGallery при подтверждении покупки.
<string name="osm_live_payment_subscription_management_hw">Оплата будет снята с вашей учётной записи AppGallery при подтверждении покупки.
\n
\nПодписка продлевается автоматически, если она не будет отменена до даты продления. С вашего счета будет взиматься плата за период продления (месяц/три месяца/год) только в дату продления.
\nПодписка продлевается автоматически, если она не будет отменена до даты продления. С вашего счёта будет взиматься плата за период продления (месяц/три месяца/год) только в дату продления.
\n
\nВы можете управлять своими подписками и отменять их, перейдя в настройки AppGallery.</string>
<string name="use_live_public_transport">Данные OsmAnd Live</string>
@ -3920,4 +3920,8 @@
<string name="perform_oauth_authorization">Войти через OAuth</string>
<string name="clear_osm_token">Очистить токен OAuth OpenStreetMap</string>
<string name="osm_edit_logout_success">Выход выполнен</string>
</resources>
<string name="shared_string_graph">График</string>
<string name="file_already_imported">Файл уже импортирован</string>
<string name="message_graph_will_be_available_after_recalculation">Дождитесь пересчёта маршрута.
\nГрафик будет доступен после пересчёта.</string>
</resources>

View file

@ -3557,20 +3557,20 @@
<string name="poi_health_specialty_radiotheraphy_yes">Radioterapia</string>
<string name="poi_hazard">Perìgulu</string>
<string name="poi_rtsa_scale_filter">Categoria de dificultade</string>
<string name="poi_rtsa_scale_nc">н/к</string>
<string name="poi_rtsa_scale_nc_asterisk">н/к*</string>
<string name="poi_rtsa_scale_1a">1А</string>
<string name="poi_rtsa_scale_1a_asterisk">1А*</string>
<string name="poi_rtsa_scale_1b">1Б</string>
<string name="poi_rtsa_scale_1b_asterisk">1Б*</string>
<string name="poi_rtsa_scale_2a">2А</string>
<string name="poi_rtsa_scale_2a_asterisk">2А*</string>
<string name="poi_rtsa_scale_2b">2Б</string>
<string name="poi_rtsa_scale_2b_asterisk">2Б*</string>
<string name="poi_rtsa_scale_3a">3А</string>
<string name="poi_rtsa_scale_3a_asterisk">3А*</string>
<string name="poi_rtsa_scale_3b">3Б</string>
<string name="poi_rtsa_scale_3b_asterisk">3Б*</string>
<string name="poi_rtsa_scale_nc">n/c</string>
<string name="poi_rtsa_scale_nc_asterisk">n/c*</string>
<string name="poi_rtsa_scale_1a">1A</string>
<string name="poi_rtsa_scale_1a_asterisk">1A*</string>
<string name="poi_rtsa_scale_1b">1B</string>
<string name="poi_rtsa_scale_1b_asterisk">1B*</string>
<string name="poi_rtsa_scale_2a">2A</string>
<string name="poi_rtsa_scale_2a_asterisk">2A*</string>
<string name="poi_rtsa_scale_2b">2B</string>
<string name="poi_rtsa_scale_2b_asterisk">2B*</string>
<string name="poi_rtsa_scale_3a">3A</string>
<string name="poi_rtsa_scale_3a_asterisk">3A*</string>
<string name="poi_rtsa_scale_3b">3B</string>
<string name="poi_rtsa_scale_3b_asterisk">3B*</string>
<string name="poi_flare">Frama de gas;Tortza de brusiadura</string>
<string name="poi_change_delete">Ogetu iscantzelladu</string>
<string name="poi_health_specialty_radiotherapy_yes">Radioterapia</string>

View file

@ -89,7 +89,7 @@
<string name="routing_preferences_descr">Preferèntzias de càrculu de sàndala</string>
<string name="speech_rate_descr">Imposta sa lestresa de sa boghe de sintetizatzione vocale (TTS).</string>
<string name="speech_rate">Lestresa de sa boghe</string>
<string name="complex_route_calculation_failed">Càrculu lestru de sàndala fallidu (%s), rinviu a su càlculu lentu.</string>
<string name="complex_route_calculation_failed">Càrculu lestru de sàndala fallidu (%s), rinviu a su càrculu lentu.</string>
<string name="disable_complex_routing_descr">Istuda su carculu de sàndala in duas fases pro simpreu in màchina.</string>
<string name="disable_complex_routing">Istuta su carculu cumplessu de sàndala</string>
<string name="amenity_type_seamark">Pidagnu</string>
@ -1540,7 +1540,7 @@
<string name="routing_attr_height_description">Dislinda sartària de su veìculu permìtida pro sos caminos.</string>
<string name="routing_attr_avoid_borders_description">Non faghet rugrare sas fronteras intre sos istados</string>
<string name="use_fast_recalculation">Recàrculu intelligente de sàndala</string>
<string name="use_fast_recalculation_desc">Pro biàgios longos, torra a carculare petzi su cantu initziale de sàndala.</string>
<string name="use_fast_recalculation_desc">Torra a carculare petzi su cantu initziale de sàndala. Podet èssere impreadu pro biàgios longos.</string>
<string name="rendering_value_disabled_name">Disabilitadu</string>
<string name="shared_string_logoff">Essi</string>
<string name="rendering_value_walkingRoutesScopeOSMC_name">Coloratzione a segunda de sa casta (afiliatzione) de àndala</string>
@ -3824,8 +3824,8 @@
<string name="overwrite_track">Subraiscrie sa rasta</string>
<string name="save_as_new_track">Sarva comente una rasta noa</string>
<string name="reverse_route">Fùrria s\'àndala</string>
<string name="route_between_points_whole_track_button_desc">Sa rasta intrea at a èssere torrada a calculare impreende su profilu ischertadu.</string>
<string name="route_between_points_next_segment_button_desc">Petzi su segmentu imbeniente at a èssere torradu a calculare impreende su profilu ischertadu.</string>
<string name="route_between_points_whole_track_button_desc">Sa rasta intrea at a èssere torrada a carculare impreende su profilu ischertadu.</string>
<string name="route_between_points_next_segment_button_desc">Petzi su segmentu imbeniente at a èssere torradu a carculare impreende su profilu ischertadu.</string>
<string name="route_between_points_desc">Ischerta comente connètere sos puntos: cun una lìnia reta o calculende un\'àndala intre issos comente dislindadu inoghe in suta.</string>
<string name="whole_track">Rasta intrea</string>
<string name="next_segment">Segmentu imbeniente</string>
@ -3913,4 +3913,22 @@
\nPodes amministrare e annullare sos abbonamentos tuos intrende in sas impostatziones de AppGallery tuas.</string>
<string name="routing_attr_avoid_footways_description">Èvita sos martzapiedis</string>
<string name="routing_attr_avoid_footways_name">Èvita sos martzapiedis</string>
<string name="what_is_new">Ite b\'at de nou</string>
<string name="development">Isvilupu</string>
<string name="use_live_public_transport">Datos de OsmAnd Live</string>
<string name="use_live_routing">Datos de OsmAnd Live</string>
<string name="complex_routing_descr">Càrculu de s\'àndala a duas fases pro sa navigatzione in màchina.</string>
<string name="use_native_pt">Isvilupu de sos trasportos pùblicos nativos</string>
<string name="use_native_pt_desc">Cola a su càrculu de s\'àndala de sos trasportos pùblicos Java (seguru)</string>
<string name="perform_oauth_authorization_description">Intra cun OAuth pro impreare sas funtzionalidades osmedit</string>
<string name="perform_oauth_authorization">Intra impreende OAuth</string>
<string name="clear_osm_token">Iscantzella su getone OAuth de OpenStreetMap</string>
<string name="osm_edit_logout_success">Essida fata chene problemas</string>
<string name="file_already_imported">Su documentu est giai importadu in OsmAnd</string>
<string name="use_two_phase_routing">Imprea un\'algoritmu de càrculu de s\'àndala A* a duas fases</string>
<string name="snowmobile_render_descr">Pro sa ghia de motoislitas cun caminos e rastas dedicados.</string>
<string name="message_need_calculate_route_before_show_graph">Datos %1$s a disponimentu in sos caminos ebbia. Depes carculare un\'àndala impreende \"Àndala intre puntos\" pro los otènnere.</string>
<string name="shared_string_graph">Gràficu</string>
<string name="message_graph_will_be_available_after_recalculation">Iseta su càrculu nou de s\'àndala.
\nSu gràficu at a èssere a disponimentu a pustis de su càrculu.</string>
</resources>

View file

@ -3653,4 +3653,15 @@
<string name="poi_sms_no">Nie</string>
<string name="poi_sms_yes">Áno</string>
<string name="poi_taxi_office">Kancelária taxislužby</string>
<string name="poi_cash_withdrawal_postbank">Postbank</string>
<string name="poi_surface_decoturf">DecoTurf</string>
<string name="poi_health_specialty_podology_yes">Podológia</string>
<string name="poi_health_specialty_obstetrics_caesarean_section_no">Zdravotná špecializácia: pôrodníctvo (cisársky rez): nie</string>
<string name="poi_health_specialty_social_paediatrics_no">Zdravotná špecializácia: sociálna pediatria: nie</string>
<string name="poi_health_specialty_social_paediatrics_yes">Sociálna pediatria</string>
<string name="poi_health_specialty_obstetrics_antenatal_no">Zdravotná špecializácia: pôrodníctvo (prenatálne): nie</string>
<string name="poi_health_specialty_obstetrics_antenatal_yes">Pôrodníctvo (prenatálne)</string>
<string name="poi_health_specialty_obstetrics_postnatal_no">Zdravotná špecializácia: pôrodníctvo (postnatálne): nie</string>
<string name="poi_wetland_palsa_bog">Rašelinisko</string>
<string name="poi_wetland_fen">Slatina</string>
</resources>

View file

@ -3919,11 +3919,18 @@
<string name="use_live_routing">Údaje OsmAnd Live</string>
<string name="use_complex_routing">Komplexný výpočet trasy</string>
<string name="complex_routing_descr">Dvojfázový výpočet trasy pre navigáciu auta.</string>
<string name="use_native_pt">Natívny vývoj hromadnej dopravy</string>
<string name="use_native_pt">Natívna hromadná doprava (vo vývoji)</string>
<string name="use_native_pt_desc">Prepnúť na výpočet trasy hromadnej dopravy v Jave (bezpečné)</string>
<string name="what_is_new">Čo je nové</string>
<string name="perform_oauth_authorization_description">Vykonať prihlásenie cez OAuth pre použitie funkcií upravovania OSM</string>
<string name="perform_oauth_authorization">Prihlásiť pomocou OAuth</string>
<string name="clear_osm_token">Vymazať token OpenStreetMap OAuth</string>
<string name="osm_edit_logout_success">Odhlásenie úspešné</string>
<string name="snowmobile_render_descr">Pre jazdu na snežnom vozidle po na to určených cestách.</string>
<string name="file_already_imported">Súbor je už importovaný v OsmAnd</string>
<string name="use_two_phase_routing">Použiť dvojfázový algoritmus A* na výpočet trasy</string>
<string name="shared_string_graph">Graf</string>
<string name="message_need_calculate_route_before_show_graph">Údaje %1$s sú dostupné len na cestách, pre ich získanie musíte vypočítať trasu pomocou “Trasa medzi bodmi”.</string>
<string name="message_graph_will_be_available_after_recalculation">Počkajte na prepočet trasy.
\nGraf bude dostupný po prepočte.</string>
</resources>

View file

@ -269,7 +269,7 @@
<string name="poi_motorway_junction">Otoyol kavşağı</string>
<string name="poi_junction">Birleşim</string>
<string name="poi_rest_area">Dinlenme alanı</string>
<string name="poi_water_well">Su kaynağı</string>
<string name="poi_water_well">Su kuyusu</string>
<string name="poi_standpipe">Yangın musluğu</string>
<string name="poi_water_works">Su işleri</string>
<string name="poi_boatyard">Tersane</string>
@ -366,7 +366,7 @@
<string name="poi_landfill">Depolama</string>
<string name="poi_waste_disposal">Çöp bertaraf</string>
<string name="poi_waste_basket">Çöp tenekesi</string>
<string name="poi_industrial">Sanayi Bölgesi</string>
<string name="poi_industrial">Sanayi bölgesi</string>
<string name="poi_quarry">Taş ocağı</string>
<string name="poi_vineyard">Üzüm bağı</string>
<string name="poi_orchard">Meyve bahçesi</string>
@ -841,7 +841,7 @@
<string name="poi_sinkhole">Düden</string>
<string name="poi_waterfall">Şelale</string>
<string name="poi_river">Irmak</string>
<string name="poi_stream">Akış</string>
<string name="poi_stream">Dere</string>
<string name="poi_rapids">Nehrin akıntılı yeri</string>
<string name="poi_stone">Değerli taş</string>
<string name="poi_cape">Pelerin</string>
@ -1068,7 +1068,7 @@
<string name="poi_takeaway">Paket servisi</string>
<string name="poi_cocktails">Kokteyller</string>
<string name="poi_microbrewery">Mikro bira imalathanesi</string>
<string name="poi_beauty_salon_service">Servis</string>
<string name="poi_beauty_salon_service">Hizmet</string>
<string name="poi_recycling_accepted_waste">Kabul edilen atık</string>
<string name="poi_fireplace">Şömine</string>
<string name="poi_seasonal">Mevsimlik</string>
@ -1184,7 +1184,7 @@
<string name="poi_climbing_crag_filter">Tırmanma kayalığı</string>
<string name="poi_climbing_crag">Evet</string>
<string name="poi_historic_tank">Tarihi tank</string>
<string name="poi_snowmobile_filter">Kar aracı erişimi</string>
<string name="poi_snowmobile_filter">Kar arabası erişimi</string>
<string name="poi_access_bus">Otobüs erişimi</string>
<string name="poi_access_caravan">Karavan erişimi</string>
<string name="poi_access_motorhome">Motokaravan erişimi</string>
@ -1344,7 +1344,7 @@
<string name="poi_trade_agricultural_supplies">Ziraat malzemeleri</string>
<string name="poi_trade_tile">Döşeme malzemeleri</string>
<string name="poi_population">Nüfus</string>
<string name="poi_parking_underground">Yeraltı</string>
<string name="poi_parking_underground">Yer altı</string>
<string name="poi_parking_multi_storey">Çok katlı</string>
<string name="poi_bicycle_parking_stands">Standlar</string>
<string name="poi_bicycle_parking_wall_loops">Duvar döngüleri</string>
@ -2801,18 +2801,18 @@
<string name="poi_counselling_type_drugs_yes">Danışma (uyuşturucu): evet</string>
<string name="poi_counselling_type_addiction_no">Danışma (bağımlılık): evet</string>
<string name="poi_counselling_type_addiction_yes">Danışma (bağımlılık): evet</string>
<string name="poi_health_person_type_psychologist">Sağlık çalışanının işi: psikolog</string>
<string name="poi_health_person_type_psychologist">Sağlık çalışanının rolü: psikolog</string>
<string name="poi_health_amenity_type_first_aid_kit">İlk yardım çantası</string>
<string name="poi_fire_hydrant_type_wall">Duvar</string>
<string name="poi_fire_hydrant_type_underground">Yeraltı</string>
<string name="poi_fire_hydrant_type_underground">Yer altı</string>
<string name="poi_health_facility_type_field_hospital">Sağlık merkezi türü: sahra hastanesi</string>
<string name="poi_health_facility_type_laboratory">Sağlık merkezi türü: laboratuvar</string>
<string name="poi_health_service_prevention_vaccination_no">Sağlık hizmeti: aşılama: hayır</string>
<string name="poi_health_service_prevention_vaccination_yes">Sağlık hizmeti: aşılama: evet</string>
<string name="poi_health_service_counselling_no">Sağlık hizmeti: danışma: hayır</string>
<string name="poi_health_service_counselling_yes">Sağlık hizmeti: danışma: evet</string>
<string name="poi_health_service_nursing_no">Sağlık hizmeti: hasta bakıcılık: hayır</string>
<string name="poi_health_service_nursing_yes">Sağlık hizmeti: hasta bakıcılık: evet</string>
<string name="poi_health_service_nursing_no">Sağlık hizmeti: hemşirelik: hayır</string>
<string name="poi_health_service_nursing_yes">Sağlık hizmeti: hemşirelik: evet</string>
<string name="poi_medical_system_tibetan_yes">Geleneksel Tibet</string>
<string name="poi_medical_system_mongolian_yes">Geleneksel Moğol</string>
<string name="poi_medical_system_chinese_yes">Geleneksel Çin</string>
@ -2915,4 +2915,219 @@
<string name="poi_cuisine_deli">Şarküteri</string>
<string name="poi_cuisine_pie">Turta</string>
<string name="poi_cuisine_tea_shop">Çay dükkanı</string>
<string name="poi_health_person_type_witchdoctor">Sağlık çalışanının rolü: büyücü</string>
<string name="poi_health_person_type_technician">Sağlık çalışanının rolü: teknisyen</string>
<string name="poi_health_person_type_physician_assitant">Sağlık çalışanının rolü: doktor asistanı</string>
<string name="poi_health_person_type_therapist">Sağlık çalışanının rolü: terapist</string>
<string name="poi_health_person_type_podologist">Sağlık çalışanının rolü: podolog</string>
<string name="poi_health_person_type_physician">Sağlık çalışanının rolü: doktor</string>
<string name="poi_health_person_type_paramedic">Sağlık çalışanının rolü: sağlık görevlisi</string>
<string name="poi_health_person_type_nurse">Sağlık çalışanının rolü: hemşire</string>
<string name="poi_health_person_type_midwife">Sağlık çalışanının rolü: ebe</string>
<string name="poi_health_person_type_healer">Sağlık çalışanının rolü: şifacı</string>
<string name="poi_health_person_type_assistant">Sağlık çalışanının rolü: asistan</string>
<string name="poi_suction_point">Emme noktası</string>
<string name="poi_health_facility_type_support_group_home">Sağlık tesisi türü: destek grubu evi</string>
<string name="poi_health_facility_type_nursing_home">Sağlık tesisi türü: huzurevi</string>
<string name="poi_health_facility_type_department">Sağlık merkezi türü: bölüm</string>
<string name="poi_health_service_test_no">Sağlık hizmeti: test: hayır</string>
<string name="poi_health_service_test_yes">Sağlık hizmeti: test: evet</string>
<string name="poi_health_service_support_no">Sağlık hizmeti: destek: hayır</string>
<string name="poi_health_service_support_yes">Sağlık hizmeti: destek: evet</string>
<string name="poi_health_service_prevention_no">Sağlık hizmeti: önleme: hayır</string>
<string name="poi_health_service_prevention_yes">Sağlık hizmeti: önleme: evet</string>
<string name="poi_health_service_child_care_no">Sağlık hizmeti: çocuk bakımı: hayır</string>
<string name="poi_health_service_child_care_yes">Sağlık hizmeti: çocuk bakımı: evet</string>
<string name="poi_health_service_examination_no">Sağlık hizmeti: muayene: hayır</string>
<string name="poi_health_service_examination_yes">Sağlık hizmeti: muayene: evet</string>
<string name="poi_health_facility_type_first_aid">Sağlık merkezi türü: ilk yardım</string>
<string name="poi_health_facility_type_dispensary">Sağlık merkezi türü: dispanser</string>
<string name="poi_health_facility_type_therapy">Sağlık merkezi türü: terapi</string>
<string name="poi_health_facility_type_counselling_centre">Sağlık merkezi türü: danışma merkezi</string>
<string name="poi_health_facility_type_office">Tıbbi ofis</string>
<string name="poi_free_flying_rigid_no">Sert serbest uçuş: hayır</string>
<string name="poi_free_flying_rigid_yes">Sert</string>
<string name="poi_free_flying_hanggliding_no">Yelken kanatla uçuş: hayır</string>
<string name="poi_free_flying_hanggliding_yes">Yelken kanatla uçuş</string>
<string name="poi_free_flying_paragliding_no">Yamaç paraşütü: hayır</string>
<string name="poi_free_flying_paragliding_yes">Yamaç paraşütü</string>
<string name="poi_free_flying_official_no">Resmi: hayır</string>
<string name="poi_free_flying_official_yes">Resmi: evet</string>
<string name="poi_free_flying_site_training">Eğitim alanı</string>
<string name="poi_free_flying_site_towing">Çekme alanı</string>
<string name="poi_free_flying_site_toplanding">Zirve iniş alanı</string>
<string name="poi_free_flying_site_landing">İniş alanı</string>
<string name="poi_free_flying_site_takeoff">Kalkış alanı</string>
<string name="poi_button_operated_no">Düğme ile etkinleştirilir: hayır</string>
<string name="poi_button_operated_yes">Düğme ile etkinleştirilir: evet</string>
<string name="poi_sport_free_flying">Serbest uçuş (spor)</string>
<string name="poi_nuclear_explosion_device">Patlama: aygıt</string>
<string name="poi_nuclear_explosion_warhead">Patlama: savaş başlığı</string>
<string name="poi_nuclear_explosion_crater_diameter">Patlama: krater çapı</string>
<string name="poi_nuclear_explosion_salvo_second_or_later_detonation">Patlama salvosu: bir salvo testinin ikinci veya daha sonraki patlaması</string>
<string name="poi_nuclear_explosion_salvo_first_detonation">Patlama salvosu: bir salvo testinin ilk patlaması</string>
<string name="poi_nuclear_explosion_body_wave_magnitude">Vücut dalgası büyüklüğü</string>
<string name="poi_nuclear_explosion_ground_zero_altitude">Patlama merkezinin yüksekliği</string>
<string name="poi_nuclear_explosion_height_of_burst">Patlama boyu</string>
<string name="poi_nuclear_explosion_hole">Patlama deliği</string>
<string name="poi_nuclear_explosion_yield">Patlama gücü</string>
<string name="poi_nuclear_explosion_purpose_industrial_application_earth_moving">Patlama amacı: sanayi uygulaması, toprak kaydırma</string>
<string name="poi_nuclear_explosion_purpose_industrial_application">Patlama amacı: sanayi uygulaması</string>
<string name="poi_nuclear_explosion_purpose_industrial_application_oil_stimulation">Patlama amacı: sanayi uygulaması, petrol uyarımı</string>
<string name="poi_nuclear_explosion_purpose_industrial_application_seismic_sounding">Patlama amacı: sanayi uygulaması, sismik sondaj</string>
<string name="poi_nuclear_explosion_purpose_industrial_application_cavity_excavation">Patlama amacı: sanayi uygulaması, kazı çalışması</string>
<string name="poi_nuclear_explosion_purpose_fundamental_science">Patlama amacı: temel bilim</string>
<string name="poi_nuclear_explosion_purpose_research_for_peaceful_applications">Patlama amacı: barışçıl uygulamalar için araştırma</string>
<string name="poi_nuclear_explosion_purpose_safety_experiment">Patlama amacı: güvenlik deneyi</string>
<string name="poi_nuclear_explosion_purpose_weapons_effects">Patlama amacı: silah etkileri</string>
<string name="poi_nuclear_explosion_purpose_nuclear_weapons_related">Patlama amacı: nükleer silahlarla ilgili</string>
<string name="poi_nuclear_explosion_series">Patlama serisi</string>
<string name="poi_nuclear_explosion_shot_name_en">Kod adı (ingilizce)</string>
<string name="poi_nuclear_explosion_type_underwater">Patlama türü: su altı</string>
<string name="poi_nuclear_explosion_type_space">Patlama türü: uzay (80 km\'nin üzerindeki yükseklik)</string>
<string name="poi_nuclear_explosion_type_atmospheric_rocket_or_missile">Patlama türü: atmosferik, roket veya füze</string>
<string name="poi_nuclear_explosion_type_cratering_burst">Patlama türü: krater patlaması (sığ yüzey altı)</string>
<string name="poi_nuclear_explosion_type_atmospheric_water_surface_barge">Patlama türü: atmosferik, su yüzeyi, mavna</string>
<string name="poi_nuclear_explosion_type_atmospheric_atmospheric_surface">Patlama türü: atmosferik, yüzey</string>
<string name="poi_nuclear_explosion_type_atmospheric_balloon">Patlama türü: atmosferik, balon</string>
<string name="poi_nuclear_explosion_type_atmospheric_surface_tower">Patlama türü: atmosferik, yüzey, kule</string>
<string name="poi_nuclear_explosion_type_atmospheric_airdrop">Patlama türü: atmosferik, havadan atma</string>
<string name="poi_nuclear_explosion_type_atmospheric">Patlama türü: atmosferik</string>
<string name="poi_nuclear_explosion_type_underground_shaft">Patlama türü: yeraltı, kuyu</string>
<string name="poi_nuclear_explosion_site">Patlama: alan</string>
<string name="poi_protection_title">Koruma türü</string>
<string name="poi_bandy">Bandy</string>
<string name="poi_street_cabinet">Sokak dolabı</string>
<string name="poi_firepit">Ateş çukuru</string>
<string name="poi_fire_hydrant_style_water_source_main">Ana</string>
<string name="poi_fire_hydrant_style_wsh">Musluk tarzı: wsh</string>
<string name="poi_fire_hydrant_position_underground">Yer altı</string>
<string name="poi_fire_hydrant_position_street">Sokak</string>
<string name="poi_fire_hydrant_position_parking_lot">Park yeri</string>
<string name="poi_fire_hydrant_position_lane">Şerit</string>
<string name="poi_fire_hydrant_position_green">Çimen</string>
<string name="poi_fire_hydrant_position_sidewalk">Kaldırım</string>
<string name="poi_fire_hydrant_flow_capacity">Musluk akış kapasitesi</string>
<string name="poi_fire_hydrant_count">Musluk sayısı</string>
<string name="poi_fire_hydrant_pressure">Musluk basıncı</string>
<string name="poi_fire_hydrant_diameter">Musluk çapı</string>
<string name="poi_office_midwife">Ebe ofisi</string>
<string name="poi_office_nursing_service">Hemşirelik hizmeti</string>
<string name="poi_office_psychologist">Psikolog ofisi</string>
<string name="poi_office_healer">Şifacı ofisi</string>
<string name="poi_office_podologist">Podolog ofisi</string>
<string name="poi_office_therapist">Terapist ofisi</string>
<string name="poi_office_physician">Doktor ofisi</string>
<string name="poi_treat_inpatient_only">Yatarak tedavi hizmetleri: yalnızca</string>
<string name="poi_treat_inpatient_no">Yatarak tedavi hizmetleri: hayır</string>
<string name="poi_treat_inpatient_yes">Yatarak tedavi hizmetleri: evet</string>
<string name="poi_counselling_type_violence_no">Danışma (şiddet): hayır</string>
<string name="poi_counselling_type_violence_yes">Danışma (şiddet): evet</string>
<string name="poi_counselling_type_victim_no">Danışma (kurban): hayır</string>
<string name="poi_counselling_type_victim_yes">Danışma (kurban): evet</string>
<string name="poi_counselling_type_sexual_abuse_no">Danışma (cinsel istismar): hayır</string>
<string name="poi_counselling_type_sexual_abuse_yes">Danışma (cinsel istismar): evet</string>
<string name="poi_counselling_type_sexual_no">Danışma (cinsellik): hayır</string>
<string name="poi_counselling_type_sexual_yes">Danışma (cinsellik): evet</string>
<string name="poi_counselling_type_rehabilitation_no">Danışma (rehabilitasyon): hayır</string>
<string name="poi_counselling_type_rehabilitation_yes">Danışma (rehabilitasyon): evet</string>
<string name="poi_counselling_type_nutrition_nfire_hydo">Danışma (beslenme): hayır</string>
<string name="poi_counselling_type_nutrition_yes">Danışma (beslenme): evet</string>
<string name="poi_counselling_type_marriage_no">Danışma (evlilik): hayır</string>
<string name="poi_counselling_type_marriage_yes">Danışma (evlilik): evet</string>
<string name="poi_counselling_type_immigrant_no">Danışma (göçmen): hayır</string>
<string name="poi_counselling_type_immigrant_yes">Danışma (göçmen): evet</string>
<string name="poi_counselling_type_education_no">Danışma (eğitim): hayır</string>
<string name="poi_counselling_type_education_yes">Danışma (eğitim): evet</string>
<string name="poi_counselling_type_crisis_no">Danışma (kriz): hayır</string>
<string name="poi_counselling_type_crisis_yes">Danışma (kriz): evet</string>
<string name="poi_counselling_type_couple_no">Danışma (çift): hayır</string>
<string name="poi_counselling_type_couple_yes">Danışma (çift): evet</string>
<string name="poi_counselling_type_child_guidance_no">Danışma (çocuk rehberliği): hayır</string>
<string name="poi_counselling_type_child_guidance_yes">Danışma (çocuk rehberliği): evet</string>
<string name="poi_counselling_type_antenatal_yes">Danışma (doğum öncesi): evet</string>
<string name="poi_counselling_type_antenatal_no">Danışma (doğum öncesi): hayır</string>
<string name="poi_spaceport">Uzay üssü</string>
<string name="poi_animal_shelter_purpose_release_no">Doğaya salma: hayır</string>
<string name="poi_animal_shelter_purpose_release_yes">Doğaya salma: evet</string>
<string name="poi_animal_shelter_purpose_adoption_no">Sahiplenme: hayır</string>
<string name="poi_animal_shelter_purpose_adoption_yes">Sahiplenme: evet</string>
<string name="poi_owner">Sahibi</string>
<string name="poi_resort_kids_camp">Çocuk kampı</string>
<string name="poi_photo_studio">Fotoğraf stüdyosu</string>
<string name="poi_nutrition_supplements">Beslenme takviyeleri</string>
<string name="poi_feeding_place">Hayvan besleme yeri</string>
<string name="poi_support_tower">Destek: kule</string>
<string name="poi_support_roof">Destek: çatı</string>
<string name="poi_support_suspended">Destek: askıda</string>
<string name="poi_support_ceiling">Destek: tavan</string>
<string name="poi_support_billboard">Destek: reklam panosu</string>
<string name="poi_support_ground">Destek: zemin</string>
<string name="poi_support_pedestal">Destek: kaide</string>
<string name="poi_support_tree">Destek: ağaç</string>
<string name="poi_support_wall_mounted">Destek: duvar</string>
<string name="poi_support_pole">Destek: direk</string>
<string name="poi_date_no">Tarih ekranı: hayır</string>
<string name="poi_date_yes">Tarih ekranı</string>
<string name="poi_pumping_station">Pompa istasyonu</string>
<string name="poi_generator_output_biogas_yes">Çıkış: biyogaz</string>
<string name="poi_generator_output_biogas">Biyogazın çıkış gücü</string>
<string name="poi_generator_output_vacuum_yes">Çıkış: vakum</string>
<string name="poi_generator_output_compressed_air_yes">Çıkış: basınçlı hava</string>
<string name="poi_generator_output_compressed_air">Basınçlı havanın çıkış gücü</string>
<string name="poi_generator_output_cold_water_yes">Çıkış: soğuk su</string>
<string name="poi_generator_output_hot_air_yes">Çıkış: sıcak hava</string>
<string name="poi_generator_output_steam_yes">Çıkış: buhar</string>
<string name="poi_generator_output_hot_water_yes">Çıkış: sıcak su</string>
<string name="poi_generator_output_hot_water">Sıcak suyun çıkış gücü</string>
<string name="poi_generator_output_electricity_no">Çıkış (elektrik): hayır</string>
<string name="poi_generator_output_electricity_yes">Çıkış: elektrik</string>
<string name="poi_generator_output_electricity">Çıkış gücü</string>
<string name="poi_voltage">Gerilim</string>
<string name="poi_greenhouse_horticulture">Sera bahçeciliği</string>
<string name="poi_observatory_type_gravitational">Yer çekimi</string>
<string name="poi_observatory_type_meteorological">Meteorolojik</string>
<string name="poi_health_amenity_type_scales">Kamu kullanımı için ölçekler</string>
<string name="poi_free_flying_guest_guidelines_no">Konuk yönergeleri: hayır</string>
<string name="poi_free_flying_guest_guidelines_yes">Konuk yönergeleri: evet</string>
<string name="poi_free_flying_no_flight_time">Uçuşa yasak zaman (serbest uçuş)</string>
<string name="poi_free_flying_site_orientation_nw">Serbest uçuş alanı yönlendirmesi: KB</string>
<string name="poi_free_flying_site_orientation_w">Serbest uçuş alanı yönlendirmesi: B</string>
<string name="poi_free_flying_site_orientation_sw">Serbest uçuş alanı yönlendirmesi: GB</string>
<string name="poi_free_flying_site_orientation_s">Serbest uçuş alanı yönlendirmesi: G</string>
<string name="poi_free_flying_site_orientation_se">Serbest uçuş alanı yönlendirmesi: GD</string>
<string name="poi_free_flying_site_orientation_e">Serbest uçuş alanı yönlendirmesi: D</string>
<string name="poi_free_flying_site_orientation_ne">Serbest uçuş alanı yönlendirmesi: KD</string>
<string name="poi_free_flying_site_orientation_n">Serbest uçuş alanı yönlendirmesi: K</string>
<string name="poi_water_place_access_multifamilies">Birden çok aile</string>
<string name="poi_water_place_access_family">Aile</string>
<string name="poi_water_place_access_community">Topluluk</string>
<string name="poi_water_supply_bottled_water">Şişelenmiş su</string>
<string name="poi_water_supply_water_tank">Su deposu</string>
<string name="poi_water_supply_water_trucking">Su tankeri</string>
<string name="poi_water_supply_borehole">Sondaj</string>
<string name="poi_water_supply_pump">Pompa</string>
<string name="poi_water_supply_running_water">Akan su</string>
<string name="poi_water_supply_pipeline">Boru hattı</string>
<string name="poi_water_supply_water_well">Su kuyusu</string>
<string name="poi_water_purification_aquatabs">Su arıtma tabletleri</string>
<string name="poi_water_purification_reverse_osmosis">Ters osmoz</string>
<string name="poi_water_purification_chlorine">Klor</string>
<string name="poi_visibility_area">Görünürlük: alan</string>
<string name="poi_surface_tartan">Tartan</string>
<string name="poi_government_social_services">Sosyal hizmetler</string>
<string name="poi_government_social_security">Sosyal güvenlik</string>
<string name="poi_electronics_repair_appliance">Elektronik tamir: alet</string>
<string name="poi_display_sundial_yes">Güneş saati</string>
<string name="poi_display_digital_yes">Dijital ekran</string>
<string name="poi_display_analog_yes">Analog ekran</string>
<string name="poi_display_no">Ekran: hayır</string>
<string name="poi_display_yes">Ekran: evet</string>
<string name="poi_dispensing_yes">Evet</string>
<string name="poi_fire_hydrant_style_water_source_cistern">Su deposu</string>
<string name="poi_fire_hydrant_style_water_source_stream">Dere</string>
<string name="poi_fire_hydrant_type_dry_barrel">Kuru varil</string>
<string name="poi_fire_hydrant_type_pillar">Sütun</string>
<string name="poi_fire_hydrant_type_pond">Gölet</string>
<string name="poi_fire_hydrant_style_water_source_pond">Gölet</string>
</resources>

View file

@ -8,7 +8,7 @@
<string name="enable_plugin_monitoring_services">Konum günlüğü hizmetlerini kullanmak için \"Yolculuk kaydı\" eklentisini etkinleştirin (GPX günlüğü, çevrim içi izleme)</string>
<string name="non_optimal_route_calculation">Uzak hedefler için tahmini rotayı hesapla</string>
<string name="gps_not_available">Lütfen GPS\'yi ayarlardan açık konuma getirin</string>
<string name="map_widget_monitoring_services">Log servisi</string>
<string name="map_widget_monitoring_services">Günlük kayıt hizmetleri</string>
<string name="no_route">Rota yok</string>
<string name="delete_target_point">Varış Noktasını kaldır</string>
<string name="target_point">Varış noktası %1$s</string>
@ -78,7 +78,7 @@
<string name="safe_mode_description">Uygulamayı güvenli modda çalıştırın (yerel kod yerine daha yavaş Android kullanarak).</string>
<string name="safe_mode">Güvenli kip</string>
<string name="native_library_not_running">Uygulama güvenli modda çalışıyor (\'Ayarlar\'dan kapatın).</string>
<string name="background_service_is_enabled_question">OsmAnd arka plan hizmeti hala çalışıyor. Onu da durdur\?</string>
<string name="background_service_is_enabled_question">OsmAnd arka plan hizmeti hala çalışıyor. O da durdurulsun mu\?</string>
<string name="local_indexes_cat_av">Ses/Video verisi</string>
<string name="stop_routing_confirm">Navigasyonu durdurmak istediğinizden emin misiniz\?</string>
<string name="clear_dest_confirm">Hedefi (ve ara hedefleri) temizlemek istediğinizden emin misiniz\?</string>
@ -633,7 +633,7 @@
<string name="local_index_installed">Yerel sürüm</string>
<string name="local_index_items_backuped">%1$d/%2$d öge devre dışı bırakıldı.</string>
<string name="local_index_items_deleted">%1$d/%2$d öge silindi.</string>
<string name="local_index_items_restored">%1$d/%2$d öge aktifleştirildi.</string>
<string name="local_index_items_restored">%1$d/%2$d öge etkinleştirildi.</string>
<string name="local_index_descr_title">Harita dosyalarını yönetin.</string>
<string name="local_index_mi_restore">Aktifleştir</string>
<string name="local_index_mi_backup">Pasifleştir</string>
@ -641,7 +641,7 @@
<string name="local_index_address_data">Adres Verisi</string>
<string name="local_index_transport_data">Toplu taşıma verileri</string>
<string name="local_index_map_data">Harita Verisi</string>
<string name="local_indexes_cat_backup">Pasifleştir</string>
<string name="local_indexes_cat_backup">Devre dışı</string>
<string name="local_indexes_cat_tts">Sesli uyarılar (TTS)</string>
<string name="local_indexes_cat_voice">Sesli uyarılar (kaydedilmiş)</string>
<string name="local_indexes_cat_poi">POI Verisi</string>
@ -837,7 +837,7 @@
<string name="background_service_provider">Konum sağlayıcı</string>
<string name="background_router_service_descr">Ekran kapalıyken konumunuzu izler.</string>
<string name="background_router_service">Arka planda Osmand başlat</string>
<string name="off_router_service_no_gps_available">Arka plan navigasyon hizmetiık olması bir konum sağlayıcı gerektirir.</string>
<string name="off_router_service_no_gps_available">Arka plan navigasyon hizmeti, bir konum sağlayıcının açık olmasını gerektirir.</string>
<string name="hide_poi_filter">Süzgeci gizle</string>
<string name="show_poi_filter">Süzgeci göster</string>
<string name="search_poi_filter">Süzgeç</string>
@ -881,7 +881,7 @@
<string name="hint_search_online">Çevrim içi arama: Ev numarası, sokak, şehir</string>
<string name="search_offline_address">Çevrim dışı arama</string>
<string name="route_general_information">Toplam uzaklık %1$s, seyahat süresi %2$d s %3$d dak.</string>
<string name="router_service_descr">Çevrim içi veya çevrim dışı navigasyon servisi.</string>
<string name="router_service_descr">Çevrim içi veya çevrim dışı navigasyon hizmeti.</string>
<string name="sd_dir_not_accessible">Bellek kartındaki depolama klasörüne erişilemiyor!</string>
<string name="download_question">{0} - {1} indir ?</string>
<string name="download_question_exist">{0} için çevrim dışı veri zaten var ({1}). ({2}) güncellensin mi\?</string>
@ -1065,7 +1065,7 @@
<string name="try_again">Tekrar deneyin</string>
<string name="archive_wikipedia_data">Eski uyumsuz Wikipedia verileriniz var. Arşivle\?</string>
<string name="download_wikipedia_files">Ekstra Wikipedia verilerini indir (%1$s MB)\?</string>
<string name="gps_network_not_enabled">Konum servisi kapalı. Aç\?</string>
<string name="gps_network_not_enabled">Konum hizmeti kapalı. Açılsın mı\?</string>
<string name="shared_string_show_details">Ayrıntıları göster</string>
<string name="rendering_value_disabled_name">Devre dışı</string>
<string name="rendering_attr_hideHouseNumbers_name">Ev kapı numaraları</string>
@ -1457,18 +1457,18 @@
<string name="layer_osm_bugs">OSM notları (çevrim içi)</string>
<string name="use_trackball_descr">Haritayı hareket ettirmek için bir izleme topu aygıtı kullanın.</string>
<string name="use_trackball">İzleme topu kullan</string>
<string name="background_service_int_descr">Arka plan servisi tarafından kullanılan uyanma aralığı:</string>
<string name="background_service_provider_descr">Arka plan servisi tarafından kullanılan konum yöntemi:</string>
<string name="route_head">Baş</string>
<string name="background_service_int_descr">Arka plan hizmeti tarafından kullanılan uyanma aralığı:</string>
<string name="background_service_provider_descr">Arka plan hizmeti tarafından kullanılan konum yöntemi:</string>
<string name="route_head">Düz gidin</string>
<string name="map_screen_orientation">Ekran yönlendirme</string>
<string name="no_address_found">Hiçbir adres belirlenmedi</string>
<string name="voices">Sesli uyarılar</string>
<string name="transport_context_menu">Durakta ulaşım aracı ara</string>
<string name="rotate_map_to_bearing">Harita yönlendirme</string>
<string name="version_index_is_not_supported">\'\'{0}\'\' indeks sürümü desteklenmemektedir</string>
<string name="osmand_routing_experimental">OsmAnd çevrim dışı navigasyon deneysel bir özelliktir ve yaklaşık 20 km\'den daha uzun mesafelerde çalışmaz.
\n
\nNavigasyon geçici olarak çevrim içi CloudMade servisine geçti.</string>
<string name="osmand_routing_experimental">OsmAnd çevrim dışı navigasyon deneysel bir özelliktir ve yaklaşık 20 km\'den daha uzun mesafelerde çalışmaz.
\n
\nNavigasyon geçici olarak çevrim içi CloudMade hizmetine geçti.</string>
<string name="install_selected_build">OsmAnd Yükle - {1} {2} üzerinden {0} MB \?</string>
<string name="tiles_to_download_estimated_size">Yakınlaştırma {0} indirmek {1} fayans ({2} MB)</string>
<string name="select_max_zoom_preload_area">Önceden yükleme için en fazla yakınlaştırma</string>
@ -1595,7 +1595,7 @@
<string name="lang_eu">Baskça</string>
<string name="lang_be">Belarusça</string>
<string name="lang_bs">Boşnakça</string>
<string name="use_points_as_intermediates">Noktalar arasındaki rotayı hesaplamak</string>
<string name="use_points_as_intermediates">Noktalar arasındaki güzergahı hesapla</string>
<string name="always_center_position_on_map">Konumu sürekli ortada tut</string>
<string name="voice_pref_title">Ses</string>
<string name="misc_pref_title">Çeşitli</string>
@ -1791,7 +1791,7 @@
<string name="lang_sw">Svahili dili</string>
<string name="lang_he">İbranice</string>
<string name="forward">İleri</string>
<string name="live_monitoring_m_descr">GPX kaydııksa, izleme verilerini belirtilen bir web servisine gönder.</string>
<string name="live_monitoring_m_descr">GPX kaydııksa, izleme verilerini belirtilen bir web hizmetine gönder.</string>
<string name="live_monitoring_m">Online izleme (GPX gerekli)</string>
<string name="live_monitoring_start">Online izleme başlat</string>
<string name="live_monitoring_stop">Online izleme durdurun</string>
@ -2094,7 +2094,7 @@
<string name="shared_string_deleted">Silindi</string>
<string name="shared_string_edited">Değiştirildi</string>
<string name="shared_string_added">Eklendi</string>
<string name="marker_activated">İşaretleyici %s aktifleştirildi.</string>
<string name="marker_activated">%s işaretleyicisi etkinleştirildi.</string>
<string name="one_tap_active_descr">İçerik menüsünü açmadan, harita üzerinde bir belirtecin üzerine bas ve aktif belirteçlerin üzerine sürükle.</string>
<string name="one_tap_active">\'Tek basış\' aktif</string>
<string name="empty_state_av_notes">Not alın!</string>
@ -2282,7 +2282,7 @@
<string name="show_passed">Geçilmiş-olanı göster</string>
<string name="hide_passed">Geçilmiş-olanı gizle</string>
<string name="marker_show_distance_descr">Haritada harita işaretleyicilerine olan uzaklık ve yönün nasıl belirtileceğini seçin:</string>
<string name="map_orientation_change_in_accordance_with_speed">Harita oryantasyon eşiği</string>
<string name="map_orientation_change_in_accordance_with_speed">Harita yönlendirme eşiği</string>
<string name="map_orientation_change_in_accordance_with_speed_descr">Harita yönünün \'Hareket yönü\'nden \'Pusula yönü\'ne geçiş hızını aşağıdan seçin.</string>
<string name="save_as_route_point">Rota noktaları olarak kaydet</string>
<string name="add_point_before">Öncesinde nokta ekle</string>
@ -2362,7 +2362,7 @@
<string name="shared_string_explore">Gezin</string>
<string name="shared_string_contents">İçerikler</string>
<string name="shared_string_result">Sonuç</string>
<string name="shared_string_travel_guides">Seyehat</string>
<string name="shared_string_travel_guides">Seyahat rehberleri</string>
<string name="shared_string_total">Toplam</string>
<string name="clear_all_intermediates">Tüm başlangıç noktalarını temizle</string>
<string name="group_deleted">Grup silindi</string>
@ -3578,7 +3578,7 @@
<string name="select_wikipedia_article_langs">Haritadaki Wikipedia makalelerinin dillerini seçin. Makaleyi okurken kullanılabilir herhangi bir dile geçiş yapın.</string>
<string name="some_articles_may_not_available_in_lang">Bazı Wikipedia makaleleri sizin dilinizde mevcut olmayabilir.</string>
<string name="lang_zhyue">Kantonca</string>
<string name="lang_zhminnan">Güney Min</string>
<string name="lang_zhminnan">Güney Mince</string>
<string name="lang_yo">Yorubaca</string>
<string name="lang_war">Varayca</string>
<string name="lang_uz">Özbekçe</string>
@ -3591,7 +3591,7 @@
<string name="lang_ne">Nepalce</string>
<string name="lang_nap">Napolice</string>
<string name="lang_my">Birmanca</string>
<string name="lang_min">Minangkabau dili</string>
<string name="lang_min">Minangkabauca</string>
<string name="lang_mg">Malgaşça</string>
<string name="lang_ky">Kırgızca</string>
<string name="lang_kk">Kazakça</string>
@ -3881,4 +3881,11 @@
<string name="perform_oauth_authorization">OAuth ile oturum aç</string>
<string name="clear_osm_token">OpenStreetMap OAuth belirtecini temizle</string>
<string name="osm_edit_logout_success">Oturum kapatma başarılı</string>
<string name="file_already_imported">Dosya zaten OsmAnd\'da içe aktarıldı</string>
<string name="use_two_phase_routing">2 aşamalı A* yönlendirme algoritması kullan</string>
<string name="snowmobile_render_descr">Ayrılmış yollar ve parkurlarla kar arabası sürüşü için.</string>
<string name="shared_string_graph">Grafik</string>
<string name="message_need_calculate_route_before_show_graph">%1$s verileri yalnızca yollarda kullanılabilir, elde etmek için “Noktalar arasındaki güzergah” kullanarak bir rota hesaplamanız gerekir.</string>
<string name="message_graph_will_be_available_after_recalculation">Güzergahın yeniden hesaplanmasını bekleyin.
\nGrafik yeniden hesaplandıktan sonra kullanılabilir olacak.</string>
</resources>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>

View file

@ -1147,7 +1147,7 @@
<string name="gpx_selection_track">%1$s
\nТрек %2$s</string>
<string name="osmo_connect_menu">З’єднатись</string>
<string name="use_points_as_intermediates">Розрахувати маршрут між точками</string>
<string name="use_points_as_intermediates">Обчислити маршрут між точками</string>
<string name="always_center_position_on_map">Відображати позицію завжди в центрі</string>
<string name="voice_pref_title">Голос</string>
<string name="misc_pref_title">Різне</string>
@ -2293,17 +2293,17 @@
<string name="osmand_extended_description_part1">OsmAnd (OSM Automated Navigation Directions) — застосунок для мап і навігації з доступом до безкоштовних глобальних високоякісних даних OpenStreetMap (OSM).
\n
\nНасолоджуйтесь голосовою та візуальною навігацією, переглядом цікавих точок (англ. POI), створенням та керуванням GPX-треками, використовуючи відображення горизонталей та даних про висоту (за допомогою зовнішнього втулка), вибором між режимами автомобіліста, велосипедиста й пішохода, редагуванням OSM та ще багато чим іншим.</string>
<string name="osmand_extended_description_part2">GPS навігація
\n • Вибір між автономним режимом (без зборів за роумінг за кордоном) або через Інтернет (швидше)
\n • Покрокові голосові підказки доставить Вас до місця призначення (записані чи синтезовані голоси)
\n • Повторна маршрутизація кожен раз після відхилення від маршруту
\n • Смуги руху, назви вулиць і приблизний час прибуття допоможуть Вам на шляху
\n • Для того, щоб зробити Вашу подорож безпечнішою, режим дня/ночі автоматично перемикається
\n • Відображення обмежень швидкості та попередження про її перевищення
\n • Мапа масштабується відповідно до Вашої швидкості
\n • Шукати місця за адресою, типом (наприклад, паркування, ресторан, готель, заправна станція, музей) чи географічними координатами
\n • Підтримка проміжних точок на Вашому маршруті
\n • Запис свого власного GPX-треку чи вивантаження готового і слідування за ним
<string name="osmand_extended_description_part2">GPS навігація
\n • Вибір між автономним режимом (без зборів за роумінг за кордоном) або через Інтернет (швидше)
\n • Покрокові голосові підказки доставить Вас до місця призначення (записані чи синтезовані голоси)
\n • Повторна маршрутизація кожен раз після відхилення від маршруту
\n • Смуги руху, назви вулиць і приблизний час прибуття допоможуть Вам на шляху
\n • Для того, щоб зробити Вашу подорож безпечнішою, режим дня/ночі автоматично перемикається
\n • Показ обмежень швидкості та попередження про її перевищення
\n • Мапа масштабується відповідно до Вашої швидкості
\n • Шукати місця за адресою, типом (наприклад, паркування, ресторан, готель, заправна станція, музей) чи географічними координатами
\n • Підтримка проміжних точок на Вашому маршруті
\n • Запис свого власного GPX-треку чи вивантаження готового і слідування за ним
\n</string>
<string name="osmand_extended_description_part3">Мапа
\n• Відображає POI (цікаві точки) навколо вас
@ -3922,4 +3922,11 @@
<string name="routing_attr_avoid_footways_description">Уникати пішохідних шляхів</string>
<string name="routing_attr_avoid_footways_name">Уникати пішохідних шляхів</string>
<string name="development">Розробка</string>
<string name="file_already_imported">Файл уже імпортовано до OsmAnd</string>
<string name="use_two_phase_routing">Використання 2-фазного A* алгоритму маршрутизації</string>
<string name="snowmobile_render_descr">Для їзди на снігоходах із відведеними дорогами та трасами.</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>
</resources>

View file

@ -3561,20 +3561,20 @@
<string name="poi_hazard">危險</string>
<string name="poi_rtsa_scale_filter">難度分類</string>
<string name="poi_health_specialty_radiotherapy_yes">放射治療</string>
<string name="poi_rtsa_scale_nc">н/к</string>
<string name="poi_rtsa_scale_nc_asterisk">н/к*</string>
<string name="poi_rtsa_scale_1a">1А</string>
<string name="poi_rtsa_scale_1a_asterisk">1А*</string>
<string name="poi_rtsa_scale_1b">1Б</string>
<string name="poi_rtsa_scale_1b_asterisk">1Б*</string>
<string name="poi_rtsa_scale_2a">2А</string>
<string name="poi_rtsa_scale_2a_asterisk">2А*</string>
<string name="poi_rtsa_scale_2b">2Б</string>
<string name="poi_rtsa_scale_2b_asterisk">2Б*</string>
<string name="poi_rtsa_scale_3a">3А</string>
<string name="poi_rtsa_scale_3a_asterisk">3А*</string>
<string name="poi_rtsa_scale_3b">3Б</string>
<string name="poi_rtsa_scale_3b_asterisk">3Б*</string>
<string name="poi_rtsa_scale_nc">n/c</string>
<string name="poi_rtsa_scale_nc_asterisk">n/c*</string>
<string name="poi_rtsa_scale_1a">1A</string>
<string name="poi_rtsa_scale_1a_asterisk">1A*</string>
<string name="poi_rtsa_scale_1b">1B</string>
<string name="poi_rtsa_scale_1b_asterisk">1B*</string>
<string name="poi_rtsa_scale_2a">2A</string>
<string name="poi_rtsa_scale_2a_asterisk">2A*</string>
<string name="poi_rtsa_scale_2b">2B</string>
<string name="poi_rtsa_scale_2b_asterisk">2B*</string>
<string name="poi_rtsa_scale_3a">3A</string>
<string name="poi_rtsa_scale_3a_asterisk">3A*</string>
<string name="poi_rtsa_scale_3b">3B</string>
<string name="poi_rtsa_scale_3b_asterisk">3B*</string>
<string name="poi_flare">燃燒塔</string>
<string name="poi_change_delete">已刪除的物件</string>
<string name="poi_climbing_crag_filter">攀岩</string>

View file

@ -3921,4 +3921,11 @@
<string name="perform_oauth_authorization">透過 OAuth 登入</string>
<string name="clear_osm_token">清除 OpenStreetMap OAuth 權杖</string>
<string name="osm_edit_logout_success">成功登出</string>
<string name="snowmobile_render_descr">適用於有專用道路與軌道的雪地摩托車駕駛。</string>
<string name="file_already_imported">檔案已在 OsmAnd 匯入</string>
<string name="use_two_phase_routing">使用 2 相的 A* 路線演算法</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>
</resources>

View file

@ -3935,20 +3935,20 @@
<string name="poi_park_ride_tram">Tram</string>
<string name="poi_park_ride_ferry">Ferry</string>
<string name="poi_rtsa_scale_nc">н/к</string>
<string name="poi_rtsa_scale_nc_asterisk">н/к*</string>
<string name="poi_rtsa_scale_1a">1А</string>
<string name="poi_rtsa_scale_1a_asterisk">1А*</string>
<string name="poi_rtsa_scale_1b">1Б</string>
<string name="poi_rtsa_scale_1b_asterisk">1Б*</string>
<string name="poi_rtsa_scale_2a">2А</string>
<string name="poi_rtsa_scale_2a_asterisk">2А*</string>
<string name="poi_rtsa_scale_2b">2Б</string>
<string name="poi_rtsa_scale_2b_asterisk">2Б*</string>
<string name="poi_rtsa_scale_3a">3А</string>
<string name="poi_rtsa_scale_3a_asterisk">3А*</string>
<string name="poi_rtsa_scale_3b">3Б</string>
<string name="poi_rtsa_scale_3b_asterisk">3Б*</string>
<string name="poi_rtsa_scale_nc">n/c</string>
<string name="poi_rtsa_scale_nc_asterisk">n/c*</string>
<string name="poi_rtsa_scale_1a">1A</string>
<string name="poi_rtsa_scale_1a_asterisk">1A*</string>
<string name="poi_rtsa_scale_1b">1B</string>
<string name="poi_rtsa_scale_1b_asterisk">1B*</string>
<string name="poi_rtsa_scale_2a">2A</string>
<string name="poi_rtsa_scale_2a_asterisk">2A*</string>
<string name="poi_rtsa_scale_2b">2B</string>
<string name="poi_rtsa_scale_2b_asterisk">2B*</string>
<string name="poi_rtsa_scale_3a">3A</string>
<string name="poi_rtsa_scale_3a_asterisk">3A*</string>
<string name="poi_rtsa_scale_3b">3B</string>
<string name="poi_rtsa_scale_3b_asterisk">3B*</string>
<string name="poi_flare">Gas flare;Flare stack</string>
<string name="poi_change_delete">Deleted object</string>
@ -4206,7 +4206,7 @@
<string name="poi_video_yes">Yes</string>
<string name="poi_video_no">No</string>
<string name="poi_internet_access_fee_customers">Signal to find the pole</string>
<string name="poi_internet_access_fee_customers">Internet access: customers</string>
<string name="poi_traffic_signals_sound_locate">Only when walking is allowed</string>
<string name="poi_tactile_paving_contrasted">Contrasted</string>
<string name="poi_tactile_paving_primitive">Primitive</string>
@ -4259,5 +4259,10 @@
<string name="poi_fuel_lng">LNG</string>
<string name="poi_gpx_point">GPX point</string>
<string name="poi_parking_rooftop">Rooftop</string>
<string name="poi_parking_sheds">Sheds</string>
<string name="poi_parking_layby">Layby</string>
</resources>

View file

@ -324,6 +324,7 @@
<dimen name="route_info_legend_padding">8dp</dimen>
<dimen name="route_info_warning_padding">18dp</dimen>
<dimen name="route_info_chart_height">71dp</dimen>
<dimen name="route_info_line_chart_height">120dp</dimen>
<dimen name="route_info_toolbar_button_size">40dp</dimen>
<dimen name="route_info_control_buttons_height">48dp</dimen>
<dimen name="route_info_button_bg_line_radius">18dp</dimen>

View file

@ -13,6 +13,10 @@
-->
<string name="app_mode_gap">Gap</string>
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
<string name="message_graph_will_be_available_after_recalculation">Wait for the route recalculation.\nGraph will be available after recalculation.</string>
<string name="message_need_calculate_route_before_show_graph">%1$s data available only on the roads, you need to calculate a route using “Route between points” to get it.</string>
<string name="shared_string_graph">Graph</string>
<string name="use_two_phase_routing">Use 2-phase A* routing algorithm</string>
<string name="file_already_imported">File is already imported in OsmAnd</string>
<string name="osm_edit_logout_success">Logout successful</string>
<string name="clear_osm_token">Clear OpenStreetMap OAuth token</string>
@ -22,7 +26,6 @@
<string name="use_native_pt">Native Public Transport development</string>
<string name="use_fast_recalculation_desc">Recalculates only the initial part of the route. Can be used for long trips.</string>
<string name="complex_routing_descr">Two-phase routing for car navigation.</string>
<string name="use_complex_routing">Complex routing</string>
<string name="use_live_routing">OsmAnd Live data</string>
<string name="use_live_public_transport">OsmAnd Live data</string>
<string name="development">Development</string>
@ -1018,6 +1021,7 @@
<string name="shared_string_bookmark">Bookmark</string>
<string name="hide_full_description">Hide full description</string>
<string name="show_full_description">Show full description</string>
<string name="snowmobile_render_descr">For snowmobile driving with dedicated roads and tracks.</string>
<string name="off_road_render_descr">For off-road driving based on \'Topo\' style and for use with green satellite images as an underlay. Reduced main road thickness, increased thickness of tracks, paths, bicycle and other routes.</string>
<string name="nautical_render_descr">For nautical navigation. Features buoys, lighthouses, riverways, sea lanes and marks, harbors, seamark services, and depth contours.</string>
<string name="ski_map_render_descr">For skiing. Features pistes, ski-lifts, cross country tracks, etc. Dims secondary map objects.</string>

View file

@ -8,9 +8,9 @@ import androidx.annotation.NonNull;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
import java.io.IOException;
import java.util.HashMap;
@ -66,13 +66,8 @@ public class AccessibilityPlugin extends OsmandPlugin {
}
@Override
public Class<? extends Activity> getSettingsActivity() {
return SettingsAccessibilityActivity.class;
}
@Override
public Class<? extends BaseSettingsFragment> getSettingsFragment() {
return AccessibilitySettingsFragment.class;
public SettingsScreenType getSettingsScreenType() {
return SettingsScreenType.ACCESSIBILITY_SETTINGS;
}
@Override

View file

@ -4,6 +4,8 @@ import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import android.widget.ImageView;
@ -13,21 +15,24 @@ import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceViewHolder;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.access.AccessibilityMode;
import net.osmand.plus.access.RelativeDirectionStyle;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.profiles.SelectCopyAppModeBottomSheet;
import net.osmand.plus.profiles.SelectCopyAppModeBottomSheet.CopyAppModePrefsListener;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.OnPreferenceChanged;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.bottomsheets.ResetProfilePrefsBottomSheet;
import net.osmand.plus.settings.bottomsheets.ResetProfilePrefsBottomSheet.ResetAppModePrefsListener;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.OnPreferenceChanged;
import net.osmand.plus.settings.preferences.ListPreferenceEx;
import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
import static net.osmand.plus.activities.PluginInfoFragment.PLUGIN_INFO;
public class AccessibilitySettingsFragment extends BaseSettingsFragment implements OnPreferenceChanged, CopyAppModePrefsListener, ResetAppModePrefsListener {
private static final String ACCESSIBILITY_OPTIONS = "accessibility_options";
@ -36,6 +41,8 @@ public class AccessibilitySettingsFragment extends BaseSettingsFragment implemen
private AccessibilityStateChangeListener accessibilityListener;
boolean showSwitchProfile = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -47,6 +54,28 @@ public class AccessibilitySettingsFragment extends BaseSettingsFragment implemen
}
}
};
Bundle args = getArguments();
if (args != null) {
showSwitchProfile = args.getBoolean(PLUGIN_INFO, false);
}
}
@Override
protected void createToolbar(LayoutInflater inflater, View view) {
super.createToolbar(inflater, view);
View switchProfile = view.findViewById(R.id.profile_button);
if (switchProfile != null) {
AndroidUiHelper.updateVisibility(switchProfile, showSwitchProfile);
}
}
@Override
public Bundle buildArguments() {
Bundle args = super.buildArguments();
args.putBoolean(PLUGIN_INFO, showSwitchProfile);
return args;
}
@Override

View file

@ -1,128 +0,0 @@
package net.osmand.access;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.access.AccessibilityMode;
import net.osmand.plus.access.RelativeDirectionStyle;
import net.osmand.plus.activities.SettingsBaseActivity;
public class SettingsAccessibilityActivity extends SettingsBaseActivity {
private ListPreference accessibilityModePreference;
private ListPreference directionStylePreference;
private ListPreference autoannouncePeriodPreference;
@Override
public void onCreate(Bundle savedInstanceState) {
((OsmandApplication) getApplication()).applyTheme(this);
super.onCreate(savedInstanceState);
getToolbar().setTitle(R.string.shared_string_accessibility);
PreferenceScreen grp = getPreferenceScreen();
String[] entries = new String[AccessibilityMode.values().length];
for (int i = 0; i < entries.length; i++) {
entries[i] = AccessibilityMode.values()[i].toHumanString(getMyApplication());
}
accessibilityModePreference = createListPreference(settings.ACCESSIBILITY_MODE, entries, AccessibilityMode.values(),
R.string.accessibility_mode, R.string.accessibility_mode_descr);
accessibilityModePreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
private final OnPreferenceChangeListener committer = accessibilityModePreference.getOnPreferenceChangeListener();
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (committer != null)
committer.onPreferenceChange(preference, newValue);
updateAllSettings();
return true;
}
});
addSpeechRateSetting(grp);
grp.addPreference(accessibilityModePreference);
PreferenceCategory cat = new PreferenceCategory(this);
cat.setKey("accessibility_options");
cat.setTitle(R.string.accessibility_options);
cat.setEnabled(getMyApplication().accessibilityEnabled());
grp.addPreference(cat);
entries = new String[RelativeDirectionStyle.values().length];
for (int i = 0; i < entries.length; i++) {
entries[i] = RelativeDirectionStyle.values()[i].toHumanString(getMyApplication());
}
directionStylePreference = createListPreference(settings.DIRECTION_STYLE, entries, RelativeDirectionStyle.values(),
R.string.settings_direction_style, R.string.settings_direction_style_descr);
directionStylePreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
private final OnPreferenceChangeListener committer = directionStylePreference.getOnPreferenceChangeListener();
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (committer != null)
committer.onPreferenceChange(preference, newValue);
updateAllSettings();
return true;
}
});
cat.addPreference(directionStylePreference);
cat.addPreference(createCheckBoxPreference(settings.ACCESSIBILITY_SMART_AUTOANNOUNCE, R.string.access_smart_autoannounce,
R.string.access_smart_autoannounce_descr));
final int[] seconds = new int[] {5, 10, 15, 20, 30, 45, 60, 90};
final int[] minutes = new int[] {2, 3, 5};
autoannouncePeriodPreference = createTimeListPreference(settings.ACCESSIBILITY_AUTOANNOUNCE_PERIOD, seconds, minutes, 1000,
R.string.access_autoannounce_period, R.string.access_autoannounce_period_descr);
autoannouncePeriodPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
private final OnPreferenceChangeListener committer = autoannouncePeriodPreference.getOnPreferenceChangeListener();
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (committer != null)
committer.onPreferenceChange(preference, newValue);
updateAllSettings();
return true;
}
});
cat.addPreference(autoannouncePeriodPreference);
cat.addPreference(createCheckBoxPreference(settings.DIRECTION_AUDIO_FEEDBACK, R.string.access_direction_audio_feedback,
R.string.access_direction_audio_feedback_descr));
cat.addPreference(createCheckBoxPreference(settings.DIRECTION_HAPTIC_FEEDBACK, R.string.access_direction_haptic_feedback,
R.string.access_direction_haptic_feedback_descr));
}
protected void addSpeechRateSetting(PreferenceGroup grp) {
Float[] sprValues = new Float[] {0.5f, 0.75f, 1f, 1.25f, 1.5f, 2f} ;
String[] sprNames = new String[sprValues.length];
for(int i = 0; i < sprNames.length; i++) {
sprNames[i] = (int)(sprValues[i] * 100) + " %";
}
grp.addPreference(createListPreference(settings.SPEECH_RATE, sprNames, sprValues, R.string.speech_rate, R.string.speech_rate_descr));
}
public void updateAllSettings() {
super.updateAllSettings();
PreferenceCategory accessibilityOptions = ((PreferenceCategory)(getPreferenceScreen().findPreference("accessibility_options")));
if (accessibilityOptions != null)
accessibilityOptions.setEnabled(getMyApplication().accessibilityEnabled());
if(accessibilityModePreference != null) {
accessibilityModePreference.setSummary(getString(R.string.accessibility_mode_descr) + " [" + settings.ACCESSIBILITY_MODE.get().toHumanString(getMyApplication()) + "]");
}
if(directionStylePreference != null) {
directionStylePreference.setSummary(getString(R.string.settings_direction_style_descr) + " [" + settings.DIRECTION_STYLE.get().toHumanString(getMyApplication()) + "]");
}
if(autoannouncePeriodPreference != null) {
autoannouncePeriodPreference.setSummary(getString(R.string.access_autoannounce_period_descr) + " [" + autoannouncePeriodPreference.getEntry() + "]");
}
}
}

View file

@ -11,9 +11,6 @@ import android.widget.CompoundButton;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import net.osmand.AndroidUtils;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuItem;
@ -21,15 +18,12 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.layers.AidlMapLayer;
import net.osmand.plus.views.layers.MapInfoLayer;
import net.osmand.plus.views.mapwidgets.widgets.TextInfoWidget;
import net.osmand.util.Algorithms;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -39,7 +33,6 @@ public class ConnectedApp implements Comparable<ConnectedApp> {
public static final String AIDL_LAYERS_PREFIX = "aidl_layers_";
public static final String AIDL_WIDGETS_PREFIX = "aidl_widgets_";
public static final String AIDL_MARGINS_PREFIX = "aidl_margins_";
static final String AIDL_OBJECT_ID = "aidl_object_id";
static final String AIDL_PACKAGE_NAME = "aidl_package_name";
@ -62,7 +55,6 @@ public class ConnectedApp implements Comparable<ConnectedApp> {
private Map<String, OsmandMapLayer> mapLayers = new ConcurrentHashMap<>();
private CommonPreference<Boolean> layersPref;
private CommonPreference<String> marginsPref;
private String pack;
private String name;
@ -76,7 +68,6 @@ public class ConnectedApp implements Comparable<ConnectedApp> {
this.pack = pack;
this.enabled = enabled;
layersPref = app.getSettings().registerBooleanPreference(AIDL_LAYERS_PREFIX + pack, true).cache();
marginsPref = app.getSettings().registerStringPreference(AIDL_MARGINS_PREFIX + pack, null).cache();
}
public boolean isEnabled() {
@ -134,45 +125,6 @@ public class ConnectedApp implements Comparable<ConnectedApp> {
}
}
void updateMapMargins(@NonNull MapActivity mapActivity) {
String marginsJson = marginsPref.get();
if (marginsJson != null) {
Type type = new TypeToken<HashMap<String, Integer>>() {
}.getType();
Map<String, Integer> margins = new Gson().fromJson(marginsJson, type);
if (margins != null) {
Integer leftMargin = margins.get("left");
Integer topMargin = margins.get("top");
Integer rightMargin = margins.get("right");
Integer bottomMargin = margins.get("bottom");
int left = leftMargin != null ? leftMargin : 0;
int top = topMargin != null ? topMargin : 0;
int right = rightMargin != null ? rightMargin : 0;
int bottom = bottomMargin != null ? bottomMargin : 0;
mapActivity.setMargins(left, top, right, bottom);
return;
}
}
mapActivity.setMargins(0, 0, 0, 0);
}
public void setMargins(@NonNull MapActivity mapActivity, String appModeKey, int leftMargin, int topMargin, int rightMargin, int bottomMargin) {
ApplicationMode mode = ApplicationMode.valueOfStringKey(appModeKey, null);
if (mode != null) {
Map<String, Integer> margins = new HashMap<>();
margins.put("left", leftMargin);
margins.put("top", topMargin);
margins.put("right", rightMargin);
margins.put("bottom", bottomMargin);
String marginsJson = new Gson().toJson(margins);
marginsPref.setModeValue(mode, marginsJson);
updateMapMargins(mapActivity);
}
}
void registerLayerContextMenu(final ContextMenuAdapter menuAdapter, final MapActivity mapActivity) {
ContextMenuAdapter.ItemClickListener listener = new ContextMenuAdapter.OnRowItemClick() {

View file

@ -81,8 +81,10 @@ import net.osmand.plus.routing.VoiceRouter;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmAndAppCustomization;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.SettingsHelper;
import net.osmand.plus.settings.backend.backup.ProfileSettingsItem;
import net.osmand.plus.settings.backend.backup.SettingsHelper;
import net.osmand.plus.settings.backend.ExportSettingsType;
import net.osmand.plus.settings.backend.backup.SettingsItem;
import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.layers.AidlMapLayer;
@ -138,7 +140,7 @@ import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_NAME;
import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DIRECTION_TURN;
import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_DISTANCE;
import static net.osmand.plus.helpers.ExternalApiHelper.PARAM_NT_IMMINENT;
import static net.osmand.plus.settings.backend.SettingsHelper.REPLACE_KEY;
import static net.osmand.plus.settings.backend.backup.SettingsHelper.REPLACE_KEY;
public class OsmandAidlApi {
@ -200,13 +202,6 @@ public class OsmandAidlApi {
private static final String AIDL_QUICK_ACTION_NUMBER = "aidl_quick_action_number";
private static final String AIDL_LOCK_STATE = "lock_state";
private static final String AIDL_SET_MAP_MARGINS = "set_map_margins";
private static final String AIDL_APP_MODE = "app_mode";
private static final String AIDL_LEFT_MARGIN = "left_margin";
private static final String AIDL_TOP_MARGIN = "top_margin";
private static final String AIDL_RIGHT_MARGIN = "right_margin";
private static final String AIDL_BOTTOM_MARGIN = "bottom_margin";
private static final ApplicationMode DEFAULT_PROFILE = ApplicationMode.CAR;
private static final ApplicationMode[] VALID_PROFILES = new ApplicationMode[]{
@ -257,7 +252,6 @@ public class OsmandAidlApi {
registerHideSqliteDbFileReceiver(mapActivity);
registerExecuteQuickActionReceiver(mapActivity);
registerLockStateReceiver(mapActivity);
registerMapMarginsReceiver(mapActivity);
initOsmandTelegram();
app.getAppCustomization().addListener(mapActivity);
this.mapActivity = mapActivity;
@ -379,28 +373,10 @@ public class OsmandAidlApi {
registerReceiver(addMapWidgetReceiver, mapActivity, AIDL_ADD_MAP_WIDGET);
}
private void registerMapMarginsReceiver(MapActivity mapActivity) {
final WeakReference<MapActivity> mapActivityRef = new WeakReference<>(mapActivity);
BroadcastReceiver addMapWidgetReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
MapActivity mapActivity = mapActivityRef.get();
String appModeKey = intent.getStringExtra(AIDL_APP_MODE);
String packName = intent.getStringExtra(AIDL_PACKAGE_NAME);
if (mapActivity != null && appModeKey != null && packName != null) {
ConnectedApp connectedApp = connectedApps.get(packName);
if (connectedApp != null) {
int leftMargin = intent.getIntExtra(AIDL_LEFT_MARGIN, 0);
int topMargin = intent.getIntExtra(AIDL_TOP_MARGIN, 0);
int bottomMargin = intent.getIntExtra(AIDL_RIGHT_MARGIN, 0);
int rightMargin = intent.getIntExtra(AIDL_BOTTOM_MARGIN, 0);
connectedApp.setMargins(mapActivity, appModeKey, leftMargin, topMargin, rightMargin, bottomMargin);
}
}
}
};
registerReceiver(addMapWidgetReceiver, mapActivity, AIDL_SET_MAP_MARGINS);
boolean setMapMargins(int left, int top, int right, int bottom, @Nullable List<String> appModeKeys) {
app.getAppCustomization().setMapMargins(left, top, right, bottom, appModeKeys);
app.getAppCustomization().updateMapMargins(mapActivity);
return true;
}
private void registerAddContextMenuButtonsReceiver(MapActivity mapActivity) {
@ -919,12 +895,6 @@ public class OsmandAidlApi {
}
}
public void updateMapMargins(@NonNull MapActivity mapActivity) {
for (ConnectedApp connectedApp : connectedApps.values()) {
connectedApp.updateMapMargins(mapActivity);
}
}
private void refreshMap() {
Intent intent = new Intent();
intent.setAction(AIDL_REFRESH_MAP);
@ -2330,19 +2300,6 @@ public class OsmandAidlApi {
return true;
}
public boolean setMapMargins(String packName, String appModeKey, int leftMargin, int topMargin, int bottomMargin, int rightMargin) {
Intent intent = new Intent();
intent.setAction(AIDL_SET_MAP_MARGINS);
intent.putExtra(AIDL_PACKAGE_NAME, packName);
intent.putExtra(AIDL_APP_MODE, appModeKey);
intent.putExtra(AIDL_LEFT_MARGIN, leftMargin);
intent.putExtra(AIDL_TOP_MARGIN, topMargin);
intent.putExtra(AIDL_RIGHT_MARGIN, bottomMargin);
intent.putExtra(AIDL_BOTTOM_MARGIN, rightMargin);
app.sendBroadcast(intent);
return true;
}
public boolean exportProfile(String appModeKey, List<String> settingsTypesKeys) {
ApplicationMode appMode = ApplicationMode.valueOfStringKey(appModeKey, null);
if (app != null && appMode != null) {
@ -2350,8 +2307,8 @@ public class OsmandAidlApi {
for (String key : settingsTypesKeys) {
settingsTypes.add(ExportSettingsType.valueOf(key));
}
List<SettingsHelper.SettingsItem> settingsItems = new ArrayList<>();
settingsItems.add(new SettingsHelper.ProfileSettingsItem(app, appMode));
List<SettingsItem> settingsItems = new ArrayList<>();
settingsItems.add(new ProfileSettingsItem(app, appMode));
File exportDir = app.getSettings().getExternalStorageDirectory();
String fileName = appMode.toHumanString();
SettingsHelper settingsHelper = app.getSettingsHelper();
@ -2362,6 +2319,14 @@ public class OsmandAidlApi {
return false;
}
public boolean isFragmentOpen() {
return mapActivity.isFragmentVisible();
}
public boolean isMenuOpen() {
return mapActivity.getContextMenu().isVisible();
}
private static class FileCopyInfo {
long startTime;
long lastAccessTime;

View file

@ -1327,9 +1327,30 @@ public class OsmandAidlServiceV2 extends Service implements AidlCallbackListener
public boolean setMapMargins(MapMarginsParams params) {
try {
OsmandAidlApi api = getApi("setMapMargins");
String packName = getCallingAppPackName();
return api != null && api.setMapMargins(packName, params.getAppModeKey(), params.getLeftMargin(),
params.getTopMargin(), params.getBottomMargin(), params.getRightMargin());
return api != null && api.setMapMargins(params.getLeftMargin(), params.getTopMargin(),
params.getBottomMargin(), params.getRightMargin(), params.getAppModesKeys());
} catch (Exception e) {
handleException(e);
return false;
}
}
@Override
public boolean isFragmentOpen() {
try {
OsmandAidlApi api = getApi("isFragmentOpen");
return api != null && api.isFragmentOpen();
} catch (Exception e) {
handleException(e);
return false;
}
}
@Override
public boolean isMenuOpen() {
try {
OsmandAidlApi api = getApi("isMenuOpen");
return api != null && api.isMenuOpen();
} catch (Exception e) {
handleException(e);
return false;

View file

@ -55,7 +55,7 @@ import net.osmand.plus.routing.TransportRoutingHelper;
import net.osmand.plus.search.QuickSearchHelper;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.SettingsHelper;
import net.osmand.plus.settings.backend.backup.SettingsHelper;
import net.osmand.plus.views.corenative.NativeCoreContext;
import net.osmand.plus.voice.CommandPlayer;
import net.osmand.plus.voice.CommandPlayerException;

View file

@ -18,15 +18,15 @@ import net.osmand.data.LatLon;
import net.osmand.map.ITileSource;
import net.osmand.map.WorldRegion;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.SettingsHelper;
import net.osmand.plus.settings.backend.SettingsHelper.AvoidRoadsSettingsItem;
import net.osmand.plus.settings.backend.SettingsHelper.MapSourcesSettingsItem;
import net.osmand.plus.settings.backend.SettingsHelper.PluginSettingsItem;
import net.osmand.plus.settings.backend.SettingsHelper.PoiUiFiltersSettingsItem;
import net.osmand.plus.settings.backend.SettingsHelper.ProfileSettingsItem;
import net.osmand.plus.settings.backend.SettingsHelper.QuickActionsSettingsItem;
import net.osmand.plus.settings.backend.SettingsHelper.SettingsCollectListener;
import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem;
import net.osmand.plus.settings.backend.backup.SettingsHelper;
import net.osmand.plus.settings.backend.backup.AvoidRoadsSettingsItem;
import net.osmand.plus.settings.backend.backup.MapSourcesSettingsItem;
import net.osmand.plus.settings.backend.backup.PluginSettingsItem;
import net.osmand.plus.settings.backend.backup.PoiUiFiltersSettingsItem;
import net.osmand.plus.settings.backend.backup.ProfileSettingsItem;
import net.osmand.plus.settings.backend.backup.QuickActionsSettingsItem;
import net.osmand.plus.settings.backend.backup.SettingsHelper.SettingsCollectListener;
import net.osmand.plus.settings.backend.backup.SettingsItem;
import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.download.DownloadResources;

View file

@ -75,7 +75,7 @@ import net.osmand.plus.search.QuickSearchHelper;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmAndAppCustomization;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.SettingsHelper;
import net.osmand.plus.settings.backend.backup.SettingsHelper;
import net.osmand.plus.voice.CommandPlayer;
import net.osmand.plus.wikivoyage.data.TravelDbHelper;
import net.osmand.router.GeneralRouter;

View file

@ -46,10 +46,9 @@ import net.osmand.plus.quickaction.QuickActionType;
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
import net.osmand.plus.search.QuickSearchDialogFragment;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandPreference;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
import net.osmand.plus.skimapsplugin.SkiMapsPlugin;
import net.osmand.plus.srtmplugin.SRTMPlugin;
import net.osmand.plus.views.OsmandMapTileView;
@ -112,11 +111,7 @@ public abstract class OsmandPlugin {
return app.getUIUtilities().getIcon(getLogoResourceId());
}
public Class<? extends Activity> getSettingsActivity() {
return null;
}
public Class<? extends BaseSettingsFragment> getSettingsFragment() {
public SettingsScreenType getSettingsScreenType() {
return null;
}
@ -499,6 +494,9 @@ public abstract class OsmandPlugin {
public void mapActivityResume(MapActivity activity) {
}
public void mapActivityResumeOnTop(MapActivity activity) {
}
public void mapActivityPause(MapActivity activity) {
}
@ -752,6 +750,12 @@ public abstract class OsmandPlugin {
}
}
public static void onMapActivityResumeOnTop(MapActivity activity) {
for (OsmandPlugin plugin : getEnabledPlugins()) {
plugin.mapActivityResumeOnTop(activity);
}
}
public static void onMapActivityPause(MapActivity activity) {
for (OsmandPlugin plugin : getEnabledPlugins()) {
plugin.mapActivityPause(activity);

View file

@ -173,7 +173,7 @@ public class HelpActivity extends OsmandActionBarActivity implements AdapterView
contextMenuAdapter.addItem(createItem(R.string.versions_item, NULL_ID,
"feature_articles/changes.html"));
contextMenuAdapter.addItem(createItem(R.string.what_is_new, NULL_ID,
"feature_articles/blog.html"));
"feature_articles/osmand-3-8-released.html"));
String releasedate = "";
if (!this.getString(R.string.app_edition).equals("")) {

View file

@ -74,9 +74,6 @@ import net.osmand.plus.OsmAndConstants;
import net.osmand.plus.OsmAndLocationSimulation;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.helpers.DayNightHelper;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.TargetPointsHelper.TargetPoint;
@ -87,6 +84,7 @@ import net.osmand.plus.base.ContextMenuFragment;
import net.osmand.plus.base.FailSafeFuntions;
import net.osmand.plus.base.MapViewTrackingUtilities;
import net.osmand.plus.chooseplan.OsmLiveCancelledDialog;
import net.osmand.plus.dashboard.DashBaseFragment;
import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.dialogs.CrashBottomSheetDialogFragment;
import net.osmand.plus.dialogs.ImportGpxBottomSheetDialogFragment;
@ -100,13 +98,14 @@ import net.osmand.plus.download.ui.DataStoragePlaceDialogFragment;
import net.osmand.plus.firstusage.FirstUsageWelcomeFragment;
import net.osmand.plus.firstusage.FirstUsageWizardFragment;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.DayNightHelper;
import net.osmand.plus.helpers.DiscountHelper;
import net.osmand.plus.importfiles.ImportHelper;
import net.osmand.plus.helpers.IntentHelper;
import net.osmand.plus.helpers.LockHelper;
import net.osmand.plus.helpers.LockHelper.LockUIAdapter;
import net.osmand.plus.helpers.ScrollHelper;
import net.osmand.plus.helpers.ScrollHelper.OnScrollEventListener;
import net.osmand.plus.importfiles.ImportHelper;
import net.osmand.plus.mapcontextmenu.AdditionalActionsBottomSheetDialogFragment;
import net.osmand.plus.mapcontextmenu.MapContextMenu;
import net.osmand.plus.mapcontextmenu.MenuController;
@ -119,6 +118,7 @@ import net.osmand.plus.measurementtool.GpxData;
import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.measurementtool.MeasurementToolFragment;
import net.osmand.plus.measurementtool.SnapTrackWarningFragment;
import net.osmand.plus.osmedit.OsmEditingFragment;
import net.osmand.plus.render.RendererRegistry;
import net.osmand.plus.resources.ResourceManager;
import net.osmand.plus.routepreparationmenu.ChooseRouteFragment;
@ -132,7 +132,9 @@ import net.osmand.plus.search.QuickSearchDialogFragment;
import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchTab;
import net.osmand.plus.search.QuickSearchDialogFragment.QuickSearchType;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmAndAppCustomization.OsmAndAppCustomizationListener;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
import net.osmand.plus.settings.fragments.ConfigureProfileFragment;
@ -885,6 +887,13 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
settings.USE_SYSTEM_SCREEN_TIMEOUT.addListener(useSystemScreenTimeoutListener);
}
@Override
public void onTopResumedActivityChanged(boolean isTopResumedActivity) {
if (isTopResumedActivity) {
OsmandPlugin.onMapActivityResumeOnTop(this);
}
}
public void applyScreenOrientation() {
if (settings.MAP_SCREEN_ORIENTATION.get() != getRequestedOrientation()) {
setRequestedOrientation(settings.MAP_SCREEN_ORIENTATION.get());
@ -1029,15 +1038,23 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
}
public boolean isMapVisible() {
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
if (fragment.isVisible()) {
return false;
}
if (isFragmentVisible()) {
return false;
}
return AndroidUtils.isActivityNotDestroyed(this) && settings.MAP_ACTIVITY_ENABLED.get()
&& !dashboardOnMap.isVisible();
}
public boolean isFragmentVisible() {
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
if (!(fragment instanceof DashBaseFragment) && fragment.isVisible()
|| dashboardOnMap.isVisible()) {
return true;
}
}
return false;
}
private void restartApp() {
AlertDialog.Builder bld = new AlertDialog.Builder(this);
bld.setMessage(R.string.storage_permission_restart_is_required);
@ -1421,7 +1438,7 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
});
getMapView().refreshMap(true);
applyScreenOrientation();
app.getAidlApi().updateMapMargins(this);
app.getAppCustomization().updateMapMargins(this);
}
public void updateNavigationBarColor() {
@ -2200,6 +2217,10 @@ public class MapActivity extends OsmandActionBarActivity implements DownloadEven
return getFragment(GpxApproximationFragment.TAG);
}
public OsmEditingFragment getOsmEditingFragment() {
return getFragment(SettingsScreenType.OPEN_STREET_MAP_EDITING.fragmentName);
}
public SnapTrackWarningFragment getSnapTrackWarningBottomSheet() {
return getFragment(SnapTrackWarningFragment.TAG);
}

View file

@ -974,10 +974,7 @@ public class MapActivityActions implements DialogProvider {
@Override
public boolean onContextMenuClick(ArrayAdapter<ContextMenuItem> adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) {
app.logEvent("drawer_plugins_open");
Intent newIntent = new Intent(mapActivity, mapActivity.getMyApplication().getAppCustomization()
.getPluginsActivity());
newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
mapActivity.startActivity(newIntent);
PluginsFragment.showInstance(mapActivity.getSupportFragmentManager());
return true;
}
}).createItem());

View file

@ -1,241 +0,0 @@
package net.osmand.plus.activities;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.chooseplan.ChoosePlanDialogFragment;
import net.osmand.plus.dialogs.PluginInstalledBottomSheetDialog;
import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.srtmplugin.SRTMPlugin;
public class PluginActivity extends OsmandActionBarActivity implements DownloadIndexesThread.DownloadEvents, PluginInstalledBottomSheetDialog.PluginStateListener {
private static final String TAG = "PluginActivity";
public static final String EXTRA_PLUGIN_ID = "plugin_id";
private OsmandPlugin plugin;
@Override
protected void onCreate(Bundle savedInstanceState) {
((OsmandApplication) getApplication()).applyTheme(this);
super.onCreate(savedInstanceState);
Intent intent = getIntent();
if (intent == null || !intent.hasExtra(EXTRA_PLUGIN_ID)) {
Log.e(TAG, "Required extra '" + EXTRA_PLUGIN_ID + "' is missing");
finish();
return;
}
String pluginId = intent.getStringExtra(EXTRA_PLUGIN_ID);
if (pluginId == null) {
Log.e(TAG, "Extra '" + EXTRA_PLUGIN_ID + "' is null");
finish();
return;
}
for (OsmandPlugin plugin : OsmandPlugin.getAvailablePlugins()) {
if (!plugin.getId().equals(pluginId))
continue;
this.plugin = plugin;
break;
}
if (plugin == null) {
Log.e(TAG, "Plugin '" + EXTRA_PLUGIN_ID + "' not found");
finish();
return;
}
setContentView(R.layout.plugin);
//noinspection ConstantConditions
getSupportActionBar().setTitle(plugin.getName());
Drawable pluginImage = plugin.getAssetResourceImage();
if (pluginImage != null) {
ImageView img = (ImageView) findViewById(R.id.plugin_image);
img.setImageDrawable(pluginImage);
} else {
findViewById(R.id.plugin_image_placeholder).setVisibility(View.VISIBLE);
}
TextView descriptionView = (TextView) findViewById(R.id.plugin_description);
descriptionView.setText(plugin.getDescription());
boolean light = getMyApplication().getSettings().isLightContent();
int linkTextColor = ContextCompat.getColor(this,
light ? R.color.ctx_menu_bottom_view_url_color_light : R.color.ctx_menu_bottom_view_url_color_dark);
descriptionView.setLinkTextColor(linkTextColor);
descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
AndroidUtils.removeLinkUnderline(descriptionView);
Button settingsButton = (Button) findViewById(R.id.plugin_settings);
settingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(PluginActivity.this, plugin.getSettingsActivity()));
}
});
CompoundButton enableDisableButton = (CompoundButton)findViewById(
R.id.plugin_enable_disable);
enableDisableButton.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (plugin.isActive() == isChecked) {
return;
}
boolean ok = OsmandPlugin.enablePlugin(PluginActivity.this, (OsmandApplication)getApplication(),
plugin, isChecked);
if (!ok) {
return;
}
updateState();
}
});
Button getButton = (Button)findViewById(R.id.plugin_get);
getButton.setText(plugin.isPaid() ? R.string.get_plugin : R.string.shared_string_install);
getButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
if (plugin instanceof SRTMPlugin) {
FragmentManager fragmentManager = getSupportFragmentManager();
if (fragmentManager != null) {
ChoosePlanDialogFragment.showHillshadeSrtmPluginInstance(fragmentManager);
}
} else {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(plugin.getInstallURL())));
}
} catch (Exception e) {
//ignored
}
}
});
updateState();
}
@Override
protected void onResume() {
super.onResume();
OsmandApplication app = getMyApplication();
OsmandPlugin.checkInstalledMarketPlugins(app, this);
app.getDownloadThread().setUiActivity(this);
updateState();
}
@Override
protected void onPause() {
super.onPause();
getMyApplication().getDownloadThread().resetUiActivity(this);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
case android.R.id.home:
finish();
return true;
}
return false;
}
@SuppressLint("NewApi")
private void updateState() {
CompoundButton enableDisableButton = (CompoundButton)findViewById(
R.id.plugin_enable_disable);
Button getButton = (Button)findViewById(R.id.plugin_get);
Button settingsButton = (Button)findViewById(R.id.plugin_settings);
settingsButton.setCompoundDrawablesWithIntrinsicBounds(
getMyApplication().getUIUtilities().getThemedIcon(R.drawable.ic_action_settings),
null, null, null);
View installHeader = findViewById(R.id.plugin_install_header);
if (plugin.needsInstallation()) {
getButton.setVisibility(View.VISIBLE);
enableDisableButton.setVisibility(View.GONE);
settingsButton.setVisibility(View.GONE);
installHeader.setVisibility(View.VISIBLE);
View worldGlobeIcon = installHeader.findViewById(R.id.ic_world_globe);
Drawable worldGlobeDrawable = getMyApplication().getUIUtilities().getThemedIcon(
R.drawable.ic_world_globe_dark);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
worldGlobeIcon.setBackground(worldGlobeDrawable);
} else {
//noinspection deprecation
worldGlobeIcon.setBackgroundDrawable(worldGlobeDrawable);
}
} else {
getButton.setVisibility(View.GONE);
enableDisableButton.setVisibility(View.VISIBLE);
enableDisableButton.setChecked(plugin.isActive());
final Class<? extends Activity> settingsActivity = plugin.getSettingsActivity();
if (settingsActivity == null || !plugin.isActive()) {
settingsButton.setVisibility(View.GONE);
} else {
settingsButton.setVisibility(View.VISIBLE);
}
installHeader.setVisibility(View.GONE);
}
}
// DownloadEvents
@Override
public void newDownloadIndexes() {
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
if (fragment instanceof DownloadIndexesThread.DownloadEvents && fragment.isAdded()) {
((DownloadIndexesThread.DownloadEvents) fragment).newDownloadIndexes();
}
}
}
@Override
public void downloadInProgress() {
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
if (fragment instanceof DownloadIndexesThread.DownloadEvents && fragment.isAdded()) {
((DownloadIndexesThread.DownloadEvents) fragment).downloadInProgress();
}
}
}
@Override
public void downloadHasFinished() {
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
if (fragment instanceof DownloadIndexesThread.DownloadEvents && fragment.isAdded()) {
((DownloadIndexesThread.DownloadEvents) fragment).downloadHasFinished();
}
}
}
@Override
public void onPluginStateChanged(OsmandPlugin plugin) {
updateState();
}
}

View file

@ -0,0 +1,258 @@
package net.osmand.plus.activities;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.chooseplan.ChoosePlanDialogFragment;
import net.osmand.plus.dialogs.PluginInstalledBottomSheetDialog.PluginStateListener;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
import net.osmand.plus.srtmplugin.SRTMPlugin;
import org.apache.commons.logging.Log;
public class PluginInfoFragment extends BaseOsmAndFragment implements PluginStateListener {
private static final Log log = PlatformUtil.getLog(PluginInfoFragment.class);
private static final String TAG = PluginInfoFragment.class.getName();
public static final String EXTRA_PLUGIN_ID = "plugin_id";
public static final String PLUGIN_INFO = "plugin_info";
private OsmandPlugin plugin;
private OsmandApplication app;
private View mainView;
private boolean nightMode;
@Override
public int getStatusBarColorId() {
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentActivity activity = requireMyActivity();
activity.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
public void handleOnBackPressed() {
dismiss();
}
});
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
app = requireMyApplication();
Bundle args = getArguments();
if (args == null || !args.containsKey(EXTRA_PLUGIN_ID)) {
log.error("Required extra '" + EXTRA_PLUGIN_ID + "' is missing");
return null;
}
String pluginId = args.getString(EXTRA_PLUGIN_ID);
if (pluginId == null) {
log.error("Extra '" + EXTRA_PLUGIN_ID + "' is null");
return null;
}
plugin = OsmandPlugin.getPlugin(pluginId);
if (plugin == null) {
log.error("Plugin '" + EXTRA_PLUGIN_ID + "' not found");
return null;
}
Context context = requireContext();
nightMode = !app.getSettings().isLightContent();
LayoutInflater themedInflater = UiUtilities.getInflater(context, nightMode);
mainView = themedInflater.inflate(R.layout.plugin, container, false);
AndroidUtils.addStatusBarPadding21v(context, mainView);
TextView toolbarTitle = mainView.findViewById(R.id.toolbar_title);
toolbarTitle.setText(plugin.getName());
ImageView closeButton = mainView.findViewById(R.id.close_button);
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Activity activity = getMyActivity();
if (activity != null) {
activity.onBackPressed();
}
}
});
UiUtilities.rotateImageByLayoutDirection(closeButton, AndroidUtils.getLayoutDirection(app));
Drawable pluginImage = plugin.getAssetResourceImage();
if (pluginImage != null) {
ImageView img = mainView.findViewById(R.id.plugin_image);
img.setImageDrawable(pluginImage);
} else {
mainView.findViewById(R.id.plugin_image_placeholder).setVisibility(View.VISIBLE);
}
TextView descriptionView = mainView.findViewById(R.id.plugin_description);
descriptionView.setText(plugin.getDescription());
int linkTextColorId = nightMode ? R.color.ctx_menu_bottom_view_url_color_dark : R.color.ctx_menu_bottom_view_url_color_light;
int linkTextColor = ContextCompat.getColor(context, linkTextColorId);
descriptionView.setLinkTextColor(linkTextColor);
descriptionView.setMovementMethod(LinkMovementMethod.getInstance());
AndroidUtils.removeLinkUnderline(descriptionView);
Button settingsButton = mainView.findViewById(R.id.plugin_settings);
settingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
FragmentActivity activity = getActivity();
if (activity != null) {
SettingsScreenType settingsScreenType = plugin.getSettingsScreenType();
if (settingsScreenType != null) {
Bundle args = new Bundle();
args.putBoolean(PLUGIN_INFO, true);
BaseSettingsFragment.showInstance(activity, settingsScreenType, null, args);
}
}
}
});
CompoundButton enableDisableButton = mainView.findViewById(R.id.plugin_enable_disable);
enableDisableButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (plugin.isActive() == isChecked) {
return;
}
boolean ok = OsmandPlugin.enablePlugin(getActivity(), app, plugin, isChecked);
if (!ok) {
return;
}
updateState();
}
});
Button getButton = mainView.findViewById(R.id.plugin_get);
getButton.setText(plugin.isPaid() ? R.string.get_plugin : R.string.shared_string_install);
getButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
if (plugin instanceof SRTMPlugin) {
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
if (fragmentManager != null) {
ChoosePlanDialogFragment.showHillshadeSrtmPluginInstance(fragmentManager);
}
} else {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(plugin.getInstallURL())));
}
} catch (Exception e) {
//ignored
}
}
});
updateState();
return mainView;
}
@Override
public void onResume() {
super.onResume();
OsmandPlugin.checkInstalledMarketPlugins(app, getActivity());
updateState();
}
private void updateState() {
CompoundButton enableDisableButton = mainView.findViewById(R.id.plugin_enable_disable);
Button getButton = mainView.findViewById(R.id.plugin_get);
Button settingsButton = mainView.findViewById(R.id.plugin_settings);
settingsButton.setCompoundDrawablesWithIntrinsicBounds(app.getUIUtilities().getThemedIcon(R.drawable.ic_action_settings), null, null, null);
View installHeader = mainView.findViewById(R.id.plugin_install_header);
if (plugin.needsInstallation()) {
getButton.setVisibility(View.VISIBLE);
enableDisableButton.setVisibility(View.GONE);
settingsButton.setVisibility(View.GONE);
installHeader.setVisibility(View.VISIBLE);
View worldGlobeIcon = installHeader.findViewById(R.id.ic_world_globe);
Drawable worldGlobeDrawable = app.getUIUtilities().getThemedIcon(R.drawable.ic_world_globe_dark);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
worldGlobeIcon.setBackground(worldGlobeDrawable);
} else {
worldGlobeIcon.setBackgroundDrawable(worldGlobeDrawable);
}
} else {
getButton.setVisibility(View.GONE);
enableDisableButton.setVisibility(View.VISIBLE);
enableDisableButton.setChecked(plugin.isActive());
if (plugin.getSettingsScreenType() == null || !plugin.isActive()) {
settingsButton.setVisibility(View.GONE);
} else {
settingsButton.setVisibility(View.VISIBLE);
}
installHeader.setVisibility(View.GONE);
}
}
@Override
public void onPluginStateChanged(OsmandPlugin plugin) {
updateState();
}
public void dismiss() {
FragmentActivity activity = getActivity();
if (activity != null) {
try {
activity.getSupportFragmentManager().popBackStack(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (Exception e) {
log.error(e);
}
}
}
public static boolean showInstance(FragmentManager fragmentManager, OsmandPlugin plugin) {
try {
Bundle args = new Bundle();
args.putString(EXTRA_PLUGIN_ID, plugin.getId());
PluginInfoFragment fragment = new PluginInfoFragment();
fragment.setArguments(args);
fragmentManager.beginTransaction()
.add(R.id.fragmentContainer, fragment, TAG)
.addToBackStack(TAG)
.commitAllowingStateLoss();
return true;
} catch (Exception e) {
return false;
}
}
}

View file

@ -1,296 +0,0 @@
package net.osmand.plus.activities;
import android.app.Activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import net.osmand.AndroidUtils;
import net.osmand.aidl.ConnectedApp;
import net.osmand.plus.CustomOsmandPlugin;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.dialogs.PluginInstalledBottomSheetDialog;
import net.osmand.plus.download.DownloadIndexesThread;
import java.util.ArrayList;
public class PluginsActivity extends OsmandListActivity implements DownloadIndexesThread.DownloadEvents, PluginInstalledBottomSheetDialog.PluginStateListener {
public static final int ACTIVE_PLUGINS_LIST_MODIFIED = 1;
private boolean listModified = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
getMyApplication().applyTheme(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.plugins);
getSupportActionBar().setTitle(R.string.plugins_screen);
setListAdapter(new PluginsListAdapter());
}
@Override
public PluginsListAdapter getListAdapter() {
return (PluginsListAdapter) super.getListAdapter();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Object tag = view.getTag();
if (tag instanceof OsmandPlugin) {
Intent intent = new Intent(this, PluginActivity.class);
intent.putExtra(PluginActivity.EXTRA_PLUGIN_ID, ((OsmandPlugin) tag).getId());
startActivity(intent);
} else if (tag instanceof ConnectedApp) {
switchEnabled((ConnectedApp) tag);
}
}
@Override
protected void onResume() {
super.onResume();
OsmandApplication app = getMyApplication();
OsmandPlugin.checkInstalledMarketPlugins(app, this);
app.getDownloadThread().setUiActivity(this);
getListAdapter().notifyDataSetChanged();
}
@Override
protected void onPause() {
super.onPause();
getMyApplication().getDownloadThread().resetUiActivity(this);
}
private void enableDisablePlugin(OsmandPlugin plugin, boolean enable) {
OsmandApplication app = getMyApplication();
if (OsmandPlugin.enablePlugin(this, app, plugin, enable)) {
if (!listModified) {
setResult(ACTIVE_PLUGINS_LIST_MODIFIED);
listModified = true;
}
getListAdapter().notifyDataSetChanged();
}
}
private void switchEnabled(@NonNull ConnectedApp app) {
getMyApplication().getAidlApi().switchEnabled(app);
getListAdapter().notifyDataSetChanged();
}
// DownloadEvents
@Override
public void newDownloadIndexes() {
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
if (fragment instanceof DownloadIndexesThread.DownloadEvents && fragment.isAdded()) {
((DownloadIndexesThread.DownloadEvents) fragment).newDownloadIndexes();
}
}
}
@Override
public void downloadInProgress() {
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
if (fragment instanceof DownloadIndexesThread.DownloadEvents && fragment.isAdded()) {
((DownloadIndexesThread.DownloadEvents) fragment).downloadInProgress();
}
}
}
@Override
public void downloadHasFinished() {
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
if (fragment instanceof DownloadIndexesThread.DownloadEvents && fragment.isAdded()) {
((DownloadIndexesThread.DownloadEvents) fragment).downloadHasFinished();
}
}
}
@Override
public void onPluginStateChanged(OsmandPlugin plugin) {
getListAdapter().notifyDataSetChanged();
}
protected class PluginsListAdapter extends ArrayAdapter<Object> {
PluginsListAdapter() {
super(PluginsActivity.this, R.layout.plugins_list_item, new ArrayList<>());
addAll(getMyApplication().getAidlApi().getConnectedApps());
addAll(OsmandPlugin.getVisiblePlugins());
}
@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
View view = convertView;
if (view == null) {
view = getLayoutInflater().inflate(R.layout.plugins_list_item, parent, false);
}
final Object item = getItem(position);
boolean active = false;
int logoContDescId = R.string.shared_string_disable;
String name = "";
boolean isLightTheme = getMyApplication().getSettings().isLightContent();
ImageButton pluginLogo = (ImageButton) view.findViewById(R.id.plugin_logo);
ImageView pluginOptions = (ImageView) view.findViewById(R.id.plugin_options);
TextView pluginDescription = (TextView) view.findViewById(R.id.plugin_description);
if (item instanceof ConnectedApp) {
final ConnectedApp app = (ConnectedApp) item;
active = app.isEnabled();
if (!active) {
logoContDescId = R.string.shared_string_enable;
}
name = app.getName();
pluginDescription.setText(R.string.third_party_application);
pluginLogo.setImageDrawable(app.getIcon());
pluginLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switchEnabled(app);
}
});
pluginOptions.setVisibility(View.GONE);
pluginOptions.setOnClickListener(null);
view.setTag(app);
} else if (item instanceof OsmandPlugin) {
final OsmandPlugin plugin = (OsmandPlugin) item;
active = plugin.isActive();
if (!active) {
logoContDescId = plugin.needsInstallation()
? R.string.access_shared_string_not_installed : R.string.shared_string_enable;
}
name = plugin.getName();
pluginDescription.setText(plugin.getDescription());
boolean light = getMyApplication().getSettings().isLightContent();
int linkTextColor = ContextCompat.getColor(PluginsActivity.this,
light ? R.color.ctx_menu_bottom_view_url_color_light : R.color.ctx_menu_bottom_view_url_color_dark);
pluginDescription.setLinkTextColor(linkTextColor);
pluginDescription.setMovementMethod(LinkMovementMethod.getInstance());
AndroidUtils.removeLinkUnderline(pluginDescription);
OsmandApplication app = getMyApplication();
int color = AndroidUtils.getColorFromAttr(PluginsActivity.this, R.attr.list_background_color);
pluginLogo.setImageDrawable(UiUtilities.tintDrawable(plugin.getLogoResource(), color));
pluginLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (plugin.isActive() || !plugin.needsInstallation()) {
enableDisablePlugin(plugin, !plugin.isActive());
}
}
});
pluginOptions.setVisibility(View.VISIBLE);
pluginOptions.setImageDrawable(getMyApplication().getUIUtilities().getThemedIcon(R.drawable.ic_overflow_menu_white));
pluginOptions.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showOptionsMenu(v, plugin);
}
});
view.setTag(plugin);
}
pluginLogo.setContentDescription(getString(logoContDescId));
if (active) {
pluginLogo.setBackgroundResource(isLightTheme ? R.drawable.bg_plugin_logo_enabled_light : R.drawable.bg_plugin_logo_enabled_dark);
} else {
TypedArray attributes = getTheme().obtainStyledAttributes(new int[] {R.attr.bg_plugin_logo_disabled});
pluginLogo.setBackgroundDrawable(attributes.getDrawable(0));
attributes.recycle();
}
TextView pluginName = (TextView) view.findViewById(R.id.plugin_name);
pluginName.setText(name);
pluginName.setContentDescription(name + " " + getString(active
? R.string.item_checked
: R.string.item_unchecked));
return view;
}
}
private void showOptionsMenu(View v, final OsmandPlugin plugin) {
final Class<? extends Activity> settingsActivity = plugin.getSettingsActivity();
final PopupMenu optionsMenu = new PopupMenu(this, v);
if (plugin.isActive() || !plugin.needsInstallation()) {
MenuItem enableDisableItem = optionsMenu.getMenu().add(
plugin.isActive() ? R.string.shared_string_disable
: R.string.shared_string_enable);
enableDisableItem
.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
enableDisablePlugin(plugin, !plugin.isActive());
optionsMenu.dismiss();
return true;
}
});
}
if (settingsActivity != null && plugin.isActive()) {
MenuItem settingsItem = optionsMenu.getMenu().add(R.string.shared_string_settings);
settingsItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
startActivity(new Intent(PluginsActivity.this, settingsActivity));
optionsMenu.dismiss();
return true;
}
});
}
if (plugin instanceof CustomOsmandPlugin) {
MenuItem settingsItem = optionsMenu.getMenu().add(R.string.shared_string_delete);
settingsItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
showDeletePluginDialog((CustomOsmandPlugin) plugin);
optionsMenu.dismiss();
return true;
}
});
}
optionsMenu.show();
}
private void showDeletePluginDialog(final CustomOsmandPlugin plugin) {
AlertDialog.Builder builder = new AlertDialog.Builder(PluginsActivity.this);
builder.setTitle(getString(R.string.delete_confirmation_msg, plugin.getName()));
builder.setMessage(R.string.are_you_sure);
builder.setNegativeButton(R.string.shared_string_cancel, null);
builder.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
OsmandApplication app = getMyApplication();
OsmandPlugin.removeCustomPlugin(app, plugin);
getListAdapter().remove(plugin);
}
});
builder.show();
}
}

View file

@ -0,0 +1,338 @@
package net.osmand.plus.activities;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.aidl.ConnectedApp;
import net.osmand.plus.CustomOsmandPlugin;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.dialogs.PluginInstalledBottomSheetDialog.PluginStateListener;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
import org.apache.commons.logging.Log;
import java.util.ArrayList;
public class PluginsFragment extends BaseOsmAndFragment implements PluginStateListener {
private static final Log log = PlatformUtil.getLog(PluginsFragment.class);
public static final String TAG = PluginsFragment.class.getName();
public static final String OPEN_PLUGINS = "open_plugins";
private OsmandApplication app;
private PluginsListAdapter adapter;
private LayoutInflater themedInflater;
private boolean nightMode;
@Override
public int getStatusBarColorId() {
return nightMode ? R.color.status_bar_color_dark : R.color.status_bar_color_light;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentActivity activity = requireMyActivity();
activity.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
public void handleOnBackPressed() {
FragmentActivity activity = getActivity();
if (activity instanceof MapActivity) {
dismissImmediate();
MapActivity mapActivity = (MapActivity) activity;
mapActivity.launchPrevActivityIntent();
}
}
});
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
app = requireMyApplication();
nightMode = !app.getSettings().isLightContent();
themedInflater = UiUtilities.getInflater(getContext(), nightMode);
View view = themedInflater.inflate(R.layout.plugins, container, false);
AndroidUtils.addStatusBarPadding21v(getContext(), view);
TextView toolbarTitle = view.findViewById(R.id.toolbar_title);
toolbarTitle.setText(R.string.plugins_screen);
ImageView closeButton = view.findViewById(R.id.close_button);
closeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Activity activity = getMyActivity();
if (activity != null) {
activity.onBackPressed();
}
}
});
UiUtilities.rotateImageByLayoutDirection(closeButton, AndroidUtils.getLayoutDirection(app));
adapter = new PluginsListAdapter(requireContext());
ListView listView = view.findViewById(R.id.plugins_list);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Object tag = view.getTag();
if (tag instanceof OsmandPlugin) {
FragmentActivity activity = getActivity();
if (activity != null) {
PluginInfoFragment.showInstance(activity.getSupportFragmentManager(), (OsmandPlugin) tag);
}
} else if (tag instanceof ConnectedApp) {
switchEnabled((ConnectedApp) tag);
}
}
});
return view;
}
@Override
public void onResume() {
super.onResume();
OsmandPlugin.checkInstalledMarketPlugins(app, getActivity());
adapter.notifyDataSetChanged();
}
private void enableDisablePlugin(OsmandPlugin plugin, boolean enable) {
if (OsmandPlugin.enablePlugin(getActivity(), app, plugin, enable)) {
adapter.notifyDataSetChanged();
}
}
private void switchEnabled(@NonNull ConnectedApp connectedApp) {
app.getAidlApi().switchEnabled(connectedApp);
adapter.notifyDataSetChanged();
}
@Override
public void onPluginStateChanged(OsmandPlugin plugin) {
adapter.notifyDataSetChanged();
}
protected class PluginsListAdapter extends ArrayAdapter<Object> {
PluginsListAdapter(Context context) {
super(context, R.layout.plugins_list_item, new ArrayList<>());
addAll(app.getAidlApi().getConnectedApps());
addAll(OsmandPlugin.getVisiblePlugins());
}
@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
View view = convertView;
if (view == null) {
view = themedInflater.inflate(R.layout.plugins_list_item, parent, false);
}
Context context = view.getContext();
boolean active = false;
int logoContDescId = R.string.shared_string_disable;
String name = "";
ImageButton pluginLogo = view.findViewById(R.id.plugin_logo);
ImageView pluginOptions = view.findViewById(R.id.plugin_options);
TextView pluginDescription = view.findViewById(R.id.plugin_description);
Object item = getItem(position);
if (item instanceof ConnectedApp) {
final ConnectedApp app = (ConnectedApp) item;
active = app.isEnabled();
if (!active) {
logoContDescId = R.string.shared_string_enable;
}
name = app.getName();
pluginDescription.setText(R.string.third_party_application);
pluginLogo.setImageDrawable(app.getIcon());
pluginLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
switchEnabled(app);
}
});
pluginOptions.setVisibility(View.GONE);
pluginOptions.setOnClickListener(null);
view.setTag(app);
} else if (item instanceof OsmandPlugin) {
final OsmandPlugin plugin = (OsmandPlugin) item;
active = plugin.isActive();
if (!active) {
logoContDescId = plugin.needsInstallation()
? R.string.access_shared_string_not_installed : R.string.shared_string_enable;
}
name = plugin.getName();
pluginDescription.setText(plugin.getDescription());
int linkTextColorId = nightMode ? R.color.ctx_menu_bottom_view_url_color_dark : R.color.ctx_menu_bottom_view_url_color_light;
int linkTextColor = ContextCompat.getColor(context, linkTextColorId);
pluginDescription.setLinkTextColor(linkTextColor);
pluginDescription.setMovementMethod(LinkMovementMethod.getInstance());
AndroidUtils.removeLinkUnderline(pluginDescription);
int color = AndroidUtils.getColorFromAttr(context, R.attr.list_background_color);
pluginLogo.setImageDrawable(UiUtilities.tintDrawable(plugin.getLogoResource(), color));
pluginLogo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (plugin.isActive() || !plugin.needsInstallation()) {
enableDisablePlugin(plugin, !plugin.isActive());
}
}
});
pluginOptions.setVisibility(View.VISIBLE);
pluginOptions.setImageDrawable(app.getUIUtilities().getThemedIcon(R.drawable.ic_overflow_menu_white));
pluginOptions.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showOptionsMenu(v, plugin);
}
});
view.setTag(plugin);
}
pluginLogo.setContentDescription(getString(logoContDescId));
if (active) {
pluginLogo.setBackgroundResource(nightMode ? R.drawable.bg_plugin_logo_enabled_dark : R.drawable.bg_plugin_logo_enabled_light);
} else {
TypedArray attributes = context.getTheme().obtainStyledAttributes(new int[] {R.attr.bg_plugin_logo_disabled});
pluginLogo.setBackgroundDrawable(attributes.getDrawable(0));
attributes.recycle();
}
TextView pluginName = view.findViewById(R.id.plugin_name);
pluginName.setText(name);
pluginName.setContentDescription(name + " " + getString(active
? R.string.item_checked
: R.string.item_unchecked));
return view;
}
}
private void showOptionsMenu(View view, final OsmandPlugin plugin) {
final PopupMenu optionsMenu = new PopupMenu(view.getContext(), view);
if (plugin.isActive() || !plugin.needsInstallation()) {
MenuItem enableDisableItem = optionsMenu.getMenu().add(
plugin.isActive() ? R.string.shared_string_disable
: R.string.shared_string_enable);
enableDisableItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
enableDisablePlugin(plugin, !plugin.isActive());
optionsMenu.dismiss();
return true;
}
});
}
final SettingsScreenType settingsScreenType = plugin.getSettingsScreenType();
if (settingsScreenType != null && plugin.isActive()) {
MenuItem settingsItem = optionsMenu.getMenu().add(R.string.shared_string_settings);
settingsItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
FragmentActivity activity = getActivity();
if (activity != null) {
BaseSettingsFragment.showInstance(activity, settingsScreenType);
}
optionsMenu.dismiss();
return true;
}
});
}
if (plugin instanceof CustomOsmandPlugin) {
MenuItem settingsItem = optionsMenu.getMenu().add(R.string.shared_string_delete);
settingsItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
showDeletePluginDialog((CustomOsmandPlugin) plugin);
optionsMenu.dismiss();
return true;
}
});
}
optionsMenu.show();
}
private void showDeletePluginDialog(final CustomOsmandPlugin plugin) {
Context context = getContext();
if (context != null) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(getString(R.string.delete_confirmation_msg, plugin.getName()));
builder.setMessage(R.string.are_you_sure);
builder.setNegativeButton(R.string.shared_string_cancel, null);
builder.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
OsmandPlugin.removeCustomPlugin(app, plugin);
adapter.remove(plugin);
}
});
builder.show();
}
}
public void dismissImmediate() {
FragmentActivity activity = getActivity();
if (activity != null) {
try {
activity.getSupportFragmentManager().popBackStackImmediate(TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
} catch (Exception e) {
log.error(e);
}
}
}
public static boolean showInstance(FragmentManager fragmentManager) {
try {
PluginsFragment fragment = new PluginsFragment();
fragmentManager.beginTransaction()
.add(R.id.fragmentContainer, fragment, TAG)
.addToBackStack(TAG)
.commitAllowingStateLoss();
return true;
} catch (Exception e) {
return false;
}
}
}

View file

@ -1,11 +1,9 @@
package net.osmand.plus.activities;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
@ -59,33 +57,24 @@ public class SettingsActivity extends SettingsBaseActivity {
}
PreferenceCategory plugins = (PreferenceCategory) screen.findPreference("plugin_settings");
for(OsmandPlugin op : OsmandPlugin.getEnabledPlugins()) {
final Class<? extends Activity> sa = op.getSettingsActivity();
if(sa != null) {
Preference preference = new Preference(this);
preference.setTitle(op.getName());
preference.setKey(op.getId());
preference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
startActivity(new Intent(SettingsActivity.this, sa));
return false;
}
});
plugins.addPreference(preference);
}
// final Class<? extends Activity> sa = op.getSettingsActivity();
// if(sa != null) {
// Preference preference = new Preference(this);
// preference.setTitle(op.getName());
// preference.setKey(op.getId());
// preference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
//
// @Override
// public boolean onPreferenceClick(Preference preference) {
// startActivity(new Intent(SettingsActivity.this, sa));
// return false;
// }
// });
// plugins.addPreference(preference);
// }
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if ((requestCode == PLUGINS_SELECTION_REQUEST) && (resultCode == PluginsActivity.ACTIVE_PLUGINS_LIST_MODIFIED)) {
finish();
startActivity(getIntent());
}
}
@Override
public boolean onPreferenceClick(Preference preference) {
if (preference == general) {

View file

@ -96,13 +96,11 @@ public class AudioVideoNoteMenuController extends MenuController {
@Override
public Drawable getRightIcon() {
if (mRecording.isPhoto()) {
return getIcon(R.drawable.ic_action_photo_dark, R.color.audio_video_icon_color);
} else if (mRecording.isAudio()) {
return getIcon(R.drawable.ic_action_micro_dark, R.color.audio_video_icon_color);
} else {
return getIcon(R.drawable.ic_action_video_dark, R.color.audio_video_icon_color);
int iconId = AudioVideoNotesPlugin.getIconIdForRecordingFile(mRecording.getFile());
if (iconId == -1) {
iconId = R.drawable.ic_action_photo_dark;
}
return getIcon(iconId, R.color.audio_video_icon_color);
}
@NonNull

View file

@ -47,14 +47,11 @@ import net.osmand.PlatformUtil;
import net.osmand.data.DataTileManager;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.ItemClickListener;
import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandPreference;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
@ -66,12 +63,15 @@ import net.osmand.plus.mapcontextmenu.MapContextMenu;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.myplaces.FavoritesActivity;
import net.osmand.plus.quickaction.QuickActionType;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.views.layers.MapInfoLayer;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandPreference;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.mapwidgets.widgetstates.WidgetState;
import net.osmand.plus.views.layers.MapInfoLayer;
import net.osmand.plus.views.mapwidgets.widgets.TextInfoWidget;
import net.osmand.plus.views.mapwidgets.widgetstates.WidgetState;
import net.osmand.util.Algorithms;
import net.osmand.util.GeoPointParserUtil.GeoParsedPoint;
import net.osmand.util.MapUtils;
@ -517,7 +517,18 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
}
return additional.toString();
}
}
public static int getIconIdForRecordingFile(@NonNull File file) {
String fileName = file.getName();
if (fileName.endsWith(IMG_EXTENSION)) {
return R.drawable.ic_action_photo_dark;
} else if (fileName.endsWith(MPEG4_EXTENSION)) {
return R.drawable.ic_action_video_dark;
} else if (fileName.endsWith(THREEGP_EXTENSION)) {
return R.drawable.ic_action_micro_dark;
}
return -1;
}
// private static void initializeRemoteControlRegistrationMethods() {
@ -893,7 +904,7 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
}
@Override
public void mapActivityResume(MapActivity activity) {
public void mapActivityResumeOnTop(MapActivity activity) {
this.mapActivity = activity;
// ((AudioManager) activity.getSystemService(Context.AUDIO_SERVICE)).registerMediaButtonEventReceiver(
// new ComponentName(activity, MediaRemoteControlReceiver.class));
@ -1800,13 +1811,8 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
}
@Override
public Class<? extends Activity> getSettingsActivity() {
return SettingsAudioVideoActivity.class;
}
@Override
public Class<? extends BaseSettingsFragment> getSettingsFragment() {
return MultimediaNotesFragment.class;
public SettingsScreenType getSettingsScreenType() {
return SettingsScreenType.MULTIMEDIA_NOTES;
}
@Override

View file

@ -13,6 +13,8 @@ import android.os.Build;
import android.os.Bundle;
import android.os.StatFs;
import android.text.SpannableString;
import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
@ -22,17 +24,18 @@ import androidx.preference.PreferenceViewHolder;
import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmAndAppCustomization;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.profiles.SelectCopyAppModeBottomSheet;
import net.osmand.plus.profiles.SelectCopyAppModeBottomSheet.CopyAppModePrefsListener;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmAndAppCustomization;
import net.osmand.plus.settings.bottomsheets.ResetProfilePrefsBottomSheet;
import net.osmand.plus.settings.bottomsheets.ResetProfilePrefsBottomSheet.ResetAppModePrefsListener;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.preferences.ListPreferenceEx;
import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
import net.osmand.plus.widgets.style.CustomTypefaceSpan;
@ -43,6 +46,7 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import static net.osmand.plus.activities.PluginInfoFragment.PLUGIN_INFO;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AUDIO_BITRATE_DEFAULT;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_CAMERA_FOCUS_AUTO;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_CAMERA_FOCUS_CONTINUOUS;
@ -66,6 +70,35 @@ public class MultimediaNotesFragment extends BaseSettingsFragment implements Cop
private static final String RESET_TO_DEFAULT = "reset_to_default";
private static final String OPEN_NOTES = "open_notes";
boolean showSwitchProfile = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle args = getArguments();
if (args != null) {
showSwitchProfile = args.getBoolean(PLUGIN_INFO, false);
}
}
@Override
protected void createToolbar(LayoutInflater inflater, View view) {
super.createToolbar(inflater, view);
View switchProfile = view.findViewById(R.id.profile_button);
if (switchProfile != null) {
AndroidUiHelper.updateVisibility(switchProfile, showSwitchProfile);
}
}
@Override
public Bundle buildArguments() {
Bundle args = super.buildArguments();
args.putBoolean(PLUGIN_INFO, showSwitchProfile);
return args;
}
@Override
protected void setupPreferences() {
AudioVideoNotesPlugin plugin = OsmandPlugin.getPlugin(AudioVideoNotesPlugin.class);

View file

@ -1,334 +0,0 @@
package net.osmand.plus.audionotes;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.os.StatFs;
import android.preference.ListPreference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.activities.SettingsBaseActivity;
import org.apache.commons.logging.Log;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AUDIO_BITRATE_DEFAULT;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_CAMERA_FOCUS_AUTO;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_CAMERA_FOCUS_CONTINUOUS;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_CAMERA_FOCUS_EDOF;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_CAMERA_FOCUS_HIPERFOCAL;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_CAMERA_FOCUS_INFINITY;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_CAMERA_FOCUS_MACRO;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_DEFAULT_ACTION_AUDIO;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_DEFAULT_ACTION_CHOOSE;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_DEFAULT_ACTION_TAKEPICTURE;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.AV_DEFAULT_ACTION_VIDEO;
import static net.osmand.plus.audionotes.AudioVideoNotesPlugin.cameraPictureSizeDefault;
// camera picture size:
// support camera focus select:
////
public class SettingsAudioVideoActivity extends SettingsBaseActivity {
private static final Log log = PlatformUtil.getLog(AudioVideoNotesPlugin.class);
@Override
public void onCreate(Bundle savedInstanceState) {
((OsmandApplication) getApplication()).applyTheme(this);
super.onCreate(savedInstanceState);
getToolbar().setTitle(R.string.av_settings);
PreferenceScreen grp = getPreferenceScreen();
AudioVideoNotesPlugin p = OsmandPlugin.getEnabledPlugin(AudioVideoNotesPlugin.class);
if (p != null) {
String[] entries;
Integer[] intValues;
entries = new String[]{getString(R.string.av_def_action_choose), getString(R.string.av_def_action_audio),
getString(R.string.av_def_action_video), getString(R.string.av_def_action_picture)};
intValues = new Integer[]{AV_DEFAULT_ACTION_CHOOSE, AV_DEFAULT_ACTION_AUDIO, AV_DEFAULT_ACTION_VIDEO,
AV_DEFAULT_ACTION_TAKEPICTURE};
ListPreference defAct = createListPreference(p.AV_DEFAULT_ACTION, entries, intValues, R.string.av_widget_action,
R.string.av_widget_action_descr);
grp.addPreference(defAct);
PreferenceCategory photo = new PreferenceCategory(this);
photo.setTitle(R.string.shared_string_photo);
grp.addPreference(photo);
final Camera cam = openCamera();
if (cam != null) {
// camera type settings
photo.addPreference(createCheckBoxPreference(p.AV_EXTERNAL_PHOTO_CAM, R.string.av_use_external_camera,
R.string.av_use_external_camera_descr));
Parameters parameters = cam.getParameters();
createCameraPictureSizesPref(p, photo, parameters);
createCameraFocusModesPref(p, photo, parameters);
// play sound on success photo
photo.addPreference(createCheckBoxPreference(p.AV_PHOTO_PLAY_SOUND, R.string.av_photo_play_sound,
R.string.av_photo_play_sound_descr));
cam.release();
}
// video settings
PreferenceCategory video = new PreferenceCategory(this);
video.setTitle(R.string.shared_string_video);
grp.addPreference(video);
video.addPreference(createCheckBoxPreference(p.AV_EXTERNAL_RECORDER, R.string.av_use_external_recorder,
R.string.av_use_external_recorder_descr));
// entries = new String[] { "3GP", "MP4" };
// intValues = new Integer[] { VIDEO_OUTPUT_3GP, VIDEO_OUTPUT_MP4 };
// ListPreference lp = createListPreference(p.AV_VIDEO_FORMAT, entries, intValues, R.string.av_video_format,
// R.string.av_video_format_descr);
// video.addPreference(lp);
List<String> qNames = new ArrayList<>();
List<Integer> qValues = new ArrayList<>();
if (Build.VERSION.SDK_INT < 11 || CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_LOW)) {
qNames.add(getString(R.string.av_video_quality_low));
qValues.add(CamcorderProfile.QUALITY_LOW);
}
if (Build.VERSION.SDK_INT >= 11 && CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P)) {
qNames.add("720 x 480 (480p)");
qValues.add(CamcorderProfile.QUALITY_480P);
}
if (Build.VERSION.SDK_INT >= 11 && CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)) {
qNames.add("1280 x 720 (720p)");
qValues.add(CamcorderProfile.QUALITY_720P);
}
if (Build.VERSION.SDK_INT >= 11 && CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P)) {
qNames.add("1920 x 1080 (1080p)");
qValues.add(CamcorderProfile.QUALITY_1080P);
}
if (Build.VERSION.SDK_INT >= 21 && CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2160P)) {
qNames.add("3840x2160 (2160p)");
qValues.add(CamcorderProfile.QUALITY_2160P);
}
if (Build.VERSION.SDK_INT < 11 || CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_HIGH)) {
qNames.add(getString(R.string.av_video_quality_high));
qValues.add(CamcorderProfile.QUALITY_HIGH);
}
ListPreference lp = createListPreference(p.AV_VIDEO_QUALITY,
qNames.toArray(new String[qNames.size()]),
qValues.toArray(new Integer[qValues.size()]),
R.string.av_video_quality,
R.string.av_video_quality_descr);
video.addPreference(lp);
// Recorder Split settings
PreferenceCategory recSplit = new PreferenceCategory(this);
recSplit.setTitle(R.string.rec_split);
grp.addPreference(recSplit);
recSplit.addPreference(createCheckBoxPreference(p.AV_RECORDER_SPLIT, R.string.rec_split_title,
R.string.rec_split_desc));
intValues = new Integer[]{1, 2, 3, 4, 5, 7, 10, 15, 20, 25, 30};
entries = new String[intValues.length];
int i = 0;
String minStr = getString(R.string.int_min);
for (int v : intValues) {
entries[i++] = String.valueOf(v) + " " + minStr;
}
lp = createListPreference(p.AV_RS_CLIP_LENGTH, entries, intValues,
R.string.rec_split_clip_length,
R.string.rec_split_clip_length_desc);
recSplit.addPreference(lp);
File dir = getMyApplication().getAppPath("").getParentFile();
long size = 0;
if (dir.canRead()) {
StatFs fs = new StatFs(dir.getAbsolutePath());
size = ((long) fs.getBlockSize() * (long) fs.getBlockCount()) / (1 << 30);
}
if (size > 0) {
int value = 1;
ArrayList<Integer> gbList = new ArrayList<>();
while (value < size) {
gbList.add(value);
if (value < 5) {
value++;
} else {
value += 5;
}
}
if (value != size) {
gbList.add((int) size);
}
entries = new String[gbList.size()];
intValues = new Integer[gbList.size()];
i = 0;
for (int v : gbList) {
intValues[i] = v;
entries[i] = AndroidUtils.formatSize(this, v * (1l << 30));
i++;
}
lp = createListPreference(p.AV_RS_STORAGE_SIZE, entries, intValues,
R.string.rec_split_storage_size,
R.string.rec_split_storage_size_desc);
recSplit.addPreference(lp);
}
// audio settings
PreferenceCategory audio = new PreferenceCategory(this);
audio.setTitle(R.string.shared_string_audio);
grp.addPreference(audio);
entries = new String[]{"Default", "AAC"};
intValues = new Integer[]{MediaRecorder.AudioEncoder.DEFAULT, MediaRecorder.AudioEncoder.AAC};
lp = createListPreference(p.AV_AUDIO_FORMAT, entries, intValues,
R.string.av_audio_format,
R.string.av_audio_format_descr);
audio.addPreference(lp);
entries = new String[]{"Default", "16 kbps", "32 kbps", "48 kbps", "64 kbps", "96 kbps", "128 kbps"};
intValues = new Integer[]{AUDIO_BITRATE_DEFAULT, 16 * 1024, 32 * 1024, 48 * 1024, 64 * 1024, 96 * 1024, 128 * 1024};
lp = createListPreference(p.AV_AUDIO_BITRATE, entries, intValues,
R.string.av_audio_bitrate,
R.string.av_audio_bitrate_descr);
audio.addPreference(lp);
}
}
private void createCameraPictureSizesPref(AudioVideoNotesPlugin p, PreferenceCategory photo, Parameters parameters) {
String[] entries;
Integer[] intValues;
// Photo picture size
// get supported sizes
List<Camera.Size> psps = parameters.getSupportedPictureSizes();
if (psps == null) {
return;
}
// list of megapixels of each resolution
List<Integer> mpix = new ArrayList<Integer>();
// list of index each resolution in list, returned by getSupportedPictureSizes()
List<Integer> picSizesValues = new ArrayList<Integer>();
// fill lists for sort
for (int index = 0; index < psps.size(); index++) {
mpix.add((psps.get(index)).width * (psps.get(index)).height);
picSizesValues.add(index);
}
// sort list for max resolution in begining of list
for (int i = 0; i < mpix.size(); i++) {
for (int j = 0; j < mpix.size() - i - 1; j++) {
if (mpix.get(j) < mpix.get(j + 1)) {
// change elements
int tmp = mpix.get(j + 1);
mpix.set(j + 1, mpix.get(j));
mpix.set(j, tmp);
tmp = picSizesValues.get(j + 1);
picSizesValues.set(j + 1, picSizesValues.get(j));
picSizesValues.set(j, tmp);
}
}
}
// set default photo size to max resolution (set index of element with max resolution in List, returned by getSupportedPictureSizes() )
cameraPictureSizeDefault = picSizesValues.get(0);
log.debug("onCreate() set cameraPictureSizeDefault=" + cameraPictureSizeDefault);
List<String> itemsPicSizes = new ArrayList<String>();
String prefix;
for (int index = 0; index < psps.size(); index++) {
float px = (float) ((psps.get(picSizesValues.get(index))).width * (psps.get(picSizesValues.get(index))).height);
if (px > 102400) // 100 K
{
px = px / 1048576;
prefix = "Mpx";
} else {
px = px / 1024;
prefix = "Kpx";
}
itemsPicSizes.add((psps.get(picSizesValues.get(index))).width +
"x" +
(psps.get(picSizesValues.get(index))).height +
" ( " +
String.format("%.2f", px) +
" " +
prefix +
" )");
}
log.debug("onCreate() set default size: width=" + psps.get(cameraPictureSizeDefault).width + " height="
+ psps.get(cameraPictureSizeDefault).height + " index in ps=" + cameraPictureSizeDefault);
entries = itemsPicSizes.toArray(new String[itemsPicSizes.size()]);
intValues = picSizesValues.toArray(new Integer[picSizesValues.size()]);
if (entries.length > 0) {
ListPreference camSizes = createListPreference(p.AV_CAMERA_PICTURE_SIZE, entries, intValues, R.string.av_camera_pic_size,
R.string.av_camera_pic_size_descr);
photo.addPreference(camSizes);
}
}
private void createCameraFocusModesPref(AudioVideoNotesPlugin p, PreferenceCategory photo, Parameters parameters) {
String[] entries;
Integer[] intValues;
// focus mode settings
// show in menu only suppoted modes
List<String> sfm = parameters.getSupportedFocusModes();
if (sfm == null) {
return;
}
List<String> items = new ArrayList<String>();
List<Integer> itemsValues = new ArrayList<Integer>();
// filtering known types for translate and set index
for (int index = 0; index < sfm.size(); index++) {
if (sfm.get(index).equals("auto")) {
items.add(getString(R.string.av_camera_focus_auto));
itemsValues.add(AV_CAMERA_FOCUS_AUTO);
} else if (sfm.get(index).equals("fixed")) {
items.add(getString(R.string.av_camera_focus_hiperfocal));
itemsValues.add(AV_CAMERA_FOCUS_HIPERFOCAL);
} else if (sfm.get(index).equals("edof")) {
items.add(getString(R.string.av_camera_focus_edof));
itemsValues.add(AV_CAMERA_FOCUS_EDOF);
} else if (sfm.get(index).equals("infinity")) {
items.add(getString(R.string.av_camera_focus_infinity));
itemsValues.add(AV_CAMERA_FOCUS_INFINITY);
} else if (sfm.get(index).equals("macro")) {
items.add(getString(R.string.av_camera_focus_macro));
itemsValues.add(AV_CAMERA_FOCUS_MACRO);
} else if (sfm.get(index).equals("continuous-picture")) {
items.add(getString(R.string.av_camera_focus_continuous));
itemsValues.add(AV_CAMERA_FOCUS_CONTINUOUS);
}
}
entries = items.toArray(new String[items.size()]);
intValues = itemsValues.toArray(new Integer[itemsValues.size()]);
if (entries.length > 0) {
ListPreference camFocus = createListPreference(p.AV_CAMERA_FOCUS_TYPE, entries, intValues, R.string.av_camera_focus,
R.string.av_camera_focus_descr);
photo.addPreference(camFocus);
}
}
protected Camera openCamera() {
try {
return Camera.open();
} catch (Exception e) {
log.error("Error open camera", e);
return null;
}
}
}

View file

@ -14,11 +14,12 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.activities.PluginActivity;
import net.osmand.plus.activities.PluginsFragment;
import net.osmand.plus.chooseplan.ChoosePlanDialogFragment;
import net.osmand.plus.dashboard.tools.DashFragmentData;
import net.osmand.plus.development.OsmandDevelopmentPlugin;
@ -68,9 +69,10 @@ public class DashPluginsFragment extends DashBaseFragment {
return new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getActivity(), PluginActivity.class);
intent.putExtra(PluginActivity.EXTRA_PLUGIN_ID, plugin.getId());
startActivity(intent);
FragmentActivity activity = getActivity();
if (activity != null) {
PluginsFragment.showInstance(activity.getSupportFragmentManager());
}
closeDashboard();
}
};
@ -84,7 +86,10 @@ public class DashPluginsFragment extends DashBaseFragment {
view.findViewById(R.id.show_all).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(getActivity(), getMyApplication().getAppCustomization().getPluginsActivity()));
FragmentActivity activity = getActivity();
if (activity != null) {
PluginsFragment.showInstance(activity.getSupportFragmentManager());
}
closeDashboard();
}
});

View file

@ -14,7 +14,7 @@ import net.osmand.plus.Version;
import net.osmand.plus.activities.ContributionVersionActivity;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dashboard.tools.DashFragmentData;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
import net.osmand.plus.views.layers.MapInfoLayer;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.views.OsmandMapTileView;
@ -122,13 +122,8 @@ public class OsmandDevelopmentPlugin extends OsmandPlugin {
}
@Override
public Class<? extends Activity> getSettingsActivity() {
return SettingsDevelopmentActivity.class;
}
@Override
public Class<? extends BaseSettingsFragment> getSettingsFragment() {
return DevelopmentSettingsFragment.class;
public SettingsScreenType getSettingsScreenType() {
return SettingsScreenType.DEVELOPMENT_SETTINGS;
}
@Override

View file

@ -1,212 +0,0 @@
package net.osmand.plus.development;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.Debug;
import android.os.Debug.MemoryInfo;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import net.osmand.plus.OsmAndLocationSimulation;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.activities.SettingsBaseActivity;
import net.osmand.plus.render.NativeOsmandLibrary;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.util.SunriseSunset;
import java.text.SimpleDateFormat;
//import net.osmand.plus.development.OsmandDevelopmentPlugin;
public class SettingsDevelopmentActivity extends SettingsBaseActivity {
@SuppressLint("SimpleDateFormat")
@Override
public void onCreate(Bundle savedInstanceState) {
OsmandApplication app = getMyApplication();
app.applyTheme(this);
super.onCreate(savedInstanceState);
getToolbar().setTitle(R.string.debugging_and_development);
PreferenceScreen category = getPreferenceScreen();
Preference pref;
if (Version.isOpenGlAvailable(app)) {
category.addPreference(createCheckBoxPreference(settings.USE_OPENGL_RENDER,
R.string.use_opengl_render, R.string.use_opengl_render_descr));
}
if (!Version.isBlackberry(app)) {
CheckBoxPreference nativeCheckbox = createCheckBoxPreference(settings.SAFE_MODE, R.string.safe_mode, R.string.safe_mode_description);
// disable the checkbox if the library cannot be used
if ((NativeOsmandLibrary.isLoaded() && !NativeOsmandLibrary.isSupported()) || settings.NATIVE_RENDERING_FAILED.get()) {
nativeCheckbox.setEnabled(false);
nativeCheckbox.setChecked(true);
}
category.addPreference(nativeCheckbox);
}
PreferenceCategory navigation = new PreferenceCategory(this);
navigation.setTitle(R.string.routing_settings);
category.addPreference(navigation);
pref = new Preference(this);
final Preference simulate = pref;
final OsmAndLocationSimulation sim = getMyApplication().getLocationProvider().getLocationSimulation();
final Runnable updateTitle = new Runnable(){
@Override
public void run() {
simulate.setSummary(sim.isRouteAnimating() ?
R.string.simulate_your_location_stop_descr : R.string.simulate_your_location_gpx_descr);
}
};
pref.setTitle(R.string.simulate_your_location);
updateTitle.run();
pref.setKey("simulate_your_location");
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
updateTitle.run();
sim.startStopRouteAnimation(SettingsDevelopmentActivity.this, true, updateTitle);
return true;
}
});
navigation.addPreference(pref);
PreferenceCategory debug = new PreferenceCategory(this);
debug.setTitle(R.string.debugging_and_development);
category.addPreference(debug);
CheckBoxPreference dbg = createCheckBoxPreference(settings.DEBUG_RENDERING_INFO,
R.string.trace_rendering, R.string.trace_rendering_descr);
debug.addPreference(dbg);
final Preference firstRunPreference = new Preference(this);
firstRunPreference.setTitle(R.string.simulate_initial_startup);
firstRunPreference.setSummary(R.string.simulate_initial_startup_descr);
firstRunPreference.setSelectable(true);
firstRunPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
getMyApplication().getAppInitializer().resetFirstTimeRun();
OsmandSettings settings = getMyApplication().getSettings();
settings.FIRST_MAP_IS_DOWNLOADED.set(false);
settings.MAPILLARY_FIRST_DIALOG_SHOWN.set(false);
settings.WEBGL_SUPPORTED.set(true);
settings.WIKI_ARTICLE_SHOW_IMAGES_ASKED.set(false);
getMyApplication().showToastMessage(R.string.shared_string_ok);
return true;
}
});
debug.addPreference(firstRunPreference);
debug.addPreference(createCheckBoxPreference(settings.SHOULD_SHOW_FREE_VERSION_BANNER,
R.string.show_free_version_banner,
R.string.show_free_version_banner_description));
pref = new Preference(this);
pref.setTitle(R.string.test_voice_prompts);
pref.setSummary(R.string.play_commands_of_currently_selected_voice);
pref.setKey("test_voice_commands");
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
startActivity(new Intent(SettingsDevelopmentActivity.this, TestVoiceActivity.class));
return true;
}
});
category.addPreference(pref);
pref = new Preference(this);
pref.setTitle(R.string.logcat_buffer);
pref.setSummary(R.string.logcat_buffer_descr);
pref.setKey("logcat_buffer");
pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
startActivity(new Intent(SettingsDevelopmentActivity.this, LogcatActivity.class));
return true;
}
});
category.addPreference(pref);
PreferenceCategory info = new PreferenceCategory(this);
info.setTitle(R.string.info_button);
category.addPreference(info);
pref = new Preference(this);
pref.setTitle(R.string.global_app_allocated_memory);
long javaAvailMem = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/ (1024*1024l);
long javaTotal = Runtime.getRuntime().totalMemory() / (1024*1024l);
long dalvikSize = android.os.Debug.getNativeHeapAllocatedSize() / (1024*1024l);
pref.setSummary(getString(R.string.global_app_allocated_memory_descr, javaAvailMem, javaTotal, dalvikSize));
pref.setSelectable(false);
//setEnabled(false) creates bad readability on some devices
//pref.setEnabled(false);
info.addPreference(pref);
// ActivityManager activityManager = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
// ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
// activityManager.getMemoryInfo(memoryInfo);
// long totalSize = memoryInfo.availMem / (1024*1024l);
MemoryInfo mem = new Debug.MemoryInfo();
Debug.getMemoryInfo(mem);
pref = new Preference(this);
pref.setTitle(R.string.native_app_allocated_memory);
pref.setSummary(getString(R.string.native_app_allocated_memory_descr
, mem.nativePrivateDirty / 1024, mem.dalvikPrivateDirty / 1024 , mem.otherPrivateDirty / 1024
, mem.nativePss / 1024, mem.dalvikPss / 1024 , mem.otherPss / 1024));
pref.setSelectable(false);
//setEnabled(false) creates bad readability on some devices
//pref.setEnabled(false);
info.addPreference(pref);
final Preference agpspref = new Preference(this);
agpspref.setTitle(R.string.agps_info);
if (settings.AGPS_DATA_LAST_TIME_DOWNLOADED.get() != 0L) {
SimpleDateFormat prt = new SimpleDateFormat("yyyy-MM-dd HH:mm");
agpspref.setSummary(getString(R.string.agps_data_last_downloaded, prt.format(settings.AGPS_DATA_LAST_TIME_DOWNLOADED.get())));
} else {
agpspref.setSummary(getString(R.string.agps_data_last_downloaded, "--"));
}
agpspref.setSelectable(true);
//setEnabled(false) creates bad readability on some devices
//pref.setEnabled(false);
agpspref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if(getMyApplication().getSettings().isInternetConnectionAvailable(true)) {
getMyApplication().getLocationProvider().redownloadAGPS();
SimpleDateFormat prt = new SimpleDateFormat("yyyy-MM-dd HH:mm");
agpspref.setSummary(getString(R.string.agps_data_last_downloaded, prt.format(settings.AGPS_DATA_LAST_TIME_DOWNLOADED.get())));
}
return true;
}
});
info.addPreference(agpspref);
SunriseSunset sunriseSunset = getMyApplication().getDaynightHelper().getSunriseSunset();
pref = new Preference(this);
pref.setTitle(R.string.day_night_info);
if (sunriseSunset != null && sunriseSunset.getSunrise() != null && sunriseSunset.getSunset() != null) {
SimpleDateFormat prt = new SimpleDateFormat("yyyy-MM-dd HH:mm");
pref.setSummary(getString(R.string.day_night_info_description, prt.format(sunriseSunset.getSunrise()),
prt.format(sunriseSunset.getSunset())));
} else {
pref.setSummary(getString(R.string.day_night_info_description, "null", "null"));
}
pref.setSelectable(false);
//setEnabled(false) creates bad readability on some devices
//pref.setEnabled(false);
info.addPreference(pref);
}
}

View file

@ -1,7 +1,6 @@
package net.osmand.plus.dialogs;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
@ -20,7 +19,7 @@ import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.MapActivityLayers;
import net.osmand.plus.activities.PluginActivity;
import net.osmand.plus.activities.PluginsFragment;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.poi.PoiUIFilter;
@ -149,9 +148,7 @@ final class MapLayerMenuListener extends OnRowItemClick {
settings.SHOW_MAP_MARKERS.set(isChecked);
} else if (itemId == R.string.layer_map) {
if (OsmandPlugin.getEnabledPlugin(OsmandRasterMapsPlugin.class) == null) {
Intent intent = new Intent(mapActivity, PluginActivity.class);
intent.putExtra(PluginActivity.EXTRA_PLUGIN_ID, OsmandRasterMapsPlugin.ID);
mapActivity.startActivity(intent);
PluginsFragment.showInstance(mapActivity.getSupportFragmentManager());
} else {
ContextMenuItem it = adapter.getItem(pos);
mapActivity.getMapLayers().selectMapLayer(mapActivity.getMapView(), it, adapter);

View file

@ -6,6 +6,7 @@ import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.MenuItem;
import android.view.View;
@ -25,6 +26,8 @@ import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.activities.LocalIndexHelper.LocalIndexType;
import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.PluginsFragment;
import net.osmand.plus.chooseplan.ChoosePlanDialogFragment;
import net.osmand.plus.download.CityItem;
import net.osmand.plus.download.CustomIndexItem;
@ -343,8 +346,7 @@ public class ItemViewHolder {
ChoosePlanDialogFragment.showSeaDepthMapsInstance(context.getSupportFragmentManager());
break;
case ASK_FOR_SEAMARKS_PLUGIN:
context.startActivity(new Intent(context, context.getMyApplication().getAppCustomization()
.getPluginsActivity()));
showPluginsScreen();
Toast.makeText(context.getApplicationContext(),
context.getString(R.string.activate_seamarks_plugin), Toast.LENGTH_SHORT).show();
break;
@ -352,8 +354,7 @@ public class ItemViewHolder {
ChoosePlanDialogFragment.showHillshadeSrtmPluginInstance(context.getSupportFragmentManager());
break;
case ASK_FOR_SRTM_PLUGIN_ENABLE:
context.startActivity(new Intent(context, context.getMyApplication().getAppCustomization()
.getPluginsActivity()));
showPluginsScreen();
Toast.makeText(context, context.getString(R.string.activate_srtm_plugin),
Toast.LENGTH_SHORT).show();
break;
@ -361,6 +362,13 @@ public class ItemViewHolder {
break;
}
}
private void showPluginsScreen() {
Bundle params = new Bundle();
params.putBoolean(PluginsFragment.OPEN_PLUGINS, true);
Intent intent = context.getIntent();
MapActivity.launchMapActivityMoveToTop(context, intent != null ? intent.getExtras() : null, null, params);
}
};
} else {
final boolean isDownloading = context.getDownloadThread().isDownloading(item);

View file

@ -13,6 +13,7 @@ import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.style.StyleSpan;
import android.view.ContextThemeWrapper;
@ -80,6 +81,7 @@ import net.osmand.plus.OsmAndConstants;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.activities.PluginsFragment;
import net.osmand.plus.helpers.enums.MetricsConstants;
import net.osmand.plus.helpers.enums.SpeedConstants;
import net.osmand.plus.settings.backend.CommonPreference;
@ -90,7 +92,6 @@ import net.osmand.plus.Version;
import net.osmand.plus.activities.ActivityResultListener;
import net.osmand.plus.activities.ActivityResultListener.OnActivityResultListener;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.PluginActivity;
import net.osmand.plus.activities.SettingsActivity;
import net.osmand.plus.dialogs.ConfigureMapMenu;
import net.osmand.plus.dialogs.GpxAppearanceAdapter;
@ -649,9 +650,9 @@ public class GpxUiHelper {
confirm.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(activity, PluginActivity.class);
intent.putExtra(PluginActivity.EXTRA_PLUGIN_ID, OsmandMonitoringPlugin.ID);
activity.startActivity(intent);
Bundle params = new Bundle();
params.putBoolean(PluginsFragment.OPEN_PLUGINS, true);
MapActivity.launchMapActivityMoveToTop(activity, null, null, params);
}
});
confirm.setNegativeButton(R.string.shared_string_cancel, null);

View file

@ -11,16 +11,18 @@ import net.osmand.PlatformUtil;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.map.TileSourceManager;
import net.osmand.plus.mapsource.EditMapSourceDialogFragment;
import net.osmand.plus.search.QuickSearchDialogFragment;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.PluginsFragment;
import net.osmand.plus.dashboard.DashboardOnMap.DashboardType;
import net.osmand.plus.mapmarkers.MapMarkersDialogFragment;
import net.osmand.plus.mapsource.EditMapSourceDialogFragment;
import net.osmand.plus.osmedit.OsmEditingFragment;
import net.osmand.plus.search.QuickSearchDialogFragment;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
import net.osmand.util.Algorithms;
@ -58,6 +60,9 @@ public class IntentHelper {
if (!applied) {
applied = parseSendIntent();
}
if (!applied) {
applied = parseOAuthIntent();
}
return applied;
}
@ -207,10 +212,22 @@ public class IntentHelper {
mapActivity.setIntent(null);
}
if (intent.hasExtra(BaseSettingsFragment.OPEN_SETTINGS)) {
String settingsType = intent.getStringExtra(BaseSettingsFragment.OPEN_SETTINGS);
String appMode = intent.getStringExtra(BaseSettingsFragment.APP_MODE_KEY);
if (BaseSettingsFragment.OPEN_CONFIG_PROFILE.equals(settingsType)) {
BaseSettingsFragment.showInstance(mapActivity, SettingsScreenType.CONFIGURE_PROFILE, ApplicationMode.valueOfStringKey(appMode, null));
String settingsTypeName = intent.getStringExtra(BaseSettingsFragment.OPEN_SETTINGS);
if (!Algorithms.isEmpty(settingsTypeName)) {
try {
SettingsScreenType screenType = SettingsScreenType.valueOf(settingsTypeName);
BaseSettingsFragment.showInstance(mapActivity, screenType, ApplicationMode.valueOfStringKey(appMode, null));
} catch (IllegalArgumentException e) {
LOG.error("error", e);
}
}
mapActivity.setIntent(null);
}
if (intent.hasExtra(PluginsFragment.OPEN_PLUGINS)) {
boolean openPlugins = intent.getBooleanExtra(PluginsFragment.OPEN_PLUGINS, false);
if (openPlugins) {
PluginsFragment.showInstance(mapActivity.getSupportFragmentManager());
}
mapActivity.setIntent(null);
}
@ -271,6 +288,23 @@ public class IntentHelper {
return false;
}
private boolean parseOAuthIntent() {
Intent intent = mapActivity.getIntent();
if (intent != null && intent.getData() != null) {
Uri uri = intent.getData();
if (uri.toString().startsWith("osmand-oauth")) {
OsmEditingFragment fragment = mapActivity.getOsmEditingFragment();
if (fragment != null) {
String oauthVerifier = uri.getQueryParameter("oauth_verifier");
fragment.authorize(oauthVerifier);
mapActivity.setIntent(null);
return true;
}
}
}
return false;
}
private boolean handleSendText(Intent intent) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (!Algorithms.isEmpty(sharedText)) {

View file

@ -34,6 +34,7 @@ class FavoritesImportTask extends BaseImportAsyncTask<Void, Void, GPXFile> {
protected GPXFile doInBackground(Void... nothing) {
List<FavouritePoint> favourites = asFavourites(app, gpxFile.getPoints(), fileName, forceImportFavourites);
FavouritesDbHelper favoritesHelper = app.getFavorites();
checkDuplicateNames(favourites);
for (FavouritePoint favourite : favourites) {
favoritesHelper.deleteFavourite(favourite, false);
favoritesHelper.addFavourite(favourite, false);
@ -43,6 +44,27 @@ class FavoritesImportTask extends BaseImportAsyncTask<Void, Void, GPXFile> {
return null;
}
public void checkDuplicateNames(List<FavouritePoint> favourites) {
for (FavouritePoint fp : favourites) {
int number = 1;
String index;
String name = fp.getName();
boolean duplicatesFound = false;
for (FavouritePoint fp2 : favourites) {
if (name.equals(fp2.getName()) && fp.getCategory().equals(fp2.getCategory()) && !fp.equals(fp2)) {
if (!duplicatesFound) {
index = " (" + number + ")";
fp.setName(name + index);
}
duplicatesFound = true;
number++;
index = " (" + number + ")";
fp2.setName(fp2.getName() + index);
}
}
}
}
@Override
protected void onPostExecute(GPXFile result) {
hideProgress();

View file

@ -34,8 +34,8 @@ import net.osmand.plus.dialogs.ImportGpxBottomSheetDialogFragment;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
import net.osmand.plus.measurementtool.MeasurementToolFragment;
import net.osmand.plus.settings.backend.SettingsHelper;
import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem;
import net.osmand.plus.settings.backend.backup.SettingsHelper;
import net.osmand.plus.settings.backend.backup.SettingsItem;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.util.Algorithms;

View file

@ -13,12 +13,12 @@ import net.osmand.FileUtils;
import net.osmand.IndexConstants;
import net.osmand.plus.CustomOsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.settings.backend.SettingsHelper.CheckDuplicatesListener;
import net.osmand.plus.settings.backend.SettingsHelper.PluginSettingsItem;
import net.osmand.plus.settings.backend.SettingsHelper.ProfileSettingsItem;
import net.osmand.plus.settings.backend.SettingsHelper.SettingsCollectListener;
import net.osmand.plus.settings.backend.SettingsHelper.SettingsImportListener;
import net.osmand.plus.settings.backend.SettingsHelper.SettingsItem;
import net.osmand.plus.settings.backend.backup.SettingsHelper.CheckDuplicatesListener;
import net.osmand.plus.settings.backend.backup.PluginSettingsItem;
import net.osmand.plus.settings.backend.backup.ProfileSettingsItem;
import net.osmand.plus.settings.backend.backup.SettingsHelper.SettingsCollectListener;
import net.osmand.plus.settings.backend.backup.SettingsHelper.SettingsImportListener;
import net.osmand.plus.settings.backend.backup.SettingsItem;
import net.osmand.plus.settings.fragments.ImportSettingsFragment;
import net.osmand.util.Algorithms;

View file

@ -22,6 +22,7 @@ import net.osmand.plus.activities.LocalIndexHelper;
import net.osmand.plus.activities.LocalIndexHelper.LocalIndexType;
import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.PluginsFragment;
import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.download.DownloadValidationManager;
@ -110,8 +111,7 @@ public class MapDataMenuController extends MenuController {
activity.getString(R.string.activate_srtm_plugin), Toast.LENGTH_LONG).show();
}
} else {
activity.startActivity(new Intent(activity, activity.getMyApplication().getAppCustomization()
.getPluginsActivity()));
PluginsFragment.showInstance(activity.getSupportFragmentManager());
Toast.makeText(activity, activity.getString(R.string.activate_srtm_plugin),
Toast.LENGTH_SHORT).show();
}

View file

@ -618,12 +618,12 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
}
}
HorizontalSelectionAdapter horizontalSelectionAdapter = new HorizontalSelectionAdapter(app, nightMode);
horizontalSelectionAdapter.setItems(new ArrayList<>(iconCategories.keySet()));
horizontalSelectionAdapter.setSelectedItem(selectedIconCategory);
horizontalSelectionAdapter.setTitledItems(new ArrayList<>(iconCategories.keySet()));
horizontalSelectionAdapter.setSelectedItemByTitle(selectedIconCategory);
horizontalSelectionAdapter.setListener(new HorizontalSelectionAdapter.HorizontalSelectionAdapterListener() {
@Override
public void onItemSelected(String item) {
selectedIconCategory = item;
public void onItemSelected(HorizontalSelectionAdapter.HorizontalSelectionItem item) {
selectedIconCategory = item.getTitle();
createIconForCategory();
updateIconSelector(selectedIcon, PointEditorFragmentNew.this.view);
}
@ -632,7 +632,7 @@ public abstract class PointEditorFragmentNew extends BaseOsmAndFragment {
iconCategoriesRecyclerView.setAdapter(horizontalSelectionAdapter);
iconCategoriesRecyclerView.setLayoutManager(new LinearLayoutManager(app, RecyclerView.HORIZONTAL, false));
horizontalSelectionAdapter.notifyDataSetChanged();
iconCategoriesRecyclerView.smoothScrollToPosition(horizontalSelectionAdapter.getItemPosition(selectedIconCategory));
iconCategoriesRecyclerView.smoothScrollToPosition(horizontalSelectionAdapter.getItemPositionByTitle(selectedIconCategory));
for (String name : iconNameList) {
selectIcon.addView(createIconItemView(name, selectIcon), new FlowLayout.LayoutParams(0, 0));
}

View file

@ -17,6 +17,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import java.util.ArrayList;
import java.util.List;
import static net.osmand.util.Algorithms.capitalizeFirstLetter;
@ -24,19 +25,28 @@ import static net.osmand.util.Algorithms.capitalizeFirstLetter;
public class HorizontalSelectionAdapter extends RecyclerView.Adapter<HorizontalSelectionAdapter.ItemViewHolder> {
private List<String> items;
public static int INVALID_ID = -1;
private List<HorizontalSelectionItem> items;
private OsmandApplication app;
private boolean nightMode;
private HorizontalSelectionAdapterListener listener;
private String selectedItem = "";
private HorizontalSelectionItem selectedItem = null;
public HorizontalSelectionAdapter(OsmandApplication app, boolean nightMode) {
this.app = app;
this.nightMode = nightMode;
}
public void setItems(List<String> items) {
public void setTitledItems(List<String> titles) {
List<HorizontalSelectionItem> items = new ArrayList<>();
for (String title : titles) {
items.add(new HorizontalSelectionItem(title));
}
setItems(items);
}
public void setItems(List<HorizontalSelectionItem> items) {
this.items = items;
}
@ -44,23 +54,30 @@ public class HorizontalSelectionAdapter extends RecyclerView.Adapter<HorizontalS
@Override
public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
view = UiUtilities.getInflater(parent.getContext(), nightMode).inflate(R.layout.point_editor_icon_category_item,
parent, false);
view = UiUtilities.getInflater(parent.getContext(), nightMode)
.inflate(R.layout.point_editor_icon_category_item, parent, false);
return new ItemViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ItemViewHolder holder, final int position) {
final String item = items.get(holder.getAdapterPosition());
final HorizontalSelectionItem item = items.get(holder.getAdapterPosition());
TextView textView = holder.buttonText;
int activeColorResId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
if (item.equals(selectedItem)) {
if (item.equals(selectedItem) && item.isEnabled()) {
AndroidUtils.setBackground(holder.button, app.getUIUtilities().getPaintedIcon(
R.drawable.bg_select_icon_group_button, ContextCompat.getColor(app, activeColorResId)));
textView.setTextColor(ContextCompat.getColor(app, R.color.color_white));
} else {
textView.setTextColor(ContextCompat.getColor(app,
nightMode ? R.color.active_color_primary_dark : R.color.preference_category_title));
if (!item.isEnabled()) {
int inactiveColorId = nightMode ?
R.color.icon_color_default_dark : R.color.icon_color_secondary_light;
textView.setTextColor(ContextCompat.getColor(app, inactiveColorId));
} else {
int defaultTitleColorId = nightMode ? R.color.active_color_primary_dark : R.color.preference_category_title;
textView.setTextColor(ContextCompat.getColor(app,
item.getTitleColorId() != INVALID_ID ? item.getTitleColorId() : defaultTitleColorId));
}
GradientDrawable buttonBackground = (GradientDrawable) AppCompatResources.getDrawable(app,
R.drawable.bg_select_icon_group_button).mutate();
buttonBackground.setStroke(AndroidUtils.dpToPx(app, 1), ContextCompat.getColor(app,
@ -69,8 +86,9 @@ public class HorizontalSelectionAdapter extends RecyclerView.Adapter<HorizontalS
buttonBackground.setColor(ContextCompat.getColor(app, R.color.color_transparent));
AndroidUtils.setBackground(holder.button, buttonBackground);
}
textView.setText(capitalizeFirstLetter(item));
textView.setText(capitalizeFirstLetter(item.title));
textView.requestLayout();
holder.button.setEnabled(item.isEnabled());
holder.button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -92,22 +110,39 @@ public class HorizontalSelectionAdapter extends RecyclerView.Adapter<HorizontalS
return items.size();
}
public int getItemPosition(String name) {
return items.indexOf(name);
public int getItemPositionByTitle(String title) {
return getItemPosition(getItemByTitle(title));
}
public void setSelectedItem(String selectedItem) {
public int getItemPosition(HorizontalSelectionItem item) {
return items.indexOf(item);
}
public void setSelectedItemByTitle(String title) {
setSelectedItem(getItemByTitle(title));
}
public void setSelectedItem(HorizontalSelectionItem selectedItem) {
this.selectedItem = selectedItem;
notifyDataSetChanged();
}
public HorizontalSelectionItem getItemByTitle(String title) {
for (HorizontalSelectionItem item : items) {
if (title.equals(item.getTitle())) {
return item;
}
}
return null;
}
public void setListener(HorizontalSelectionAdapterListener listener) {
this.listener = listener;
}
public interface HorizontalSelectionAdapterListener {
void onItemSelected(String item);
void onItemSelected(HorizontalSelectionItem item);
}
static class ItemViewHolder extends RecyclerView.ViewHolder {
@ -120,4 +155,44 @@ public class HorizontalSelectionAdapter extends RecyclerView.Adapter<HorizontalS
button = itemView.findViewById(R.id.button);
}
}
public static class HorizontalSelectionItem {
private String title;
private boolean enabled = true;
private int titleColorId = INVALID_ID;
private Object object;
public HorizontalSelectionItem(String title) {
this.title = title;
}
public HorizontalSelectionItem(String title, Object object) {
this.title = title;
this.object = object;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public void setTitleColorId(int titleColorId) {
this.titleColorId = titleColorId;
}
public String getTitle() {
return title;
}
public boolean isEnabled() {
return enabled;
}
public int getTitleColorId() {
return titleColorId;
}
public Object getObject() {
return object;
}
}
}

View file

@ -0,0 +1,396 @@
package net.osmand.plus.measurementtool;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.github.mikephil.charting.charts.HorizontalBarChart;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.data.BarData;
import com.github.mikephil.charting.data.ChartData;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.SettingsBaseActivity;
import net.osmand.plus.helpers.GpxUiHelper;
import net.osmand.plus.helpers.GpxUiHelper.OrderedLineDataSet;
import net.osmand.plus.helpers.GpxUiHelper.GPXDataSetAxisType;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter;
import net.osmand.plus.measurementtool.MeasurementToolFragment.OnUpdateAdditionalInfoListener;
import net.osmand.plus.routepreparationmenu.RouteDetailsFragment;
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.router.RouteSegmentResult;
import net.osmand.util.Algorithms;
import static net.osmand.router.RouteStatisticsHelper.RouteStatistics;
import static net.osmand.GPXUtilities.GPXTrackAnalysis;
import static net.osmand.GPXUtilities.GPXFile;
import static net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class GraphsCard extends BaseCard implements OnUpdateAdditionalInfoListener {
private static String GRAPH_DATA_GPX_FILE_NAME = "graph_data_tmp";
private MeasurementEditingContext editingCtx;
private MeasurementToolFragment fragment;
private GraphType visibleGraphType;
private List<GraphType> graphTypes = new ArrayList<>();
private View commonGraphContainer;
private View customGraphContainer;
private View messageContainer;
private LineChart commonGraphChart;
private HorizontalBarChart customGraphChart;
private RecyclerView graphTypesMenu;
private enum CommonGraphType {
OVERVIEW(R.string.shared_string_overview, false),
ALTITUDE(R.string.altitude, true),
SLOPE(R.string.shared_string_slope, true),
SPEED(R.string.map_widget_speed, false);
CommonGraphType(int titleId, boolean canBeCalculated) {
this.titleId = titleId;
this.canBeCalculated = canBeCalculated;
}
final int titleId;
final boolean canBeCalculated;
}
public GraphsCard(@NonNull MapActivity mapActivity, MeasurementToolFragment fragment) {
super(mapActivity);
this.fragment = fragment;
}
@Override
protected void updateContent() {
if (mapActivity == null || fragment == null) return;
editingCtx = fragment.getEditingCtx();
commonGraphContainer = view.findViewById(R.id.common_graphs_container);
customGraphContainer = view.findViewById(R.id.custom_graphs_container);
messageContainer = view.findViewById(R.id.message_container);
commonGraphChart = (LineChart) view.findViewById(R.id.line_chart);
customGraphChart = (HorizontalBarChart) view.findViewById(R.id.horizontal_chart);
updateGraphData();
graphTypesMenu = view.findViewById(R.id.graph_types_recycler_view);
graphTypesMenu.setLayoutManager(
new LinearLayoutManager(mapActivity, RecyclerView.HORIZONTAL, false));
refreshGraphTypesSelectionMenu();
updateDataView();
}
@Override
public int getCardLayoutId() {
return R.layout.fragment_measurement_tool_graph;
}
@Override
public void onUpdateAdditionalInfo() {
if (!isRouteCalculating()) {
updateGraphData();
refreshGraphTypesSelectionMenu();
}
updateDataView();
}
private void refreshGraphTypesSelectionMenu() {
graphTypesMenu.removeAllViews();
OsmandApplication app = getMyApplication();
int activeColorId = nightMode ? R.color.active_color_primary_dark : R.color.active_color_primary_light;
final HorizontalSelectionAdapter adapter = new HorizontalSelectionAdapter(app, nightMode);
final ArrayList<HorizontalSelectionItem> items = new ArrayList<>();
for (GraphType type : graphTypes) {
HorizontalSelectionItem item = new HorizontalSelectionItem(type.getTitle(), type);
if (type.isCustom()) {
item.setTitleColorId(activeColorId);
}
if (type.isAvailable()) {
items.add(item);
}
}
adapter.setItems(items);
String selectedItemKey = visibleGraphType.getTitle();
adapter.setSelectedItemByTitle(selectedItemKey);
adapter.setListener(new HorizontalSelectionAdapter.HorizontalSelectionAdapterListener() {
@Override
public void onItemSelected(HorizontalSelectionAdapter.HorizontalSelectionItem item) {
adapter.setItems(items);
adapter.setSelectedItem(item);
GraphType chosenGraphType = (GraphType) item.getObject();
if (!isCurrentVisibleType(chosenGraphType)) {
setupVisibleGraphType(chosenGraphType);
}
}
});
graphTypesMenu.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
private void setupVisibleGraphType(GraphType type) {
visibleGraphType = type;
updateDataView();
}
private boolean isCurrentVisibleType(GraphType type) {
if (visibleGraphType != null && type != null) {
return Algorithms.objectEquals(visibleGraphType.getTitle(), type.getTitle());
}
return false;
}
private GraphType getFirstAvailableGraphType() {
for (GraphType type : graphTypes) {
if (type.isAvailable()) {
return type;
}
}
return null;
}
private void updateDataView() {
if (isRouteCalculating()) {
showProgressMessage();
} else if (visibleGraphType.hasData()) {
showGraph();
} else if (visibleGraphType.canBeCalculated()) {
showMessage();
}
}
private void showProgressMessage() {
commonGraphContainer.setVisibility(View.GONE);
customGraphContainer.setVisibility(View.GONE);
messageContainer.setVisibility(View.VISIBLE);
TextView tvMessage = messageContainer.findViewById(R.id.message_text);
ImageView icon = messageContainer.findViewById(R.id.message_icon);
ProgressBar pb = messageContainer.findViewById(R.id.progress_bar);
pb.setVisibility(View.VISIBLE);
icon.setVisibility(View.GONE);
tvMessage.setText(R.string.message_graph_will_be_available_after_recalculation);
}
private void showGraph() {
if (visibleGraphType.isCustom()) {
customGraphChart.clear();
commonGraphContainer.setVisibility(View.GONE);
customGraphContainer.setVisibility(View.VISIBLE);
messageContainer.setVisibility(View.GONE);
prepareCustomGraphView((BarData) visibleGraphType.getGraphData());
} else {
commonGraphChart.clear();
commonGraphContainer.setVisibility(View.VISIBLE);
customGraphContainer.setVisibility(View.GONE);
messageContainer.setVisibility(View.GONE);
prepareCommonGraphView((LineData) visibleGraphType.getGraphData());
}
}
private void showMessage() {
commonGraphContainer.setVisibility(View.GONE);
customGraphContainer.setVisibility(View.GONE);
messageContainer.setVisibility(View.VISIBLE);
TextView tvMessage = messageContainer.findViewById(R.id.message_text);
ImageView icon = messageContainer.findViewById(R.id.message_icon);
ProgressBar pb = messageContainer.findViewById(R.id.progress_bar);
pb.setVisibility(View.GONE);
icon.setVisibility(View.VISIBLE);
tvMessage.setText(app.getString(
R.string.message_need_calculate_route_before_show_graph,
visibleGraphType.getTitle()));
icon.setImageResource(R.drawable.ic_action_altitude_average);
}
private void prepareCommonGraphView(LineData data) {
GpxUiHelper.setupGPXChart(commonGraphChart, 4, 24f, 16f, !nightMode, true);
commonGraphChart.setData(data);
}
private void prepareCustomGraphView(BarData data) {
OsmandApplication app = getMyApplication();
if (app == null) return;
GpxUiHelper.setupHorizontalGPXChart(app, customGraphChart, 5, 9, 24, true, nightMode);
customGraphChart.setExtraRightOffset(16);
customGraphChart.setExtraLeftOffset(16);
customGraphChart.setData(data);
}
private void updateGraphData() {
graphTypes.clear();
OsmandApplication app = getMyApplication();
GPXTrackAnalysis analysis = createGpxTrackAnalysis();
// update common graph data
for (CommonGraphType commonType : CommonGraphType.values()) {
List<ILineDataSet> dataSets = getDataSets(commonType, commonGraphChart, analysis);
LineData data = null;
if (!Algorithms.isEmpty(dataSets)) {
data = new LineData(dataSets);
}
String title = app.getString(commonType.titleId);
graphTypes.add(new GraphType(title, false, commonType.canBeCalculated, data));
}
// update custom graph data
List<RouteSegmentResult> routeSegments = editingCtx.getAllRouteSegments();
List<RouteStatistics> routeStatistics = calculateRouteStatistics(routeSegments);
if (analysis != null && routeStatistics != null) {
for (RouteStatistics statistics : routeStatistics) {
String title = SettingsBaseActivity.getStringRouteInfoPropertyValue(app, statistics.name);
BarData data = null;
if (!Algorithms.isEmpty(statistics.elements)) {
data = GpxUiHelper.buildStatisticChart(
app, customGraphChart, statistics, analysis, true, nightMode);
}
graphTypes.add(new GraphType(title, true, false, data));
}
}
// update current visible graph type
if (visibleGraphType == null) {
visibleGraphType = getFirstAvailableGraphType();
} else {
for (GraphType type : graphTypes) {
if (isCurrentVisibleType(type)) {
visibleGraphType = type.isAvailable() ? type : getFirstAvailableGraphType();
break;
}
}
}
}
private List<ILineDataSet> getDataSets(CommonGraphType type, LineChart chart, GPXTrackAnalysis analysis) {
List<ILineDataSet> dataSets = new ArrayList<>();
if (chart != null && analysis != null) {
OsmandApplication app = getMyApplication();
switch (type) {
case OVERVIEW: {
List<OrderedLineDataSet> dataList = new ArrayList<>();
if (analysis.hasSpeedData) {
OrderedLineDataSet speedDataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart,
analysis, GPXDataSetAxisType.DISTANCE, true, true, false);
dataList.add(speedDataSet);
}
if (analysis.hasElevationData) {
OrderedLineDataSet elevationDataSet = GpxUiHelper.createGPXElevationDataSet(app, chart,
analysis, GPXDataSetAxisType.DISTANCE, false, true, false);
dataList.add(elevationDataSet);
OrderedLineDataSet slopeDataSet = GpxUiHelper.createGPXSlopeDataSet(app, chart,
analysis, GPXDataSetAxisType.DISTANCE, null, true, true, false);
dataList.add(slopeDataSet);
}
if (dataList.size() > 0) {
Collections.sort(dataList, new Comparator<OrderedLineDataSet>() {
@Override
public int compare(OrderedLineDataSet o1, OrderedLineDataSet o2) {
return Float.compare(o1.getPriority(), o2.getPriority());
}
});
}
dataSets.addAll(dataList);
break;
}
case ALTITUDE: {
if (analysis.hasElevationData) {
OrderedLineDataSet elevationDataSet = GpxUiHelper.createGPXElevationDataSet(app, chart,
analysis, GPXDataSetAxisType.DISTANCE, false, true, false);//calcWithoutGaps);
dataSets.add(elevationDataSet);
}
break;
}
case SLOPE:
if (analysis.hasElevationData) {
OrderedLineDataSet slopeDataSet = GpxUiHelper.createGPXSlopeDataSet(app, chart,
analysis, GPXDataSetAxisType.DISTANCE, null, true, true, false);
dataSets.add(slopeDataSet);
}
break;
case SPEED: {
if (analysis.hasSpeedData) {
OrderedLineDataSet speedDataSet = GpxUiHelper.createGPXSpeedDataSet(app, chart,
analysis, GPXDataSetAxisType.DISTANCE, false, true, false);//calcWithoutGaps);
dataSets.add(speedDataSet);
}
break;
}
}
}
return dataSets;
}
private GPXTrackAnalysis createGpxTrackAnalysis() {
GPXFile gpx;
if (editingCtx.getGpxData() != null) {
gpx = editingCtx.getGpxData().getGpxFile();
} else {
gpx = editingCtx.exportRouteAsGpx(GRAPH_DATA_GPX_FILE_NAME);
}
return gpx != null ? gpx.getAnalysis(0) : null;
}
private List<RouteStatistics> calculateRouteStatistics(List<RouteSegmentResult> route) {
OsmandApplication app = getMyApplication();
if (route == null || app == null) return null;
return RouteDetailsFragment.calculateRouteStatistics(app, route, nightMode);
}
private boolean isRouteCalculating() {
return fragment.isProgressBarVisible();
}
private static class GraphType {
private String title;
private boolean isCustom;
private boolean canBeCalculated;
private ChartData graphData;
public GraphType(String title, boolean isCustom, boolean canBeCalculated, ChartData graphData) {
this.title = title;
this.isCustom = isCustom;
this.canBeCalculated = canBeCalculated;
this.graphData = graphData;
}
public String getTitle() {
return title;
}
public boolean isCustom() {
return isCustom;
}
public boolean isAvailable() {
return hasData() || canBeCalculated();
}
public boolean canBeCalculated() {
return canBeCalculated;
}
public boolean hasData() {
return getGraphData() != null;
}
public ChartData getGraphData() {
return graphData;
}
}
}

View file

@ -398,6 +398,20 @@ public class MeasurementEditingContext {
return before.points.size();
}
public List<RouteSegmentResult> getAllRouteSegments() {
List<RouteSegmentResult> allSegments = new ArrayList<>();
for (Pair<WptPt, WptPt> key : getOrderedRoadSegmentDataKeys()) {
RoadSegmentData data = roadSegmentData.get(key);
if (data != null) {
List<RouteSegmentResult> segments = data.getSegments();
if (segments != null) {
allSegments.addAll(segments);
}
}
}
return allSegments.size() > 0 ? allSegments : null;
}
void splitSegments(int position) {
List<WptPt> points = new ArrayList<>();
points.addAll(before.points);
@ -623,6 +637,16 @@ public class MeasurementEditingContext {
return res;
}
private List<Pair<WptPt, WptPt>> getOrderedRoadSegmentDataKeys() {
List<Pair<WptPt, WptPt>> keys = new ArrayList<>();
for (List<WptPt> points : Arrays.asList(before.points, after.points)) {
for (int i = 0; i < points.size() - 1; i++) {
keys.add(new Pair<>(points.get(i), points.get(i + 1)));
}
}
return keys;
}
private void recreateSegments(List<TrkSegment> segments, List<TrkSegment> segmentsForSnap, List<WptPt> points, boolean calculateIfNeeded) {
List<Integer> roadSegmentIndexes = new ArrayList<>();
TrkSegment s = new TrkSegment();

View file

@ -5,7 +5,6 @@ import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.LayoutInflater;
@ -14,6 +13,7 @@ import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
@ -24,10 +24,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.widget.TextViewCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.snackbar.Snackbar;
@ -59,7 +57,6 @@ import net.osmand.plus.measurementtool.RouteBetweenPointsBottomSheetDialogFragme
import net.osmand.plus.measurementtool.RouteBetweenPointsBottomSheetDialogFragment.RouteBetweenPointsFragmentListener;
import net.osmand.plus.measurementtool.SaveGpxRouteAsyncTask.SaveGpxRouteListener;
import net.osmand.plus.measurementtool.SelectedPointBottomSheetDialogFragment.SelectedPointFragmentListener;
import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter;
import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter.MeasurementAdapterListener;
import net.osmand.plus.measurementtool.command.AddPointCommand;
import net.osmand.plus.measurementtool.command.ApplyGpxApproximationCommand;
@ -70,9 +67,9 @@ import net.osmand.plus.measurementtool.command.MovePointCommand;
import net.osmand.plus.measurementtool.command.RemovePointCommand;
import net.osmand.plus.measurementtool.command.ReorderPointCommand;
import net.osmand.plus.measurementtool.command.ReversePointsCommand;
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback;
import net.osmand.plus.views.layers.MapControlsLayer;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
@ -90,6 +87,8 @@ import java.util.Locale;
import static net.osmand.IndexConstants.GPX_FILE_EXT;
import static net.osmand.IndexConstants.GPX_INDEX_DIR;
import static net.osmand.plus.UiUtilities.CustomRadioButtonType.END;
import static net.osmand.plus.UiUtilities.CustomRadioButtonType.START;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.CalculationMode;
import static net.osmand.plus.measurementtool.MeasurementEditingContext.SnapToRoadProgressListener;
import static net.osmand.plus.measurementtool.SaveAsNewTrackBottomSheetDialogFragment.SaveAsNewTrackFragmentListener;
@ -107,18 +106,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public static final String TAG = MeasurementToolFragment.class.getSimpleName();
public static final String TAPS_DISABLED_KEY = "taps_disabled_key";
private RecyclerView pointsRv;
private String previousToolBarTitle = "";
private MeasurementToolBarController toolBarController;
private MeasurementToolAdapter adapter;
private TextView distanceTv;
private TextView pointsTv;
private TextView distanceToCenterTv;
private String pointsSt;
private Drawable upIcon;
private Drawable downIcon;
private View pointsListContainer;
private View upDownRow;
private View additionalInfoContainer;
private ViewGroup additionalInfoCardsContainer;
private BaseCard visibleAdditionalInfoCard;
private LinearLayout customRadioButton;
private View mainView;
private ImageView upDownBtn;
private ImageView undoBtn;
@ -127,9 +124,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private Snackbar snackbar;
private String fileName;
private AdditionalInfoType currentAdditionalInfoType;
private boolean wasCollapseButtonVisible;
private boolean progressBarVisible;
private boolean pointsListOpened;
private boolean additionalInfoExpanded;
private static final int PLAN_ROUTE_MODE = 0x1;
private static final int DIRECTION_MODE = 0x2;
@ -156,8 +155,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
SHOW_IS_SAVED_FRAGMENT
}
protected MeasurementEditingContext getEditingCtx() {
return editingCtx;
private enum AdditionalInfoType {
POINTS,
GRAPH
}
private void setEditingCtx(MeasurementEditingContext editingCtx) {
@ -219,6 +219,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override
public void showProgressBar() {
MeasurementToolFragment.this.showProgressBar();
updateAdditionalInfoView();
}
@Override
@ -230,6 +231,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public void hideProgressBar() {
((ProgressBar) mainView.findViewById(R.id.snap_to_road_progress_bar)).setVisibility(View.GONE);
progressBarVisible = false;
updateAdditionalInfoView();
}
@Override
@ -241,17 +243,9 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
measurementLayer.setEditingCtx(editingCtx);
// If rotate the screen from landscape to portrait when the list of points is displayed then
// the RecyclerViewFragment will exist without view. This is necessary to remove it.
if (!portrait) {
hidePointsListFragment();
}
nightMode = mapActivity.getMyApplication().getDaynightHelper().isNightModeForMapControls();
portrait = AndroidUiHelper.isOrientationPortrait(mapActivity);
upIcon = getContentIcon(R.drawable.ic_action_arrow_up);
downIcon = getContentIcon(R.drawable.ic_action_arrow_down);
pointsSt = getString(R.string.shared_string_gpx_points).toLowerCase();
View view = UiUtilities.getInflater(getContext(), nightMode)
@ -259,12 +253,30 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
mainView = view.findViewById(R.id.main_view);
AndroidUtils.setBackground(mapActivity, mainView, nightMode, R.drawable.bg_bottom_menu_light, R.drawable.bg_bottom_menu_dark);
pointsListContainer = view.findViewById(R.id.points_list_container);
if (portrait && pointsListContainer != null) {
final int backgroundColor = ContextCompat.getColor(mapActivity, nightMode
? R.color.activity_background_color_dark
: R.color.activity_background_color_light);
pointsListContainer.setBackgroundColor(backgroundColor);
additionalInfoContainer = mainView.findViewById(R.id.additional_info_container);
additionalInfoCardsContainer = mainView.findViewById(R.id.cards_container);
if (portrait) {
customRadioButton = mainView.findViewById(R.id.custom_radio_buttons);
View pointListBtn = customRadioButton.findViewById(R.id.left_button_container);
TextView tvPointListBtn = customRadioButton.findViewById(R.id.left_button);
tvPointListBtn.setText(R.string.shared_string_gpx_points);
pointListBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
changeAdditionalInfoType(AdditionalInfoType.POINTS);
}
});
View graphBtn = customRadioButton.findViewById(R.id.right_button_container);
TextView tvGraphBtn = customRadioButton.findViewById(R.id.right_button);
tvGraphBtn.setText(R.string.shared_string_graph);
graphBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
changeAdditionalInfoType(AdditionalInfoType.GRAPH);
}
});
}
if (progressBarVisible) {
@ -277,7 +289,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
mainIcon = (ImageView) mainView.findViewById(R.id.main_icon);
upDownBtn = (ImageView) mainView.findViewById(R.id.up_down_button);
upDownBtn.setImageDrawable(upIcon);
updateUpDownBtn();
mainView.findViewById(R.id.cancel_move_point_button).setOnClickListener(new OnClickListener() {
@Override
@ -293,14 +305,14 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
});
upDownRow = mainView.findViewById(R.id.up_down_row);
View upDownRow = mainView.findViewById(R.id.up_down_row);
upDownRow.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
if (!pointsListOpened && editingCtx.getPointsCount() > 0 && editingCtx.getSelectedPointPosition() == -1) {
showPointsList();
if (!additionalInfoExpanded && editingCtx.getPointsCount() > 0 && editingCtx.getSelectedPointPosition() == -1) {
expandAdditionalInfoView();
} else {
hidePointsList();
collapseAdditionalInfoView();
}
}
});
@ -393,8 +405,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override
public void onSelectPoint(int selectedPointPos) {
if (pointsListOpened) {
hidePointsList();
if (additionalInfoExpanded) {
collapseAdditionalInfoView();
}
if (selectedPointPos != -1) {
openSelectedPointMenu(mapActivity);
@ -417,8 +429,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
measurementLayer.setOnEnterMovePointModeListener(new MeasurementToolLayer.OnEnterMovePointModeListener() {
@Override
public void onEnterMovePointMode() {
if (pointsListOpened) {
hidePointsList();
if (additionalInfoExpanded) {
collapseAdditionalInfoView();
}
switchMovePointMode(true);
}
@ -471,17 +483,6 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
updateToolbar();
final GpxData gpxData = editingCtx.getGpxData();
adapter = new MeasurementToolAdapter(getMapActivity(), editingCtx.getPoints());
if (portrait) {
pointsRv = mainView.findViewById(R.id.measure_points_recycler_view);
} else {
pointsRv = new RecyclerView(getActivity());
}
ItemTouchHelper touchHelper = new ItemTouchHelper(new ReorderItemTouchHelperCallback(adapter));
touchHelper.attachToRecyclerView(pointsRv);
adapter.setAdapterListener(createMeasurementAdapterListener(touchHelper));
pointsRv.setLayoutManager(new LinearLayoutManager(getContext()));
pointsRv.setAdapter(adapter);
ImageButton snapToRoadBtn = (ImageButton) mapActivity.findViewById(R.id.snap_to_road_image_button);
snapToRoadBtn.setBackgroundResource(nightMode ? R.drawable.btn_circle_night : R.drawable.btn_circle);
@ -508,6 +509,36 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
return view;
}
private void changeAdditionalInfoType(@NonNull AdditionalInfoType type) {
if (!additionalInfoExpanded || !isCurrentAdditionalInfoType(type)) {
MapActivity ma = getMapActivity();
if (ma == null) return;
currentAdditionalInfoType = type;
updateUpDownBtn();
OsmandApplication app = ma.getMyApplication();
BaseCard additionalInfoCard = null;
if (AdditionalInfoType.POINTS == type) {
additionalInfoCard = new PointsCard(ma, this);
UiUtilities.updateCustomRadioButtons(app, customRadioButton, nightMode, START);
} else if (AdditionalInfoType.GRAPH == type) {
additionalInfoCard = new GraphsCard(ma, this);
UiUtilities.updateCustomRadioButtons(app, customRadioButton, nightMode, END);
}
if (additionalInfoCard != null) {
visibleAdditionalInfoCard = additionalInfoCard;
additionalInfoCardsContainer.removeAllViews();
additionalInfoCardsContainer.addView(additionalInfoCard.build(ma));
additionalInfoExpanded = true;
}
}
}
private void updateAdditionalInfoView() {
if (visibleAdditionalInfoCard instanceof OnUpdateAdditionalInfoListener) {
((OnUpdateAdditionalInfoListener) visibleAdditionalInfoCard).onUpdateAdditionalInfo();
}
}
public boolean isInEditMode() {
return !isPlanRouteMode() && !editingCtx.isNewData() && !isDirectionMode() && !isFollowTrackMode();
}
@ -516,12 +547,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
this.fileName = fileName;
}
public MeasurementEditingContext getEditingCtx() {
return editingCtx;
}
private void updateUndoRedoCommonStuff() {
hidePointsListIfNoPoints();
collapseAdditionalInfoIfNoPointsEnough();
if (editingCtx.getPointsCount() > 0) {
enable(upDownBtn);
}
adapter.notifyDataSetChanged();
updateAdditionalInfoView();
updateDistancePointsText();
updateSnapToRoadControls();
}
@ -576,9 +611,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
super.onDestroyView();
cancelModes();
exitMeasurementMode();
adapter.setAdapterListener(null);
if (pointsListOpened) {
hidePointsList();
if (additionalInfoExpanded) {
collapseAdditionalInfoView();
}
MeasurementToolLayer layer = getMeasurementLayer();
if (layer != null) {
@ -626,6 +660,10 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
progressBarVisible = true;
}
public boolean isProgressBarVisible() {
return progressBarVisible;
}
private void updateMainIcon() {
GpxData gpxData = editingCtx.getGpxData();
mainIcon.setImageDrawable(getActiveIcon(gpxData != null ? R.drawable.ic_action_polygom_dark : R.drawable.ic_action_ruler));
@ -826,8 +864,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
MeasurementToolLayer measurementLayer = getMeasurementLayer();
editingCtx.getCommandManager().execute(new ClearPointsCommand(measurementLayer, ALL));
editingCtx.cancelSnapToRoad();
if (pointsListOpened) {
hidePointsList();
if (additionalInfoExpanded) {
collapseAdditionalInfoView();
}
updateUndoRedoButton(false, redoBtn);
disable(upDownBtn);
@ -842,8 +880,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (points.size() > 1) {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
editingCtx.getCommandManager().execute(new ReversePointsCommand(measurementLayer));
if (pointsListOpened) {
hidePointsList();
if (additionalInfoExpanded) {
collapseAdditionalInfoView();
}
updateUndoRedoButton(false, redoBtn);
updateUndoRedoButton(true, undoBtn);
@ -911,8 +949,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private void trimRoute(ClearCommandMode before) {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
editingCtx.getCommandManager().execute(new ClearPointsCommand(measurementLayer, before));
if (pointsListOpened) {
hidePointsList();
if (additionalInfoExpanded) {
collapseAdditionalInfoView();
}
editingCtx.setSelectedPointPosition(-1);
editingCtx.splitSegments(editingCtx.getBeforePoints().size() + editingCtx.getAfterPoints().size());
@ -1065,11 +1103,11 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
private void removePoint(MeasurementToolLayer measurementLayer, int position) {
if (measurementLayer != null) {
editingCtx.getCommandManager().execute(new RemovePointCommand(measurementLayer, position));
adapter.notifyDataSetChanged();
updateAdditionalInfoView();
updateUndoRedoButton(true, undoBtn);
updateUndoRedoButton(false, redoBtn);
updateDistancePointsText();
hidePointsListIfNoPoints();
collapseAdditionalInfoIfNoPointsEnough();
}
}
@ -1078,7 +1116,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
saveNewGpx(folderName, fileName, showOnMap, simplified, FinalSaveAction.SHOW_IS_SAVED_FRAGMENT);
}
private MeasurementAdapterListener createMeasurementAdapterListener(final ItemTouchHelper touchHelper) {
MeasurementAdapterListener createMeasurementAdapterListener(final ItemTouchHelper touchHelper) {
return new MeasurementAdapterListener() {
final MapActivity mapActivity = getMapActivity();
@ -1094,8 +1132,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
@Override
public void onItemClick(int position) {
if (mapActivity != null && measurementLayer != null) {
if (pointsListOpened) {
hidePointsList();
if (additionalInfoExpanded) {
collapseAdditionalInfoView();
}
if (portrait) {
setMapPosition(OsmandSettings.MIDDLE_TOP_CONSTANT);
@ -1117,7 +1155,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
toPosition = holder.getAdapterPosition();
if (toPosition >= 0 && fromPosition >= 0 && toPosition != fromPosition) {
editingCtx.getCommandManager().execute(new ReorderPointCommand(measurementLayer, fromPosition, toPosition));
adapter.notifyDataSetChanged();
updateAdditionalInfoView();
updateUndoRedoButton(false, redoBtn);
updateDistancePointsText();
mapActivity.refreshMap();
@ -1179,7 +1217,7 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (!isUndoMode()) {
editingCtx.addPoints();
}
adapter.notifyDataSetChanged();
updateAdditionalInfoView();
updateDistancePointsText();
}
}
@ -1375,80 +1413,48 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
updateUndoRedoButton(true, undoBtn);
updateUndoRedoButton(false, redoBtn);
updateDistancePointsText();
adapter.notifyDataSetChanged();
updateAdditionalInfoView();
}
private void showPointsList() {
pointsListOpened = true;
upDownBtn.setImageDrawable(downIcon);
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
if (portrait && pointsListContainer != null) {
pointsListContainer.setVisibility(View.VISIBLE);
} else {
showPointsListFragment();
private void expandAdditionalInfoView() {
if (portrait) {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
additionalInfoContainer.setVisibility(View.VISIBLE);
AdditionalInfoType typeToShow = currentAdditionalInfoType == null
? AdditionalInfoType.POINTS : currentAdditionalInfoType;
changeAdditionalInfoType(typeToShow);
setMapPosition(portrait
? OsmandSettings.MIDDLE_TOP_CONSTANT
: OsmandSettings.LANDSCAPE_MIDDLE_RIGHT_CONSTANT);
}
setMapPosition(portrait
? OsmandSettings.MIDDLE_TOP_CONSTANT
: OsmandSettings.LANDSCAPE_MIDDLE_RIGHT_CONSTANT);
}
}
private void hidePointsList() {
pointsListOpened = false;
upDownBtn.setImageDrawable(upIcon);
if (portrait && pointsListContainer != null) {
pointsListContainer.setVisibility(View.GONE);
} else {
hidePointsListFragment();
private void collapseAdditionalInfoView() {
if (portrait) {
additionalInfoExpanded = false;
updateUpDownBtn();
additionalInfoContainer.setVisibility(View.GONE);
setDefaultMapPosition();
}
setDefaultMapPosition();
}
private void hidePointsListIfNoPoints() {
private void collapseAdditionalInfoIfNoPointsEnough() {
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (measurementLayer != null) {
if (editingCtx.getPointsCount() < 1) {
int pointsCount = editingCtx.getPointsCount();
if (isCurrentAdditionalInfoType(AdditionalInfoType.GRAPH) && pointsCount < 2) {
collapseAdditionalInfoView();
} else if (pointsCount < 1) {
disable(upDownBtn);
if (pointsListOpened) {
hidePointsList();
if (additionalInfoExpanded) {
collapseAdditionalInfoView();
}
}
}
}
private void showPointsListFragment() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
boolean transparentStatusBar = Build.VERSION.SDK_INT >= 21;
int statusBarHeight = transparentStatusBar ? 0 : AndroidUtils.getStatusBarHeight(mapActivity);
int screenHeight = AndroidUtils.getScreenHeight(mapActivity) - statusBarHeight;
RecyclerViewFragment fragment = new RecyclerViewFragment();
fragment.setRecyclerView(pointsRv);
fragment.setWidth(upDownRow.getWidth());
fragment.setHeight(screenHeight - upDownRow.getHeight());
fragment.setTransparentStatusBar(transparentStatusBar);
mapActivity.getSupportFragmentManager().beginTransaction()
.add(R.id.fragmentContainer, fragment, RecyclerViewFragment.TAG)
.commitAllowingStateLoss();
}
}
private void hidePointsListFragment() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
try {
FragmentManager manager = mapActivity.getSupportFragmentManager();
Fragment fragment = manager.findFragmentByTag(RecyclerViewFragment.TAG);
if (fragment != null) {
manager.beginTransaction().remove(fragment).commitAllowingStateLoss();
}
} catch (Exception e) {
// ignore
}
}
}
private void setDefaultMapPosition() {
setMapPosition(OsmandSettings.CENTER_CONSTANT);
}
@ -1472,6 +1478,16 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
}
}
private void updateUpDownBtn() {
Drawable icon = getContentIcon(additionalInfoExpanded
? R.drawable.ic_action_arrow_down : R.drawable.ic_action_arrow_up);
upDownBtn.setImageDrawable(icon);
}
private boolean isCurrentAdditionalInfoType(@NonNull AdditionalInfoType type) {
return type.equals(currentAdditionalInfoType);
}
private String getSuggestedFileName() {
GpxData gpxData = editingCtx.getGpxData();
String displayedName = null;
@ -1750,8 +1766,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
final MapActivity mapActivity = getMapActivity();
MeasurementToolLayer measurementLayer = getMeasurementLayer();
if (mapActivity != null && measurementLayer != null) {
if (pointsListOpened && hidePointsListFirst) {
hidePointsList();
if (additionalInfoExpanded && hidePointsListFirst) {
collapseAdditionalInfoView();
return;
}
if (!editingCtx.hasChanges()) {
@ -1771,8 +1787,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (clearContext) {
editingCtx.clearSegments();
}
if (pointsListOpened) {
hidePointsList();
if (additionalInfoExpanded) {
collapseAdditionalInfoView();
}
resetAppMode();
hideSnapToRoadIcon();
@ -1910,8 +1926,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
if (!approximationMode || !editingCtx.getCommandManager().update(command)) {
editingCtx.getCommandManager().execute(command);
}
if (pointsListOpened) {
hidePointsList();
if (additionalInfoExpanded) {
collapseAdditionalInfoView();
}
updateSnapToRoadControls();
}
@ -1984,4 +2000,8 @@ public class MeasurementToolFragment extends BaseOsmAndFragment implements Route
public boolean isNightModeForMapControls() {
return nightMode;
}
public interface OnUpdateAdditionalInfoListener {
void onUpdateAdditionalInfo();
}
}

View file

@ -0,0 +1,48 @@
package net.osmand.plus.measurementtool;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.measurementtool.MeasurementToolFragment.OnUpdateAdditionalInfoListener;
import net.osmand.plus.measurementtool.adapter.MeasurementToolAdapter;
import net.osmand.plus.routepreparationmenu.cards.BaseCard;
import net.osmand.plus.views.controls.ReorderItemTouchHelperCallback;
public class PointsCard extends BaseCard implements OnUpdateAdditionalInfoListener {
private MeasurementToolAdapter adapter;
private MeasurementToolFragment fragment;
public PointsCard(@NonNull MapActivity mapActivity, MeasurementToolFragment fragment) {
super(mapActivity);
this.fragment = fragment;
}
@Override
public void onUpdateAdditionalInfo() {
adapter.notifyDataSetChanged();
}
@Override
public int getCardLayoutId() {
return R.layout.fragment_measurement_tool_points_list;
}
@Override
protected void updateContent() {
MeasurementEditingContext editingCtx = fragment.getEditingCtx();
final GpxData gpxData = editingCtx.getGpxData();
adapter = new MeasurementToolAdapter(mapActivity, editingCtx.getPoints(),
gpxData != null ? gpxData.getActionType() : null);
RecyclerView pointsRv = view.findViewById(R.id.measure_points_recycler_view);
ItemTouchHelper touchHelper = new ItemTouchHelper(new ReorderItemTouchHelperCallback(adapter));
touchHelper.attachToRecyclerView(pointsRv);
adapter.setAdapterListener(fragment.createMeasurementAdapterListener(touchHelper));
pointsRv.setLayoutManager(new LinearLayoutManager(app));
pointsRv.setAdapter(adapter);
}
}

View file

@ -28,6 +28,7 @@ import net.osmand.plus.helpers.GpxUiHelper.GPXInfo;
import net.osmand.plus.helpers.enums.TracksSortByMode;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionAdapterListener;
import net.osmand.plus.mapcontextmenu.other.HorizontalSelectionAdapter.HorizontalSelectionItem;
import java.io.File;
import java.util.ArrayList;
@ -128,7 +129,7 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
sortButton.setImageResource(mode.getIconId());
updateDescription(descriptionView);
sortFolderList();
folderAdapter.setItems(getFolderNames());
folderAdapter.setTitledItems(getFolderNames());
folderAdapter.notifyDataSetChanged();
sortFileList();
adapter.notifyDataSetChanged();
@ -191,13 +192,13 @@ public class SelectFileBottomSheet extends BottomSheetBehaviourDialogFragment {
folders = new ArrayList<>();
collectDirs(gpxDir, folders);
sortFolderList();
folderAdapter.setItems(getFolderNames());
folderAdapter.setSelectedItem(selectedFolder);
folderAdapter.setTitledItems(getFolderNames());
folderAdapter.setSelectedItemByTitle(selectedFolder);
foldersRecyclerView.setAdapter(folderAdapter);
folderAdapter.setListener(new HorizontalSelectionAdapterListener() {
@Override
public void onItemSelected(String item) {
selectedFolder = item;
public void onItemSelected(HorizontalSelectionItem item) {
selectedFolder = item.getTitle();
updateFileList(folderAdapter);
}
});

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