Merge branch 'master' of github.com:osmandapp/Osmand

This commit is contained in:
Victor Shcherb 2019-01-18 18:17:09 +01:00
commit 4eff967cac
143 changed files with 4796 additions and 754 deletions

View file

@ -554,7 +554,6 @@ public class BinaryMapIndexReader {
}
return false;
}
public List<TransportStop> searchTransportIndex(SearchRequest<TransportStop> req) throws IOException {
for (TransportIndex index : transportIndexes) {
if (index.stopsFileLength == 0 || index.right < req.left || index.left > req.right || index.top > req.bottom
@ -878,6 +877,8 @@ public class BinaryMapIndexReader {
continue;
}
// lazy initializing trees
if (index.trees == null) {
index.trees = new ArrayList<MapTree>();

View file

@ -402,12 +402,12 @@ public class BinaryMapTransportReaderAdapter {
int oldLimit = codedIS.pushLimit(ind.stringTable.length);
int current = 0;
int i = 0;
while (i < values.length) {
while (i < values.length && codedIS.getBytesUntilLimit() > 0) {
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch (tag) {
case 0:
break;
return;
case OsmandOdb.StringTable.S_FIELD_NUMBER:
if (current == values[i]) {
String value = codedIS.readString();

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="@color/ctrl_active_light" />
<corners android:radius="@dimen/dialog_button_radius" />
</shape>
</item>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<solid android:color="@color/ctrl_light" />
<corners android:radius="@dimen/dialog_button_radius" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="@null" />
<corners android:radius="@dimen/dialog_button_radius" />
<stroke android:width="1dp" android:color="@color/app_bar_divider" />
</shape>
</item>
</selector>

View file

@ -0,0 +1,184 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/card_bg_color">
<LinearLayout
android:id="@+id/title_row"
android:layout_width="match_parent"
android:layout_height="@dimen/action_bar_height"
android:gravity="center_vertical">
<net.osmand.telegram.ui.views.TextViewEx
android:layout_width="0dp"
android:layout_height="@dimen/action_bar_height"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_vertical"
android:letterSpacing="@dimen/title_letter_spacing"
android:maxLines="1"
android:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard"
android:text="@string/timeline"
android:textColor="@color/app_bar_title_light"
android:textSize="@dimen/title_text_size"
app:typeface="@string/font_roboto_mono_bold" />
<ImageView
android:id="@+id/options"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/content_padding_standard"
android:layout_marginRight="@dimen/content_padding_standard"
android:background="?attr/selectableItemBackgroundBorderless"
android:paddingLeft="@dimen/content_padding_half"
android:paddingRight="@dimen/content_padding_half"
tools:src="@drawable/ic_action_other_menu"
tools:tint="@color/icon_light"
tools:visibility="visible" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/action_bar_descr_bottom_margin"
android:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard"
android:text="@string/timeline_description"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/descr_text_size" />
<FrameLayout
android:id="@+id/monitoring_container"
android:layout_width="match_parent"
android:layout_height="@dimen/action_bar_height"
android:background="?attr/selectableItemBackground"
android:orientation="horizontal"
android:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/monitoring_title"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|start"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:text="@string/monitoring_is_enabled"
android:textColor="@color/ctrl_active_light"
android:textSize="@dimen/descr_text_size"
app:typeface="@string/font_roboto_medium" />
<Switch
android:id="@+id/monitoring_switcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:background="@null"
android:clickable="false"
android:focusable="false" />
</FrameLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/app_bar_divider" />
<LinearLayout
android:id="@+id/date_row"
android:layout_width="match_parent"
android:layout_height="@dimen/list_header_height"
android:background="@color/screen_bg_light"
android:orientation="horizontal"
android:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/date_start_btn"
android:layout_width="0dp"
android:layout_height="@dimen/dialog_button_height"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/content_padding_half"
android:layout_marginRight="@dimen/content_padding_half"
android:layout_weight="1"
android:background="@drawable/btn_round_border"
android:drawablePadding="@dimen/content_padding_half"
android:ellipsize="end"
android:gravity="start|center_vertical"
android:maxLines="1"
android:paddingLeft="@dimen/image_button_padding"
android:paddingRight="@dimen/image_button_padding"
android:text="@string/start_date"
android:textColor="?attr/ctrl_active_color"
android:textSize="@dimen/text_button_text_size"
app:typeface="@string/font_roboto_medium" />
<View
android:layout_width="16dp"
android:layout_height="1dp"
android:layout_gravity="center_vertical"
android:background="@color/app_bar_divider" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/date_end_btn"
android:layout_width="0dp"
android:layout_height="@dimen/dialog_button_height"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/content_padding_half"
android:layout_marginStart="@dimen/content_padding_half"
android:layout_weight="1"
android:background="@drawable/btn_round_border"
android:drawablePadding="@dimen/content_padding_half"
android:ellipsize="end"
android:gravity="start|center_vertical"
android:maxLines="1"
android:paddingLeft="@dimen/image_button_padding"
android:paddingRight="@dimen/image_button_padding"
android:text="@string/end_date"
android:textColor="?attr/ctrl_active_color"
android:textSize="@dimen/text_button_text_size"
app:typeface="@string/font_roboto_medium" />
</LinearLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/last_telegram_update_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal"
android:gravity="center"
android:paddingTop="@dimen/content_padding_half"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
android:visibility="gone"
app:typeface="@string/font_roboto_regular" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="@dimen/list_item_content_margin"
android:scrollbars="vertical" />
</FrameLayout>
</LinearLayout>

View file

@ -0,0 +1,509 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="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/card_bg_color">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:id="@+id/image_container"
android:layout_width="match_parent"
android:layout_height="120dp"
app:layout_scrollFlags="scroll">
<ImageView
android:id="@+id/back_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="@dimen/content_padding_standard"
android:background="?attr/selectableItemBackgroundBorderless"
android:contentDescription="@string/shared_string_back"
android:padding="@dimen/content_padding_standard"
tools:src="@drawable/ic_arrow_back"
tools:tint="@color/icon_light" />
<ImageView
android:id="@+id/user_icon"
android:layout_width="@dimen/my_location_user_icon_size"
android:layout_height="@dimen/my_location_user_icon_size"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/content_padding_standard"
tools:src="@drawable/img_user_picture" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:text="@string/start_location_sharing"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/title_text_size"
app:typeface="@string/font_roboto_mono_bold" />
</FrameLayout>
<LinearLayout
android:id="@+id/interval_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="@dimen/content_padding_standard"
android:paddingRight="@dimen/content_padding_standard">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/start_descr"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/content_padding_standard"
android:layout_marginRight="@dimen/content_padding_standard"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/start_date"
android:textColor="?attr/android:textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
app:firstBaselineToTopHeight="@dimen/list_item_baseline_to_top_height"
app:typeface="@string/font_roboto_regular" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/end_descr"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="@dimen/content_padding_standard"
android:layout_marginStart="@dimen/content_padding_standard"
android:layout_weight="1"
android:ellipsize="end"
android:maxLines="1"
android:text="@string/end_date"
android:textColor="?attr/android:textColorSecondary"
android:textSize="@dimen/list_item_description_text_size"
app:firstBaselineToTopHeight="@dimen/list_item_baseline_to_top_height"
app:typeface="@string/font_roboto_regular" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/list_header_height"
android:orientation="horizontal">
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/date_start_btn"
android:layout_width="0dp"
android:layout_height="@dimen/dialog_button_height"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/content_padding_half"
android:layout_marginRight="@dimen/content_padding_half"
android:layout_weight="1"
android:background="@drawable/btn_round"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingLeft="@dimen/image_button_padding"
android:paddingRight="@dimen/image_button_padding"
android:textSize="@dimen/text_button_text_size"
app:typeface="@string/font_roboto_medium"
tools:textColor="?attr/ctrl_active_color"
tools:visibility="visible" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/time_start_btn"
android:layout_width="wrap_content"
android:layout_height="@dimen/dialog_button_height"
android:layout_gravity="center_vertical"
android:background="@drawable/btn_round"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingLeft="@dimen/image_button_padding"
android:paddingRight="@dimen/image_button_padding"
android:textSize="@dimen/text_button_text_size"
app:typeface="@string/font_roboto_medium"
tools:textColor="?attr/ctrl_active_color"
tools:visibility="visible" />
<View
android:layout_width="16dp"
android:layout_height="1dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/content_padding_half"
android:layout_marginRight="@dimen/content_padding_half"
android:background="@color/card_divider_light" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/date_end_btn"
android:layout_width="0dp"
android:layout_height="@dimen/dialog_button_height"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/content_padding_half"
android:layout_marginRight="@dimen/content_padding_half"
android:layout_weight="1"
android:background="@drawable/btn_round"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingLeft="@dimen/image_button_padding"
android:paddingRight="@dimen/image_button_padding"
android:textSize="@dimen/text_button_text_size"
app:typeface="@string/font_roboto_medium"
tools:textColor="?attr/ctrl_active_color"
tools:visibility="visible" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/time_end_btn"
android:layout_width="wrap_content"
android:layout_height="@dimen/dialog_button_height"
android:layout_gravity="center_vertical"
android:background="@drawable/btn_round"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingLeft="@dimen/image_button_padding"
android:paddingRight="@dimen/image_button_padding"
android:textSize="@dimen/text_button_text_size"
app:typeface="@string/font_roboto_medium"
tools:textColor="?attr/ctrl_active_color"
tools:visibility="visible" />
</LinearLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/map_container"
android:layout_width="match_parent"
android:layout_height="152dp"
android:layout_marginLeft="@dimen/content_padding_standard"
android:layout_marginRight="@dimen/content_padding_standard">
<ImageView
android:id="@+id/gpx_map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="@string/shared_string_map" />
</FrameLayout>
<LinearLayout
android:id="@+id/gpx_statistic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/distance_time_span"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="11dp"
android:paddingTop="13dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:paddingLeft="16dp">
<ImageView
android:id="@+id/distance_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:src="@drawable/ic_action_polygom_dark" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="18dp"
android:orientation="vertical">
<TextView
android:id="@+id/distance_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:background="@null"
android:text="@string/shared_string_distance"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/list_item_description_text_size" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/distance_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:text="40 km"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_medium" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:paddingLeft="16dp">
<ImageView
android:id="@+id/duration_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:src="@drawable/ic_action_share_location" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="18dp"
android:orientation="vertical">
<TextView
android:id="@+id/duration_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:background="@null"
android:text="@string/time_on_the_move"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/list_item_description_text_size" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/duration_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:text="3:32:44"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_medium" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/list_divider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:paddingLeft="16dp"
android:paddingRight="8dp">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/card_divider_light" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:paddingLeft="8dp"
android:paddingRight="16dp">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/card_divider_light" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/start_end_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="11dp"
android:paddingTop="13dp">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:paddingLeft="16dp">
<ImageView
android:id="@+id/average_speed_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:src="@drawable/ic_action_speed_average" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="18dp"
android:orientation="vertical">
<TextView
android:id="@+id/average_speed_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="@null"
android:text="@string/average_speed"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/list_item_description_text_size" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/average_speed_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:text="15:04:58"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_medium" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"
android:paddingLeft="16dp">
<ImageView
android:id="@+id/average_altitude_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:src="@drawable/ic_action_share_location" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="18dp"
android:orientation="vertical">
<TextView
android:id="@+id/average_altitude_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:background="@null"
android:text="@string/average_altitude"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/list_item_description_text_size" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/average_altitude_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@null"
android:text="20:58:00"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/hint_text_size"
app:typeface="@string/font_roboto_medium" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/open_in_osmand_btn"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height_min"
android:layout_marginBottom="@dimen/content_padding_standard"
android:layout_marginLeft="@dimen/content_padding_half"
android:layout_marginRight="@dimen/content_padding_half"
android:background="@drawable/btn_round"
android:gravity="center_vertical"
android:paddingLeft="@dimen/content_padding_half"
android:paddingRight="@dimen/content_padding_half">
<ImageView
android:id="@+id/open_in_osmand_icon"
android:layout_width="@dimen/list_item_icon_size"
android:layout_height="@dimen/list_item_icon_size"
android:src="@drawable/ic_logo_osmand_free" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/open_in_osmand_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/content_padding_big"
android:layout_marginRight="@dimen/content_padding_big"
android:text="@string/open_in_osmand"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/list_item_title_text_size"
app:typeface="@string/font_roboto_medium" />
</LinearLayout>
<LinearLayout
android:id="@+id/share_gpx_btn"
android:layout_width="match_parent"
android:layout_height="@dimen/list_item_height_min"
android:layout_marginBottom="@dimen/content_padding_standard"
android:layout_marginLeft="@dimen/content_padding_half"
android:layout_marginRight="@dimen/content_padding_half"
android:background="@drawable/btn_round"
android:gravity="center_vertical"
android:paddingLeft="@dimen/content_padding_half"
android:paddingRight="@dimen/content_padding_half">
<ImageView
android:id="@+id/share_gpx_icon"
android:layout_width="@dimen/list_item_icon_size"
android:layout_height="@dimen/list_item_icon_size"
android:src="@drawable/ic_action_share"
android:tint="@color/ctrl_active_light" />
<net.osmand.telegram.ui.views.TextViewEx
android:id="@+id/share_gpx_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/content_padding_big"
android:layout_marginRight="@dimen/content_padding_big"
android:text="@string/shared_string_share"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/list_item_title_text_size"
app:typeface="@string/font_roboto_medium" />
</LinearLayout>
</LinearLayout>
</ScrollView>

View file

@ -9,4 +9,9 @@
android:id="@+id/action_live_now"
android:icon="@drawable/ic_action_live_now"
android:title="@string/live_now"/>
<item
android:id="@+id/action_timeline"
android:icon="@drawable/ic_action_timeline"
android:title="@string/timeline"/>
</menu>

View file

@ -1,4 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" encoding="utf-8"?>
<resources><string name="last_update_from_telegram">Апошняе абнаўленне з Telegram</string>
<string name="enter_another_device_name">Абярыце імя, якое вы яшчэ не выкарыстоўвалі</string>
<string name="device_added_successfully">%1$s дададзена.</string>
@ -10,7 +10,7 @@
<string name="device_name">Назва прылады</string>
<string name="shared_string_hide">Схаваць</string>
<string name="share_location_as_description_second_line">Вы можаце стварыць і праглядзець ідэнтыфікатар прылады ў кліенце Тэлеграма, выкарыстоўваючы %1$s бота. %2$s</string>
<string name="share_location_as_description">Калі вы хочаце падлучыць некалькі прылад да аднаго рахунка тэлеграм, то вам неабходна выкарыстаць розныя прылады, каб падзяліцца месцазнаходжаннем.</string>
<string name="share_location_as_description">Калі вы хочаце падлучыць некалькі прылад да аднаго акаўнта тэлеграм, то вам неабходна выкарыстаць розныя прылады, каб падзяліцца месцазнаходжаннем.</string>
<string name="last_updated_location">Апошняе абнаўленне месцазнаходжання:</string>
<string name="successfully_sent_and_updated">Паспяхова адпраўлена і абноўлена</string>
<string name="not_possible_to_send_to_telegram_chats">Немагчыма адправіць у размову Тэлеграм:</string>
@ -61,7 +61,7 @@
<string name="disconnect_from_telegram_desc">Для таго, каб скасаваць абмен месцазнаходжаннем, адкрыйце Тэлеграм, перайдзіце ў Налады → Прыватнасць і бяспека → Сеансы і спыніце сеанс OsmAnd Telegram.</string>
<string name="disconnect_from_telegram">Як выключыць абмен месцазнаходжаннем у OsmAnd праз Тэлеграм</string>
<string name="logout_help_desc">Як выключыць абмен месцазнаходжаннем у OsmAnd праз Тэлеграм</string>
<string name="connected_account">Падлучаны рахунак</string>
<string name="connected_account">Падлучаны акаўнт</string>
<string name="shared_string_account">Рахунак</string>
<string name="in_time">у %1$s</string>
<string name="osmand_connect_desc">Абраць версію OsmAnd, якую OsmAnd Telegram будзе выкарыстоўваць для адлюстравання пазіцыі.</string>
@ -81,13 +81,13 @@
<string name="shared_string_live">Дзейных</string>
<string name="shared_string_bot">Бот</string>
<string name="get_telegram_title">Рэгістрацыя ў Telegram</string>
<string name="get_telegram_account_first">Для абмену вам неабходны рахунак Тэлеграм.</string>
<string name="get_telegram_description_continue">Калі ласка, ўсталюйце Тэлеграм і наладзьце рахунак.</string>
<string name="get_telegram_account_first">Для абмену вам неабходны акаўнт Тэлеграм.</string>
<string name="get_telegram_description_continue">Калі ласка, ўсталюйце Тэлеграм і наладзьце акаўнт.</string>
<string name="get_telegram_after_creating_account">Пасля гэтага вы зможаце выкарыстоўваць дадатак.</string>
<string name="shared_string_all">Усе</string>
<string name="shared_string_off">Выкл</string>
<string name="already_registered_in_telegram">Вам неабходна мець рахунак Тэлеграм і нумар тэлефона</string>
<string name="do_not_have_telegram">У мяне няма рахунка Тэлеграм</string>
<string name="already_registered_in_telegram">Вам неабходна мець акаўнт Тэлеграм і нумар тэлефона</string>
<string name="do_not_have_telegram">У мяне няма акаўнта Тэлеграм</string>
<string name="enter_phone_number">Увядзіце нумар тэлефона</string>
<string name="enter_authentication_code">Увядзіце код аўтарызацыі</string>
<string name="set_visible_time_for_all">Вызначце бачны час для ўсіх</string>
@ -110,7 +110,7 @@
<string name="shared_string_password">Пароль</string>
<string name="enter_code">Увядзіце код</string>
<string name="authentication_code">Код аўтэнтыфікацыі</string>
<string name="authentication_code_descr">Тэлеграм адправіў вам код для OsmAnd для ўваходу ў рахунак.</string>
<string name="authentication_code_descr">Тэлеграм адправіў вам код для OsmAnd для ўваходу ў акаўнт.</string>
<string name="enter_password">Увядзіце пароль</string>
<string name="password_descr">Пароль Тэлеграм</string>
<string name="shared_string_login">Увайсці</string>
@ -167,7 +167,7 @@
<string name="shared_string_hour_short">г</string>
<string name="shared_string_minute_short">хвіл</string>
<string name="shared_string_second_short">сек</string>
<string name="welcome_descr"><b>Абмен месцазнаходжаннем OsmAnd</b> Дае магчымасць дзяліцца сваім месцазнаходжаннем і бачыць месцазнаходжанне іншых у OsmAnd.<br/><br/> Дадатак выкарыстоўвае Telegram API, таму вам неабходны рахунак Тэлеграм.</string>
<string name="welcome_descr"><b>Абмен месцазнаходжаннем OsmAnd</b> Дае магчымасць дзяліцца сваім месцазнаходжаннем і бачыць месцазнаходжанне іншых у OsmAnd.<br/><br/> Дадатак выкарыстоўвае Telegram API, таму вам неабходны акаўнт Тэлеграм.</string>
<string name="my_location">Маё месцазнаходжанне</string>
<string name="live_now">Зараз дзейнічае</string>
@ -177,4 +177,4 @@
<string name="shared_string_map">Мапа</string>
<string name="shared_string_text">Тэкст</string>
<string name="map_and_text">Мапа і тэкст</string>
</resources>
</resources>

View file

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<resources><string name="send_location_as">Enviar localização como</string>
<string name="send_location_as_descr">Escolha como as mensagens com sua localização serão exibidas.</string>
<string name="shared_string_map">Mapa</string>
<string name="shared_string_text">Texto</string>
<string name="map_and_text">Mapa e texto</string>
<string name="last_update_from_telegram">Última atualização do Telegram</string>
<string name="enter_another_device_name">Escolha um nome que você ainda não usou</string>
<string name="device_added_successfully">%1$s adicionado.</string>
<string name="shared_string_add">Adicionar</string>
<string name="error_adding_new_device">Não foi possível adicionar novo dispositivo</string>
<string name="enter_device_name_description">Nomeie seu novo dispositivo no máximo 200 símbolos.</string>
<string name="device_name_is_too_long">Nome do dispositivo muito longo</string>
<string name="device_name_cannot_be_empty">O nome do dispositivo não pode estar vazio</string>
<string name="device_name">Nome do dispositivo</string>
<string name="shared_string_hide">Ocultar</string>
<string name="share_location_as_description_second_line">Você pode criar e visualizar o ID do dispositivo no cliente de telegrama usando o bot de bate-papo %1$s. %2$s</string>
<string name="share_location_as_description">Se você deseja conectar vários dispositivos a uma conta de telegrama, é necessário usar um dispositivo diferente para compartilhar sua localização.</string>
<string name="last_updated_location">Última localização atualizada:</string>
<string name="successfully_sent_and_updated">Enviado e atualizado com sucesso</string>
<string name="not_possible_to_send_to_telegram_chats">Não é possível enviar para bate-papo do Telegram:</string>
<string name="waiting_for_response_from_telegram">Aguardando resposta do Telegram</string>
<string name="sending_location_messages">enviando localização</string>
<string name="initializing">Iniciando</string>
<string name="searching_for_gps">Posicionando…</string>
<string name="connecting_to_the_internet">Conectando-se à Internet</string>
<string name="background_work_description">Altere as configurações de otimização da bateria para estabilizar o compartilhamento de local.</string>
<string name="background_work">Trabalho de fundo</string>
<string name="battery_optimization_description">Desative a otimização da bateria do OsmAnd Telegram para que não seja desligado repentinamente quando estiver em segundo plano.</string>
<string name="sharing_in_background">Compartilhando em segundo plano</string>
<string name="go_to_settings">Vá para as configurações</string>
<string name="shared_string_later">Mais tarde</string>
<string name="not_sent_yet">Ainda não enviado</string>
<string name="not_found_yet">Ainda não encontrado</string>
<string name="re_send_location">Reenvie o local</string>
<string name="last_available_location">Última localização disponível</string>
<string name="sharing_status">Status de compartilhamento</string>
<string name="sharing_enabled">Compartilhamento: Ativado</string>
<string name="shared_string_status">Status</string>
<string name="no_gps_connection">Sem conexão GPS</string>
<string name="no_internet_connection">Sem conexão com a internet</string>
<string name="shared_string_disable">Desabilitar</string>
<string name="shared_string_save">Salvar</string>
<string name="add_device">Adicionar dispositivo</string>
<string name="share_location_as">Compartilhar localização como</string>
<string name="live_now_description">Contatos e grupos compartilhando o local para você.</string>
<string name="logout_from_osmand_telegram_descr">Tem certeza de que deseja sair do OsmAnd Telegram para que você não possa compartilhar a localização ou ver a localização de outras pessoas\?</string>
<string name="logout_from_osmand_telegram">Sair do OsmAnd Telegram\?</string>
<string name="shared_string_name">Nome</string>
<string name="by_distance">Pela distância</string>
<string name="by_name">Por nome</string>
<string name="by_group">Por grupo</string>
<string name="shared_string_sort">Ordenar</string>
<string name="shared_string_sort_by">Classificar por</string>
<string name="choose_osmand_desc">Selecione a versão OsmAnd, onde os contatos serão exibidos no mapa.</string>
<string name="choose_osmand">Selecione a versão do OsmAnd para usar</string>
<string name="disable_all_sharing_desc">Desativa o compartilhamento de local para todos os bate-papos selecionados (%1$d).</string>
<string name="disable_all_sharing">Desativar todo o compartilhamento</string>
<string name="turn_off_all">Desligue todos</string>
<string name="shared_string_exit">Sair</string>
<string name="time_ago">atrás</string>
<string name="last_response">Última resposta</string>
<string name="shared_string_group">Grupo</string>
<string name="logout_no_internet_msg">Conecte-se à Internet para efetuar a saída do Telegram corretamente.</string>
<string name="shared_string_close">Fechar</string>
<string name="disconnect_from_telegram_desc">Para revogar o acesso ao compartilhamento de local. Abra o Telegram, vá para Configurações → Privacidade e Segurança → Sessões e termine a sessão do OsmAnd Telegram.</string>
<string name="disconnect_from_telegram">"Como desativar o compartilhamento de local do OsmAnd para Telegram"</string>
<string name="logout_help_desc">"Como desativar o compartilhamento de local do OsmAnd para Telegram"</string>
<string name="connected_account">Conta conectada</string>
<string name="shared_string_account">Conta</string>
<string name="in_time">no %1$s</string>
<string name="osmand_connect_desc">Escolha a versão OsmAnd que OsmAnd Telegram usa para exibir posições.</string>
<string name="osmand_connect">"conectar ao OsmAnd "</string>
<string name="location_history_desc">Ocultar contatos que não foram movidos em um determinado momento.</string>
<string name="location_history">Histórico de localização</string>
<string name="stale_location_desc">A última vez que um contato foi movido.</string>
<string name="stale_location">Parado</string>
<string name="send_my_location_desc">Defina o intervalo mínimo para o compartilhamento de local.</string>
<string name="send_my_location">Enviar minha localização</string>
<string name="gps_and_location">Posição</string>
<string name="sharing_time">Tempo de compartilhamento</string>
<string name="expire_at">Expira</string>
<string name="stop_sharing_all">O compartilhamento está ativado (desativado)</string>
<string name="turn_off_location_sharing">Desativar o compartilhamento de local</string>
<string name="open_osmand">Abrir OsmAnd</string>
<string name="shared_string_live">Vivo</string>
<string name="shared_string_bot">Robô</string>
<string name="get_telegram_title">Registro no Telegram</string>
<string name="get_telegram_account_first">Você precisa de uma conta do Telegram para usar o compartilhamento de local.</string>
<string name="get_telegram_description_continue">Por favor, instale o Telegram e configure uma conta.</string>
<string name="get_telegram_after_creating_account">Então você pode usar este aplicativo.</string>
<string name="shared_string_all">Todos</string>
<string name="shared_string_off">Desativado</string>
<string name="already_registered_in_telegram">Você precisa de uma conta e número de telefone registrados no Telegram</string>
<string name="do_not_have_telegram">Eu não tenho conta Telegram</string>
<string name="enter_phone_number">Digite o número de telefone</string>
<string name="enter_authentication_code">Digite o código de autenticação</string>
<string name="set_visible_time_for_all">Definir tempo visível para todos</string>
<string name="hours_and_minutes_format">%1$d h %2$d m</string>
<string name="minutes_format">%1$d m</string>
<string name="hours_format">%1$d h</string>
<string name="shared_string_install">Instalar</string>
<string name="shared_string_share">Compartilhar</string>
<string name="shared_string_back">Voltar</string>
<string name="visible_time_for_all">Hora visível para todos</string>
<string name="set_time_description">Defina a hora em que seus contatos e grupos selecionados verão sua localização em tempo real.</string>
<string name="set_time">Definir tempo</string>
<string name="location_sharing_description">Selecione os contatos e grupos com os quais você deseja compartilhar sua localização.</string>
<string name="my_location_search_hint">Pesquisa: Grupo ou contato</string>
<string name="start_location_sharing">Compartilhar localização</string>
<string name="show_on_map">Mostrar no mapa</string>
<string name="app_name">OsmAnd Telegram</string>
<string name="phone_number_title">Número de telefone</string>
<string name="phone_number_descr">Número de telefone no formato internacional</string>
<string name="shared_string_password">Senha</string>
<string name="enter_code">Coloque o código</string>
<string name="authentication_code">Código de Autenticação</string>
<string name="authentication_code_descr">Uma faixa GPX é salva automaticamente durante a navegação.</string>
<string name="enter_password">Digite a senha</string>
<string name="password_descr">Senha do telegrama</string>
<string name="shared_string_login">Entrar</string>
<string name="shared_string_logout">Sair</string>
<string name="initialization">Iniciando</string>
<string name="logging_out">Saindo</string>
<string name="closing">Fechando</string>
<string name="gps_network_not_enabled">Ativar \"Localização\"\?</string>
<string name="not_logged_in">você não está logado no</string>
<string name="shared_string_continue">Continuar</string>
<string name="shared_string_cancel">Cancelar</string>
<string name="shared_string_settings">Configurações</string>
<string name="no_location_permission">O aplicativo não tem permissão para acessar os dados de localização.</string>
<string name="gps_not_available">Por favor, ligue \"Localização\" nas configurações do sistema</string>
<string name="location_service_no_gps_available">Selecione um dos provedores de localização para compartilhar sua localização.</string>
<string name="osmand_service">Modo em segundo plano</string>
<string name="osmand_service_descr">OsmAnd Telegram é executado em segundo plano com a tela desligada.</string>
<string name="shared_string_distance">Distância</string>
<string name="share_location">Compartilhar localização</string>
<string name="sharing_location">Compartilhando localização</string>
<string name="process_service">Serviço OsmAnd Telegram</string>
<string name="osmand_logo">Logotipo do OsmAnd</string>
<string name="install_osmand_dialog_message">Você precisa instalar a versão gratuita ou paga do OsmAnd primeiro</string>
<string name="install_osmand">Instalar OsmAnd</string>
<string name="show_users_on_map">Mostrar usuários no mapa</string>
<string name="active_chats">Bate-papos ativos</string>
<string name="shared_string_authorization">Autorização</string>
<string name="shared_string_authorization_descr">Por favor, insira o número de telefone do seu Telegram em formato internacional</string>
<string name="shared_string_welcome">Boas vindas</string>
<string name="yard">yd</string>
<string name="foot">ft</string>
<string name="mile">mi</string>
<string name="km">km</string>
<string name="m">m</string>
<string name="nm">mn</string>
<string name="min_mile">min/m</string>
<string name="min_km">min/km</string>
<string name="nm_h">mn/h</string>
<string name="m_s">m/s</string>
<string name="km_h">km/h</string>
<string name="mile_per_hour">mph</string>
<string name="si_kmh">Quilômetros por hora</string>
<string name="si_mph">Milhas por hora</string>
<string name="si_m_s">Metros por segundo</string>
<string name="si_min_km">Minutos por quilômetro</string>
<string name="si_min_m">Minutos por milha</string>
<string name="si_nm_h">Milhas náuticas por hora (nó)</string>
<string name="si_mi_feet">Milhas/pés</string>
<string name="si_mi_yard">Milhas/jardas</string>
<string name="si_km_m">Quilômetros/metros</string>
<string name="si_nm">Milhas náuticas</string>
<string name="si_mi_meters">Milhas/metros</string>
<string name="shared_string_hour_short">h</string>
<string name="shared_string_minute_short">min</string>
<string name="shared_string_second_short">seg</string>
<string name="welcome_descr"><b>Compartilhamento de local OsmAnd</b> permite que você compartilhe sua localização e veja a dos outros no OsmAnd.<br/><br/>O aplicativo usa a API Telegram e você precisa de uma conta Telegram.</string>
<string name="my_location">Minha localização</string>
<string name="live_now">Ao vivo agora</string>
</resources>

View file

@ -1,5 +1,6 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
<string name="timeline_description">Включите мониторинг, для сбора данных о перемещении в фоновом режиме.</string>
<string name="last_update_from_telegram">Последнее обновление в Telegram</string>
<string name="device_name">Имя устройства</string>
<string name="shared_string_hide">Спрятать</string>

View file

@ -1,2 +1,178 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
<resources><string name="send_location_as">傳送位置為</string>
<string name="send_location_as_descr">選擇您所在位置怎樣的訊息外觀。</string>
<string name="shared_string_map">地圖</string>
<string name="shared_string_text">文字</string>
<string name="map_and_text">地圖與文字</string>
<string name="device_added_successfully">%1$s 已新增。</string>
<string name="shared_string_add">新增</string>
<string name="error_adding_new_device">無法增加新的裝置</string>
<string name="enter_device_name_description">命名您的新裝置,最多 200 個字符。</string>
<string name="device_name_is_too_long">裝置名稱太長</string>
<string name="device_name_cannot_be_empty">裝置名稱不能為空白</string>
<string name="device_name">裝置名稱</string>
<string name="shared_string_hide">隱藏</string>
<string name="last_updated_location">上次更新的位置:</string>
<string name="sending_location_messages">正在傳送位置</string>
<string name="initializing">正在啟動</string>
<string name="searching_for_gps">正在定位…</string>
<string name="connecting_to_the_internet">正在連線至網路</string>
<string name="background_work">背景工作</string>
<string name="sharing_in_background">在背景分享</string>
<string name="go_to_settings">轉至設定</string>
<string name="shared_string_later">隨後</string>
<string name="not_sent_yet">尚未傳送</string>
<string name="not_found_yet">尚未找到</string>
<string name="re_send_location">重新傳送位置</string>
<string name="last_available_location">最後可用的位置</string>
<string name="sharing_status">分享狀態</string>
<string name="sharing_enabled">分享:已啟用</string>
<string name="shared_string_status">狀態</string>
<string name="no_gps_connection">沒有 GPS 連接</string>
<string name="no_internet_connection">沒有網際網路連線</string>
<string name="shared_string_disable">停用</string>
<string name="shared_string_save">儲存</string>
<string name="add_device">新增裝置</string>
<string name="share_location_as">分享位置為</string>
<string name="shared_string_name">名稱</string>
<string name="by_distance">按距離</string>
<string name="by_name">按名稱</string>
<string name="by_group">按群組</string>
<string name="shared_string_sort">分類</string>
<string name="shared_string_sort_by">排序方式</string>
<string name="disable_all_sharing">停用所有分享</string>
<string name="turn_off_all">關閉全部</string>
<string name="shared_string_exit">離開</string>
<string name="last_update_from_telegram">Telegram 的最後一次更新</string>
<string name="enter_another_device_name">選擇一個尚未使用的名稱</string>
<string name="share_location_as_description_second_line">您可以使用 %1$s 聊天機器人在電報用戶端中創建和查看裝置 ID。 %2$s</string>
<string name="share_location_as_description">如果要將多個設備連接到一個 Telegram 帳戶,則需要使用不同的設備來共用您的位置。</string>
<string name="successfully_sent_and_updated">已成功發送和更新</string>
<string name="not_possible_to_send_to_telegram_chats">無法發送到 Telegram 聊天:</string>
<string name="waiting_for_response_from_telegram">等待 Telegram 回復</string>
<string name="background_work_description">更改電池最佳化設置以穩定位置共用。</string>
<string name="battery_optimization_description">關閉 OsmAnd Telegram 的電池最佳化,這樣在後臺時就不會突然關閉。</string>
<string name="live_now_description">連絡人和群組共用位置給您。</string>
<string name="logout_from_osmand_telegram_descr">你確定要登出 OsmAnd Telegram這樣你就不能共用位置或看到其他人的位置嗎</string>
<string name="logout_from_osmand_telegram">要登出 OsmAnd Telegram 嗎\?</string>
<string name="choose_osmand_desc">選擇將在地圖上顯示連絡人的 OsmAnd 版本。</string>
<string name="choose_osmand">選擇要使用的 OsmAnd 版本</string>
<string name="disable_all_sharing_desc">關閉所有選定聊天的位置共用(%1$d)。</string>
<string name="time_ago"></string>
<string name="last_response">上次回應</string>
<string name="shared_string_group">群組</string>
<string name="logout_no_internet_msg">連接到網路以正確登出 Telegram。</string>
<string name="shared_string_close">關閉</string>
<string name="disconnect_from_telegram_desc">撤銷位置共用訪問。打開 Telegram進入設定→隱私和安全→會話並終 OsmAnd Telegram 會話。</string>
<string name="disconnect_from_telegram">如何關閉 Telegram 中的 OsmAnd 交給位置共用</string>
<string name="logout_help_desc">如何關閉 Telegram 中的 OsmAnd 交給位置共用</string>
<string name="connected_account">已連接帳戶</string>
<string name="shared_string_account">帳戶</string>
<string name="in_time">在 %1$s</string>
<string name="osmand_connect_desc">選擇 OsmAnd 和版本的 OsmAnd Telegram 用於顯示位置。</string>
<string name="osmand_connect">OsMand 連接</string>
<string name="location_history_desc">隱藏在給定時間內未移動的連絡人。</string>
<string name="location_history">位置歷史記錄</string>
<string name="stale_location_desc">上次移動連絡人的時間。</string>
<string name="stale_location">沒有移動
\n</string>
<string name="send_my_location_desc">設置位置共用的最小間隔。</string>
<string name="send_my_location">發送我的位置</string>
<string name="gps_and_location">位置</string>
<string name="sharing_time">共用時間</string>
<string name="expire_at">到期</string>
<string name="stop_sharing_all">共用已打開 (關閉)</string>
<string name="turn_off_location_sharing">關閉位置共用</string>
<string name="open_osmand">打開 OsmAnd</string>
<string name="shared_string_live">即時</string>
<string name="shared_string_bot">提供</string>
<string name="get_telegram_title">註冊 Telegram</string>
<string name="get_telegram_account_first">您需要一個 Telegram 帳戶才能使用位置共用。</string>
<string name="get_telegram_description_continue">請安裝 Telegram 並建立帳戶。</string>
<string name="get_telegram_after_creating_account">然後您可以使用這個應用程式。</string>
<string name="shared_string_all">所有</string>
<string name="shared_string_off">關閉</string>
<string name="already_registered_in_telegram">你需要一個 Telegram 帳號和電話號碼</string>
<string name="do_not_have_telegram">我沒有 Telegram 帳戶</string>
<string name="enter_phone_number">添加電話號碼</string>
<string name="enter_authentication_code">輸入身份驗證程式碼</string>
<string name="set_visible_time_for_all">為所有人設定可見時間</string>
<string name="hours_and_minutes_format">%1$d 時 %2$d 分</string>
<string name="minutes_format">%1$d 分</string>
<string name="hours_format">%1$d 時</string>
<string name="shared_string_install">安裝</string>
<string name="shared_string_share">分享</string>
<string name="shared_string_back">返回</string>
<string name="visible_time_for_all">所有人的可見時間</string>
<string name="set_time_description">設置所選連絡人和組即時查看您的位置的時間。</string>
<string name="set_time">設定時間</string>
<string name="location_sharing_description">選擇要共用位置的連絡人和群組。</string>
<string name="my_location_search_hint">搜尋:群組或連絡人</string>
<string name="start_location_sharing">共用位置</string>
<string name="show_on_map">在地圖上顯示</string>
<string name="app_name">OsmAnd Telegram</string>
<string name="phone_number_title">電話號碼</string>
<string name="phone_number_descr">國際格式的電話號碼</string>
<string name="shared_string_password">密碼</string>
<string name="enter_code">輸入代碼</string>
<string name="authentication_code">身份驗證代碼</string>
<string name="authentication_code_descr">Telegram 給你發了一個代碼,要求 OsmAnd 登入你的帳戶。</string>
<string name="enter_password">輸入密碼</string>
<string name="password_descr">Telegram 密碼</string>
<string name="shared_string_login">登入</string>
<string name="shared_string_logout">登出</string>
<string name="initialization">正在啟動</string>
<string name="logging_out">已登出</string>
<string name="closing">關閉</string>
<string name="gps_network_not_enabled">打開“位置”?</string>
<string name="not_logged_in">您沒有登入</string>
<string name="shared_string_continue">繼續</string>
<string name="shared_string_cancel">取消</string>
<string name="shared_string_settings">設定</string>
<string name="no_location_permission">應用程式沒有存取位置數據的許可權。</string>
<string name="gps_not_available">請在系統設置中打開“位置”</string>
<string name="location_service_no_gps_available">選擇一個位置提供商來共享您的位置。</string>
<string name="osmand_service">背景模式</string>
<string name="osmand_service_descr">當螢幕關閉後,讓 OsmAnd 在背景運行。</string>
<string name="shared_string_distance">距離</string>
<string name="share_location">共用位置</string>
<string name="sharing_location">共用位置</string>
<string name="process_service">OsmAnd Telegram 伺服器</string>
<string name="osmand_logo">OsmAnd 圖示</string>
<string name="install_osmand_dialog_message">您需要先安裝免費或付費版本的 OsmAnd</string>
<string name="install_osmand">安裝 OsMand</string>
<string name="show_users_on_map">在地圖上顯示用戶</string>
<string name="active_chats">主動聊天</string>
<string name="shared_string_authorization">授權</string>
<string name="shared_string_authorization_descr">請以國際格式輸入 Telegram 電話號碼</string>
<string name="shared_string_welcome">歡迎</string>
<string name="yard"></string>
<string name="foot"></string>
<string name="mile"></string>
<string name="km">公里</string>
<string name="m">公尺</string>
<string name="nm"></string>
<string name="min_mile">分/公尺</string>
<string name="min_km">分/公里</string>
<string name="nm_h">浬/時</string>
<string name="m_s">公尺/秒</string>
<string name="km_h">公里/小時</string>
<string name="mile_per_hour">哩/小時</string>
<string name="si_kmh">公里每小時</string>
<string name="si_mph">英里每小時</string>
<string name="si_m_s">公尺每秒</string>
<string name="si_min_km">分鐘每公里</string>
<string name="si_min_m">分鐘每英里</string>
<string name="si_nm_h">浬每小時 (節)</string>
<string name="si_mi_feet">英哩/英呎</string>
<string name="si_mi_yard">英哩/碼</string>
<string name="si_km_m">公里/公尺</string>
<string name="si_nm">海浬</string>
<string name="si_mi_meters">英里/米</string>
<string name="shared_string_hour_short"></string>
<string name="shared_string_minute_short"></string>
<string name="shared_string_second_short"></string>
<string name="welcome_descr"><b>OsmAnd 位置共用</b>可以讓您共用您的位置,並在 OsmAnd 中看到其他人的位置。<br/><br/>該應用程式使用電報 API你需要一個 Telegram 帳戶。</string>
<string name="my_location">我的位置</string>
<string name="live_now">即時狀況</string>
</resources>

View file

@ -1,4 +1,13 @@
<resources>
<string name="monitoring_is_enabled">Monitoring is enabled</string>
<string name="monitoring_is_disabled">Monitoring is disabled</string>
<string name="time_on_the_move">time on the move</string>
<string name="average_altitude">Average altitude</string>
<string name="average_speed">Average speed</string>
<string name="open_in_osmand">Open in OsmAnd</string>
<string name="end_date">End date</string>
<string name="start_date">Start date</string>
<string name="timeline_description">Enable monitoring to collect movement data in the background.</string>
<string name="send_location_as">Send location as</string>
<string name="send_location_as_descr">Choose how messages with your location will look like.</string>
<string name="shared_string_map">Map</string>
@ -176,6 +185,7 @@
<string name="welcome_descr"><![CDATA[<b>OsmAnd Location Sharing</b> lets you share your location and see that of others in the OsmAnd.<br/><br/>The app uses Telegram API and you need a Telegram account.]]></string>
<string name="my_location">My location</string>
<string name="live_now">Live now</string>
<string name="timeline">Timeline</string>
</resources>

View file

@ -1,9 +1,14 @@
package net.osmand.aidl;
import net.osmand.aidl.search.SearchResult;
import net.osmand.aidl.gpx.AGpxBitmap;
interface IOsmAndAidlCallback {
void onSearchComplete(in List<SearchResult> resultSet);
void onUpdate();
void onAppInitialized();
void onGpxBitmapCreated(in AGpxBitmap bitmap);
}

View file

@ -55,6 +55,9 @@ import net.osmand.aidl.maplayer.point.ShowMapPointParams;
import net.osmand.aidl.navdrawer.SetNavDrawerItemsParams;
import net.osmand.aidl.navdrawer.NavDrawerFooterParams;
import net.osmand.aidl.navdrawer.NavDrawerHeaderParams;
import net.osmand.aidl.navigation.PauseNavigationParams;
import net.osmand.aidl.navigation.ResumeNavigationParams;
import net.osmand.aidl.navigation.StopNavigationParams;
@ -67,6 +70,16 @@ import net.osmand.aidl.search.SearchResult;
import net.osmand.aidl.search.SearchParams;
import net.osmand.aidl.navigation.NavigateSearchParams;
import net.osmand.aidl.customization.SetWidgetsParams;
import net.osmand.aidl.customization.OsmandSettingsParams;
import net.osmand.aidl.gpx.AGpxFile;
import net.osmand.aidl.gpx.AGpxFileDetails;
import net.osmand.aidl.gpx.CreateGpxBitmapParams;
import net.osmand.aidl.tiles.ASqliteDbFile;
import net.osmand.aidl.plugins.PluginParams;
// NOTE: Add new methods at the end of file!!!
interface IOsmAndAidlInterface {
@ -133,4 +146,34 @@ interface IOsmAndAidlInterface {
long registerForUpdates(in long updateTimeMS, IOsmAndAidlCallback callback);
boolean unregisterFromUpdates(in long callbackId);
boolean setNavDrawerLogo(in String imageUri);
boolean setEnabledIds(in List<String> ids);
boolean setDisabledIds(in List<String> ids);
boolean setEnabledPatterns(in List<String> patterns);
boolean setDisabledPatterns(in List<String> patterns);
boolean regWidgetVisibility(in SetWidgetsParams params);
boolean regWidgetAvailability(in SetWidgetsParams params);
boolean customizeOsmandSettings(in OsmandSettingsParams params);
boolean getImportedGpx(out List<AGpxFile> files);
boolean getSqliteDbFiles(out List<ASqliteDbFile> files);
boolean getActiveSqliteDbFiles(out List<ASqliteDbFile> files);
boolean showSqliteDbFile(String fileName);
boolean hideSqliteDbFile(String fileName);
boolean setNavDrawerLogoWithParams(in NavDrawerHeaderParams params);
boolean setNavDrawerFooterWithParams(in NavDrawerFooterParams params);
boolean restoreOsmand();
boolean changePluginState(in PluginParams params);
boolean registerForOsmandInitListener(in IOsmAndAidlCallback callback);
boolean getBitmapForGpx(in CreateGpxBitmapParams file, IOsmAndAidlCallback callback);
}

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.customization;
parcelable OsmandSettingsParams;

View file

@ -0,0 +1,60 @@
package net.osmand.aidl.customization;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class OsmandSettingsParams implements Parcelable {
private String sharedPreferencesName;
private Bundle bundle;
public OsmandSettingsParams(@NonNull String sharedPreferencesName, @Nullable Bundle bundle) {
this.sharedPreferencesName = sharedPreferencesName;
this.bundle = bundle;
}
public OsmandSettingsParams(Parcel in) {
readFromParcel(in);
}
public static final Creator<OsmandSettingsParams> CREATOR = new Creator<OsmandSettingsParams>() {
@Override
public OsmandSettingsParams createFromParcel(Parcel in) {
return new OsmandSettingsParams(in);
}
@Override
public OsmandSettingsParams[] newArray(int size) {
return new OsmandSettingsParams[size];
}
};
public String getSharedPreferencesName() {
return sharedPreferencesName;
}
public Bundle getBundle() {
return bundle;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(sharedPreferencesName);
out.writeBundle(bundle);
}
@SuppressLint("ParcelClassLoader")
private void readFromParcel(Parcel in) {
sharedPreferencesName = in.readString();
bundle = in.readBundle();
}
@Override
public int describeContents() {
return 0;
}
}

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.customization;
parcelable SetWidgetsParams;

View file

@ -0,0 +1,93 @@
package net.osmand.aidl.customization;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class SetWidgetsParams implements Parcelable {
private String widgetKey;
private List<String> appModesKeys;
public SetWidgetsParams(String widgetKey, @Nullable List<String> appModesKeys) {
this.widgetKey = widgetKey;
this.appModesKeys = appModesKeys;
}
public SetWidgetsParams(Parcel in) {
readFromParcel(in);
}
public static final Creator<SetWidgetsParams> CREATOR = new Creator<SetWidgetsParams>() {
@Override
public SetWidgetsParams createFromParcel(Parcel in) {
return new SetWidgetsParams(in);
}
@Override
public SetWidgetsParams[] newArray(int size) {
return new SetWidgetsParams[size];
}
};
public String getWidgetKey() {
return widgetKey;
}
public List<String> getAppModesKeys() {
return appModesKeys;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(widgetKey);
writeStringList(out, appModesKeys);
}
private void readFromParcel(Parcel in) {
widgetKey = in.readString();
appModesKeys = readStringList(in);
}
@Override
public int describeContents() {
return 0;
}
private void writeStringList(Parcel out, List<String> val) {
if (val == null) {
out.writeInt(-1);
return;
}
int N = val.size();
int i = 0;
out.writeInt(N);
while (i < N) {
out.writeString(val.get(i));
i++;
}
}
private List<String> readStringList(Parcel in) {
List<String> list = new ArrayList<>();
int M = list.size();
int N = in.readInt();
if (N == -1) {
return null;
}
int i = 0;
for (; i < M && i < N; i++) {
list.set(i, in.readString());
}
for (; i < N; i++) {
list.add(in.readString());
}
for (; i < M; i++) {
list.remove(N);
}
return list;
}
}

View file

@ -0,0 +1,4 @@
package net.osmand.aidl.gpx;
parcelable AGpxBitmap;

View file

@ -0,0 +1,50 @@
package net.osmand.aidl.gpx;
import android.graphics.Bitmap;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
public class AGpxBitmap implements Parcelable {
private Bitmap bitmap;
public AGpxBitmap(@NonNull Bitmap bitmap) {
this.bitmap = bitmap;
}
public AGpxBitmap(Parcel in) {
readFromParcel(in);
}
public Bitmap getBitmap() {
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public static final Creator<AGpxBitmap> CREATOR = new
Creator<AGpxBitmap>() {
public AGpxBitmap createFromParcel(Parcel in) {
return new AGpxBitmap(in);
}
public AGpxBitmap[] newArray(int size) {
return new AGpxBitmap[size];
}
};
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(bitmap, flags);
}
private void readFromParcel(Parcel in) {
bitmap = in.readParcelable(Bitmap.class.getClassLoader());
}
public int describeContents() {
return 0;
}
}

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.gpx;
parcelable AGpxFile;

View file

@ -0,0 +1,89 @@
package net.osmand.aidl.gpx;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class AGpxFile implements Parcelable {
private String fileName;
private long modifiedTime;
private long fileSize;
private boolean active;
private AGpxFileDetails details;
public AGpxFile(@NonNull String fileName, long modifiedTime, long fileSize, boolean active, @Nullable AGpxFileDetails details) {
this.fileName = fileName;
this.modifiedTime = modifiedTime;
this.fileSize = fileSize;
this.active = active;
this.details = details;
}
public AGpxFile(Parcel in) {
readFromParcel(in);
}
public static final Creator<AGpxFile> CREATOR = new
Creator<AGpxFile>() {
public AGpxFile createFromParcel(Parcel in) {
return new AGpxFile(in);
}
public AGpxFile[] newArray(int size) {
return new AGpxFile[size];
}
};
public String getFileName() {
return fileName;
}
public long getModifiedTime() {
return modifiedTime;
}
public long getFileSize() {
return fileSize;
}
public boolean isActive() {
return active;
}
public AGpxFileDetails getDetails() {
return details;
}
public void writeToParcel(Parcel out, int flags) {
out.writeString(fileName);
out.writeLong(modifiedTime);
out.writeLong(fileSize);
out.writeByte((byte) (active ? 1 : 0));
out.writeByte((byte) (details != null ? 1 : 0));
if (details != null) {
out.writeParcelable(details, flags);
}
}
private void readFromParcel(Parcel in) {
fileName = in.readString();
modifiedTime = in.readLong();
fileSize = in.readLong();
active = in.readByte() != 0;
boolean hasDetails= in.readByte() != 0;
if (hasDetails) {
details = in.readParcelable(AGpxFileDetails.class.getClassLoader());
} else {
details = null;
}
}
public int describeContents() {
return 0;
}
}

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.gpx;
parcelable AGpxFileDetails;

View file

@ -0,0 +1,196 @@
package net.osmand.aidl.gpx;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class AGpxFileDetails implements Parcelable {
private float totalDistance = 0;
private int totalTracks = 0;
private long startTime = Long.MAX_VALUE;
private long endTime = Long.MIN_VALUE;
private long timeSpan = 0;
private long timeMoving = 0;
private float totalDistanceMoving = 0;
private double diffElevationUp = 0;
private double diffElevationDown = 0;
private double avgElevation = 0;
private double minElevation = 99999;
private double maxElevation = -100;
private float minSpeed = Float.MAX_VALUE;
private float maxSpeed = 0;
private float avgSpeed;
private int points;
private int wptPoints = 0;
private List<String> wptCategoryNames = new ArrayList<>();
public AGpxFileDetails(float totalDistance, int totalTracks,
long startTime, long endTime,
long timeSpan, long timeMoving, float totalDistanceMoving,
double diffElevationUp, double diffElevationDown,
double avgElevation, double minElevation, double maxElevation,
float minSpeed, float maxSpeed, float avgSpeed,
int points, int wptPoints, Set<String> wptCategoryNames) {
this.totalDistance = totalDistance;
this.totalTracks = totalTracks;
this.startTime = startTime;
this.endTime = endTime;
this.timeSpan = timeSpan;
this.timeMoving = timeMoving;
this.totalDistanceMoving = totalDistanceMoving;
this.diffElevationUp = diffElevationUp;
this.diffElevationDown = diffElevationDown;
this.avgElevation = avgElevation;
this.minElevation = minElevation;
this.maxElevation = maxElevation;
this.minSpeed = minSpeed;
this.maxSpeed = maxSpeed;
this.avgSpeed = avgSpeed;
this.points = points;
this.wptPoints = wptPoints;
if (wptCategoryNames != null) {
this.wptCategoryNames = new ArrayList<>(wptCategoryNames);
}
}
public AGpxFileDetails(Parcel in) {
readFromParcel(in);
}
public static final Creator<AGpxFileDetails> CREATOR = new
Creator<AGpxFileDetails>() {
public AGpxFileDetails createFromParcel(Parcel in) {
return new AGpxFileDetails(in);
}
public AGpxFileDetails[] newArray(int size) {
return new AGpxFileDetails[size];
}
};
public float getTotalDistance() {
return totalDistance;
}
public int getTotalTracks() {
return totalTracks;
}
public long getStartTime() {
return startTime;
}
public long getEndTime() {
return endTime;
}
public long getTimeSpan() {
return timeSpan;
}
public long getTimeMoving() {
return timeMoving;
}
public float getTotalDistanceMoving() {
return totalDistanceMoving;
}
public double getDiffElevationUp() {
return diffElevationUp;
}
public double getDiffElevationDown() {
return diffElevationDown;
}
public double getAvgElevation() {
return avgElevation;
}
public double getMinElevation() {
return minElevation;
}
public double getMaxElevation() {
return maxElevation;
}
public float getMinSpeed() {
return minSpeed;
}
public float getMaxSpeed() {
return maxSpeed;
}
public float getAvgSpeed() {
return avgSpeed;
}
public int getPoints() {
return points;
}
public int getWptPoints() {
return wptPoints;
}
public List<String> getWptCategoryNames() {
return wptCategoryNames;
}
public void writeToParcel(Parcel out, int flags) {
out.writeFloat(totalDistance);
out.writeInt(totalTracks);
out.writeLong(startTime);
out.writeLong(endTime);
out.writeLong(timeSpan);
out.writeLong(timeMoving);
out.writeFloat(totalDistanceMoving);
out.writeDouble(diffElevationUp);
out.writeDouble(diffElevationDown);
out.writeDouble(avgElevation);
out.writeDouble(minElevation);
out.writeDouble(maxElevation);
out.writeFloat(minSpeed);
out.writeFloat(maxSpeed);
out.writeFloat(avgSpeed);
out.writeInt(points);
out.writeInt(wptPoints);
out.writeStringList(wptCategoryNames);
}
private void readFromParcel(Parcel in) {
totalDistance = in.readFloat();
totalTracks = in.readInt();
startTime = in.readLong();
endTime = in.readLong();
timeSpan = in.readLong();
timeMoving = in.readLong();
totalDistanceMoving = in.readFloat();
diffElevationUp = in.readDouble();
diffElevationDown = in.readDouble();
avgElevation = in.readDouble();
minElevation = in.readDouble();
maxElevation = in.readDouble();
minSpeed = in.readFloat();
maxSpeed = in.readFloat();
avgSpeed = in.readFloat();
points = in.readInt();
wptPoints = in.readInt();
in.readStringList(wptCategoryNames);
}
public int describeContents() {
return 0;
}
}

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.gpx;
parcelable CreateGpxBitmapParams;

View file

@ -0,0 +1,101 @@
package net.osmand.aidl.gpx;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import java.io.File;
public class CreateGpxBitmapParams implements Parcelable {
private File gpxFile;
private Uri gpxUri;
private float density;
private int widthPixels;
private int heightPixels;
private int color; //ARGB color int
public CreateGpxBitmapParams(File gpxFile, float density, int widthPixels, int heightPixels, int color) {
this.gpxFile = gpxFile;
this.density = density;
this.widthPixels = widthPixels;
this.heightPixels = heightPixels;
this.color = color;
}
public CreateGpxBitmapParams(Uri gpxUri, float density, int widthPixels, int heightPixels, int color) {
this.gpxUri = gpxUri;
this.density = density;
this.widthPixels = widthPixels;
this.heightPixels = heightPixels;
this.color = color;
}
public CreateGpxBitmapParams(Parcel in) {
readFromParcel(in);
}
public static final Creator<CreateGpxBitmapParams> CREATOR = new
Creator<CreateGpxBitmapParams>() {
public CreateGpxBitmapParams createFromParcel(Parcel in) {
return new CreateGpxBitmapParams(in);
}
public CreateGpxBitmapParams[] newArray(int size) {
return new CreateGpxBitmapParams[size];
}
};
public File getGpxFile() {
return gpxFile;
}
public Uri getGpxUri() {
return gpxUri;
}
public int getWidthPixels() {
return widthPixels;
}
public int getHeightPixels() {
return heightPixels;
}
public float getDensity() {
return density;
}
public int getColor() {
return color;
}
public void writeToParcel(Parcel out, int flags) {
if (gpxFile != null) {
out.writeString(gpxFile.getAbsolutePath());
} else {
out.writeString(null);
}
out.writeParcelable(gpxUri, flags);
out.writeFloat(density);
out.writeInt(widthPixels);
out.writeInt(heightPixels);
out.writeInt(color);
}
private void readFromParcel(Parcel in) {
String gpxAbsolutePath = in.readString();
if (gpxAbsolutePath != null) {
gpxFile = new File(gpxAbsolutePath);
}
gpxUri = in.readParcelable(Uri.class.getClassLoader());
density = in.readFloat();
widthPixels = in.readInt();
heightPixels = in.readInt();
color = in.readInt();
}
public int describeContents() {
return 0;
}
}

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.navdrawer;
parcelable NavDrawerFooterParams;

View file

@ -0,0 +1,68 @@
package net.osmand.aidl.navdrawer;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class NavDrawerFooterParams implements Parcelable {
@NonNull
private String packageName;
@Nullable
private String intent;
@Nullable
private String appName;
@NonNull
public String getPackageName() {
return packageName;
}
@Nullable
public String getIntent() {
return intent;
}
@Nullable
public String getAppName() {
return appName;
}
public NavDrawerFooterParams(@NonNull String packageName, @Nullable String intent,
@Nullable String appName) {
this.packageName = packageName;
this.intent = intent;
this.appName = appName;
}
protected NavDrawerFooterParams(Parcel in) {
packageName = in.readString();
intent = in.readString();
appName = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(packageName);
dest.writeString(intent);
dest.writeString(appName);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<NavDrawerFooterParams> CREATOR = new Creator<NavDrawerFooterParams>() {
@Override
public NavDrawerFooterParams createFromParcel(Parcel in) {
return new NavDrawerFooterParams(in);
}
@Override
public NavDrawerFooterParams[] newArray(int size) {
return new NavDrawerFooterParams[size];
}
};
}

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.navdrawer;
parcelable NavDrawerHeaderParams;

View file

@ -0,0 +1,68 @@
package net.osmand.aidl.navdrawer;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class NavDrawerHeaderParams implements Parcelable {
@NonNull
private String imageUri;
@NonNull
private String packageName;
@Nullable
private String intent;
@NonNull
public String getImageUri() {
return imageUri;
}
@NonNull
public String getPackageName() {
return packageName;
}
@Nullable
public String getIntent() {
return intent;
}
public NavDrawerHeaderParams(@NonNull String imageUri, @NonNull String packageName,
@Nullable String intent) {
this.imageUri = imageUri;
this.packageName = packageName;
this.intent = intent;
}
public NavDrawerHeaderParams(Parcel in) {
imageUri = in.readString();
packageName = in.readString();
intent = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(imageUri);
dest.writeString(packageName);
dest.writeString(intent);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<NavDrawerHeaderParams> CREATOR = new Creator<NavDrawerHeaderParams>() {
@Override
public NavDrawerHeaderParams createFromParcel(Parcel in) {
return new NavDrawerHeaderParams(in);
}
@Override
public NavDrawerHeaderParams[] newArray(int size) {
return new NavDrawerHeaderParams[size];
}
};
}

View file

@ -0,0 +1,5 @@
// PluginParams.aidl
package net.osmand.aidl.plugins;
parcelable PluginParams;

View file

@ -0,0 +1,51 @@
package net.osmand.aidl.plugins;
import android.os.Parcel;
import android.os.Parcelable;
public class PluginParams implements Parcelable {
private String pluginId;
private int newState; //0- off, 1 - on
public PluginParams(String pluginId, int newState) {
this.pluginId = pluginId;
this.newState = newState;
}
public String getPluginId() {
return pluginId;
}
public int getNewState() {
return newState;
}
protected PluginParams(Parcel in) {
pluginId = in.readString();
newState = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(pluginId);
dest.writeInt(newState);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<PluginParams> CREATOR = new Creator<PluginParams>() {
@Override
public PluginParams createFromParcel(Parcel in) {
return new PluginParams(in);
}
@Override
public PluginParams[] newArray(int size) {
return new PluginParams[size];
}
};
}

View file

@ -0,0 +1,3 @@
package net.osmand.aidl.tiles;
parcelable ASqliteDbFile;

View file

@ -0,0 +1,69 @@
package net.osmand.aidl.tiles;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
public class ASqliteDbFile implements Parcelable {
private String fileName;
private long modifiedTime;
private long fileSize;
private boolean active;
public ASqliteDbFile(@NonNull String fileName, long modifiedTime, long fileSize, boolean active) {
this.fileName = fileName;
this.modifiedTime = modifiedTime;
this.fileSize = fileSize;
this.active = active;
}
public ASqliteDbFile(Parcel in) {
readFromParcel(in);
}
public static final Creator<ASqliteDbFile> CREATOR = new
Creator<ASqliteDbFile>() {
public ASqliteDbFile createFromParcel(Parcel in) {
return new ASqliteDbFile(in);
}
public ASqliteDbFile[] newArray(int size) {
return new ASqliteDbFile[size];
}
};
public String getFileName() {
return fileName;
}
public long getModifiedTime() {
return modifiedTime;
}
public long getFileSize() {
return fileSize;
}
public boolean isActive() {
return active;
}
public void writeToParcel(Parcel out, int flags) {
out.writeString(fileName);
out.writeLong(modifiedTime);
out.writeLong(fileSize);
out.writeByte((byte) (active ? 1 : 0));
}
private void readFromParcel(Parcel in) {
fileName = in.readString();
modifiedTime = in.readLong();
fileSize = in.readLong();
active = in.readByte() != 0;
}
public int describeContents() {
return 0;
}
}

View file

@ -79,6 +79,8 @@ private const val SHARE_CHATS_INFO_KEY = "share_chats_info"
private const val BATTERY_OPTIMISATION_ASKED = "battery_optimisation_asked"
private const val MONITORING_ENABLED = "monitoring_enabled"
private const val SHARING_INITIALIZATION_TIME = 60 * 2L // 2 minutes
private const val GPS_UPDATE_EXPIRED_TIME = 60 * 3L // 3 minutes
@ -111,6 +113,8 @@ class TelegramSettings(private val app: TelegramApplication) {
var batteryOptimisationAsked = false
var monitoringEnabled = false
init {
updatePrefs()
read()
@ -435,6 +439,8 @@ class TelegramSettings(private val app: TelegramApplication) {
edit.putBoolean(BATTERY_OPTIMISATION_ASKED, batteryOptimisationAsked)
edit.putBoolean(MONITORING_ENABLED, monitoringEnabled)
val jArray = convertShareChatsInfoToJson()
if (jArray != null) {
edit.putString(SHARE_CHATS_INFO_KEY, jArray.toString())
@ -491,6 +497,8 @@ class TelegramSettings(private val app: TelegramApplication) {
)
batteryOptimisationAsked = prefs.getBoolean(BATTERY_OPTIMISATION_ASKED,false)
monitoringEnabled = prefs.getBoolean(MONITORING_ENABLED,false)
}
private fun convertShareDevicesToJson():JSONObject?{

View file

@ -75,6 +75,12 @@ class OsmandAidlHelper(private val app: TelegramApplication) {
fun onSearchComplete(resultSet: List<SearchResult>)
}
private var gpxBitmapCreatedListener: GpxBitmapCreatedListener? = null
interface GpxBitmapCreatedListener {
fun onGpxBitmapCreated(bitmap: AGpxBitmap)
}
private val mIOsmAndAidlCallback = object : IOsmAndAidlCallback.Stub() {
@Throws(RemoteException::class)
@ -90,12 +96,26 @@ class OsmandAidlHelper(private val app: TelegramApplication) {
mUpdatesListener!!.update()
}
}
override fun onAppInitialized() {
}
override fun onGpxBitmapCreated(bitmap: AGpxBitmap) {
if (gpxBitmapCreatedListener != null) {
gpxBitmapCreatedListener!!.onGpxBitmapCreated(bitmap)
}
}
}
fun setSearchCompleteListener(mSearchCompleteListener: SearchCompleteListener) {
this.mSearchCompleteListener = mSearchCompleteListener
}
fun setGpxBitmapCreatedListener(gpxBitmapCreatedListener: GpxBitmapCreatedListener) {
this.gpxBitmapCreatedListener = gpxBitmapCreatedListener
}
private var mUpdatesListener: UpdatesListener? = null
interface UpdatesListener {
@ -1059,4 +1079,16 @@ class OsmandAidlHelper(private val app: TelegramApplication) {
}
return false
}
fun getBitmapForGpx(gpxUri: Uri, density: Float, widthPixels: Int, heightPixels: Int, color: Int): Boolean {
if (mIOsmAndAidlInterface != null) {
try {
app.grantUriPermission(app.settings.appToConnectPackage, gpxUri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
return mIOsmAndAidlInterface!!.getBitmapForGpx(CreateGpxBitmapParams(gpxUri, density, widthPixels, heightPixels, color), mIOsmAndAidlCallback)
} catch (e: RemoteException) {
e.printStackTrace()
}
}
return false
}
}

View file

@ -7,7 +7,6 @@ import android.os.AsyncTask;
import net.osmand.PlatformUtil;
import net.osmand.telegram.TelegramApplication;
import net.osmand.telegram.ui.LiveNowTabFragment;
import net.osmand.telegram.utils.GPXUtilities;
import net.osmand.telegram.utils.GPXUtilities.GPXFile;
import net.osmand.telegram.utils.GPXUtilities.Track;
@ -19,7 +18,6 @@ import org.drinkless.td.libcore.telegram.TdApi;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.lang.ref.WeakReference;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
@ -50,7 +48,7 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
+ TRACK_COL_ALTITUDE + " double, " + TRACK_COL_SPEED + " double, " //$NON-NLS-1$ //$NON-NLS-2$
+ TRACK_COL_HDOP + " double, " + TRACK_COL_DATE + " long, " + TRACK_COL_TEXT_INFO + " int )";
public final static Log log = PlatformUtil.getLog(SavingTracksDbHelper.class);
private final static Log log = PlatformUtil.getLog(SavingTracksDbHelper.class);
private final TelegramApplication app;
@ -110,23 +108,32 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
}
}
public void saveAsyncUserDataToGpx(LiveNowTabFragment fragment, File dir, int userId, long interval) {
GPXFile gpxFile = app.getSavingTracksDbHelper().collectRecordedDataForUser(userId, interval);
public void saveUserDataToGpx(SaveGpxListener listener, File dir, int userId, long chatId, long start, long end) {
GPXFile gpxFile = collectRecordedDataForUserAndChat(userId, chatId, start, end);
if (gpxFile != null && !gpxFile.isEmpty()) {
LiveUpdatesPurchaseTask task = new LiveUpdatesPurchaseTask(fragment, gpxFile, dir, userId);
SaveGPXTrackToFileTask task = new SaveGPXTrackToFileTask(app, listener, gpxFile, dir, userId);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
public void saveGpx(SaveGpxListener listener, File dir, GPXFile gpxFile) {
if (gpxFile != null && !gpxFile.isEmpty()) {
SaveGPXTrackToFileTask task = new SaveGPXTrackToFileTask(app, listener, gpxFile, dir, 0);
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
private void updateLocationMessage(TdApi.Message message) {
log.debug(message);
TdApi.MessageContent content = message.content;
int senderId = app.getTelegramHelper().getSenderMessageId(message);
if (content instanceof TdApi.MessageLocation) {
long lastTextMessageUpdate = getLastTextTrackPointTimeForUser(message.senderUserId);
long currentTime = System.currentTimeMillis();
if (lastTextMessageUpdate == 0 || currentTime - lastTextMessageUpdate < 10 * 1000) {
log.debug("Add map message" + message.senderUserId);
log.debug("Add map message " + message.senderUserId);
TdApi.MessageLocation messageLocation = (TdApi.MessageLocation) content;
insertData(message.senderUserId, message.chatId, messageLocation.location.latitude,
insertData(senderId, message.chatId, messageLocation.location.latitude,
messageLocation.location.longitude, 0.0, 0.0, 0.0,
Math.max(message.date, message.editDate), 0);
} else {
@ -135,7 +142,7 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
} else if (content instanceof TelegramHelper.MessageLocation) {
log.debug("Add text message " + message.senderUserId);
TelegramHelper.MessageLocation messageLocation = (TelegramHelper.MessageLocation) content;
insertData(message.senderUserId, message.chatId, messageLocation.getLat(), messageLocation.getLon(),
insertData(senderId, message.chatId, messageLocation.getLat(), messageLocation.getLon(),
messageLocation.getAltitude(), messageLocation.getSpeed(), messageLocation.getHdop(),
messageLocation.getLastUpdated() * 1000L, 1);
}
@ -181,12 +188,12 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
return res;
}
private GPXFile collectRecordedDataForUser(int userId, long interval) {
public GPXFile collectRecordedDataForUserAndChat(int userId, long chatId, long start, long end) {
GPXFile gpxFile = null;
SQLiteDatabase db = getReadableDatabase();
if (db != null && db.isOpen()) {
try {
gpxFile = collectDBTracksForUser(db, userId, interval);
gpxFile = collectDBTracksForUser(db, userId, chatId, start, end);
} finally {
db.close();
}
@ -194,21 +201,53 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
return gpxFile;
}
private GPXFile collectDBTracksForUser(SQLiteDatabase db, int userId, long interval) {
Cursor query = db.rawQuery("SELECT " + TRACK_COL_USER_ID + "," + TRACK_COL_CHAT_ID + "," + TRACK_COL_LAT + "," + TRACK_COL_LON + "," + TRACK_COL_ALTITUDE + "," //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+ TRACK_COL_SPEED + "," + TRACK_COL_HDOP + "," + TRACK_COL_DATE + " FROM " + TRACK_NAME +
" WHERE " + TRACK_COL_USER_ID + " = ? ORDER BY " + TRACK_COL_DATE + " ASC ", new String[]{String.valueOf(userId)}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
GPXFile gpxFile = new GPXFile();
public GPXFile collectRecordedDataForUser(int userId, long chatId, long start, long end) {
GPXFile gpxFile = null;
SQLiteDatabase db = getReadableDatabase();
if (db != null && db.isOpen()) {
try {
if (chatId == 0) {
gpxFile = collectDBTracksForUser(db, userId, start, end);
} else {
gpxFile = collectDBTracksForUser(db, userId, chatId, start, end);
}
} finally {
db.close();
}
}
return gpxFile;
}
public ArrayList<GPXFile> collectRecordedDataForUsers(long start, long end, ArrayList<Integer> ignoredUsersIds) {
ArrayList<GPXFile> data = new ArrayList<>();
SQLiteDatabase db = getReadableDatabase();
if (db != null && db.isOpen()) {
try {
collectDBTracksForUsers(db, data, start, end, ignoredUsersIds);
} finally {
db.close();
}
}
return data;
}
private GPXFile collectDBTracksForUser(SQLiteDatabase db, int userId, long chatId, long start, long end) {
Cursor query = db.rawQuery("SELECT " + TRACK_COL_USER_ID + "," + TRACK_COL_CHAT_ID + ","
+ TRACK_COL_LAT + "," + TRACK_COL_LON + "," + TRACK_COL_ALTITUDE + "," + TRACK_COL_SPEED + ","
+ TRACK_COL_HDOP + "," + TRACK_COL_DATE + " FROM " + TRACK_NAME + " WHERE " + TRACK_COL_USER_ID + " = ?"
+ " AND " + TRACK_COL_CHAT_ID + " = ?" + " AND " + TRACK_COL_DATE + " BETWEEN " + start + " AND " + end
+ " ORDER BY " + TRACK_COL_DATE + " ASC ", new String[]{String.valueOf(userId), String.valueOf(chatId)});
GPXFile gpxFile = null;
long previousTime = 0;
TrkSegment segment = null;
Track track = null;
if (query.moveToFirst()) {
gpxFile = new GPXFile();
gpxFile.chatId = chatId;
gpxFile.userId = userId;
do {
long time = query.getLong(7);
long curTime = System.currentTimeMillis();
if (curTime - time > interval) {
continue;
}
WptPt pt = new WptPt();
pt.userId = query.getInt(0);
pt.chatId = query.getLong(1);
@ -244,19 +283,136 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
return gpxFile;
}
private static class LiveUpdatesPurchaseTask extends AsyncTask<Void, Void, List<String>> {
private GPXFile collectDBTracksForUser(SQLiteDatabase db, int userId, long start, long end) {
Cursor query = db.rawQuery("SELECT " + TRACK_COL_USER_ID + "," + TRACK_COL_CHAT_ID + ","
+ TRACK_COL_LAT + "," + TRACK_COL_LON + "," + TRACK_COL_ALTITUDE + "," + TRACK_COL_SPEED + ","
+ TRACK_COL_HDOP + "," + TRACK_COL_DATE + " FROM " + TRACK_NAME + " WHERE " + TRACK_COL_USER_ID + " = ?"
+ " AND " + TRACK_COL_DATE + " BETWEEN " + start + " AND " + end
+ " ORDER BY " + TRACK_COL_DATE + " ASC ", new String[]{String.valueOf(userId)});
GPXFile gpxFile = null;
long previousTime = 0;
TrkSegment segment = null;
Track track = null;
if (query.moveToFirst()) {
gpxFile = new GPXFile();
gpxFile.userId = userId;
do {
long time = query.getLong(7);
WptPt pt = new WptPt();
pt.userId = query.getInt(0);
pt.chatId = query.getLong(1);
pt.lat = query.getDouble(2);
pt.lon = query.getDouble(3);
pt.ele = query.getDouble(4);
pt.speed = query.getDouble(5);
pt.hdop = query.getDouble(6);
pt.time = time;
long currentInterval = Math.abs(time - previousTime);
if (track != null) {
if (currentInterval < 30 * 60 * 1000) {
// 30 minute - same segment
segment.points.add(pt);
} else {
segment = new TrkSegment();
segment.points.add(pt);
track.segments.add(segment);
}
} else {
track = new Track();
segment = new TrkSegment();
track.segments.add(segment);
segment.points.add(pt);
gpxFile.tracks.add(track);
}
previousTime = time;
} while (query.moveToNext());
}
query.close();
return gpxFile;
}
private void collectDBTracksForUsers(SQLiteDatabase db, ArrayList<GPXFile> dataTracks, long start, long end, ArrayList<Integer> ignoredUsersIds) {
Cursor query = db.rawQuery("SELECT " + TRACK_COL_USER_ID + "," + TRACK_COL_CHAT_ID + ","
+ TRACK_COL_LAT + "," + TRACK_COL_LON + "," + TRACK_COL_ALTITUDE + "," + TRACK_COL_SPEED + ","
+ TRACK_COL_HDOP + "," + TRACK_COL_DATE + " FROM " + TRACK_NAME + " WHERE " + TRACK_COL_DATE
+ " BETWEEN " + start + " AND " + end + " ORDER BY " + TRACK_COL_USER_ID + " ASC, "
+ TRACK_COL_CHAT_ID + " ASC, " + TRACK_COL_DATE + " ASC ", null);
long previousTime = 0;
long previousChatId = 0;
int previousUserId = 0;
TrkSegment segment = null;
Track track = null;
GPXFile gpx = new GPXFile();
if (query.moveToFirst()) {
do {
int userId = query.getInt(0);
if (ignoredUsersIds.contains(userId)) {
continue;
}
int chatId = query.getInt(1);
long time = query.getLong(7);
if (previousUserId != userId || previousChatId != chatId) {
gpx = new GPXFile();
gpx.chatId = chatId;
gpx.userId = userId;
previousTime = 0;
track = null;
segment = null;
dataTracks.add(gpx);
}
WptPt pt = new WptPt();
pt.userId = userId;
pt.chatId = chatId;
pt.lat = query.getDouble(2);
pt.lon = query.getDouble(3);
pt.ele = query.getDouble(4);
pt.speed = query.getDouble(5);
pt.hdop = query.getDouble(6);
pt.time = time;
long currentInterval = Math.abs(time - previousTime);
if (track != null) {
if (currentInterval < 30 * 60 * 1000) {
// 30 minute - same segment
segment.points.add(pt);
} else {
segment = new TrkSegment();
segment.points.add(pt);
track.segments.add(segment);
}
} else {
track = new Track();
segment = new TrkSegment();
track.segments.add(segment);
segment.points.add(pt);
gpx.tracks.add(track);
}
previousTime = time;
previousUserId = userId;
previousChatId = chatId;
} while (query.moveToNext());
}
query.close();
}
private static class SaveGPXTrackToFileTask extends AsyncTask<Void, Void, List<String>> {
private TelegramApplication app;
private WeakReference<LiveNowTabFragment> fragmentRef;
private SaveGpxListener listener;
private final GPXFile gpxFile;
private File dir;
private int userId;
LiveUpdatesPurchaseTask(LiveNowTabFragment fragment, GPXFile gpxFile, File dir, int userId) {
SaveGPXTrackToFileTask(TelegramApplication app, SaveGpxListener listener, GPXFile gpxFile, File dir, int userId) {
this.gpxFile = gpxFile;
this.fragmentRef = new WeakReference<>(fragment);
this.app = (TelegramApplication) fragment.getActivity().getApplication();
this.listener = listener;
this.app = app;
this.dir = dir;
this.userId = userId;
}
@ -300,12 +456,21 @@ public class SavingTracksDbHelper extends SQLiteOpenHelper {
@Override
protected void onPostExecute(List<String> warnings) {
if (warnings != null && warnings.isEmpty()) {
LiveNowTabFragment fragment = fragmentRef.get();
if (fragment != null && fragment.isResumed()) {
fragment.shareGpx(gpxFile.path);
if (listener != null) {
if (warnings != null && warnings.isEmpty()) {
listener.onSavingGpxFinish(gpxFile.path);
} else {
listener.onSavingGpxError(warnings);
}
}
}
}
public interface SaveGpxListener {
void onSavingGpxFinish(String path);
void onSavingGpxError(List<String> warnings);
}
}

View file

@ -66,6 +66,8 @@ class TelegramHelper private constructor() {
const val MIN_LOCATION_MESSAGE_LIVE_PERIOD_SEC = 61
const val MAX_LOCATION_MESSAGE_LIVE_PERIOD_SEC = 60 * 60 * 24 - 1 // one day
const val MAX_LOCATION_MESSAGE_HISTORY_SCAN_SEC = 60 * 60 * 24 // one day
const val SEND_NEW_MESSAGE_INTERVAL_SEC = 10 * 60 // 10 minutes
private var helper: TelegramHelper? = null
@ -389,6 +391,15 @@ class TelegramHelper private constructor() {
fun isBot(userId: Int) = users[userId]?.type is TdApi.UserTypeBot
fun getSenderMessageId(message: TdApi.Message): Int {
val forwardInfo = message.forwardInfo
return if (forwardInfo != null && forwardInfo is TdApi.MessageForwardedFromUser) {
forwardInfo.senderUserId
} else {
message.senderUserId
}
}
fun startLiveMessagesUpdates(interval: Long) {
stopLiveMessagesUpdates()
@ -450,7 +461,7 @@ class TelegramHelper private constructor() {
}
}
private fun requestChats(reload: Boolean = false) {
private fun requestChats(reload: Boolean = false, onComplete: (() -> Unit)?) {
synchronized(chatList) {
if (reload) {
chatList.clear()
@ -481,7 +492,8 @@ class TelegramHelper private constructor() {
}
}
// chats had already been received through updates, let's retry request
requestChats()
requestChats(false, this@TelegramHelper::scanChatsHistory)
onComplete?.invoke()
}
else -> listener?.onTelegramError(-1, "Receive wrong response from TDLib: $obj")
}
@ -615,6 +627,49 @@ class TelegramHelper private constructor() {
}
}
fun scanChatsHistory() {
log.debug("scanChatsHistory: chatList: ${chatList.size}")
chatList.forEach {
scanChatHistory(it.chatId, 0, 0, 100)
}
}
private fun scanChatHistory(
chatId: Long,
fromMessageId: Long,
offset: Int,
limit: Int,
onlyLocal: Boolean = false
) {
client?.send(TdApi.GetChatHistory(chatId, fromMessageId, offset, limit, onlyLocal)) { obj ->
when (obj.constructor) {
TdApi.Error.CONSTRUCTOR -> {
val error = obj as TdApi.Error
if (error.code != IGNORED_ERROR_CODE) {
listener?.onTelegramError(error.code, error.message)
}
}
TdApi.Messages.CONSTRUCTOR -> {
val messages = (obj as TdApi.Messages).messages
log.debug("scanChatHistory: chatId: $chatId fromMessageId: $fromMessageId size: ${messages.size}")
if (messages.isNotEmpty()) {
messages.forEach {
addNewMessage(it)
}
val lastMessage = messages.last()
val currentTime = System.currentTimeMillis() / 1000
if (currentTime-Math.max(lastMessage.date, lastMessage.editDate) < MAX_LOCATION_MESSAGE_HISTORY_SCAN_SEC) {
scanChatHistory(chatId, lastMessage.id, 0, 100)
log.debug("scanChatHistory searchMessageId: ${lastMessage.id}")
} else {
log.debug("scanChatHistory finishForChat: $chatId")
}
}
}
}
}
}
private fun requestUser(id: Int) {
client?.send(TdApi.GetUser(id)) { obj ->
when (obj.constructor) {
@ -671,8 +726,9 @@ class TelegramHelper private constructor() {
}
private fun addNewMessage(message: TdApi.Message) {
lastTelegramUpdateTime = Math.max(message.date, message.editDate)
lastTelegramUpdateTime = Math.max(lastTelegramUpdateTime, Math.max(message.date, message.editDate))
if (message.isAppropriate()) {
log.debug("addNewMessage: $message")
val fromBot = isOsmAndBot(message.senderUserId)
val viaBot = isOsmAndBot(message.viaBotUserId)
val oldContent = message.content
@ -691,9 +747,15 @@ class TelegramHelper private constructor() {
}
} else {
removeOldMessages(message, fromBot, viaBot)
usersLocationMessages[message.id] = message
val oldMessage = usersLocationMessages.values.firstOrNull { getSenderMessageId(it) == getSenderMessageId(message) && !fromBot && !viaBot }
val hasNewerMessage = oldMessage != null && (Math.max(message.editDate, message.date) < Math.max(oldMessage.editDate, oldMessage.date))
if (!hasNewerMessage) {
usersLocationMessages[message.id] = message
}
incomingMessagesListeners.forEach {
it.onReceiveChatLocationMessages(message.chatId, message)
if (!hasNewerMessage || it is SavingTracksDbHelper) {
it.onReceiveChatLocationMessages(message.chatId, message)
}
}
}
}
@ -704,7 +766,7 @@ class TelegramHelper private constructor() {
while (iterator.hasNext()) {
val message = iterator.next().value
if (newMessage.chatId == message.chatId) {
val sameSender = newMessage.senderUserId == message.senderUserId
val sameSender = getSenderMessageId(newMessage) == getSenderMessageId(message)
val viaSameBot = newMessage.viaBotUserId == message.viaBotUserId
if (fromBot || viaBot) {
if ((fromBot && sameSender) || (viaBot && viaSameBot)) {
@ -716,7 +778,8 @@ class TelegramHelper private constructor() {
}
}
}
} else if (sameSender && isUserLocationMessage(message) && isUserLocationMessage(newMessage)) {
} else if (sameSender && isUserLocationMessage(message) && isUserLocationMessage(newMessage)
&& Math.max(newMessage.editDate, newMessage.date) > Math.max(message.editDate, message.date)) {
iterator.remove()
}
}
@ -1024,23 +1087,6 @@ class TelegramHelper private constructor() {
return TdApi.InputMessageText(TdApi.FormattedText(textMessage, entities.toTypedArray()), true, true)
}
/**
* @chatId Id of the chat
* @message Text of the message
*/
fun sendTextMessage(chatId: Long, message: String): Boolean {
// initialize reply markup just for testing
//val row = arrayOf(TdApi.InlineKeyboardButton("https://telegram.org?1", TdApi.InlineKeyboardButtonTypeUrl()), TdApi.InlineKeyboardButton("https://telegram.org?2", TdApi.InlineKeyboardButtonTypeUrl()), TdApi.InlineKeyboardButton("https://telegram.org?3", TdApi.InlineKeyboardButtonTypeUrl()))
//val replyMarkup = TdApi.ReplyMarkupInlineKeyboard(arrayOf(row, row, row))
if (haveAuthorization) {
val content = TdApi.InputMessageText(TdApi.FormattedText(message, null), false, true)
client?.send(TdApi.SendMessage(chatId, 0, false, true, null, content), defaultHandler)
return true
}
return false
}
fun logout(): Boolean {
return if (libraryLoaded) {
haveAuthorization = false
@ -1138,7 +1184,7 @@ class TelegramHelper private constructor() {
if (wasAuthorized != haveAuthorization) {
needRefreshActiveLiveLocationMessages = true
if (haveAuthorization) {
requestChats(true)
requestChats(true, null)
requestCurrentUser()
requestContacts()
}
@ -1718,4 +1764,4 @@ class TelegramHelper private constructor() {
}// result is already received through UpdateAuthorizationState, nothing to do
}
}
}
}

View file

@ -8,6 +8,7 @@ import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.helpers.TelegramHelper.MessageOsmAndBotLocation
import net.osmand.telegram.helpers.TelegramHelper.MessageUserTextLocation
import net.osmand.telegram.utils.GPXUtilities
import org.drinkless.td.libcore.telegram.TdApi
object TelegramUiHelper {
@ -129,6 +130,10 @@ object TelegramUiHelper {
}
}
fun gpxToChatItem(helper: TelegramHelper, gpx: GPXUtilities.GPXFile, simpleUserItem: Boolean): GpxChatItem? {
return if (simpleUserItem) gpxToUserGpxChatItem(helper, gpx) else gpxToGpxChatItem(helper, gpx)
}
private fun botMessageToLocationItem(
chat: TdApi.Chat,
content: MessageOsmAndBotLocation
@ -224,6 +229,49 @@ object TelegramUiHelper {
}
}
private fun gpxToGpxChatItem(
helper: TelegramHelper,
gpx: GPXUtilities.GPXFile
): GpxChatItem? {
val user = helper.getUser(gpx.userId) ?: return null
val chat = helper.getChat(gpx.chatId) ?: return null
return GpxChatItem().apply {
chatId = chat.id
chatTitle = chat.title
gpxFile = gpx
name = TelegramUiHelper.getUserName(user)
if (helper.isGroup(chat)) {
photoPath = helper.getUserPhotoPath(user)
groupPhotoPath = chat.photo?.small?.local?.path
} else {
photoPath = user.profilePhoto?.small?.local?.path
}
grayscalePhotoPath = helper.getUserGreyPhotoPath(user)
placeholderId = R.drawable.img_user_picture
userId = user.id
privateChat = helper.isPrivateChat(chat) || helper.isSecretChat(chat)
chatWithBot = helper.isBot(userId)
lastUpdated = (gpx.modifiedTime / 1000).toInt()
}
}
private fun gpxToUserGpxChatItem(
helper: TelegramHelper,
gpx: GPXUtilities.GPXFile
): GpxChatItem? {
val user = helper.getUser(gpx.userId) ?: return null
return GpxChatItem().apply {
gpxFile = gpx
name = TelegramUiHelper.getUserName(user)
photoPath = user.profilePhoto?.small?.local?.path
grayscalePhotoPath = helper.getUserGreyPhotoPath(user)
placeholderId = R.drawable.img_user_picture
userId = user.id
chatWithBot = helper.isBot(userId)
lastUpdated = (gpx.modifiedTime / 1000).toInt()
}
}
abstract class ListItem {
var chatId: Long = 0
@ -272,6 +320,24 @@ object TelegramUiHelper {
override fun getVisibleName() = chatTitle
}
class GpxChatItem : ListItem() {
var gpxFile: GPXUtilities.GPXFile? = null
internal set
var groupPhotoPath: String? = null
internal set
var privateChat: Boolean = false
internal set
var chatWithBot: Boolean = false
internal set
override fun canBeOpenedOnMap() = latLon != null
override fun getMapPointId() = "${chatId}_$userId"
override fun getVisibleName() = chatTitle
}
class LocationItem : ListItem() {
override fun canBeOpenedOnMap() = latLon != null

View file

@ -11,10 +11,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.LinearInterpolator
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.*
import net.osmand.Location
import net.osmand.data.LatLon
import net.osmand.telegram.R
@ -22,6 +19,7 @@ import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.TelegramLocationProvider.TelegramCompassListener
import net.osmand.telegram.TelegramLocationProvider.TelegramLocationListener
import net.osmand.telegram.TelegramSettings
import net.osmand.telegram.helpers.SavingTracksDbHelper
import net.osmand.telegram.helpers.TelegramHelper.*
import net.osmand.telegram.helpers.TelegramUiHelper
import net.osmand.telegram.helpers.TelegramUiHelper.ChatItem
@ -33,7 +31,7 @@ import net.osmand.telegram.utils.OsmandFormatter
import net.osmand.telegram.utils.UiUtils.UpdateLocationViewCache
import net.osmand.util.MapUtils
import org.drinkless.td.libcore.telegram.TdApi
import java.io.File
import java.util.*
private const val CHAT_VIEW_TYPE = 0
private const val LOCATION_ITEM_VIEW_TYPE = 1
@ -233,15 +231,6 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
stopLocationUpdate()
}
fun shareGpx(path: String) {
val fileUri = AndroidUtils.getUriForFile(app, File(path))
val sendIntent = Intent(Intent.ACTION_SEND)
sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri)
sendIntent.type = "application/gpx+xml"
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(sendIntent)
}
private fun chooseOsmAnd() {
val ctx = context ?: return
val installedApps = TelegramSettings.AppConnect.getInstalledApps(ctx)
@ -456,15 +445,6 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
app.showLocationHelper.showLocationOnMap(item, staleLocation)
}
}
openOnMapView?.setOnLongClickListener {
app.savingTracksDbHelper.saveAsyncUserDataToGpx(
this@LiveNowTabFragment,
app.getExternalFilesDir(null),
item.userId,
60 * 60 * 6 * 1000
)
true
}
} else {
openOnMapView?.setOnClickListener(null)
}
@ -485,17 +465,6 @@ class LiveNowTabFragment : Fragment(), TelegramListener, TelegramIncomingMessage
if (lastItem) {
holder.lastTelegramUpdateTime?.visibility = View.VISIBLE
holder.lastTelegramUpdateTime?.text = OsmandFormatter.getListItemLiveTimeDescr(app, telegramHelper.lastTelegramUpdateTime, lastTelegramUpdateStr)
holder.lastTelegramUpdateTime?.setOnClickListener {
val currentUserId = telegramHelper.getCurrentUser()?.id
if (currentUserId != null) {
app.savingTracksDbHelper.saveAsyncUserDataToGpx(
this@LiveNowTabFragment,
app.getExternalFilesDir(null),
currentUserId,
60 * 60 * 6 * 1000
)
}
}
} else {
holder.lastTelegramUpdateTime?.visibility = View.GONE
}

View file

@ -27,6 +27,7 @@ import net.osmand.telegram.ui.MyLocationTabFragment.ActionButtonsListener
import net.osmand.telegram.ui.views.LockableViewPager
import net.osmand.telegram.utils.*
import org.drinkless.td.libcore.telegram.TdApi
import java.io.File
import java.lang.ref.WeakReference
const val OPEN_MY_LOCATION_TAB_KEY = "open_my_location_tab"
@ -35,6 +36,7 @@ private const val PERMISSION_REQUEST_LOCATION = 1
private const val MY_LOCATION_TAB_POS = 0
private const val LIVE_NOW_TAB_POS = 1
private const val TIMELINE_TAB_POS = 2
class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListener, TelegramIncomingMessagesListener {
@ -54,6 +56,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
private var myLocationTabFragment: MyLocationTabFragment? = null
private var liveNowTabFragment: LiveNowTabFragment? = null
private var timelineTabFragment: TimelineTabFragment? = null
private lateinit var buttonsBar: LinearLayout
private lateinit var bottomNav: BottomNavigationView
@ -72,7 +75,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
val viewPager = findViewById<LockableViewPager>(R.id.view_pager).apply {
swipeLocked = true
offscreenPageLimit = 2
offscreenPageLimit = 3
adapter = ViewPagerAdapter(supportFragmentManager)
}
@ -82,11 +85,13 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
when (it.itemId) {
R.id.action_my_location -> pos = MY_LOCATION_TAB_POS
R.id.action_live_now -> pos = LIVE_NOW_TAB_POS
R.id.action_timeline -> pos = TIMELINE_TAB_POS
}
if (pos != -1 && pos != viewPager.currentItem) {
when (pos) {
MY_LOCATION_TAB_POS -> liveNowTabFragment?.tabClosed()
LIVE_NOW_TAB_POS -> liveNowTabFragment?.tabOpened()
TIMELINE_TAB_POS -> liveNowTabFragment?.tabClosed()
}
viewPager.currentItem = pos
return@setOnNavigationItemSelectedListener true
@ -139,10 +144,10 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
if (fragment is TelegramListener) {
listeners.add(WeakReference(fragment))
}
if (fragment is MyLocationTabFragment) {
myLocationTabFragment = fragment
} else if (fragment is LiveNowTabFragment) {
liveNowTabFragment = fragment
when (fragment) {
is MyLocationTabFragment -> myLocationTabFragment = fragment
is LiveNowTabFragment -> liveNowTabFragment = fragment
is TimelineTabFragment -> timelineTabFragment = fragment
}
}
@ -317,6 +322,15 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
android.os.Process.killProcess(android.os.Process.myPid())
}
fun shareGpx(path: String) {
val fileUri = AndroidUtils.getUriForFile(app, File(path))
val sendIntent = Intent(Intent.ACTION_SEND)
sendIntent.putExtra(Intent.EXTRA_STREAM, fileUri)
sendIntent.type = "application/gpx+xml"
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(sendIntent)
}
fun loginTelegram() {
if (telegramHelper.getTelegramAuthorizationState() != TelegramAuthorizationState.CLOSED) {
telegramHelper.logout()
@ -463,7 +477,7 @@ class MainActivity : AppCompatActivity(), TelegramListener, ActionButtonsListene
class ViewPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
private val fragments = listOf<Fragment>(MyLocationTabFragment(), LiveNowTabFragment())
private val fragments = listOf<Fragment>(MyLocationTabFragment(), LiveNowTabFragment(), TimelineTabFragment())
override fun getItem(position: Int) = fragments[position]

View file

@ -599,12 +599,6 @@ class MyLocationTabFragment : Fragment(), TelegramListener {
}
holder.title?.text = title
holder.icon?.setOnClickListener {
app.forceUpdateMyLocation()
val curUser = telegramHelper.getCurrentUser()
val text = "${curUser?.id} ${curUser?.firstName} ${curUser?.lastName}"
Toast.makeText(app, text, Toast.LENGTH_LONG).show()
}
if (holder is ChatViewHolder) {
holder.description?.visibility = View.GONE
if (live) {

View file

@ -0,0 +1,272 @@
package net.osmand.telegram.ui
import android.app.DatePickerDialog
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import android.support.annotation.DrawableRes
import android.support.v4.app.Fragment
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.Switch
import android.widget.TextView
import net.osmand.PlatformUtil
import net.osmand.telegram.R
import net.osmand.telegram.TelegramApplication
import net.osmand.telegram.helpers.TelegramUiHelper
import net.osmand.telegram.helpers.TelegramUiHelper.ListItem
import net.osmand.telegram.ui.TimelineTabFragment.LiveNowListAdapter.BaseViewHolder
import net.osmand.telegram.utils.AndroidUtils
import net.osmand.telegram.utils.GPXUtilities
import net.osmand.telegram.utils.OsmandFormatter
import java.util.*
class TimelineTabFragment : Fragment() {
private val log = PlatformUtil.getLog(TimelineTabFragment::class.java)
private val app: TelegramApplication
get() = activity?.application as TelegramApplication
private val telegramHelper get() = app.telegramHelper
private val settings get() = app.settings
private lateinit var adapter: LiveNowListAdapter
private lateinit var dateStartBtn: TextView
private lateinit var dateEndBtn: TextView
private lateinit var mainView: View
private var start = 0L
private var end = 0L
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
mainView = inflater.inflate(R.layout.fragment_timeline_tab, container, false)
val appBarLayout = mainView.findViewById<View>(R.id.app_bar_layout)
start = System.currentTimeMillis()
end = System.currentTimeMillis()
AndroidUtils.addStatusBarPadding19v(context!!, appBarLayout)
adapter = LiveNowListAdapter()
mainView.findViewById<RecyclerView>(R.id.recycler_view).apply {
layoutManager = LinearLayoutManager(context)
adapter = this@TimelineTabFragment.adapter
}
val switcher = mainView.findViewById<Switch>(R.id.monitoring_switcher)
val monitoringTv = mainView.findViewById<TextView>(R.id.monitoring_title)
monitoringTv.setText(if (settings.monitoringEnabled) R.string.monitoring_is_enabled else R.string.monitoring_is_disabled)
mainView.findViewById<View>(R.id.monitoring_container).setOnClickListener {
val monitoringEnabled = !settings.monitoringEnabled
settings.monitoringEnabled = monitoringEnabled
switcher.isChecked = monitoringEnabled
monitoringTv.setText(if (monitoringEnabled) R.string.monitoring_is_enabled else R.string.monitoring_is_disabled)
}
dateStartBtn = mainView.findViewById<TextView>(R.id.date_start_btn).apply {
setOnClickListener {
selectStartDate()
}
setCompoundDrawablesWithIntrinsicBounds(getPressedStateIcon(R.drawable.ic_action_date_start), null, null, null)
}
dateEndBtn = mainView.findViewById<TextView>(R.id.date_end_btn).apply {
setOnClickListener {
selectEndDate()
}
setCompoundDrawablesWithIntrinsicBounds(getPressedStateIcon(R.drawable.ic_action_date_add), null, null, null)
}
setupBtnTextColor(dateStartBtn)
setupBtnTextColor(dateEndBtn)
return mainView
}
private fun setupBtnTextColor(textView: TextView) {
textView.setTextColor(AndroidUtils.createPressedColorStateList(app, true, R.color.ctrl_active_light, R.color.ctrl_light))
}
private fun selectStartDate() {
val dateFromDialog =
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
val from = Calendar.getInstance()
from.set(Calendar.YEAR, year)
from.set(Calendar.MONTH, monthOfYear)
from.set(Calendar.DAY_OF_MONTH, dayOfMonth)
from.set(Calendar.HOUR_OF_DAY, 0)
from.clear(Calendar.MINUTE)
from.clear(Calendar.SECOND)
from.clear(Calendar.MILLISECOND)
start = from.timeInMillis
updateList()
updateDateButtons()
}
val startCalendar = Calendar.getInstance()
startCalendar.timeInMillis = start
DatePickerDialog(context, dateFromDialog,
startCalendar.get(Calendar.YEAR),
startCalendar.get(Calendar.MONTH),
startCalendar.get(Calendar.DAY_OF_MONTH)
).show()
}
private fun selectEndDate() {
val dateFromDialog =
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
val from = Calendar.getInstance()
from.set(Calendar.YEAR, year)
from.set(Calendar.MONTH, monthOfYear)
from.set(Calendar.DAY_OF_MONTH, dayOfMonth)
from.set(Calendar.HOUR_OF_DAY, 23)
from.set(Calendar.MINUTE, 59)
from.set(Calendar.SECOND, 59)
from.set(Calendar.MILLISECOND, 999)
end = from.timeInMillis
updateList()
updateDateButtons()
}
val endCalendar = Calendar.getInstance()
endCalendar.timeInMillis = end
DatePickerDialog(context, dateFromDialog,
endCalendar.get(Calendar.YEAR),
endCalendar.get(Calendar.MONTH),
endCalendar.get(Calendar.DAY_OF_MONTH)
).show()
}
private fun updateDateButtons() {
dateStartBtn.text = OsmandFormatter.getFormattedDate(start / 1000)
dateEndBtn.text = OsmandFormatter.getFormattedDate(end / 1000)
dateEndBtn.setCompoundDrawablesWithIntrinsicBounds(getPressedStateIcon(R.drawable.ic_action_date_end), null, null, null)
}
private fun getPressedStateIcon(@DrawableRes iconId: Int): Drawable? {
val normal = app.uiUtils.getActiveIcon(iconId)
if (Build.VERSION.SDK_INT >= 21) {
val active = app.uiUtils.getIcon(iconId, R.color.ctrl_light)
if (normal != null && active != null) {
return AndroidUtils.createPressedStateListDrawable(normal, active)
}
}
return normal
}
private fun updateList() {
val res = mutableListOf<ListItem>()
val s = System.currentTimeMillis()
log.debug("updateList $s")
val ignoredUsersIds = ArrayList<Int>()
val currentUserId = telegramHelper.getCurrentUser()?.id
if (currentUserId != null) {
val currentUserGpx:GPXUtilities.GPXFile? = app.savingTracksDbHelper.collectRecordedDataForUser(currentUserId, 0, start, end)
if (currentUserGpx != null) {
TelegramUiHelper.gpxToChatItem(telegramHelper, currentUserGpx, true)?.also {
res.add(it)
}
}
ignoredUsersIds.add(currentUserId)
}
val gpxFiles = app.savingTracksDbHelper.collectRecordedDataForUsers(start, end, ignoredUsersIds)
val e = System.currentTimeMillis()
gpxFiles.forEach {
TelegramUiHelper.gpxToChatItem(telegramHelper, it,false)?.also { chatItem ->
res.add(chatItem)
}
}
adapter.items = sortAdapterItems(res)
log.debug("updateList $s dif: ${e - s}")
}
private fun sortAdapterItems(list: MutableList<ListItem>): MutableList<ListItem> {
val currentUserId = telegramHelper.getCurrentUser()?.id ?: 0
list.sortWith(java.util.Comparator { lhs, rhs ->
when (currentUserId) {
lhs.userId -> return@Comparator 1
rhs.userId -> return@Comparator 1
else -> return@Comparator lhs.name.compareTo(rhs.name)
}
})
return list
}
inner class LiveNowListAdapter : RecyclerView.Adapter<BaseViewHolder>() {
var items: List<ListItem> = emptyList()
set(value) {
field = value
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val inflater = LayoutInflater.from(parent.context)
return BaseViewHolder(inflater.inflate(R.layout.live_now_chat_card, parent, false))
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
val lastItem = position == itemCount - 1
val item = items[position]
val currentUserId = telegramHelper.getCurrentUser()?.id ?: 0
TelegramUiHelper.setupPhoto(app, holder.icon, item.photoPath, R.drawable.img_user_picture_active, false)
holder.title?.text = item.name
holder.bottomShadow?.visibility = if (lastItem) View.VISIBLE else View.GONE
holder.lastTelegramUpdateTime?.visibility = View.GONE
if (item is TelegramUiHelper.GpxChatItem) {
val gpx = item.gpxFile
val groupDescrRowVisible = (!item.privateChat || item.chatWithBot) && item.userId != currentUserId
if (groupDescrRowVisible) {
holder.groupDescrContainer?.visibility = View.VISIBLE
holder.groupTitle?.text = item.getVisibleName()
TelegramUiHelper.setupPhoto(app, holder.groupImage, item.groupPhotoPath, item.placeholderId, false)
} else {
holder.groupDescrContainer?.visibility = View.GONE
}
holder.userRow?.setOnClickListener {
if (gpx != null) {
childFragmentManager.also {
UserGpxInfoFragment.showInstance(it, gpx, start, end)
}
}
}
holder.imageButton?.visibility = View.GONE
holder.showOnMapRow?.visibility = View.GONE
holder.bottomDivider?.visibility = if (lastItem) View.GONE else View.VISIBLE
holder.topDivider?.visibility = if (position != 0) View.GONE else View.VISIBLE
}
}
override fun getItemCount() = items.size
inner class BaseViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val icon: ImageView? = view.findViewById(R.id.icon)
val title: TextView? = view.findViewById(R.id.title)
val description: TextView? = view.findViewById(R.id.description)
val bottomShadow: View? = view.findViewById(R.id.bottom_shadow)
val lastTelegramUpdateTime: TextView? = view.findViewById(R.id.last_telegram_update_time)
val userRow: View? = view.findViewById(R.id.user_row)
val groupDescrContainer: View? = view.findViewById(R.id.group_container)
val groupImage: ImageView? = view.findViewById(R.id.group_icon)
val groupTitle: TextView? = view.findViewById(R.id.group_title)
val imageButton: ImageView? = view.findViewById(R.id.image_button)
val showOnMapRow: View? = view.findViewById(R.id.show_on_map_row)
val topDivider: View? = view.findViewById(R.id.top_divider)
val bottomDivider: View? = view.findViewById(R.id.bottom_divider)
}
}
}

View file

@ -0,0 +1,321 @@
package net.osmand.telegram.ui
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.support.v4.app.FragmentManager
import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.widget.Toast
import net.osmand.PlatformUtil
import net.osmand.aidl.gpx.AGpxBitmap
import net.osmand.telegram.R
import net.osmand.telegram.helpers.OsmandAidlHelper
import net.osmand.telegram.helpers.SavingTracksDbHelper
import net.osmand.telegram.helpers.TelegramUiHelper
import net.osmand.telegram.utils.AndroidUtils
import net.osmand.telegram.utils.GPXUtilities
import net.osmand.telegram.utils.OsmandFormatter
import net.osmand.util.Algorithms
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
class UserGpxInfoFragment : BaseDialogFragment() {
private val log = PlatformUtil.getLog(UserGpxInfoFragment::class.java)
private val uiUtils get() = app.uiUtils
private lateinit var gpxFile: GPXUtilities.GPXFile
private lateinit var dateStartBtn: TextView
private lateinit var timeStartBtn: TextView
private lateinit var dateEndBtn: TextView
private lateinit var timeEndBtn: TextView
private lateinit var avgElevationTv: TextView
private lateinit var avgSpeedTv: TextView
private lateinit var totalDistanceTv: TextView
private lateinit var timeSpanTv: TextView
private var startCalendar = Calendar.getInstance()
private var endCalendar = Calendar.getInstance()
override fun onCreateView(
inflater: LayoutInflater,
parent: ViewGroup?,
savedInstanceState: Bundle?
): View {
val mainView = inflater.inflate(R.layout.fragment_user_gpx_info, parent)
AndroidUtils.addStatusBarPadding19v(context!!, mainView)
readFromBundle(savedInstanceState ?: arguments)
val userId = gpxFile.userId
val chatId = gpxFile.chatId
val user = app.telegramHelper.getUser(userId)
if (user != null) {
mainView.findViewById<TextView>(R.id.title).text = TelegramUiHelper.getUserName(user)
TelegramUiHelper.setupPhoto(app, mainView.findViewById<ImageView>(R.id.user_icon),
telegramHelper.getUserPhotoPath(user), R.drawable.img_user_placeholder, false)
}
app.osmandAidlHelper.setGpxBitmapCreatedListener(
object : OsmandAidlHelper.GpxBitmapCreatedListener {
override fun onGpxBitmapCreated(bitmap: AGpxBitmap) {
activity?.runOnUiThread {
mainView.findViewById<ImageView>(R.id.gpx_map).setImageDrawable(BitmapDrawable(app.resources, bitmap.bitmap))
}
}
})
updateGPXMap()
val backBtn = mainView.findViewById<ImageView>(R.id.back_button)
backBtn.setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_arrow_back))
backBtn.setOnClickListener {
dismiss()
}
dateStartBtn = mainView.findViewById<TextView>(R.id.date_start_btn)
timeStartBtn = mainView.findViewById<TextView>(R.id.time_start_btn)
dateEndBtn = mainView.findViewById<TextView>(R.id.date_end_btn)
timeEndBtn = mainView.findViewById<TextView>(R.id.time_end_btn)
dateStartBtn.setOnClickListener { selectStartDate() }
timeStartBtn.setOnClickListener { selectStartTime() }
dateEndBtn.setOnClickListener { selectEndDate() }
timeEndBtn.setOnClickListener { selectEndTime() }
setupBtnTextColor(dateStartBtn)
setupBtnTextColor(timeStartBtn)
setupBtnTextColor(dateEndBtn)
setupBtnTextColor(timeEndBtn)
updateDateAndTimeButtons()
avgElevationTv = mainView.findViewById<TextView>(R.id.average_altitude_text)
avgSpeedTv = mainView.findViewById<TextView>(R.id.average_speed_text)
totalDistanceTv = mainView.findViewById<TextView>(R.id.distance_text)
timeSpanTv = mainView.findViewById<TextView>(R.id.duration_text)
mainView.findViewById<ImageView>(R.id.average_altitude_icon).apply {
setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_altitude_range))
}
mainView.findViewById<ImageView>(R.id.average_speed_icon).apply {
setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_speed_average))
}
mainView.findViewById<ImageView>(R.id.distance_icon).apply {
setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_altitude_range))
}
mainView.findViewById<ImageView>(R.id.duration_icon).apply {
setImageDrawable(uiUtils.getThemedIcon(R.drawable.ic_action_altitude_range))
}
updateGPXStatisticRow()
mainView.findViewById<ImageView>(R.id.open_in_osmand_icon).setImageResource(R.drawable.ic_logo_osmand_free)
mainView.findViewById<LinearLayout>(R.id.open_in_osmand_btn).apply {
setOnClickListener {
val gpx = gpxFile
if (gpx.path.isNotEmpty()) {
openGpx(gpx.path)
} else {
saveCurrentGpxToFile(object :
SavingTracksDbHelper.SaveGpxListener {
override fun onSavingGpxFinish(path: String) {
openGpx(path)
}
override fun onSavingGpxError(warnings: MutableList<String>?) {
Toast.makeText(app, warnings?.firstOrNull(), Toast.LENGTH_LONG).show()
}
})
}
}
}
mainView.findViewById<ImageView>(R.id.share_gpx_icon).setImageDrawable(uiUtils.getActiveIcon(R.drawable.ic_action_share))
mainView.findViewById<LinearLayout>(R.id.share_gpx_btn).apply {
setOnClickListener {
val gpx = gpxFile
if (gpx.path.isNotEmpty()) {
(activity as MainActivity).shareGpx(gpx.path)
} else {
saveCurrentGpxToFile(object :
SavingTracksDbHelper.SaveGpxListener {
override fun onSavingGpxFinish(path: String) {
(activity as MainActivity).shareGpx(path)
}
override fun onSavingGpxError(warnings: MutableList<String>?) {
Toast.makeText(app, warnings?.firstOrNull(), Toast.LENGTH_LONG).show()
}
})
}
}
}
return mainView
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putLong(START_KEY, startCalendar.timeInMillis)
outState.putLong(END_KEY, endCalendar.timeInMillis)
}
private fun openGpx(path: String) {
val fileUri = AndroidUtils.getUriForFile(app, File(path))
val openGpxIntent = Intent(Intent.ACTION_VIEW)
openGpxIntent.setDataAndType(fileUri, "application/gpx+xml")
openGpxIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
val resolved = activity?.packageManager?.resolveActivity(openGpxIntent, PackageManager.MATCH_DEFAULT_ONLY)
if (resolved != null) {
startActivity(openGpxIntent)
}
}
private fun saveCurrentGpxToFile(listener: SavingTracksDbHelper.SaveGpxListener) {
app.savingTracksDbHelper.saveGpx(listener, app.getExternalFilesDir(null), gpxFile)
}
private fun readFromBundle(bundle: Bundle?) {
bundle?.also {
startCalendar.timeInMillis = it.getLong(START_KEY)
endCalendar.timeInMillis = it.getLong(END_KEY)
}
}
private fun setupBtnTextColor(textView: TextView) {
textView.setTextColor(AndroidUtils.createPressedColorStateList(app, true, R.color.ctrl_active_light, R.color.ctrl_light))
}
private fun updateGpxInfo() {
gpxFile = app.savingTracksDbHelper.collectRecordedDataForUser(gpxFile.userId, gpxFile.chatId, startCalendar.timeInMillis, endCalendar.timeInMillis)
updateGPXStatisticRow()
updateDateAndTimeButtons()
updateGPXMap()
}
private fun updateDateAndTimeButtons() {
dateStartBtn.text = SimpleDateFormat("dd MMM", Locale.getDefault()).format(startCalendar.timeInMillis)
dateEndBtn.text = SimpleDateFormat("dd MMM", Locale.getDefault()).format(endCalendar.timeInMillis)
timeStartBtn.text = SimpleDateFormat("HH:mm", Locale.getDefault()).format(startCalendar.timeInMillis)
timeEndBtn.text = SimpleDateFormat("HH:mm", Locale.getDefault()).format(endCalendar.timeInMillis)
}
private fun updateGPXStatisticRow() {
val analysis: GPXUtilities.GPXTrackAnalysis = gpxFile.getAnalysis(0)
avgElevationTv.text = OsmandFormatter.getFormattedAlt(analysis.avgElevation, app)
avgSpeedTv.text = if (analysis.isSpeedSpecified) OsmandFormatter.getFormattedSpeed(analysis.avgSpeed, app) else ""
totalDistanceTv.text = OsmandFormatter.getFormattedDistance(analysis.totalDistance, app)
timeSpanTv.text = Algorithms.formatDuration((analysis.timeSpan / 1000).toInt(), true)
}
private fun updateGPXMap() {
saveCurrentGpxToFile(object :
SavingTracksDbHelper.SaveGpxListener {
override fun onSavingGpxFinish(path: String) {
val mgr = activity?.getSystemService(Context.WINDOW_SERVICE)
if (mgr != null) {
val dm = DisplayMetrics()
(mgr as WindowManager).defaultDisplay.getMetrics(dm)
val widthPixels = dm.widthPixels - (2 * app.resources.getDimensionPixelSize(R.dimen.content_padding_standard))
val heightPixels = AndroidUtils.dpToPx(app, 152f)
val gpxUri = AndroidUtils.getUriForFile(app, File(path))
app.osmandAidlHelper.getBitmapForGpx(gpxUri, dm.density , widthPixels, heightPixels, GPX_TRACK_COLOR)
}
}
override fun onSavingGpxError(warnings: MutableList<String>?) {
log.debug("onSavingGpxError ${warnings?.firstOrNull()}")
}
})
}
private fun selectStartDate() {
val dateFromDialog =
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
startCalendar.set(Calendar.YEAR, year)
startCalendar.set(Calendar.MONTH, monthOfYear)
startCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
updateGpxInfo()
}
DatePickerDialog(context, dateFromDialog,
startCalendar.get(Calendar.YEAR),
startCalendar.get(Calendar.MONTH),
startCalendar.get(Calendar.DAY_OF_MONTH)).show()
}
private fun selectStartTime() {
TimePickerDialog(context,
TimePickerDialog.OnTimeSetListener { _, hours, minutes ->
startCalendar.set(Calendar.HOUR_OF_DAY, hours)
startCalendar.set(Calendar.MINUTE, minutes)
updateGpxInfo()
}, 0, 0, true).show()
}
private fun selectEndDate() {
val dateFromDialog =
DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
endCalendar.set(Calendar.YEAR, year)
endCalendar.set(Calendar.MONTH, monthOfYear)
endCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth)
updateGpxInfo()
}
DatePickerDialog(context, dateFromDialog,
endCalendar.get(Calendar.YEAR),
endCalendar.get(Calendar.MONTH),
endCalendar.get(Calendar.DAY_OF_MONTH)).show()
}
private fun selectEndTime() {
TimePickerDialog(context,
TimePickerDialog.OnTimeSetListener { _, hours, minutes ->
endCalendar.set(Calendar.HOUR_OF_DAY, hours)
endCalendar.set(Calendar.MINUTE, minutes)
updateGpxInfo()
}, 0, 0, true).show()
}
companion object {
private const val TAG = "UserGpxInfoFragment"
private const val START_KEY = "start_key"
private const val END_KEY = "end_key"
private const val GPX_TRACK_COLOR = -65536
fun showInstance(fm: FragmentManager, gpxFile: GPXUtilities.GPXFile, start: Long, end: Long): Boolean {
return try {
val fragment = UserGpxInfoFragment().apply {
arguments = Bundle().apply {
putLong(START_KEY, start)
putLong(END_KEY, end)
}
}
fragment.gpxFile = gpxFile
fragment.show(fm, TAG)
true
} catch (e: RuntimeException) {
false
}
}
}
}

View file

@ -10,6 +10,7 @@ import android.text.TextUtils;
import net.osmand.Location;
import net.osmand.PlatformUtil;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
import net.osmand.telegram.TelegramApplication;
import net.osmand.util.Algorithms;
@ -49,7 +50,7 @@ import java.util.Set;
import java.util.Stack;
import java.util.TimeZone;
// copy from net.osmand.plus.GPXUtilities and changes done to WptPt (userId,chatId)
// copy from net.osmand.plus.GPXUtilities and changes done to WptPt and GPXFile (userId,chatId)
public class GPXUtilities {
public final static Log log = PlatformUtil.getLog(GPXUtilities.class);
@ -815,6 +816,8 @@ public class GPXUtilities {
public String path = "";
public boolean showCurrentTrack;
public long modifiedTime = 0;
public int userId;
public long chatId;
private Track generalTrack;
private TrkSegment generalSegment;
@ -1248,6 +1251,57 @@ public class GPXUtilities {
}
return categories;
}
public QuadRect getRect() {
double left = 0, right = 0;
double top = 0, bottom = 0;
for (Track track : tracks) {
for (TrkSegment segment : track.segments) {
for (WptPt p : segment.points) {
if (left == 0 && right == 0) {
left = p.getLongitude();
right = p.getLongitude();
top = p.getLatitude();
bottom = p.getLatitude();
} else {
left = Math.min(left, p.getLongitude());
right = Math.max(right, p.getLongitude());
top = Math.max(top, p.getLatitude());
bottom = Math.min(bottom, p.getLatitude());
}
}
}
}
for (WptPt p : points) {
if (left == 0 && right == 0) {
left = p.getLongitude();
right = p.getLongitude();
top = p.getLatitude();
bottom = p.getLatitude();
} else {
left = Math.min(left, p.getLongitude());
right = Math.max(right, p.getLongitude());
top = Math.max(top, p.getLatitude());
bottom = Math.min(bottom, p.getLatitude());
}
}
for (GPXUtilities.Route route : routes) {
for (WptPt p : route.points) {
if (left == 0 && right == 0) {
left = p.getLongitude();
right = p.getLongitude();
top = p.getLatitude();
bottom = p.getLatitude();
} else {
left = Math.min(left, p.getLongitude());
right = Math.max(right, p.getLongitude());
top = Math.max(top, p.getLatitude());
bottom = Math.min(bottom, p.getLatitude());
}
}
}
return new QuadRect(left, top, right, bottom);
}
}
public static String asString(GPXFile file, TelegramApplication ctx) {

View file

@ -23,6 +23,7 @@ object OsmandFormatter {
private const val SHORT_TIME_FORMAT = "%02d:%02d"
private const val SIMPLE_TIME_OF_DAY_FORMAT = "HH:mm"
private const val SIMPLE_DATE_FORMAT = "dd MMM HH:mm:ss"
private const val SHORT_DATE_FORMAT = "dd MMM yyyy"
private const val MIN_DURATION_FOR_DATE_FORMAT = 48 * 60 * 60
@ -77,8 +78,13 @@ object OsmandFormatter {
}
}
fun getFormattedDate(seconds: Long): String =
SimpleDateFormat(SIMPLE_DATE_FORMAT, Locale.getDefault()).format(seconds * 1000L)
fun getFormattedDate(seconds: Long, shortFormat: Boolean = false): String {
return if (shortFormat) {
SimpleDateFormat(SIMPLE_DATE_FORMAT, Locale.getDefault()).format(seconds * 1000L)
} else {
SimpleDateFormat(SHORT_DATE_FORMAT, Locale.getDefault()).format(seconds * 1000L)
}
}
fun getListItemLiveTimeDescr(ctx: TelegramApplication, lastUpdated: Int, prefix: String = ""): String {
return if (lastUpdated > 0) {

View file

@ -163,24 +163,12 @@
<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=".*\\.kml" />
<data android:pathPattern=".*\\..*\\.kml" />
<data android:pathPattern=".*\\..*\\..*\\.kml" />
<data android:pathPattern=".*\\..*\\..*\\..*\\.kml" />
<data android:pathPattern=".*\\..*\\..*\\..*\\..*\\.kml" />
</intent-filter>
<intent-filter
android:label="@string/app_name"
android:priority="50">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="file"/>
<data android:scheme="data"/>
<data android:host="*"/>
<data android:mimeType="*/*"/>
<data android:pathPattern="*.kml"/>
<data android:pathPattern=".*\\.kml" />
<data android:pathPattern=".*\\..*\\.kml" />
<data android:pathPattern=".*\\..*\\..*\\.kml" />
@ -194,8 +182,11 @@
<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:scheme="data"/>
<data android:host="*"/>
<data android:mimeType="*/*"/>
<data android:pathPattern=".*\\.kmz" />
<data android:pathPattern=".*\\..*\\.kmz" />
<data android:pathPattern=".*\\..*\\..*\\.kmz" />
@ -271,9 +262,12 @@
<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:scheme="data"/>
<data android:host="*"/>
<data android:mimeType="*/*"/>
<data android:pathPattern="*.sqlitedb" />
<data android:pathPattern=".*\\.sqlitedb" />
<data android:pathPattern=".*\\..*\\.sqlitedb" />
<data android:pathPattern=".*\\..*\\..*\\.sqlitedb" />

View file

@ -21,6 +21,7 @@
<asset source="voice/fa/fa_tts.js" destination="voice/fa-tts/fa_tts.js" mode="overwriteOnlyIfExists" />
<asset source="voice/fi/fi_tts.js" destination="voice/fi-tts/fi_tts.js" mode="overwriteOnlyIfExists" />
<asset source="voice/fr/fr_tts.js" destination="voice/fr-tts/fr_tts.js" mode="alwaysOverwriteOrCopy" />
<asset source="voice/gn-py/gn-py_tts.js" destination="voice/gn-py-tts/gn-py_tts.js" mode="overwriteOnlyIfExists" />
<!--<asset source="voice/he/he_tts.js" destination="voice/he-tts/he_tts.js" mode="overwriteOnlyIfExists" />-->
<asset source="voice/nb/nb_tts.js" destination="voice/nb-tts/nb_tts.js" mode="overwriteOnlyIfExists" />
<asset source="voice/hi/hi_tts.js" destination="voice/hi-tts/hi_tts.js" mode="overwriteOnlyIfExists" />

View file

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_card"
android:layout_marginTop="@dimen/dash_margin"
android:layout_marginBottom="@dimen/dash_margin"
android:layout_marginLeft="@dimen/dash_margin_h"
android:layout_marginRight="@dimen/dash_margin_h"
android:orientation="vertical">
<TextView
android:id="@+id/run_full_osmand_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dashSearchPaddingTop"
android:layout_marginBottom="@dimen/dashSearchPaddingBot"
android:layout_marginRight="@dimen/subHeaderMarginRight"
android:layout_marginStart="@dimen/subHeaderMarginLeft"
android:layout_marginLeft="@dimen/subHeaderMarginLeft"
android:layout_marginEnd="@dimen/subHeaderMarginRight"
android:layout_gravity="center_horizontal"
android:text="@string/run_full_osmand_header"
android:textColor="?android:textColorPrimary"
/>
<TextView
android:id="@+id/run_full_osmand_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/subHeaderPadding"
android:layout_marginBottom="@dimen/dashSearchPaddingBot"
android:layout_marginRight="@dimen/subHeaderMarginRight"
android:layout_marginStart="@dimen/subHeaderMarginLeft"
android:layout_marginLeft="@dimen/subHeaderMarginLeft"
android:layout_marginEnd="@dimen/subHeaderMarginRight"
android:layout_weight="1"
tools:text="@string/lorem_ipsum"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="@dimen/list_header_height"
android:orientation="horizontal">
<Button
android:id="@+id/cancel_full_osmand_btn"
style="@style/DashboardGeneralButton"
android:layout_width="0dp"
android:gravity="center"
android:layout_weight="1"
android:text="@string/shared_string_cancel"/>
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="?attr/dashboard_divider"/>
<Button
android:id="@+id/launch_full_osmand_btn"
style="@style/DashboardGeneralButton"
android:layout_width="0dp"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/shared_string_launch"/>
</LinearLayout>
</LinearLayout>

View file

@ -1,10 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/mapBackground">
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/mapBackground"
android:layout_gravity="start">
<FrameLayout
android:layout_width="match_parent"
@ -103,10 +105,10 @@
android:id="@+id/menuItems"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="?attr/bg_color"
android:clipToPadding="false"
android:drawSelectorOnTop="true" />
android:drawSelectorOnTop="true"
android:layout_gravity="start"/>
<RelativeLayout
android:id="@+id/drawer_footer_layout"
@ -114,6 +116,7 @@
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:layout_alignParentBottom="true"
android:layout_gravity="start"
android:visibility="gone">
<include layout="@layout/powered_by_osmand_item"/>

View file

@ -12,10 +12,13 @@
android:layout_gravity="center_vertical"
android:drawablePadding="24dp"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingLeft="16dp"
android:paddingRight = "16dp"
android:textAppearance="@style/TextAppearance.ListItemTitle"
android:textStyle="normal"
tools:drawableLeft="@drawable/ic_action_search_dark"
tools:drawableStart="@drawable/ic_action_search_dark"
tools:text="@string/layer_poi"/>
</LinearLayout>

View file

@ -3948,4 +3948,13 @@
<string name="poi_substation_field_gathering">Збіральная</string>
<string name="poi_craft_confectionery">Кандытарская вытворчасць</string>
<string name="poi_shop_wholesale">Аптовы склад</string>
<string name="poi_books_type">Кнігі</string>
<string name="poi_laboratory">Медыцынская лабараторыя</string>
<string name="poi_blood_donation">Здача крыві</string>
<string name="poi_books_comic">Коміксы</string>
<string name="poi_books_antiquarian">Антыкварыят</string>
<string name="poi_books_religion">Рэлігіёзныя</string>
<string name="poi_books_academic">Акадэмічныя</string>
<string name="poi_books_children">Дзіцячыя</string>
<string name="poi_atoll">Атол</string>
</resources>

View file

@ -1,4 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" encoding="utf-8"?>
<resources><string name="auto_zoom_none">Без аўтаматычнага маштабавання</string>
<string name="auto_zoom_close">Буйней</string>
<string name="auto_zoom_far">Для сярэдняга маштабу</string>
@ -68,7 +68,7 @@
<string name="intermediate_items_sort_by_distance">Упарадкаваць ад дзвярэй да дзвярэй</string>
<string name="local_osm_changes_backup_successful">Файл OSM-змен створаны ў %1$s</string>
<string name="local_osm_changes_backup_failed">Не атрымалася зарэзерваваць OSM-змены</string>
<string name="local_osm_changes_backup">Рэзервовае капіраванне файлу змен OSM</string>
<string name="local_osm_changes_backup">Рэзервовае капіяванне файлу змен OSM</string>
<string name="delete_point">Выдаліць пункт</string>
<string name="plugin_distance_point_time">час</string>
<string name="plugin_distance_point_hdop">дакладнасць</string>
@ -146,7 +146,7 @@
<string name="recording_photo_description">Фота %1$s %2$s</string>
<string name="av_def_action_picture">Сфатаграфаваць</string>
<string name="recording_context_menu_precord">Сфатаграфаваць</string>
<string name="dropbox_plugin_description">Убудова Dropbox дазваляе вам сінхранізаваць сляды і аўдыё/відэа натакi з вашым рахункам Dropbox.</string>
<string name="dropbox_plugin_description">Убудова Dropbox дазваляе вам сінхранізаваць сляды і аўдыё/відэа натакi з вашым акаўнтам Dropbox.</string>
<string name="dropbox_plugin_name">Убудова Dropbox</string>
<string name="intermediate_points_change_order">Змяніць парадак</string>
@ -454,7 +454,7 @@
\n
\nЛюбая з гэтых мапаў можа быць выкарыстана ў якасці асноўнай (базавай) мапы для адлюстравання на экране OsmAnd або ў выглядзе накладкі / падкладкі да іншай базавай мапы (стандартнай аўтаномнай мапы OsmAnd). Для таго каб зрабіць любую падкладку больш бачнай, некаторыя элементы вектарнай мапы OsmAnd могуць быць па жаданні лёгка схаваныя праз меню «Налады мапы».
\n
\nТайлавыя мапы могуць быць атрыманыя непасрэдна з дапамогай сеціўных крыніц або могуць быць падрыхтаваныя для выкарыстання ў аўтаномным рэжыме (і ўласнаручна скапіраваныя ў каталог даных OsmAnd) як база даных SQLite, якую можна атрымаць з дапамогай розных інструментаў падрыхтоўкі мапаў іншых вытворцаў.</string>
\nТайлавыя мапы могуць быць атрыманыя непасрэдна з дапамогай сеціўных крыніц або могуць быць падрыхтаваныя для выкарыстання ў аўтаномным рэжыме (і ўласнаручна скапіяваныя ў каталог даных OsmAnd) як база даных SQLite, якую можна атрымаць з дапамогай розных інструментаў падрыхтоўкі мапаў іншых вытворцаў.</string>
<string name="osmand_accessibility_description">Убудова дадае падтрымку дадатковых магчымасцяў непасрэдна ў OsmAnd. Гэта палягчае, напрыклад, рэгуляванне хуткасці вымаўлення для голасу TTS, наладу накіраванасці экрана навігацыі, кіраванне маштабам пры дапамозе трэкбола або выкарыстанне галасавых загадаў зваротнай сувязі для аўтаматычнага агалошвання вашага месцазнаходжання.</string>
@ -466,7 +466,7 @@
<string name="prefs_plugins_descr">Убудовы актывуюць дадатковыя налады і магчымасці.</string>
<string name="prefs_plugins">Убудовы</string>
<string name="osm_editing_plugin_description">З дапамогай гэтай убудовы OsmAnd можа быць выкарыстаны для паляпшэння OSM праз стварэнне альбо змену аб\'ектаў OSM POI, адкрыццё або каментаванне OSM-нататак, адпраўленне запісаных GPX-файлаў. OSM развіваецца грамадствам. Гэта глабальны праект па стварэнні свабоднай мапы. Для атрымання дадатковай інфармацыі, калі ласка, наведайце https://openstreetmap.org. Актыўны ўдзел цэніцца, і ўнёскі могуць быць зробленыя непасрэдна праз OsmAnd, калі вы ўкажаце даныя свайго рахунка OSM у наладах.</string>
<string name="osm_editing_plugin_description">З дапамогай гэтай убудовы OsmAnd можа быць выкарыстаны для паляпшэння OSM праз стварэнне альбо змену аб\'ектаў OSM POI, адкрыццё або каментаванне OSM-нататак, адпраўленне запісаных GPX-файлаў. OSM развіваецца грамадствам. Гэта глабальны праект па стварэнні свабоднай мапы. Для атрымання дадатковай інфармацыі, калі ласка, наведайце https://openstreetmap.org. Актыўны ўдзел цэніцца, і ўнёскі могуць быць зробленыя непасрэдна праз OsmAnd, калі вы ўкажаце даныя свайго акаўнта OSM у наладах.</string>
<string name="vector_maps_may_display_faster_on_some_devices">Вектарныя мапы могуць адлюстроўвацца хутчэй. Падтрымліваецца не ўсімі прыладамі.</string>
<string name="play_commands_of_currently_selected_voice">Абраць голас і прайграць падказкі</string>
<string name="debugging_and_development">Для распрацоўшчыкаў OsmAnd</string>
@ -1287,7 +1287,7 @@
<string name="local_osm_changes_delete_all_confirm">Вы збіраецеся выдаліць %1$d змены OSM. Вы ўпэўненыя\?</string>
<string name="animate_routing_route_not_calculated">Калі ласка, спачатку разлічыце маршрут</string>
<string name="android_19_location_disabled">З версіі 4.4 Android (KitKat) вы не можаце спампоўваць і абнаўляць мапу ў старым каталогу захоўвання (%s). Скапіраваць усе файлы OsmAnd у новае сховішча\?
<string name="android_19_location_disabled">З версіі 4.4 Android (KitKat) вы не можаце спампоўваць і абнаўляць мапу ў старым каталогу захоўвання (%s). Скапіяваць усе файлы OsmAnd у новае сховішча\?
\n Заўвага 1: Вашы старыя файлы застануцца некранутымі (вы можаце выдаліць іх самастойна).         
\n Заўвага 2: У новым месцы захоўвання будзе немагчыма адначасова выкарыстоўваць файлы ў OsmAnd і OsmAnd+.</string>
@ -1841,7 +1841,7 @@
<string name="rendering_value__name">Прадвызначана</string>
<string name="rendering_value_highContrastRoads_name">Высокая кантрастнасць дарог</string>
<string name="specified_directiory_not_writeable">Немагчыма стварыць мапы ў вызначаным каталозе</string>
<string name="copying_osmand_file_failed">Скапіраваць файлы не атрымалася</string>
<string name="copying_osmand_file_failed">Скапіяваць файлы не атрымалася</string>
<string name="storage_directory_internal_app">Унутраная памяць дадатка</string>
<string name="storage_directory_manual">Вызначана ўласнаручна</string>
<string name="storage_directory_default">Унутраная памяць</string>
@ -1849,7 +1849,7 @@
<string name="storage_directory_external">Вонкавы носьбіт інфармацыі</string>
<string name="storage_directory">Захоўванне мапы</string>
<string name="storage_directory_multiuser">Агульнае сховішча</string>
<string name="application_dir_change_warning3">Скапіраваць файлы даных OsmAnd у новае месца\?</string>
<string name="application_dir_change_warning3">Скапіяваць файлы даных OsmAnd у новае месца\?</string>
<string name="rendering_attr_hideHouseNumbers_name">Нумары дамоў</string>
<string name="routing_attr_avoid_borders_description">Пазбягаць перасячэння нацыянальных межаў</string>
@ -2083,7 +2083,7 @@
<string name="save_poi_without_poi_type_message">Вы сапраўды хочаце захаваць POI без тыпу?</string>
<string name="share_osm_edits_subject">Праўкі OSM, апублікаваныя праз OsmAnd</string>
<string name="shared_string_location">Месцазнаходжанне</string>
<string name="copied_to_clipboard">Скапіравана ў буфер абмену</string>
<string name="copied_to_clipboard">Скапіявана ў буфер абмену</string>
<string name="osm_save_offline">Захаваць лакальна</string>
<string name="osm_edit_modified_poi">OSM POI адрэдагаваная</string>
<string name="osm_edit_deleted_poi">OSM POI выдаленая</string>
@ -2992,7 +2992,7 @@
<string name="touring_view_renderer">Турыстычны выгляд</string>
<string name="nautical_renderer">Марскі</string>
<string name="will_open_tomorrow_at">Адчыніцца заўтра а</string>
<string name="copy_location_name">Скапіраваць назву пункта/POI</string>
<string name="copy_location_name">Скапіяваць назву пункта/POI</string>
<string name="toast_empty_name_error">Месца без назвы</string>
<string name="shared_string_current">Цяперашні</string>
<string name="last_intermediate_dest_description">Дадае прамежкавы прыпынак</string>
@ -3168,7 +3168,7 @@
\n
\n • Пазнакі мапы: выпраўленне ўключэння/выключэння групаў, магчымасць хаваць адмеціны на мапе
\n
\n • Рэдагаванне OSM: магчымасць рэдагавання пазнак для некропкавых аб\'ектаў і шляхоў, выпраўленне адсутных каментароў на нататках, рэзервовае капіраванне правак
\n • Рэдагаванне OSM: магчымасць рэдагавання пазнак для некропкавых аб\'ектаў і шляхоў, выпраўленне адсутных каментароў на нататках, рэзервовае капіяванне правак
\n
\n • Паляпшэнне разбору Wikipedia і Wikivoyage, абноўленыя файлы ўжо даступныя
\n
@ -3222,4 +3222,4 @@
<string name="powered_by_osmand">Працуе на OsmAnd</string>
<string name="mapillary_menu_title_pano">Паказаць толькі 360° малюнкі</string>
<string name="osm_live_subscriptions">Падпіскі</string>
</resources>
</resources>

View file

@ -3053,4 +3053,7 @@ Abasta l\'àrea: %1$s x %2$s</string>
<string name="powered_by_osmand">Recolzat en OsmAnd</string>
<string name="osm_live_subscriptions">Subscripcions</string>
<string name="mapillary_menu_title_pano">Només mostra imatges de 360º</string>
</resources>
<string name="shared_string_launch">Arrenca</string>
<string name="run_full_osmand_msg">"Esteu utilitzant el mapa {0} mitjançant OsmAnd. Voleu iniciar la versió sencera d\'OsmAnd \?"</string>
<string name="run_full_osmand_header">Voleu iniciar OsmAnd\?</string>
</resources>

View file

@ -2990,4 +2990,9 @@ Zobrazená oblast: %1$s x %2$s</string>
<string name="osm_live_payment_header">Vyberte si frekvenci plateb, která vám vyhovuje:</string>
<string name="osm_live_payment_contribute_descr">Část příjmů je posílána přispěvatelům OpenStreetMap.</string>
<string name="powered_by_osmand">Běží na OsmAnd</string>
</resources>
<string name="osm_live_subscriptions">Předplatné</string>
<string name="mapillary_menu_title_pano">Zobrazit pouze 360° obrázky</string>
<string name="shared_string_launch">Spustit</string>
<string name="run_full_osmand_msg">Používáte mapu {0}, která běží na aplikaci OsmAnd. Chcete spustit plnou verzi OsmAnd\?</string>
<string name="run_full_osmand_header">Spustit OsmAnd\?</string>
</resources>

View file

@ -1,4 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="srtm_paid_version_msg">Overvej at betale for \'Højdekurve\' udvidelsen for at støtte videre udvikling.</string>
<string name="av_def_action_video">Optag video</string>
@ -3211,7 +3211,7 @@ Repræsenterer område: %1$s x %2$s</string>
\n</string>
<string name="ask_for_location_permission">Giv OsmAnd tilladelse til placering for at fortsætte.</string>
<string name="rendering_value_black_name">Sort</string>
<string name="more_transport_on_stop_hint">Der er andre transportmidler ved dette stop.</string>
<string name="more_transport_on_stop_hint">Der er flere transportmidler ved dette stop.</string>
<string name="markers_remove_dialog_msg">Slet kortmarkør \'%s\'\?</string>
<string name="edit_map_marker">Rediger kortmarkør</string>
<string name="third_party_application">Tredjepartsprogram</string>
@ -3237,4 +3237,6 @@ Repræsenterer område: %1$s x %2$s</string>
<string name="powered_by_osmand">Drevet af OsmAnd</string>
<string name="osm_live_subscriptions">Abonnementer</string>
<string name="mapillary_menu_title_pano">Vis kun 360° billeder</string>
</resources>
<string name="shared_string_launch">Start</string>
<string name="run_full_osmand_header">Start OsmAnd\?</string>
</resources>

View file

@ -3090,7 +3090,7 @@ Abgedeckte Fläche: %1$s x %2$s</string>
<string name="poi_cannot_be_found">Knoten oder Weg kann nicht gefunden werden.</string>
<string name="search_no_results_feedback">Keine Suchergebnisse?
\nGeben Sie uns eine Rückmeldung</string>
<string name="commiting_way">Übermitteln via</string>
<string name="commiting_way">Übermitteln Linie</string>
<string name="test_voice_desrc">Tippen Sie auf eine Schaltfläche und hören Sie sich die entsprechende Sprachausgabe an, um fehlende oder fehlerhafte Anweisungen zu erkennen.</string>
<string name="release_3_2_pre">• Absturz beim Start behoben, der bei manchen Geräten auftrat
\n

View file

@ -1,4 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" encoding="utf-8"?>
<resources><string name="shared_string_topbar">Supra breto</string>
<string name="recalculate_route">Rekalkuli kurson</string>
<string name="donations">Donacoj</string>
@ -3006,4 +3006,7 @@ Indikas lokon: %1$s x %2$s"</string>
<string name="powered_by_osmand">Povigata de OsmAnd</string>
<string name="osm_live_subscriptions">Abonoj</string>
<string name="mapillary_menu_title_pano">Montri nur bildojn 360°</string>
</resources>
<string name="shared_string_launch">Lanĉi</string>
<string name="run_full_osmand_msg">Vi uzas mapon {0}, kiu estas povigata de OsmAnd. Ĉu lanĉi la plenan version de OsmAnd\?</string>
<string name="run_full_osmand_header">Ĉu lanĉi OsmAnd\?</string>
</resources>

View file

@ -3046,4 +3046,7 @@ Lon %2$s</string>
<string name="powered_by_osmand">Desarrollado por OsmAnd</string>
<string name="osm_live_subscriptions">Suscripciones</string>
<string name="mapillary_menu_title_pano">Sólo mostrar imágenes en 360°</string>
</resources>
<string name="shared_string_launch">Ejecutar</string>
<string name="run_full_osmand_msg">Estás utilizando el mapa {0} que funciona con OsmAnd. ¿Quieres ejecutar la versión completa de OsmAnd\?</string>
<string name="run_full_osmand_header">¿Ejecutar OsmAnd\?</string>
</resources>

View file

@ -3609,24 +3609,24 @@
<string name="poi_service_car">Servicio automotriz</string>
<string name="poi_service_vehicle_car_repair_yes">Taller mecánico</string>
<string name="poi_service_vehicle_car_repair_yes">Taller para automóviles</string>
<string name="poi_service_vehicle_oil_change_yes">Cambio de aceite</string>
<string name="poi_service_vehicle_used_car_sales_yes">Venta de autos usados</string>
<string name="poi_service_vehicle_brakes_yes">Frenos</string>
<string name="poi_service_vehicle_new_car_sales_yes">Venta de autos nuevos</string>
<string name="poi_service_vehicle_diagnostics_yes">Diagnóstico</string>
<string name="poi_service_vehicle_diagnostics_yes">Diagnósticos</string>
<string name="poi_service_vehicle_car_parts_yes">Autopartes</string>
<string name="poi_service_vehicle_batteries_yes">Baterías</string>
<string name="poi_service_vehicle_air_conditioning_yes">Aire acondicionado</string>
<string name="poi_service_vehicle_body_repair_yes">Reparación de carrocería</string>
<string name="poi_service_vehicle_body_repair_yes">Reparación de carrocerías</string>
<string name="poi_service_vehicle_electrical_yes">Eléctrico</string>
<string name="poi_service_vehicle_wheels_yes">Ruedas</string>
<string name="poi_service_vehicle_glass_yes">Vidrio</string>
<string name="poi_service_vehicle_truck_repair_yes">Taller mecánico para camiones</string>
<string name="poi_service_vehicle_glass_yes">Vidrios</string>
<string name="poi_service_vehicle_truck_repair_yes">Taller para camiones</string>
<string name="poi_service_vehicle_muffler_yes">Silenciador</string>
<string name="poi_service_vehicle_alignment_yes">Alineación</string>
<string name="poi_service_vehicle_transmission_repair_yes">Reparación de la transmisión</string>
<string name="poi_service_vehicle_motor_yes">Motor</string>
<string name="poi_service_vehicle_motor_yes">Motores</string>
<string name="poi_service_vehicle_insurance_yes">Aseguradora</string>
<string name="poi_service_vehicle_tyres_yes">Neumáticos</string>

View file

@ -3047,4 +3047,7 @@ Lon %2$s</string>
<string name="powered_by_osmand">Desarrollado por OsmAnd</string>
<string name="osm_live_subscriptions">Suscripciones</string>
<string name="mapillary_menu_title_pano">Sólo mostrar imágenes en 360°</string>
</resources>
<string name="shared_string_launch">Ejecutar</string>
<string name="run_full_osmand_msg">Estás utilizando el mapa «{0}» que funciona con OsmAnd. ¿Quieres ejecutar la versión completa de OsmAnd\?</string>
<string name="run_full_osmand_header">¿Ejecutar OsmAnd\?</string>
</resources>

View file

@ -3832,24 +3832,24 @@
<string name="poi_service_car">Servicio para el automóvil</string>
<string name="poi_service_vehicle_car_repair_yes">Taller mecánico</string>
<string name="poi_service_vehicle_car_repair_yes">Taller para automóviles</string>
<string name="poi_service_vehicle_oil_change_yes">Cambio de aceite</string>
<string name="poi_service_vehicle_used_car_sales_yes">Venta de autos usados</string>
<string name="poi_service_vehicle_brakes_yes">Frenos</string>
<string name="poi_service_vehicle_new_car_sales_yes">Venta de autos nuevos</string>
<string name="poi_service_vehicle_diagnostics_yes">Diagnóstico</string>
<string name="poi_service_vehicle_diagnostics_yes">Diagnósticos</string>
<string name="poi_service_vehicle_car_parts_yes">Autopartes</string>
<string name="poi_service_vehicle_batteries_yes">Baterías</string>
<string name="poi_service_vehicle_air_conditioning_yes">Aire acondicionado</string>
<string name="poi_service_vehicle_body_repair_yes">Reparación de carrocería</string>
<string name="poi_service_vehicle_body_repair_yes">Reparación de carrocerías</string>
<string name="poi_service_vehicle_electrical_yes">Eléctrico</string>
<string name="poi_service_vehicle_wheels_yes">Ruedas</string>
<string name="poi_service_vehicle_glass_yes">Vidrio</string>
<string name="poi_service_vehicle_truck_repair_yes">Taller mecánico para camiones</string>
<string name="poi_service_vehicle_glass_yes">Vidrios</string>
<string name="poi_service_vehicle_truck_repair_yes">Taller para camiones</string>
<string name="poi_service_vehicle_muffler_yes">Silenciador</string>
<string name="poi_service_vehicle_alignment_yes">Alineación</string>
<string name="poi_service_vehicle_transmission_repair_yes">Reparación de la transmisión</string>
<string name="poi_service_vehicle_motor_yes">Motor</string>
<string name="poi_service_vehicle_motor_yes">Motores</string>
<string name="poi_service_vehicle_insurance_yes">Aseguradora</string>
<string name="poi_service_vehicle_tyres_yes">Neumáticos</string>

View file

@ -3186,4 +3186,7 @@ Area honi dagokio: %1$s x %2$s</string>
<string name="powered_by_osmand">OsmAnd-ek bultzatua</string>
<string name="osm_live_subscriptions">Harpidetzak</string>
<string name="mapillary_menu_title_pano">Erakutsi 360º argazkiak besterik ez</string>
</resources>
<string name="shared_string_launch">Abiatu</string>
<string name="run_full_osmand_msg">OsmAnd darabilen {0} mapa erabiltzen ari zara eta. OsmAnd bertsio osoa abiatu nahi duzu\?</string>
<string name="run_full_osmand_header">Abiatu OsmAnd\?</string>
</resources>

View file

@ -1,4 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="offline_edition">Modifications hors-ligne</string>
<string name="offline_edition_descr">Toujours utiliser l\'édition hors-ligne.</string>
@ -1772,7 +1772,7 @@ Mémoire proportionnelle %4$s Mo (limite Android %5$s Mo, Dalvik %6$s Mo).</stri
<string name="shared_string_ellipsis"></string>
<string name="shared_string_deselect">Désélectionner</string>
<string name="shared_string_deselect_all">Désélectionner tout</string>
<string name="shared_string_unexpected_error">Erreur inconnue</string>
<string name="shared_string_unexpected_error">Erreur inattendue</string>
<string name="shared_string_action_template">Action {0}</string>
<string name="shared_string_video">Vidéo</string>
<string name="shared_string_photo">Photo</string>
@ -2204,7 +2204,7 @@ Actuellement seuls {2} Mo sont disponibles.</string>
<string name="osm_live_month_cost_desc">Règlement mensuel</string>
<string name="osm_live_active">Actif</string>
<string name="osm_live_not_active">Inactif</string>
<string name="osm_live_enter_email">Merci de saisir un courriel valide</string>
<string name="osm_live_enter_email">Veuillez saisir une adresse email valide</string>
<string name="osm_live_thanks">Merci pour votre soutien à OsmAnd !
\nPour activer toutes les nouvelles fonctionnalités, merci de redémarrer OsmAnd.</string>
<string name="osm_live_subscription_settings">Paramétrage de l\'abonnement</string>
@ -2354,7 +2354,7 @@ Si vous appréciez OsmAnd et OSM et que vous souhaitez soutenir ces projets, c\'
<string name="get_it">Obtenir</string>
<string name="osm_live_banner_desc">Téléchargez un nombre illimité de cartes et obtenez des mises à jour plus fréquentes (chaque semaine, chaque jour, chaque heure; au lieu de chaque mois).</string>
<string name="osmand_plus_banner_desc">Téléchargements illimités des cartes, des mises à jour et des données pour le greffon Wikipédia.</string>
<string name="donation_to_osm">Faire un don à la communauté OpenStreetMap</string>
<string name="donation_to_osm">Don à la communauté OpenStreetMap</string>
<string name="osm_live_subscription_desc">L\'abonnement permet de bénéficier des mises à jour horaires, quotidiennes, hebdomadaires et de télécharger de nouvelles cartes sans limite.</string>
<string name="osm_live_payment_desc">Abonnement mensuel. Vous pouvez l\'annuler à tout moment sur Google Play.</string>
<string name="donation_to_osm_desc">Une partie de votre don sera reversée aux contributeurs OSM qui mettent à jour OpenStreetMap. Le coût de l\'abonnement reste identique.</string>
@ -3213,4 +3213,7 @@ représentant la zone : %1$s x %2$s</string>
<string name="powered_by_osmand">Propulsé par OsmAnd</string>
<string name="osm_live_subscriptions">Abonnements</string>
<string name="mapillary_menu_title_pano">N\'afficher que les images à 360°</string>
</resources>
<string name="shared_string_launch">Ouvrir</string>
<string name="run_full_osmand_msg">Vous utilisez la carte {0} qui est proposée par OsmAnd. Souhaitez-vous lancer la version complète d\'OsmAnd \?</string>
<string name="run_full_osmand_header">Ouvrir OsmAnd \?</string>
</resources>

View file

@ -383,7 +383,7 @@
<string name="poi_bag">Tenda de bolsos e/ou maletas</string>
<string name="poi_hardware">Ferraxaría</string>
<string name="poi_shop">Tenda</string>
<string name="poi_shop_food">Tenda de comestíbeis e supermercado</string>
<string name="poi_shop_food">Tenda de ultramarinos e supermercado</string>
<string name="poi_emergency">Urxencias</string>
<string name="poi_transportation">Transporte</string>
<string name="poi_road_obstacle">Obstáculo na estrada</string>
@ -507,7 +507,7 @@
<string name="poi_recycling_fridge_and_freezer">Neveira e conxelador</string>
<string name="poi_meadow">Lameiro</string>
<string name="poi_canal">Canle</string>
<string name="poi_canal">Canle fluvial</string>
<string name="poi_pier">Peirao</string>
<string name="poi_tower">Torre</string>
<string name="poi_radar">Radar</string>
@ -1490,7 +1490,7 @@
<string name="poi_glacier_type">Tipo do glaciar</string>
<string name="poi_checkpoint_type">Tipo do posto de control</string>
<string name="poi_convenience">Tenda de comestíbeis</string>
<string name="poi_convenience">Tenda de ultramarinos</string>
<string name="poi_halt">Paraxe de trens</string>
<string name="poi_railway_buffer_stop">Fin da vía</string>
<string name="poi_food_court">Estabelecemento de comidas</string>

View file

@ -3166,4 +3166,7 @@ Lon %2$s</string>
<string name="powered_by_osmand">Desenvolvido polo OsmAnd</string>
<string name="osm_live_subscriptions">Subscricións</string>
<string name="mapillary_menu_title_pano">Amosar só imaxes 360°</string>
</resources>
<string name="shared_string_launch">Executar</string>
<string name="run_full_osmand_msg">Estás a emprega-lo mapa {0} que funciona co OsmAnd. Desexas executar a versión completa do OsmAnd\?</string>
<string name="run_full_osmand_header">Executar OsmAnd\?</string>
</resources>

View file

@ -3127,4 +3127,7 @@
<string name="powered_by_osmand">מופעל על ידי OsmAnd</string>
<string name="osm_live_subscriptions">מינויים</string>
<string name="mapillary_menu_title_pano">הצגת תמונות 360° בלבד</string>
<string name="shared_string_launch">הפעלה</string>
<string name="run_full_osmand_msg">המפה שבשימוש היא {0} שמוגשת על ידי OsmAnd. להפעיל את הגרסה המלאה של OsmAnd\?</string>
<string name="run_full_osmand_header">להפעיל את OsmAnd\?</string>
</resources>

View file

@ -720,7 +720,7 @@ Ehhez {1} MB helyre van szükség.
<string name="poi_edit_title">POI szerkesztése</string>
<string name="poi_create_title">POI létrehozása</string>
<string name="poi_error_poi_not_found">A pont nem található, vagy a létesítmény több pontból áll, ami pillanatnyilag nem támogatott.</string>
<string name="poi_remove_confirm_template">{0} törlése (írj megjegyzést)?</string>
<string name="poi_remove_confirm_template">{0} törlése (megjegyzés)\?</string>
<string name="poi_remove_title">POI törlése</string>
<string name="shared_string_delete">Törlés</string>
<string name="poi_remove_success">POI törölve</string>
@ -1243,7 +1243,7 @@ Proporcionális memória %4$s MB (Android korlát %5$s MB, Dalvik %6$s MB).</str
<string name="app_modes_choose_descr">Válaszd ki az alkalmazásban megjelenő profilokat.</string>
<string name="app_modes_choose">Alkalmazás profilok</string>
<string name="map_widget_map_rendering">Térkép megjelenítése</string>
<string name="app_mode_hiking">Gyalogtúra</string>
<string name="app_mode_hiking">Túrázás</string>
<string name="app_mode_motorcycle">Motorkerékpár</string>
<string name="app_mode_boat">Hajó</string>
<string name="app_mode_aircraft">Légi jármű</string>
@ -2161,7 +2161,7 @@ Hosszúság: %2$s</string>
<string name="osm_user_stat">Szerkesztések: %1$s, helyezés: %2$s, összes szerkesztés: %3$s</string>
<string name="osm_editors_ranking">OSM szerkesztők rangsora</string>
<string name="osm_live_subscription">OsmAnd Live előfizetés</string>
<string name="osm_live_subscribe_btn">Előfizetés</string>
<string name="osm_live_subscribe_btn">Feliratkozás</string>
<string name="osm_live_user_public_name">Nyilvános név</string>
<string name="osm_live_hide_user_name">Ne jelenjen meg a nevem a jelentésekben</string>
<string name="osm_live_support_region">Támogatott régió</string>
@ -2897,7 +2897,7 @@ Kérlek adj meg egy teljes kódot</string>
<string name="rendering_attr_hidePOILabels_name">POI-feliratok</string>
<string name="shared_string_without_name">Névtelen</string>
<string name="empty_state_markers_history_desc">Ezen a képernyőn az elvégzett térképjelölők fognak megjelenni.</string>
<string name="mark_passed">Térképjelölő megjelölése elvégzettként</string>
<string name="mark_passed">Megjelölés elhagyottként</string>
<string name="lang_lo">laoszi</string>
<string name="day_off_label">zárva</string>
<string name="winter_and_ski_renderer">Tél és síelés</string>
@ -3028,7 +3028,7 @@ Kérlek adj meg egy teljes kódot</string>
<string name="touring_view_render_descr">"Nagyon részletes stílus utazásokhoz. Tartalmazza az alapértelmezett stílus összes beállítási lehetőségét, valamint: annyi részletet jelenít meg, amennyit csak lehetséges, különösen az utak, ösvények és más utazásnál hasznos utak tekintetében. Tisztán elkülönülnek a különféle úttípusok, felidézve az utazóatlaszok stílusát. Nagy kontrasztú színvilág kültéri használatra, nappali és éjszakai móddal."</string>
<string name="default_render_descr">Általános célú stílus. Egyszerű, tiszta kinézet sűrűn lakott településeken. Főbb tulajdonságok: szintvonalak, útvonalak, útminőség, behajtási korlátozások, útszám pajzsok, ösvények megjelenítése SAC-skála szerint, vadvízi sportok.</string>
<string name="shared_string_gpx_files">GPX fájlok</string>
<string name="quick_action_edit_actions">Szerkesztés műveletek</string>
<string name="quick_action_edit_actions">Műveletek szerkesztése</string>
<string name="shared_string_dont">Nem</string>
<string name="shared_string_do">Igen</string>
<string name="shared_string_total">Összesen</string>
@ -3040,4 +3040,72 @@ Kérlek adj meg egy teljes kódot</string>
<string name="coord_input_add_point">Pont hozzáadása</string>
<string name="coord_input_save_as_track">Mentés nyomvonalként</string>
<string name="more_transport_on_stop_hint">Ebben a megállóban több közlekedési eszköz is előfordul.</string>
</resources>
<string name="send_search_query">Elküldöd a keresést\?</string>
<string name="osmand_extended_description_part5">Kerékpározás
\n • A kerékpárutak megjelennek a térképen
\n • A GPS navigáció kerékpáros módban kerékpárutakat használva tervez utat
\n • Láthatod a sebességed és milyen magasan jársz
\n • GPX felvétel opcióval felveheted és megoszthatod a túráidat
\n • Bővítményen keresztül bekapcsolhatóak a szintvonalak és a domborzatárnyékolás</string>
<string name="osm_live_subscriptions">Előfizetések</string>
<string name="osm_live_plan_pricing">Csomag &amp; Árak</string>
<string name="osm_live_payment_monthly_title">Fizetés havonta</string>
<string name="osm_live_payment_3_months_title">Fizetés három havonta</string>
<string name="osm_live_payment_annual_title">Fizetés évente egyszer</string>
<string name="osm_live_payment_month_cost_descr">%1$s / hó</string>
<string name="osm_live_payment_month_cost_descr_ex">%1$.2f %2$s / hó</string>
<string name="osm_live_payment_discount_descr">Takaríts meg ennyit: %1$s!</string>
<string name="osm_live_payment_current_subscription">Jelenlegi előfizetéseid</string>
<string name="osm_live_payment_renews_monthly">Havonta megújul</string>
<string name="osm_live_payment_renews_quarterly">Negyedévente megújul</string>
<string name="osm_live_payment_renews_annually">Évente megújul</string>
<string name="default_price_currency_format">%1$.2f %2$s</string>
<string name="osm_live_payment_header">Válaszd ki a számodra kényelmes fizetési időszakot:</string>
<string name="osm_live_payment_contribute_descr">A bevétel egy részét az OpenStreetMap közreműködői kapják.</string>
<string name="markers_remove_dialog_msg">Törlöd „%s” térképjelölőt\?</string>
<string name="edit_map_marker">Térképjelölő szerkesztése</string>
<string name="search_street">Utca keresése</string>
<string name="start_search_from_city">Előbb a város kiválasztása</string>
<string name="shared_string_restore">Visszaállítás</string>
<string name="keep_passed_markers">Elhagyott jelölők megtartása a térképen</string>
<string name="ask_for_location_permission">A folytatáshoz kérlek engedélyezd a helymeghatározást az OsmAnd számára.</string>
<string name="thank_you_for_feedback">Köszönjük a visszajelzést</string>
<string name="release_3_2_pre">• Pár eszközt érintő indításkori összeomlás javítása
\n
\n • Új térképjelölők lehetőség: a már elhagyott jelölők térképen tartása
\n
\n • A keresési előzmények a korábban keresett kategóriákat is megjeleníti
\n
\n • A nem latin betűs térképek okozta indításkori összeomlás javítása
\n
\n • Térkép megjelentési sebesség javítása Android 8.0 eszközön
\n
\n • Sokszögkén ábrázolt objektumok (nem szolgáltatás) szerkesztése
\n
\n • Távolságmérés: Mérés gomb hozzáadva Műveletekhez a helyi menüben
\n
\n</string>
<string name="release_3_1">• Navigáció: folyamatjelző sáv javítása, az út kezdő és célpontjának gyors felcserélése
\n
\n • Térképjelölők: csoportok ki-be kapcsolásának javítása, lehetőség a jelölők eltüntetésére
\n
\n • OSM szerkesztés: Nem pontként ábrázolt objektumok és vonalak címkéinek szerkesztése, hiányzó megjegyzések javítása a jegyzeteken, szerkesztések biztonsági mentése
\n
\n • Wikipédia és Wikivoyage cikkek feldolgozásának javítása, a frissített fájlok már elérhetőek
\n
\n • Helyi menü: pajzsok javítása éjszakai módban, további menüméretek javítása
\n
\n • Hajós navigáció: vízi utak támogatása
\n
\n • Egyéb hibajavítások
\n
\n</string>
<string name="commiting_way">Vonal beküldése…</string>
<string name="increase_search_radius_to">Keresési sugár növelése: %1$s</string>
<string name="point_deleted">%1$s pont törölve</string>
<string name="coord_input_save_as_track_descr">%1$s pontot hoztál létre. Adj meg egy fájlnevet és nyomj a „Mentés”-re.</string>
<string name="error_notification_desc">Kérlek, küldj egy képernyőképet erről a figyelmeztetésről a support@osmand.net-re</string>
<string name="mapillary_menu_title_pano">Csak 360°-os képek megjelenítése</string>
<string name="rendering_value_black_name">Fekete</string>
<string name="test_voice_desrc">Nyomj egy gombra és hallgasd meg a hangutasítást, hogy megtaláld a hiányzó, vagy hibás utasításokat.</string>
</resources>

View file

@ -3888,7 +3888,16 @@
<string name="poi_blood_donation">Blóðgjöf</string>
<string name="poi_books_comic">Myndasögur</string>
<string name="poi_books_religion">Trúarbrögð</string>
<string name="poi_books_academic">Akademískt</string>
<string name="poi_books_children">Börn</string>
<string name="poi_books_academic">Akademískar</string>
<string name="poi_books_children">Barnabækur</string>
<string name="poi_atoll">Kóralrif</string>
<string name="poi_pipeline_substation">Millistöð leiðslu</string>
<string name="poi_substation_transmission">Spennuvirki</string>
<string name="poi_substation_minor_distribution">Minni háttar dreifing</string>
<string name="poi_substation_transition">Millistöð</string>
<string name="poi_substation_traction">Spennustöð lestakerfis</string>
<string name="poi_substation_converter">Umbreytir</string>
<string name="poi_substation_compensation">Mótvægisjöfnun</string>
<string name="poi_substation_field_gathering">Safnstöð</string>
<string name="poi_books_antiquarian">Gamlar bækur</string>
</resources>

View file

@ -3007,4 +3007,7 @@ Stendur fyrir svæði: %1$s x %2$s</string>
<string name="powered_by_osmand">Keyrt með OsmAnd</string>
<string name="osm_live_subscriptions">Áskriftir</string>
<string name="mapillary_menu_title_pano">Einungis birta 360° myndir</string>
</resources>
<string name="shared_string_launch">Keyra</string>
<string name="run_full_osmand_msg">Þú ert að nota kortið {0} sem er keyrt með OsmAnd. Myndirðu vilja keyra fulla útgáfu af OsmAnd\?</string>
<string name="run_full_osmand_header">Ræsa OsmAnd\?</string>
</resources>

View file

@ -2770,7 +2770,7 @@
<string name="poi_error_info_not_loaded">Info om knutepunktet ble ikke lastet inn</string>
<string name="poi_dialog_other_tags_message">Alle andre etiketter beholdes</string>
<string name="we_really_care_about_your_opinion">Vi bryr oss om din mening og din tilbakemelding er viktig.</string>
<string name="number_of_rows_in_dash">Antall rader %1$s</string>
<string name="number_of_rows_in_dash">Antall rader i oversikt: %1$s</string>
<string name="show_free_version_banner">Vis gratisversjonsbanner</string>
<string name="show_free_version_banner_description">Vis gratisversjonsbanneret selv i den betalte versjonen.</string>
<string name="commiting_node">Sjekker inn knutepunkt…</string>
@ -3078,7 +3078,7 @@
<string name="search_street">Gatesøk</string>
<string name="start_search_from_city">Velg byen først</string>
<string name="shared_string_restore">Gjenopprett</string>
<string name="keep_passed_markers_descr">Markører lagt til som favorittgrupper eller GPX-veipunkter markert som passert vil forbli på kartet. Hvis gruppen ikke er aktiv, vil markørene forsvinne fra kartet.</string>
<string name="keep_passed_markers_descr">Markører lagt til som favorittgrupper eller GPX-rutepunkter markert som passert vil forbli på kartet. Hvis gruppen ikke er aktiv, vil markørene forsvinne fra kartet.</string>
<string name="keep_passed_markers">Behold passerte markører på kartet</string>
<string name="osm_live_plan_pricing">Betalingsplan og pris</string>
<string name="osm_live_payment_monthly_title">Betal månedlig</string>
@ -3097,4 +3097,17 @@
<string name="powered_by_osmand">Muliggjort av OsmAnd</string>
<string name="osm_live_subscriptions">Abonnementer</string>
<string name="mapillary_menu_title_pano">Vis kun 360°-bilder</string>
<string name="release_3_0">• New: Støtte for verdensomspennende reiseguider. Nevnte plasseringer lenkes til på kartet. Initiell data fra Wikivoyage.
\n
\n • Wikipedia: Nytt utseende, aktive lenker og støtte for bilder
\n
\n • Open Track UI: Støtte for rutepunktgrupper
\n
\n • Kartmarkører: Import av valgte grupper fra GPX-filer, koordiner inndata, nytt utseende
\n
\n • OsmAnd Live-abonnement støtter nå alle OsmAnd-funksjoner
\n</string>
<string name="shared_string_launch">Kjør</string>
<string name="run_full_osmand_msg">Du bruker {0}-kart, muliggjort av OsmAnd. Ønsker du å kjøre fullversjonen av OsmAnd\?</string>
<string name="run_full_osmand_header">Kjør OsmAnd\?</string>
</resources>

View file

@ -1984,7 +1984,7 @@ Lengtegraad:\t\t%2$s</string>
<string name="shared_string_navigation">Navigatie</string>
<string name="favourites_edit_dialog_title">Informatie over favoriet</string>
<string name="simulate_your_location_stop_descr">Positiesimulatie beëindigen.</string>
<string name="simulate_your_location_descr">Positiesimulatie met een berekende route of een opgenomen GPX-track.</string>
<string name="simulate_your_location_descr">Routesimulatie met een berekende route of een opgeslagen GPX-track</string>
<string name="av_locations_descr">GPX-bestand met notities.</string>
<string name="av_locations">Locaties van geselecteerde AV-Notities</string>
<string name="plugin_settings">Plugins</string>
@ -2213,20 +2213,21 @@ Lengtegraad:\t\t%2$s</string>
<string name="osm_editors_ranking">OSM-Bijdragers Ranglijst</string>
<string name="osm_live_subscription">OsmAnd Live abonnement</string>
<string name="osm_live_subscribe_btn">Abonneren</string>
<string name="osm_live_email_desc">Dit is nodig om je informatie te geven over bijdragen.</string>
<string name="osm_live_email_desc">Nodig om je informatie te geven over bijdragen.</string>
<string name="osm_live_user_public_name">Openbare Naam</string>
<string name="osm_live_hide_user_name">Mijn naam niet tonen in verslagen</string>
<string name="osm_live_support_region">Ondersteunde regio</string>
<string name="osm_live_month_cost">Maandelijkse kosten</string>
<string name="osm_live_month_cost_desc">Abonnementskosten per maand.</string>
<string name="osm_live_month_cost_desc">Abonnementskosten per maand</string>
<string name="osm_live_active">Actief</string>
<string name="osm_live_not_active">Niet actief</string>
<string name="osm_live_enter_email">Voer een geldig emailadres in</string>
<string name="osm_live_enter_user_name">Voer je Openbare Naam in</string>
<string name="osm_live_thanks">Bedankt voor je OSM Live Abonnement!</string>
<string name="osm_live_thanks">Bedankt voor je OSM Live Abonnement! Een herstart van OsmAnd is nodig.</string>
<string name="osm_live_region_desc">Een gedeelte van je betaling gaat naar OSM-bijdragers in deze regio.</string>
<string name="osm_live_subscription_settings">Abonnementsgegevens</string>
<string name="osm_live_ask_for_purchase">Neem alsjeblieft eerst een OsmAnd Live Abonnement</string>
<string name="osm_live_ask_for_purchase">Neem alsjeblieft eerst een
\nabonnement op OsmAnd Live</string>
<string name="osm_live_header">"Met dit abonnement ontvang je dagelijks updates voor kaarten over de hele wereld.
Een gedeelte van uw bijdrage gaat naar de OSM-gemeenschap en wordt uitbetaald naar het aantal OSM-bewerkingen.
@ -2261,11 +2262,11 @@ Er is nu {2} MB beschikbaar</string>
<string name="recalculate_route">Route opnieuw berekenen</string>
<string name="shared_string_topbar">Bovenste balk</string>
<string name="storage_directory_readonly_desc">De geselecteerde opslagmap is niet schrijfbaar. Daarom wordt nu intern geheugen gebruikt. Kies een geldige opslagmap.</string>
<string name="storage_directory_readonly_desc">De geselecteerde opslagmap is niet beschrijfbaar. Daarom wordt nu intern geheugen gebruikt. Kies een geldige opslagmap.</string>
<string name="storage_directory_shared">Gedeeld geheugen</string>
<string name="avoid_road">Deze weg vermijden</string>
<string name="shared_string_move_up">Omhoog</string>
<string name="shared_string_move_down">Omlaag</string>
<string name="shared_string_move_up">Omhoog</string>
<string name="shared_string_move_down">Omlaag</string>
<string name="finish_navigation">Navigatie stoppen</string>
<string name="storage_permission_restart_is_required">OsmAnd heeft nu toestemming om de externe opslag te gebruiken. Een handmatige herstart is noodzakelijk.</string>
@ -2296,9 +2297,9 @@ Er is nu {2} MB beschikbaar</string>
<string name="access_sort">Sorteren</string>
<string name="map_widget_bearing">Relatieve koers</string>
<string name="access_disable_offroute_recalc">Geen herberekeing als u van de berekende route afwijkt</string>
<string name="access_disable_offroute_recalc_descr">Voorkom automatische hercalculatie van de route wanneer u van de route afwijkt.</string>
<string name="access_disable_offroute_recalc_descr">Geen automatische herberekening van de route, wanneer u van de route afwijkt.</string>
<string name="access_disable_wrong_direction_recalc">Wijzig de route niet als u de verkeerde kant op gaat</string>
<string name="access_disable_wrong_direction_recalc_descr">Voorkom automatische herberekening van de route als u in tegenovergestelde richting beweegt.</string>
<string name="access_disable_wrong_direction_recalc_descr">Geen automatische herberekening van de route als u in tegenovergestelde richting beweegt.</string>
<string name="access_smart_autoannounce">Slimme aankondigingen</string>
<string name="access_smart_autoannounce_descr">Geef alleen instructie als de richting naar het doel veranderd is.</string>
<string name="access_autoannounce_period">Tijd tussen meldingen</string>
@ -2351,8 +2352,8 @@ Er is nu {2} MB beschikbaar</string>
<string name="get_started">Aan de slag</string>
<string name="routing_attr_short_way_name">Economische route</string>
<string name="routing_attr_short_way_description">Economische route gebruiken (meestal korter).</string>
<string name="replace_favorite_confirmation">Wil je favoriet %1$s inderdaad vervangen?</string>
<string name="update_all_maps_now">Wil u alle kaarten nu updaten?</string>
<string name="replace_favorite_confirmation">Wil je Favoriet %1$s inderdaad vervangen\?</string>
<string name="update_all_maps_now">Nu alle kaarten updaten\?</string>
<string name="si_mi_meters">Mijlen/meters</string>
<string name="skip_map_downloading">Kaarten later downloaden</string>
<string name="search_another_country">Kies een andere regio</string>
@ -2377,9 +2378,9 @@ Er is nu {2} MB beschikbaar</string>
<string name="get_for_month">Abonneren voor %1$s per maand</string>
<string name="osm_live_banner_desc">Krijg onbeperkte downloads van kaarten en updates vaker dan eens per maand: wekelijks, dagelijks of elk uur.</string>
<string name="osmand_plus_banner_desc">Onbeperkte downloads van kaarten, updates, en Wikipedia plugin.</string>
<string name="skip_map_downloading_desc">Er is geen kaart geïnstalleerd. Kies een kaart uit de lijst, of download later kaarten via Menu - %1$s.</string>
<string name="skip_map_downloading_desc">"Er is geen kaart geïnstalleerd. Kies een kaart uit de lijst, of download later kaarten via \'Menu - %1$s\'. "</string>
<string name="first_usage_wizard_desc">Kies kaarten om te downloaden aan de hand van uw huidige locatie.</string>
<string name="storage_place_description">OsmAnd bewaart gegevens (kaarten, tracks, enz.) in: %1$s</string>
<string name="storage_place_description">OsmAnd bewaart gegevens (kaarten, GPX-tracks, enz.) in: %1$s.</string>
<string name="no_update_info_desc">Controleer niet op nieuwe versies en aanbiedingen van OsmAnd.</string>
<string name="driving_region_australia">Australië</string>
<string name="lang_kab">Kabylisch</string>
@ -2396,7 +2397,7 @@ Er is nu {2} MB beschikbaar</string>
<string name="subcategories">Subcategorieën</string>
<string name="translit_names">Transliteratie van namen</string>
<string name="translit_name_if_miss">Weergeven in westers schrift als naam in %1$s ontbreekt</string>
<string name="search_hint">Tik stad, adres of naam</string>
<string name="search_hint">Plaatsnaam, adres of naam invoeren</string>
<string name="rendering_value_light_brown_name">Lichtbruin</string>
<string name="rendering_value_dark_brown_name">Donkerbruin</string>
<string name="rendering_attr_contourColorScheme_name">Kleur van hoogtelijnen</string>
@ -2406,7 +2407,7 @@ Er is nu {2} MB beschikbaar</string>
<string name="christmas_desc_q">Kerst-POI tonen?</string>
<string name="rendering_attr_contourColorScheme_description">Kleur van hoogtelijnen</string>
<string name="save_track_min_speed">Minimum snelheid om te registreren</string>
<string name="save_track_min_speed_descr">Filter: Kies minimumsnelheid waarboven GPX-opname actief wordt.</string>
<string name="save_track_min_speed_descr">Filter: Geen GPX-opname bij lagere snelheid.</string>
<string name="save_track_min_distance">GPX-opname: minimale afstand</string>
<string name="save_track_min_distance_descr">Filter: kies de minumumafstand vanaf het vorige punt, waarboven een nieuw GPX-punt wordt opgenomen.</string>
<string name="save_track_precision">Minimale GPS-nauwkeurigheid</string>
@ -2420,7 +2421,7 @@ Er is nu {2} MB beschikbaar</string>
<string name="gpx_no_tracks_title">Je hebt nog geen GPX-tracks</string>
<string name="gpx_no_tracks_title_folder">Je kunt ook GPX-tracks toevoegen aan de map</string>
<string name="gpx_add_track">GPX-track toevoegen</string>
<string name="gpx_add_track">"GPX-track toevoegen... "</string>
<string name="gpx_appearance">GPX-stijl</string>
@ -2446,8 +2447,8 @@ Er is nu {2} MB beschikbaar</string>
<string name="rendering_value_high_name">Hoog</string>
<string name="rendering_value_medium_w_name">Gemiddeld</string>
<string name="rendering_value_low_name">Laag</string>
<string name="rendering_attr_contourWidth_description">Hoogtelijnen dikte</string>
<string name="rendering_attr_contourWidth_name">Hoogtelijnen dikte</string>
<string name="rendering_attr_contourWidth_description">Hoogtelijnen: dikte</string>
<string name="rendering_attr_contourWidth_name">Hoogtelijnen: dikte</string>
<string name="rendering_attr_hideWaterPolygons_description">Watervlakten</string>
<string name="rendering_attr_hideWaterPolygons_name">Verberg watervlakten</string>
@ -2580,7 +2581,7 @@ voor Gebied: %1$s x %2$s</string>
<string name="select_city">Plaatsnaam kiezen</string>
<string name="select_postcode">Postcode kiezen</string>
<string name="quick_action_auto_zoom">Autozoom aan/uit</string>
<string name="quick_action_auto_zoom_desc">Een drukop op de sneltoets zet de automatische zoom volgens de snelheid aan of uit.</string>
<string name="quick_action_auto_zoom_desc">Een druk op op de sneltoets zet de automatische zoom volgens de snelheid aan of uit.</string>
<string name="quick_action_auto_zoom_on">Autozoom aan</string>
<string name="quick_action_auto_zoom_off">Autozoom uit</string>
<string name="quick_action_add_destination">Bestemming toevoegen</string>
@ -2594,7 +2595,7 @@ voor Gebied: %1$s x %2$s</string>
<string name="subscribe_email_error">Foutmelding</string>
<string name="subscribe_email_desc">Abonneer op de mailinglist voor aanbiedingen en ontvang 3 extra kaart-downloads!</string>
<string name="depth_contour_descr">Deze kaarten tonen de dieptepunten en -contouren van zeeën en oceanen.</string>
<string name="sea_depth_thanks">Bedankt voor het aanschaffen van Zeediepten en -contouren!</string>
<string name="sea_depth_thanks">Bedankt voor het aanschaffen van Zeediepten en -contouren</string>
<string name="index_item_depth_contours_osmand_ext">Zeediepte-contourlijnen</string>
<string name="index_item_depth_points_southern_hemisphere">Zeediepten Zuidelijk Halfrond</string>
<string name="index_item_depth_points_northern_hemisphere">Zeediepten Noordelijk Halfrond</string>
@ -2604,7 +2605,7 @@ voor Gebied: %1$s x %2$s</string>
<string name="shared_string_visible">Zichtbaar</string>
<string name="restore_purchases">Aankopen herstellen</string>
<string name="fonts_header">Lettertypes voor de kaart</string>
<string name="do_not_show_startup_messages_desc">Onderdruk meldingen van app-aanbiedingen en speciale lokale gebeurtenissen.</string>
<string name="do_not_show_startup_messages_desc">Geen meldingen van app-aanbiedingen en speciale lokale gebeurtenissen tonen.</string>
<string name="parking_options">Parkeermogelijkheden</string>
<string name="full_version_thanks">Dank voor het aanschaffen van de volledige versie van OsmAnd!</string>
<string name="routing_attr_relief_smoothness_factor_hills_name">Heuvelachtige wegen</string>
@ -2621,17 +2622,17 @@ voor Gebied: %1$s x %2$s</string>
<string name="animate_my_location_desc">De kaart vloeiend weergeven tijdens navigatie.</string>
<string name="shared_string_slope">Helling</string>
<string name="add_new_folder">Nieuwe map ttoevoegen</string>
<string name="points_delete_multiple_succesful">Punt(en) met succes verwijderd.</string>
<string name="points_delete_multiple_succesful">Punt(en) verwijderd.</string>
<string name="points_delete_multiple">Er worden %1$d punt(en) verwijderd. Doorgaan ?</string>
<string name="route_points_category_name">Afslagen op de route</string>
<string name="track_points_category_name">Belangrijke punten op deze route</string>
<string name="routing_attr_relief_smoothness_factor_name">Kies voorkeur voor hoogteverschillen</string>
<string name="shared_string_paused">In pauze</string>
<string name="lang_ber">Berbers</string>
<string name="hillshade_menu_download_descr">Om reliëfschaduw weer te geven, moet je de reliëfschaduwkaart voor deze regio downloaden.</string>
<string name="hillshade_purchase_header">Om reliëfschaduw op de kaart weer te geven, moet je de Hoogtelijnen-plugin kopen en installeren.</string>
<string name="hillshade_menu_download_descr">Om reliëfschaduw weer te geven, de reliëfschaduwkaart voor deze regio downloaden.</string>
<string name="hillshade_purchase_header">Om reliëfschaduw op de kaart weer te geven, de Hoogtelijnen-plugin kopen en installeren</string>
<string name="hide_from_zoom_level">Niet tonen vanaf zoom-niveau</string>
<string name="srtm_menu_download_descr">Download de hoogtelijnenkaart voor deze regio om hoogtelijnen te zien.</string>
<string name="srtm_menu_download_descr">Download de hoogtelijnenkaart voor deze regio.</string>
<string name="shared_string_plugin">Plugin</string>
<string name="srtm_purchase_header">Om hoogtelijnen weer te geven, moet je de Hoogtelijnen-plugin kopen en installeren</string>
<string name="srtm_color_scheme">Kleurschema</string>
@ -2687,13 +2688,13 @@ voor Gebied: %1$s x %2$s</string>
\n • Afrika: **
\n • Antarctica: * Van bijna alle landen is een kaart te downloaden: van Afghanistan tot Zimbabwe, Australië tot de VS, Nederland, Duitsland, Spanje, Japan, …</string>
<string name="save_poi_too_many_uppercase">Naam bevat erg veel hoofdletters, toch doorgaan?</string>
<string name="search_favorites">Zoek favorieten</string>
<string name="search_favorites">Zoek Favorieten</string>
<string name="quick_action_showhide_osmbugs_title">OSM-opmerkingen tonen/verbergen</string>
<string name="quick_action_osmbugs_show">Toon OSM-opmerkingen</string>
<string name="quick_action_osmbugs_hide">Verberg OSM-opmerkingen</string>
<string name="quick_action_showhide_osmbugs_descr">Een druk op de sneltoets toont of verbergt OSM-opmerkingen.</string>
<string name="sorted_by_distance">Gesorteerd op afstand</string>
<string name="private_access_routing_req">Uw bestemming ligt in een gebied dat particulier eigendom is. Wilt u gebruik van particuliere wegen voor deze route toestaan?</string>
<string name="private_access_routing_req">Uw bestemming ligt in een gebied dat particulier eigendom is. Wilt je gebruik van particuliere wegen voor deze route toestaan\?</string>
<string name="restart_search">Opnieuw zoeken</string>
<string name="increase_search_radius">Zoekgebied vergroten</string>
<string name="nothing_found">Niets gevonden</string>
@ -2709,7 +2710,7 @@ voor Gebied: %1$s x %2$s</string>
<string name="improve_coverage_mapillary">Verbeter de fotocollectie van Mapillary</string>
<string name="improve_coverage_install_mapillary_desc">Installeer Mapillary om een of meerdere foto\'s aan deze locatie toe te voegen.</string>
<string name="mapillary_action_descr">Voeg zelf foto\'s van deze plek toe via Mapillary.</string>
<string name="mapillary_widget_descr">Voeg eenvoudig info toe aan Mapillary.</string>
<string name="mapillary_widget_descr">Snel bijdragen aan Mapillary.</string>
<string name="mapillary_descr">Foto\'s van buiten voor iedereen. Ondek plaatsen, werk samen, en leg de wereld vast.</string>
<string name="plugin_mapillary_descr">Foto\'s van buiten voor iedereen. Ondek plaatsen, werk samen, en leg de wereld vast.</string>
<string name="shared_string_permissions">Rechten</string>
@ -2769,7 +2770,7 @@ voor Gebied: %1$s x %2$s</string>
<string name="osn_modify_dialog_title">Wijzig notitie</string>
<string name="context_menu_item_modify_note">Wijzig OSM-notitie</string>
<string name="make_round_trip_descr">Kopieer het beginpunt en voeg het toe als bestemming.</string>
<string name="make_round_trip">Ga heen en terug</string>
<string name="make_round_trip">Een rondreis maken</string>
<string name="shared_string_markers">Markeringen</string>
<string name="coordinates_format">Coördinatenformaat</string>
@ -2781,29 +2782,29 @@ voor Gebied: %1$s x %2$s</string>
<string name="use_location">Gebruik mijn positie</string>
<string name="add_location_as_first_point_descr">Voeg je positie toe als startpunt voor de optimale route.</string>
<string name="my_location">Mijn positie</string>
<string name="shared_string_finish">Einde</string>
<string name="shared_string_finish">Afsluiten</string>
<string name="plan_route">Plan route</string>
<string name="shared_string_sort">Sorteer</string>
<string name="coordinate_input">Invoer van coördinaten</string>
<string name="is_saved">is opgeslagen</string>
<string name="marker_save_as_track_descr">Exporteer uw markeringen naar een bestand dat u hier opgeeft:</string>
<string name="marker_save_as_track">Bewaar als spoor</string>
<string name="marker_save_as_track_descr">Exporteer uw Markeervlaggetjes naar het volgende bestand:</string>
<string name="marker_save_as_track">Opslaan als GPX-track</string>
<string name="move_to_history">Verplaats naar geschiedenis</string>
<string name="group_will_be_removed_after_restart">De groep wordt verwijderd na een herstart van de app.</string>
<string name="group_will_be_removed_after_restart">De groep is verwijderd na een herstart van de app.</string>
<string name="show_guide_line">Richtingslijnen tonen</string>
<string name="show_arrows_on_the_map">Toon pijlen op de kaart</string>
<string name="show_passed">Toon afgelopen</string>
<string name="hide_passed">Verberg afgelopen</string>
<string name="show_passed">Afgehandelde tonen</string>
<string name="hide_passed">Afgehandelde verbergen</string>
<string name="remove_from_map_markers">Uit kaartmarkeringen verwijderen</string>
<string name="date_added">Toegevoegd op</string>
<string name="order_by">Sorteer op:</string>
<string name="marker_show_distance_descr">Weergave van afstand en richting naar markeingen op het kaartscherm:</string>
<string name="map_orientation_change_in_accordance_with_speed">Kaart naar beweegrichting draaien vanaf</string>
<string name="map_orientation_change_in_accordance_with_speed_descr">Kies de snelheid waarboven de kaart gedraaid wordt van \'In richting van beweging\' naar \'volgens kompasrichting\'.</string>
<string name="map_orientation_change_in_accordance_with_speed">Snelheidsdrempel beweegrichting</string>
<string name="map_orientation_change_in_accordance_with_speed_descr">Kies de snelheid waarboven Kaartrotatie wijzigt van \'Volgens kompas\' naar \'In beweegrichting\'.</string>
<string name="all_markers_moved_to_history">Alle kaartmarkeringen zijn naar de geschiedenis verplaatst</string>
<string name="marker_moved_to_history">Kaartmerkering naar geschiedenis verplaatst</string>
<string name="marker_moved_to_active">Kaartmarkering actief gemaakt</string>
<string name="passed">Laatst gebruikte: %1$s</string>
<string name="passed">Laatst gebruikt: %1$s</string>
<string name="make_active">Maak actief</string>
<string name="measurement_tool_snap_to_road_descr">OsmAnd zal de punten verbinden met een route voor het gekozen profiel.</string>
<string name="measurement_tool_save_as_new_track_descr">Sla de punten op als routepunten of als een lijn.</string>
@ -2815,7 +2816,7 @@ voor Gebied: %1$s x %2$s</string>
<string name="store_tracks_in_monthly_directories">Bewaar opgenomen sporen per maand in een map</string>
<string name="store_tracks_in_monthly_directories_descrp">Bewaar opgenomen sporen in een map voor elke maand (bijvoorbeeld 2018-01).</string>
<string name="mapillary_menu_descr_tile_cache">Herlaad de tegels om de gegevens te verversen.</string>
<string name="mapillary_menu_title_tile_cache">Tegel-cache</string>
<string name="mapillary_menu_title_tile_cache">Tegel-cachegeheugen</string>
<string name="mapillary_menu_descr_username">Alleen afbeeldingen bekijken die zijn toegevoegd door</string>
<string name="rendering_value_translucent_pink_name">Transparant roze</string>
<string name="ascent_descent">Stijgen/Dalen</string>
@ -2842,7 +2843,7 @@ voor Gebied: %1$s x %2$s</string>
<string name="import_track_desc">Bestand %1$s bevat geen waypoints. Importeren als een track?</string>
<string name="move_point">Verplaats punt</string>
<string name="add_segment_to_the_track">Voeg toe aan GPX-track</string>
<string name="mapillary_menu_filter_description">Filter afbeeldingen op gebruikersnaam of datum. Alleen actief wanneer ingezoomd.</string>
<string name="mapillary_menu_filter_description">"Filter afbeeldingen op gebruikersnaam, datum of type. Alleen actief wanneer ingezoomd."</string>
<string name="show_map">Kaart weergeven</string>
<string name="route_is_calculated">Route berekend</string>
<string name="round_trip">Retour</string>
@ -2859,9 +2860,9 @@ voor Gebied: %1$s x %2$s</string>
<string name="tap_on_map_to_hide_interface">Volledig scherm</string>
<string name="mark_passed">Markering gepasseerd</string>
<string name="import_gpx_file_description">kan worden geïmporteerd als favoriet of trackbestand.</string>
<string name="import_gpx_file_description">kan worden geïmporteerd als Favorieten of als GPX-track.</string>
<string name="import_as_gpx">importeer als GPX bestand</string>
<string name="import_as_favorites">Importeren als favoriet</string>
<string name="import_as_favorites">"Importeren als Favorieten "</string>
<string name="import_file">Importeer bestand</string>
<string name="appearance_on_the_map">Weergave op de kaart</string>
<string name="favourites_group">Favorietencategorie</string>
@ -2869,7 +2870,7 @@ voor Gebied: %1$s x %2$s</string>
<string name="empty_state_markers_active">Maak markeringen aan op de kaart!</string>
<string name="shared_string_two">Twee</string>
<string name="shared_string_one">Een</string>
<string name="active_markers_descr">Kies hoeveel richtingaanwijzers u wilt zien.</string>
<string name="active_markers_descr">"Kies hoeveel richtingaanwijzers getoond worden. "</string>
<string name="digits_quantity">Aantal decimalen</string>
<string name="shared_string_right">Rechts</string>
<string name="shared_string_left">Links</string>
@ -3038,7 +3039,7 @@ voor Gebied: %1$s x %2$s</string>
<string name="read_wikipedia_offline">Wikipedia offline lezen</string>
<string name="download_all">Alles downloaden</string>
<string name="will_open_on">Gaat open om</string>
<string name="add_favourites_group_to_markers_descr">Kies een categorie favorieten om aan de markeringen toe te voegen.</string>
<string name="add_favourites_group_to_markers_descr">Kies een categorie Favorieten avorieten om aan de markeringen toe te voegen.</string>
<string name="empty_state_markers_groups">Groepen importeren</string>
<string name="distance_indication_descr">Kies hoe de afstand naar actieve markeringen weergegeven wordt.</string>
<string name="index_item_world_wikivoyage">Wereldwijde Wikivoyage-artikelen</string>
@ -3129,4 +3130,8 @@ voor Gebied: %1$s x %2$s</string>
<string name="keep_passed_markers">Gepasseerde vlaggetjes op de kaart behouden</string>
<string name="more_transport_on_stop_hint">"Op deze halte zijn er meerdere verbindingen. "</string>
<string name="ask_for_location_permission">"Geef OsmAnd toegang tot Locatievoorzieningen om door te gaan. "</string>
<string name="keep_passed_markers_descr">Markeervlaggetjes die als Favorieten of als GPX-track toegevoegd zijn, en afgehandeld zijn, blijven zichtbaar op de kaart. Als die groep niet meer actief is, zullen ze verdwijnen.</string>
<string name="mapillary_menu_title_pano">Alleen 360°-foto\'s tonen</string>
<string name="rendering_value_black_name">Zwart</string>
<string name="copy_location_name">"Naam kopiëren "</string>
</resources>

View file

@ -1,4 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?>
<?xml version="1.0" encoding="utf-8"?>
<resources><string name="poi_shop">Loja</string>
<string name="poi_shop_food">Loja de conveniência e supermercado</string>
<string name="poi_emergency">Emergência</string>
@ -21,7 +21,7 @@
<string name="poi_education">Educação</string>
<string name="poi_administrative">Administrativo</string>
<string name="poi_healthcare">Saúde</string>
<string name="poi_office">Escritório</string>
<string name="poi_office">Ponto de informação</string>
<string name="poi_sport">Esporte</string>
<string name="poi_tourism">Turismo</string>
<string name="poi_accomodation">Alojamento</string>
@ -220,7 +220,7 @@
<string name="poi_railway_platform">Plataforma ferroviária</string>
<string name="poi_halt">Parada ferroviária</string>
<string name="poi_subway_entrance">Entrada do metrô</string>
<string name="poi_subway_station">Estação de metrô</string>
<string name="poi_subway_station">Sim</string>
<string name="poi_vacuum_cleaner">Loja de aspiradores de pó</string>
<string name="poi_variety_store">Loja de variedades</string>
<string name="poi_video">Loja/locadora de vídeos</string>
@ -944,7 +944,7 @@
<string name="poi_access_agricultural">Acesso agrícola</string>
<string name="poi_monitoring_station">Estação de medição ambiental</string>
<string name="poi_capital">Capital</string>
<string name="poi_capital">Sim</string>
<string name="poi_fee_no">Não</string>
<string name="poi_email">Email</string>
@ -1272,7 +1272,7 @@
<string name="poi_information_guidepost">Poste com direções</string>
<string name="poi_information_board">Painel</string>
<string name="poi_information_map">Mapa</string>
<string name="poi_information_office">Centro de informação</string>
<string name="poi_information_office">Ponto de informação</string>
<string name="poi_information_trail_blaze">Marca de caminho</string>
<string name="poi_information_terminal">Terminal</string>
<string name="poi_information_route_marker">Marcador de rota</string>
@ -1343,7 +1343,7 @@
<string name="poi_dead_wood">Árvores mortas</string>
<string name="poi_passing_place">Lugar de passagem</string>
<string name="poi_level">Nível</string>
<string name="poi_level">Andar</string>
<string name="poi_bird_hide">Observatório de aves</string>
<string name="poi_internet_access_yes">Com acesso à Internet</string>
@ -1458,26 +1458,26 @@
<string name="poi_payment_american_express_no">Não aceita cartão American Express (AMEX)</string>
<string name="poi_payment_diners_club_yes">Diners Club</string>
<string name="poi_payment_diners_club_no">Não aceita cartão Diners Club</string>
<string name="poi_payment_dkv_yes">Aceita DKV</string>
<string name="poi_payment_dkv_yes">DKV</string>
<string name="poi_payment_dkv_no">Não aceita DKV</string>
<string name="poi_payment_uta_yes">Aceita cartão UTA</string>
<string name="poi_payment_uta_yes">UTA</string>
<string name="poi_payment_uta_no">Não aceita cartão UTA</string>
<string name="poi_payment_efectivo_yes">Efectivo</string>
<string name="poi_payment_efectivo_no">Não aceita Efectivo</string>
<string name="poi_payment_girocard_yes">Aceita Girocard</string>
<string name="poi_payment_girocard_yes">Girocard</string>
<string name="poi_payment_girocard_no">Não aceita Girocard</string>
<string name="poi_payment_discover_card_yes">Aceita Discover Card</string>
<string name="poi_payment_discover_card_yes">Discover Card</string>
<string name="poi_payment_discover_card_no">Não aceita Discover Card</string>
<string name="poi_payment_visa_electron_yes">Aceita Visa Electron</string>
<string name="poi_payment_visa_electron_yes">Visa Electron</string>
<string name="poi_payment_visa_electron_no">Não aceita Visa Electron</string>
<string name="poi_payment_litecoin_yes">Aceita Litecoin</string>
<string name="poi_payment_litecoin_yes">Litecoin</string>
<string name="poi_payment_litecoin_no">Não aceita Litecoin</string>
<string name="poi_payment_cheque_yes">Cheque</string>
<string name="poi_payment_cheque_no">Não aceita cheque</string>
<string name="poi_payment_pikepass_yes">Aceita PIKEPASS</string>
<string name="poi_payment_pikepass_yes">PIKEPASS</string>
<string name="poi_payment_pikepass_no">Não aceita PIKEPASS</string>
<string name="poi_payment_pikepass_designated">Aceita PIKEPASS (designated)</string>
<string name="poi_payment_visa_debit_yes">Aceita cartão Visa Débito</string>
<string name="poi_payment_pikepass_designated">PIKEPASS (designado)</string>
<string name="poi_payment_visa_debit_yes">Cartão Visa Débito</string>
<string name="poi_payment_visa_debit_no">Não aceita cartão Visa Débito</string>
<string name="poi_payment_cryptocurrencies_no">Não aceita criptomoedas</string>
<string name="poi_payment_others_yes">Outros</string>
@ -1796,7 +1796,7 @@
<string name="poi_aerialway_bubble_yes">Bolha</string>
<string name="poi_aerialway_bubble_no">Sem bolha</string>
<string name="poi_vending_bicycle_tube">Tubos para bicicletas</string>
<string name="poi_vending_bicycle_tube">Câmaras de ar para bicicleta</string>
<string name="poi_branch">Seção</string>
<string name="poi_memorial_cross">Cruzeiro</string>
@ -2100,11 +2100,11 @@
<string name="poi_historic_milestone">Marco histórico</string>
<string name="poi_shoes_children">Calçados infantis</string>
<string name="poi_shoes_women">Calçados femininos</string>
<string name="poi_shoes_sport">Calçados esportivos</string>
<string name="poi_shoes_men">Calçados masculinos</string>
<string name="poi_shoes_orthopedic">Calçados ortopédicos</string>
<string name="poi_shoes_children">Crianças</string>
<string name="poi_shoes_women">femininos</string>
<string name="poi_shoes_sport">esportivos</string>
<string name="poi_shoes_men">Masculinos</string>
<string name="poi_shoes_orthopedic">Ortopédicos</string>
<string name="poi_historic_manor">Mansão histórica</string>
<string name="poi_castle_type_stately">Tipo de castelo: majestoso</string>
@ -2554,7 +2554,7 @@
<string name="poi_craft_electronics_repair">Conserto de eletrônicos</string>
<string name="poi_fireworks">Loja de fogos de artifício</string>
<string name="poi_memorial_fassade_decoration">Decoração da fachada</string>
<string name="poi_memorial_fassade_decoration">Decoração de fachada</string>
<string name="poi_site_type_hut_circle">Círculo de cabana</string>
<string name="poi_fortification_type_ring_ditch">Tipo de fortificação: vala circular</string>
@ -3900,5 +3900,34 @@
<string name="poi_shoe_repair">Conserto de sapatos</string>
<string name="poi_license_classes">Categorias</string>
</resources>
<string name="poi_bulk_purchase">Compra a granel</string>
<string name="poi_substation_type">Tipo</string>
<string name="poi_books_type">Livros</string>
<string name="poi_bulk_purchase_yes">Sim</string>
<string name="poi_bulk_purchase_only">Somente</string>
<string name="poi_pipeline_substation">Subestação de oleoduto</string>
<string name="poi_substation_transmission">Transmissão</string>
<string name="poi_substation_distribution">Distribuição</string>
<string name="poi_substation_minor_distribution">Distribuição menor</string>
<string name="poi_substation_industrial">Industrial</string>
<string name="poi_substation_transition">Transição</string>
<string name="poi_substation_traction">Tração</string>
<string name="poi_substation_converter">Conversor</string>
<string name="poi_substation_compensation">Compensação</string>
<string name="poi_substation_compression">Compressão</string>
<string name="poi_substation_measurement">Medição</string>
<string name="poi_substation_valve">Válvula</string>
<string name="poi_substation_valve_group">Grupo de válvulas</string>
<string name="poi_substation_inspection_gauge">Medidor de inspeção</string>
<string name="poi_substation_field_gathering">Recolhimento de campo</string>
<string name="poi_craft_confectionery">Produção de confeitos</string>
<string name="poi_shop_wholesale">Loja de atacado</string>
<string name="poi_laboratory">Laboratório médico</string>
<string name="poi_blood_donation">Doação de sangue</string>
<string name="poi_books_comic">Quadrinho</string>
<string name="poi_books_antiquarian">Antiquário</string>
<string name="poi_books_religion">Religião</string>
<string name="poi_books_academic">Acadêmicos</string>
<string name="poi_books_children">Crianças</string>
<string name="poi_atoll">Atol</string>
</resources>

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