Merge pull request #10760 from osmandapp/master

update test branch
This commit is contained in:
Hardy 2021-02-04 08:12:40 +01:00 committed by GitHub
commit b767cc0941
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
102 changed files with 2475 additions and 1552 deletions

3
.gitignore vendored
View file

@ -16,7 +16,8 @@ OsmAndCore_*.aar
*.iml *.iml
.settings .settings
.idea .idea
.project **/.project
**/.classpath
out/ out/
# Huawei # Huawei

View file

@ -0,0 +1,218 @@
package net.osmand.osm;
public enum RouteActivityType {
WATER("Water", "yellow"), WINTER("Winter", "yellow"), SNOWMOBILE("Snowmobile", "yellow"), RIDING("Riding", "yellow"), RACING("Racing", "yellow"),
MOUNTAINBIKE("Mountainbike", "blue"), CYCLING("Cycling", "blue"),
HIKING("Hiking", "orange"), RUNNING("Running", "orange"), WALKING("Walking", "orange"),
OFFROAD("Off-road", "yellow"),
MOTORBIKE("Motorbike", "green"), CAR("Car", "green");
// less specific bottom order
String name;
String color;
private RouteActivityType(String nm, String clr) {
this.name = nm;
this.color = clr;
}
public String getName() {
return name;
}
public String getColor() {
return color;
}
public static RouteActivityType getTypeFromTags(String[] tags) {
RouteActivityType activityType = null;
for (String tg : tags) {
RouteActivityType rat = RouteActivityType.convertFromOsmGPXTag(tg);
if (rat != null) {
if (activityType == null || activityType.ordinal() > rat.ordinal()) {
activityType = rat;
}
}
}
return activityType;
}
public static RouteActivityType convertFromOsmGPXTag(String tg) {
String t = tg.toLowerCase();
if ("mountain hiking".equalsIgnoreCase(t)) {
return HIKING;
}
if ("motorcar".equalsIgnoreCase(t)) {
return CAR;
}
if ("laufen".equalsIgnoreCase(t)) {
return RUNNING;
}
if ("pedestrian".equalsIgnoreCase(t)) {
return WALKING;
}
switch (t) {
case "mountainbiking":
case "mtb":
case "mountainbike":
case "mountain bike":
case "mountain biking":
case "mountbarker":
case "mtb-tour":
case "ciclismo-mtb-gravel":
case "vtt":
case "btt":
case "vth":
case "mtb ride":
return MOUNTAINBIKE;
case "hiking":
case "route=hiking":
case "mountain hiking":
case "hiking trail":
case "wandern":
case "hike":
case "randonnée":
case "trekking":
case "climbing":
return HIKING;
case "bike":
case "biking":
case "bicycling":
case "bicycle":
case "cycling":
case "cycle":
case "cycleway":
case "cykel":
case "handcycle":
case "cyclotourisme":
case "route=bicycle":
case "cyclotourism":
case "fietsen":
case "вело":
case "велосипед":
case "rower":
case "trasa rowerem":
case "vélo":
case "velo":
case "radtour":
case "bici":
case "fiets":
case "fahrrad":
case "ncn":
case "icn":
case "lcn":
case "network=ncn":
case "network=icn":
case "network=lcn":
return CYCLING;
case "car":
case "motorcar":
case "by car":
case "auto":
case "автомобиль":
case "automobile":
case "autós":
case "driving":
case "drive":
case "van":
case "авто":
case "на автомобиле":
case "bus":
case "truck":
case "taxi":
return CAR;
case "running":
case "run":
case "rungis":
case "trail running":
case "trailrunning":
case "бег":
case "laufen":
case "langlauf":
case "lauf":
case "course":
case "jogging":
case "fitotrack":
return RUNNING;
case "wanderung":
case "walking":
case "walk":
case "nightwalk":
case "walkway":
case "пешком":
case "пеший":
case "pěšky":
case "marche":
case "pedestrian":
case "foot":
case "footing":
case "on_foot":
case "byfoot":
case "onfoot":
case "sightseeing":
case "geocaching":
case "etnanatura":
case "etna":
case "iwn":
case "lwn":
case "rwn":
case "network=iwn":
case "network=lwn":
case "network=rwn":
return WALKING;
case "ling-moto":
case "motorbiking":
case "motorcycle":
case "motorrad":
case "motorbike":
case "motor bike":
case "FVbike":
case "Motorrad":
return MOTORBIKE;
case "offroad":
case "off-road":
case "off road":
case "4x4":
case "terrain":
case "quad":
case "enduro":
case "feldwege":
case "feldweg":
return OFFROAD;
case "boat":
case "water":
case "boating":
case "kayak":
case "river":
case "lake":
case "lakes":
case "canal":
return WATER;
case "ski":
case "skiing":
case "skating":
case "skitour":
case "winter":
case "wintersports":
case "snowboard":
case "лыжи":
case "лыжня":
case "nordic":
case "piste":
return WINTER;
case "snowmobile=designated":
case "snowmobile=permissive":
case "snowmobile=yes":
case "snowmobile":
return SNOWMOBILE;
case "ride":
case "horse":
case "horse trail":
return RIDING;
case "racing":
return RACING;
}
return null;
}
}

View file

@ -94,6 +94,10 @@ public class OsmOAuthAuthorizationClient {
return accessToken; return accessToken;
} }
public OAuth1RequestToken getRequestToken() {
return requestToken;
}
public Response performRequestWithoutAuth(String url, String requestMethod, String requestBody) public Response performRequestWithoutAuth(String url, String requestMethod, String requestBody)
throws InterruptedException, ExecutionException, IOException { throws InterruptedException, ExecutionException, IOException {
Verb verb = parseRequestMethod(requestMethod); Verb verb = parseRequestMethod(requestMethod);

View file

@ -367,8 +367,9 @@ public class RouteStatisticsHelper {
RouteDataObject obj = segment.obj; RouteDataObject obj = segment.obj;
for (int type : obj.getTypes()) { for (int type : obj.getTypes()) {
BinaryMapRouteReaderAdapter.RouteTypeRule tp = obj.region.quickGetEncodingRule(type); BinaryMapRouteReaderAdapter.RouteTypeRule tp = obj.region.quickGetEncodingRule(type);
if (tp.getTag().equals("highway") || tp.getTag().equals("route") || if (tp.getTag().equals("highway") || tp.getTag().equals("route")
tp.getTag().equals("railway") || tp.getTag().equals("aeroway") || tp.getTag().equals("aerialway")) { || tp.getTag().equals("railway") || tp.getTag().equals("aeroway")
|| tp.getTag().equals("aerialway") || tp.getTag().equals("piste:type")) {
if (!mainTagAdded) { if (!mainTagAdded) {
req.setStringFilter(rrs.PROPS.R_TAG, tp.getTag()); req.setStringFilter(rrs.PROPS.R_TAG, tp.getTag());
req.setStringFilter(rrs.PROPS.R_VALUE, tp.getValue()); req.setStringFilter(rrs.PROPS.R_VALUE, tp.getValue());

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -8,7 +8,7 @@
android:layout_weight="1"> android:layout_weight="1">
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/tab_title" android:id="@+id/center_button"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"

View file

@ -3,12 +3,12 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/custom_radio_buttons" android:id="@+id/custom_radio_buttons"
android:layout_width="match_parent" android:layout_width="match_parent"
android:minHeight="@dimen/dialog_button_height"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/content_padding" android:layout_marginStart="@dimen/content_padding"
android:layout_marginEnd="@dimen/content_padding" android:layout_marginEnd="@dimen/content_padding"
android:background="?attr/btn_bg_border_inactive" android:background="?attr/btn_bg_border_inactive"
android:baselineAligned="false" android:baselineAligned="false"
android:minHeight="@dimen/dialog_button_height"
android:orientation="horizontal" android:orientation="horizontal"
tools:showIn="@layout/fragment_route_between_points_bottom_sheet_dialog"> tools:showIn="@layout/fragment_route_between_points_bottom_sheet_dialog">
@ -22,7 +22,8 @@
layout="@layout/center_button_container" layout="@layout/center_button_container"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1" /> android:layout_weight="1"
android:visibility="gone" />
<include <include
layout="@layout/right_button_container" layout="@layout/right_button_container"

View file

@ -9,7 +9,8 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/card_row_min_height"> android:layout_height="wrap_content"
android:minHeight="@dimen/card_row_min_height">
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@android:id/icon" android:id="@android:id/icon"
@ -31,11 +32,15 @@
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_weight="1" android:layout_weight="1"
android:paddingLeft="@dimen/content_padding" android:paddingLeft="@dimen/content_padding"
android:paddingStart="@dimen/content_padding"
android:paddingRight="0dp"
android:paddingEnd="0dp"
android:paddingTop="@dimen/content_padding_half"
android:paddingBottom="@dimen/content_padding_half"
android:textColor="?android:textColorPrimary" android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_desc_text_size" android:textSize="@dimen/default_desc_text_size"
osmand:typeface="@string/font_roboto_regular" osmand:typeface="@string/font_roboto_regular"
tools:text="Internal application memory" tools:text="Internal application memory" />
android:paddingStart="@dimen/content_padding" />
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/memory" android:id="@+id/memory"

View file

@ -1,36 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/bg_color" android:background="?attr/bg_color"
android:clickable="true" android:orientation="vertical">
android:focusable="true"
android:orientation="vertical">
<LinearLayout <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height" android:layout_height="@dimen/toolbar_height"
android:layout_marginTop="@dimen/dialog_content_margin"> android:gravity="center_vertical"
android:padding="0dp" />
<androidx.appcompat.widget.AppCompatImageView <ScrollView
android:id="@+id/back_button"
style="@style/Widget.AppCompat.Toolbar.Button.Navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:contentDescription="@string/shared_string_back"
app:srcCompat="@drawable/ic_arrow_back"
app:tint="@color/icon_color_default_light" />
</LinearLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dp"
android:layout_below="@id/toolbar" android:layout_weight="1">
android:layout_above="@id/buttons">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -49,7 +35,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/content_padding" android:layout_marginLeft="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding" android:layout_marginTop="@dimen/content_padding_small"
android:layout_marginRight="@dimen/content_padding" android:layout_marginRight="@dimen/content_padding"
android:layout_marginBottom="@dimen/dashPadding" android:layout_marginBottom="@dimen/dashPadding"
android:gravity="center_horizontal" android:gravity="center_horizontal"
@ -68,23 +54,25 @@
android:layout_marginTop="@dimen/dashPadding" android:layout_marginTop="@dimen/dashPadding"
android:layout_marginRight="@dimen/content_padding" android:layout_marginRight="@dimen/content_padding"
android:lineSpacingMultiplier="@dimen/bottom_sheet_text_spacing_multiplier" android:lineSpacingMultiplier="@dimen/bottom_sheet_text_spacing_multiplier"
app:typeface="@string/font_roboto_regular"
android:text="@string/register_on_openplacereviews_desc" android:text="@string/register_on_openplacereviews_desc"
android:textColor="?android:textColorPrimary" android:textColor="?android:textColorPrimary"
android:textColorLink="@color/icon_color_active_light"
android:textSize="@dimen/default_list_text_size" android:textSize="@dimen/default_list_text_size"
android:textColorLink="@color/icon_color_active_light" /> app:typeface="@string/font_roboto_regular" />
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView>
</ScrollView>
<LinearLayout <LinearLayout
android:id="@+id/buttons" android:id="@+id/buttons"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginLeft="@dimen/content_padding" android:layout_marginLeft="@dimen/content_padding"
android:layout_marginTop="@dimen/content_padding_small" android:layout_marginTop="@dimen/content_padding_small"
android:layout_marginRight="@dimen/content_padding" android:layout_marginRight="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding_small" android:layout_marginBottom="@dimen/content_padding_small"
android:layout_alignParentBottom="true"
android:orientation="vertical"> android:orientation="vertical">
<include <include
@ -102,4 +90,4 @@
</LinearLayout> </LinearLayout>
</RelativeLayout> </LinearLayout>

View file

@ -8,7 +8,7 @@
android:layout_weight="1"> android:layout_weight="1">
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/tab_title" android:id="@+id/left_button"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"

View file

@ -61,6 +61,13 @@
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:text="@string/amenity_type_finance"/> android:text="@string/amenity_type_finance"/>
<LinearLayout
android:id="@+id/context_menu_custom_address_line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -8,7 +8,7 @@
android:layout_weight="1"> android:layout_weight="1">
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/tab_title" android:id="@+id/right_button"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/selectableItemBackground" android:background="?attr/selectableItemBackground"

View file

@ -1,5 +1,4 @@
<LinearLayout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -8,7 +7,8 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="56dp" android:layout_height="wrap_content"
android:minHeight="@dimen/context_menu_action_buttons_height"
android:background="?attr/pstsTabBackground" android:background="?attr/pstsTabBackground"
android:gravity="center_vertical" android:gravity="center_vertical"
android:orientation="horizontal"> android:orientation="horizontal">
@ -19,19 +19,19 @@
android:layout_width="52dp" android:layout_width="52dp"
android:layout_height="52dp" android:layout_height="52dp"
android:contentDescription="@string/shared_string_close" android:contentDescription="@string/shared_string_close"
app:srcCompat="@drawable/ic_action_remove_dark"/> app:srcCompat="@drawable/ic_action_remove_dark" />
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/titleTextView" android:id="@+id/titleTextView"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp" android:layout_marginLeft="20dp"
android:text="@string/osm_live_subscription" android:text="@string/osm_live_subscription"
android:textColor="@color/color_white" android:textColor="@color/color_white"
android:textSize="@dimen/default_list_text_size_large" android:textSize="@dimen/default_list_text_size_large"
android:textStyle="bold" android:textStyle="bold"
app:typeface="@string/font_roboto_regular" app:typeface="@string/font_roboto_regular" />
android:layout_marginStart="20dp" />
</LinearLayout> </LinearLayout>
@ -39,7 +39,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<include layout="@layout/card_bottom_divider"/> <include layout="@layout/card_bottom_divider" />
<ScrollView <ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
@ -67,8 +67,8 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:minHeight="56dp" android:minHeight="56dp"
android:orientation="horizontal"> android:orientation="horizontal">
@ -76,54 +76,81 @@
android:layout_width="56dp" android:layout_width="56dp"
android:layout_height="48dp" android:layout_height="48dp"
android:scaleType="center" android:scaleType="center"
app:srcCompat="@drawable/ic_action_osm_live" android:tint="@color/osmand_orange"
android:tint="@color/osmand_orange"/> app:srcCompat="@drawable/ic_action_osm_live" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp" android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:paddingStart="2dp"
android:paddingLeft="2dp" android:paddingLeft="2dp"
android:text="@string/osm_live_subscription_desc" android:text="@string/osm_live_subscription_desc"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary" />
android:layout_marginEnd="16dp"
android:paddingStart="2dp"
android:layout_marginStart="16dp" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:layout_marginBottom="8dp"
android:minHeight="56dp" android:minHeight="56dp"
android:orientation="vertical"> android:orientation="horizontal">
<androidx.appcompat.widget.AppCompatCheckBox <androidx.appcompat.widget.AppCompatCheckBox
android:id="@+id/donationCheckbox" android:id="@+id/donationCheckbox"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="16dp" android:layout_marginTop="@dimen/context_menu_second_line_top_margin"
android:paddingLeft="34dp" android:layout_marginStart="@dimen/list_content_padding"
android:text="@string/donation_to_osm" android:layout_marginLeft="@dimen/list_content_padding"
android:paddingStart="34dp" android:paddingStart="@dimen/local_size_height"
android:layout_marginStart="16dp" /> android:paddingLeft="@dimen/local_size_height"
android:paddingEnd="@dimen/local_size_height"
android:paddingRight="@dimen/local_size_height"
android:text="@string/donation_to_osm" />
<TextView <LinearLayout
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="72dp" android:minHeight="56dp"
android:layout_marginRight="16dp" android:orientation="vertical">
android:layout_marginTop="8dp"
android:paddingLeft="2dp" <TextView
android:text="@string/donation_to_osm_desc" android:layout_width="match_parent"
android:textColor="?android:attr/textColorSecondary" android:layout_height="wrap_content"
android:layout_marginEnd="16dp" android:layout_marginStart="@dimen/list_content_padding_large"
android:layout_marginStart="72dp" android:layout_marginLeft="@dimen/context_menu_progress_padding_left"
android:paddingStart="2dp" /> android:layout_marginEnd="@dimen/context_menu_progress_padding_left"
android:layout_marginRight="@dimen/context_menu_progress_padding_left"
android:paddingStart="@dimen/subHeaderPadding"
android:paddingLeft="@dimen/subHeaderPadding"
android:paddingEnd="@dimen/subHeaderPadding"
android:paddingRight="@dimen/subHeaderPadding"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
android:text="@string/donation_to_osm" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/list_content_padding_large"
android:layout_marginLeft="@dimen/context_menu_progress_padding_left"
android:layout_marginEnd="@dimen/context_menu_progress_padding_left"
android:layout_marginRight="@dimen/context_menu_progress_padding_left"
android:paddingStart="@dimen/subHeaderPadding"
android:paddingLeft="@dimen/subHeaderPadding"
android:paddingEnd="@dimen/subHeaderPadding"
android:paddingRight="@dimen/subHeaderPadding"
android:text="@string/donation_to_osm_desc"
android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
@ -140,13 +167,13 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"
android:layout_marginBottom="6dp" android:layout_marginBottom="6dp"
android:background="?attr/dashboard_divider"/> android:background="?attr/dashboard_divider" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:layout_marginBottom="8dp"
android:minHeight="56dp" android:minHeight="56dp"
android:orientation="horizontal"> android:orientation="horizontal">
@ -155,47 +182,48 @@
android:layout_width="56dp" android:layout_width="56dp"
android:layout_height="48dp" android:layout_height="48dp"
android:scaleType="center" android:scaleType="center"
app:srcCompat="@drawable/ic_world_globe_dark"/> app:srcCompat="@drawable/ic_world_globe_dark" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp" android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:orientation="vertical" android:layout_marginEnd="16dp"
android:layout_marginStart="16dp" android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"> android:orientation="vertical">
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingLeft="2dp" android:paddingStart="@dimen/subHeaderPadding"
android:paddingEnd="@dimen/subHeaderPadding"
android:paddingLeft="@dimen/subHeaderPadding"
android:paddingRight="@dimen/subHeaderPadding"
android:text="@string/osm_live_support_region" android:text="@string/osm_live_support_region"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary" />
android:paddingStart="2dp" />
<net.osmand.plus.widgets.AutoCompleteTextViewEx <net.osmand.plus.widgets.AutoCompleteTextViewEx
android:id="@+id/selectCountryEdit" android:id="@+id/selectCountryEdit"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:drawableRightCompat="@drawable/ic_action_arrow_drop_down" android:paddingStart="2dp"
app:drawableEndCompat="@drawable/ic_action_arrow_drop_down"
android:editable="false"
android:paddingLeft="2dp" android:paddingLeft="2dp"
android:paddingEnd="0dp"
android:paddingRight="0dp" android:paddingRight="0dp"
android:text="Ukraine" android:text="Ukraine"
android:paddingStart="2dp" app:drawableEndCompat="@drawable/ic_action_arrow_drop_down"
android:paddingEnd="0dp" /> app:drawableRightCompat="@drawable/ic_action_arrow_drop_down" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:paddingStart="2dp"
android:paddingLeft="2dp" android:paddingLeft="2dp"
android:text="@string/osm_live_region_desc" android:text="@string/osm_live_region_desc"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary" />
android:paddingStart="2dp" />
</LinearLayout> </LinearLayout>
@ -213,21 +241,21 @@
android:layout_width="56dp" android:layout_width="56dp"
android:layout_height="48dp" android:layout_height="48dp"
android:scaleType="center" android:scaleType="center"
app:srcCompat="@drawable/ic_action_message"/> app:srcCompat="@drawable/ic_action_message" />
<EditText <EditText
android:id="@+id/emailEdit" android:id="@+id/emailEdit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp" android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:hint="@string/shared_string_email_address" android:hint="@string/shared_string_email_address"
android:inputType="textEmailAddress" android:inputType="textEmailAddress"
android:paddingLeft="2dp" android:paddingStart="2dp"
android:layout_marginStart="16dp" android:paddingLeft="2dp" />
android:layout_marginEnd="16dp"
android:paddingStart="2dp" />
</LinearLayout> </LinearLayout>
@ -235,14 +263,14 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginStart="72dp"
android:layout_marginLeft="72dp" android:layout_marginLeft="72dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:paddingStart="2dp"
android:paddingLeft="2dp" android:paddingLeft="2dp"
android:text="@string/osm_live_email_desc" android:text="@string/osm_live_email_desc"
android:textColor="?android:attr/textColorSecondary" android:textColor="?android:attr/textColorSecondary" />
android:paddingStart="2dp"
android:layout_marginStart="72dp"
android:layout_marginEnd="16dp" />
<LinearLayout <LinearLayout
@ -261,21 +289,21 @@
android:layout_width="56dp" android:layout_width="56dp"
android:layout_height="48dp" android:layout_height="48dp"
android:scaleType="center" android:scaleType="center"
app:srcCompat="@drawable/ic_action_user"/> app:srcCompat="@drawable/ic_action_user" />
<EditText <EditText
android:id="@+id/userNameEdit" android:id="@+id/userNameEdit"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp" android:layout_marginLeft="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:hint="@string/osm_live_user_public_name" android:hint="@string/osm_live_user_public_name"
android:inputType="text" android:inputType="text"
android:paddingLeft="2dp" android:paddingStart="2dp"
android:layout_marginEnd="16dp" android:paddingLeft="2dp" />
android:layout_marginStart="16dp"
android:paddingStart="2dp" />
</LinearLayout> </LinearLayout>
@ -284,16 +312,16 @@
android:id="@+id/hideUserNameCheckbox" android:id="@+id/hideUserNameCheckbox"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="12dp" android:layout_marginStart="72dp"
android:layout_marginLeft="72dp" android:layout_marginLeft="72dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="12dp"
android:paddingStart="4dp"
android:paddingLeft="4dp" android:paddingLeft="4dp"
android:text="@string/osm_live_hide_user_name" android:text="@string/osm_live_hide_user_name"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary" />
android:layout_marginEnd="16dp"
android:paddingStart="4dp"
android:layout_marginStart="72dp" />
</LinearLayout> </LinearLayout>
@ -303,35 +331,35 @@
android:id="@+id/editModeBottomView" android:id="@+id/editModeBottomView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:visibility="visible"> android:visibility="visible">
<Button <Button
android:id="@+id/saveChangesButton" android:id="@+id/saveChangesButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="72dp"
android:layout_marginLeft="72dp" android:layout_marginLeft="72dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:background="?attr/btn_round" android:background="?attr/btn_round"
android:paddingStart="16dp"
android:paddingLeft="16dp" android:paddingLeft="16dp"
android:paddingEnd="16dp"
android:paddingRight="16dp" android:paddingRight="16dp"
android:text="@string/shared_string_save_changes" android:text="@string/shared_string_save_changes"
android:textColor="@color/color_white" android:textColor="@color/color_white" />
android:layout_marginStart="72dp"
android:layout_marginEnd="16dp"
android:paddingStart="16dp"
android:paddingEnd="16dp" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<include layout="@layout/card_bottom_divider"/> <include layout="@layout/card_bottom_divider" />
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="16dp"/> android:layout_height="16dp" />
</LinearLayout> </LinearLayout>

View file

@ -24,7 +24,7 @@
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginRight="@dimen/favorites_icon_right_margin" android:layout_marginRight="@dimen/favorites_icon_right_margin"
tools:src="@drawable/ic_map" tools:src="@drawable/ic_map"
android:layout_marginEnd="@dimen/favorites_icon_right_margin" /> android:layout_marginEnd="@dimen/favorites_icon_right_margin" />
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
@ -81,26 +81,26 @@
android:visibility="gone" android:visibility="gone"
tools:src="@drawable/ic_action_import" tools:src="@drawable/ic_action_import"
tools:visibility="visible" tools:visibility="visible"
android:layout_marginStart="@dimen/dashFavIconMargin" /> android:layout_marginStart="@dimen/dashFavIconMargin" />
<Button <Button
android:id="@+id/rightButton" android:id="@+id/rightButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="33dp" android:layout_height="wrap_content"
android:minWidth="40dp"
android:paddingLeft="18dp"
android:paddingRight="18dp"
android:background="@drawable/buy_btn_background_light"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_marginStart="@dimen/dashFavIconMargin"
android:layout_marginLeft="@dimen/dashFavIconMargin" android:layout_marginLeft="@dimen/dashFavIconMargin"
android:layout_marginRight="8dp" android:layout_marginEnd="@dimen/list_header_padding"
android:textColor="@color/buy_button_color" android:layout_marginRight="@dimen/list_header_padding"
android:minWidth="@dimen/list_header_height"
android:minHeight="@dimen/list_content_padding_large"
android:paddingStart="@dimen/context_menu_progress_padding_left"
android:paddingLeft="@dimen/context_menu_progress_padding_left"
android:paddingEnd="@dimen/context_menu_progress_padding_left"
android:paddingRight="@dimen/context_menu_progress_padding_left"
android:text="@string/buy" android:text="@string/buy"
android:visibility="gone" android:textColor="@color/text_color_tab_active_light"
android:layout_marginStart="@dimen/dashFavIconMargin" android:visibility="gone" />
android:layout_marginEnd="8dp"
android:paddingEnd="18dp"
android:paddingStart="18dp" />
</LinearLayout> </LinearLayout>

View file

@ -4069,4 +4069,9 @@
<string name="delete_waypoints">حذف نقاط الطريق</string> <string name="delete_waypoints">حذف نقاط الطريق</string>
<string name="copy_to_map_markers">نسخ لعلامات الخريطة</string> <string name="copy_to_map_markers">نسخ لعلامات الخريطة</string>
<string name="copy_to_map_favorites">نسخ للمفضلة</string> <string name="copy_to_map_favorites">نسخ للمفضلة</string>
<string name="upload_photo">يتم الرفع</string>
<string name="upload_photo_completed">اكتمال الرفع</string>
<string name="uploading_count">رفع %1$d من %2$d</string>
<string name="uploaded_count">تم رفع %1$d من %2$d</string>
<string name="toast_select_edits_for_upload">تحديد التعديلات للتحميل</string>
</resources> </resources>

View file

@ -4008,4 +4008,9 @@
<string name="delete_waypoints">Wegpunkte löschen</string> <string name="delete_waypoints">Wegpunkte löschen</string>
<string name="copy_to_map_favorites">In Favoriten kopieren</string> <string name="copy_to_map_favorites">In Favoriten kopieren</string>
<string name="copy_to_map_markers">In Kartenmarkierungen kopieren</string> <string name="copy_to_map_markers">In Kartenmarkierungen kopieren</string>
</resources> <string name="upload_photo">Lade hoch</string>
<string name="upload_photo_completed">Hochladen abgeschlossen</string>
<string name="uploading_count">Lade %1$d von %2$d hoch</string>
<string name="uploaded_count">%1$d von %2$d hochgeladen</string>
<string name="toast_select_edits_for_upload">Bearbeitungen zum Hochladen auswählen</string>
</resources>

View file

@ -3948,4 +3948,9 @@
<string name="shared_string_last_used">Viimati kasutatud</string> <string name="shared_string_last_used">Viimati kasutatud</string>
<string name="message_server_error">Serveri viga: %1$s</string> <string name="message_server_error">Serveri viga: %1$s</string>
<string name="message_name_is_already_exists">Selline nimi on juba olemas</string> <string name="message_name_is_already_exists">Selline nimi on juba olemas</string>
<string name="toast_select_edits_for_upload">Vali tehtud muudatused üleslaadimiseks</string>
<string name="uploaded_count">Üleslaaditud %1$d/%2$d</string>
<string name="uploading_count">Laadin üles muudatusi %1$d/%2$d</string>
<string name="upload_photo_completed">Sai üleslaaditud</string>
<string name="upload_photo">Laadin üles</string>
</resources> </resources>

View file

@ -2739,4 +2739,15 @@ Jos pidät OsmAndista ja OSMsta ja haluat tukea niitä, on tämä täydellinen t
<string name="routing_engine_vehicle_type_foot">Kävely</string> <string name="routing_engine_vehicle_type_foot">Kävely</string>
<string name="routing_engine_vehicle_type_bike">Polkupyörä</string> <string name="routing_engine_vehicle_type_bike">Polkupyörä</string>
<string name="routing_engine_vehicle_type_car">Auto</string> <string name="routing_engine_vehicle_type_car">Auto</string>
<string name="message_server_error">Palvelimen virhe: %1$s</string>
<string name="message_name_is_already_exists">Nimi on jo käytössä</string>
<string name="context_menu_read_full">Lue kaikki</string>
<string name="context_menu_edit_descr">Muokkaa kuvausta</string>
<string name="copy_to_map_markers">Kopioi karttamerkkeihin</string>
<string name="copy_to_map_favorites">Kopioi suosikkeihin</string>
<string name="upload_photo">Lähetetään</string>
<string name="upload_photo_completed">Lähetys valmis</string>
<string name="uploading_count">Lähetetty %1$d muutosta %2$d muutoksesta</string>
<string name="uploaded_count">Lähetettiin %1$d muutosta %2$d muutoksesta</string>
<string name="toast_select_edits_for_upload">Valitse lähetettävät muutokset</string>
</resources> </resources>

View file

@ -708,7 +708,7 @@
<string name="poi_recycling_cars">Autó</string> <string name="poi_recycling_cars">Autó</string>
<string name="poi_recycling_bicycles">Kerékpár</string> <string name="poi_recycling_bicycles">Kerékpár</string>
<string name="poi_landfill_waste_nuclear">Radioaktívhulladék-lerakó</string> <string name="poi_landfill_waste_nuclear">Radioaktívhulladék-lerakó</string>
<string name="poi_basin">Vízgyűjtő</string> <string name="poi_basin">Vízgyűjtő medence</string>
<string name="poi_monitoring_station">Megfigyelőállomás</string> <string name="poi_monitoring_station">Megfigyelőállomás</string>
<string name="poi_crane">Daru</string> <string name="poi_crane">Daru</string>
<string name="poi_construction">Építkezés</string> <string name="poi_construction">Építkezés</string>
@ -2633,7 +2633,7 @@
<string name="poi_lottery">Lottózó</string> <string name="poi_lottery">Lottózó</string>
<string name="poi_gambling">Szerencsejáték-helyszín</string> <string name="poi_gambling">Szerencsejáték-helyszín</string>
<string name="poi_gambling_type">Típus</string> <string name="poi_gambling_type">Típus</string>
<string name="poi_gambling_lottery">Lottó</string> <string name="poi_gambling_lottery">Lottó</string>
<string name="poi_gambling_slot_machines">Játékgépek</string> <string name="poi_gambling_slot_machines">Játékgépek</string>
<string name="poi_gambling_betting">Fogadás</string> <string name="poi_gambling_betting">Fogadás</string>
<string name="poi_e_cigarette">E-cigaretta-bolt</string> <string name="poi_e_cigarette">E-cigaretta-bolt</string>
@ -3446,7 +3446,7 @@
<string name="poi_service_vehicle_motor_yes">Motorszerelés</string> <string name="poi_service_vehicle_motor_yes">Motorszerelés</string>
<string name="poi_service_vehicle_insurance_yes">Biztosítás</string> <string name="poi_service_vehicle_insurance_yes">Biztosítás</string>
<string name="poi_service_vehicle_tyres_yes">Gumiszerelés</string> <string name="poi_service_vehicle_tyres_yes">Gumiszerelés</string>
<string name="poi_aerialway_zip_line">Kötélpálya</string> <string name="poi_aerialway_zip_line">Csúszópálya</string>
<string name="poi_climbing_adventure">Kalandpark</string> <string name="poi_climbing_adventure">Kalandpark</string>
<string name="poi_via_ferrata">Via ferrata (vasalt út)</string> <string name="poi_via_ferrata">Via ferrata (vasalt út)</string>
<string name="poi_cable_number">Sodronyok száma</string> <string name="poi_cable_number">Sodronyok száma</string>
@ -3524,7 +3524,7 @@
<string name="poi_books_academic">akadémiai</string> <string name="poi_books_academic">akadémiai</string>
<string name="poi_books_children">gyermekkönyv</string> <string name="poi_books_children">gyermekkönyv</string>
<string name="poi_atoll">Atoll</string> <string name="poi_atoll">Atoll</string>
<string name="poi_toll_gantry">Útdíjellenőrző kapu</string> <string name="poi_toll_gantry">Automatikus útdíjbeszedő kapu</string>
<string name="poi_childcare">Gyermekgondozás (bölcsőde)</string> <string name="poi_childcare">Gyermekgondozás (bölcsőde)</string>
<string name="poi_denotation_natural_monument">Természeti emlék</string> <string name="poi_denotation_natural_monument">Természeti emlék</string>
<string name="poi_denotation_landmark">Tájékozódási pont</string> <string name="poi_denotation_landmark">Tájékozódási pont</string>

View file

@ -931,7 +931,7 @@
<string name="files_limit">%1$d resterende bestanden</string> <string name="files_limit">%1$d resterende bestanden</string>
<string name="available_downloads_left">%1$d resterende bestanden nog te downloaden</string> <string name="available_downloads_left">%1$d resterende bestanden nog te downloaden</string>
<string name="install_paid">Volledige versie</string> <string name="install_paid">Volledige versie</string>
<string name="cancel_route">Annuleer route</string> <string name="cancel_route">Annuleer route \?</string>
<string name="cancel_navigation">Stop navigatie</string> <string name="cancel_navigation">Stop navigatie</string>
<string name="clear_destination">Bestemming wissen</string> <string name="clear_destination">Bestemming wissen</string>
<string name="use_magnetic_sensor_descr">Gebruik magnetische sensor in plaats van oriëntatiesensor voor het kompas.</string> <string name="use_magnetic_sensor_descr">Gebruik magnetische sensor in plaats van oriëntatiesensor voor het kompas.</string>
@ -3726,31 +3726,31 @@
<string name="plan_a_route">Plan een route</string> <string name="plan_a_route">Plan een route</string>
<string name="use_two_phase_routing">Gebruik de twee-fase A* route berekening methode</string> <string name="use_two_phase_routing">Gebruik de twee-fase A* route berekening methode</string>
<string name="shared_string_graph">Grafiek</string> <string name="shared_string_graph">Grafiek</string>
<string name="message_graph_will_be_available_after_recalculation">Wacht op de herberekening van de route. <string name="message_graph_will_be_available_after_recalculation">Wacht totdat route herberekend is.
\nDe grafiek is beschikbaar na herberekening.</string> \nNa herberekening is de grafiek zichtbaar.</string>
<string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string> <string name="ltr_or_rtl_combine_via_dash">%1$s — %2$s</string>
<string name="import_track_descr">Kies een trackbestand om te volgen of importeer het, vanaf uw apparaat.</string> <string name="import_track_descr">Kies een trackbestand om te volgen of importeer het, vanaf uw apparaat.</string>
<string name="app_mode_gap">Onderbreking</string> <string name="app_mode_gap">Onderbreking</string>
<string name="shared_string_custom">Aangepast</string> <string name="shared_string_custom">Aangepast</string>
<string name="perform_oauth_authorization_description">Voer een OAuth-login uit om osm edit functies te gebruiken</string> <string name="perform_oauth_authorization_description">Voer een OAuth-login uit om osm edit functies te gebruiken</string>
<string name="release_3_5">"• Bijgewerkte app- en profielinstellingen: instellingen zijn nu gerangschikt op type. Elk profiel kan afzonderlijk worden aangepast. <string name="release_3_5">• Bijgewerkte app- en profielinstellingen: instellingen zijn nu gerangschikt op type. Elk profiel kan afzonderlijk worden aangepast.
\n \n
\n • Nieuw dialoogvenster voor het downloaden van kaarten waarin wordt voorgesteld een kaart te downloaden tijdens het browsen \n • Nieuw dialoogvenster voor het downloaden van kaarten waarin wordt voorgesteld een kaart te downloaden tijdens het browsen
\n \n
\n • Donkere thema-fixes \n • Donkere thema-fixes
\n \n
\n • Verschillende routeringsproblemen over de hele wereld opgelost \n • Verschillende routeringsproblemen over de hele wereld opgelost
\n \n
\n • Bijgewerkte basiskaart met meer gedetailleerd wegennet \n • Bijgewerkte basiskaart met meer gedetailleerd wegennet
\n \n
\n • Vaste overstroomde gebieden over de hele wereld \n • Vaste overstroomde gebieden over de hele wereld
\n \n
\n • Skirouting: hoogteprofiel en routecomplexiteit toegevoegd aan de routedetails \n • Skirouting: hoogteprofiel en routecomplexiteit toegevoegd aan de routedetails
\n \n
\n • Andere bugs opgelost \n • Andere bugs opgelost
\n \n
\n"</string> \n</string>
<string name="release_3_6">"• Profielen: nu kunt u de volgorde wijzigen, het pictogram voor de kaart instellen, alle instellingen voor basisprofielen wijzigen en ze terugzetten naar de standaardinstellingen <string name="release_3_6">• Profielen: nu kunt u de volgorde wijzigen, het pictogram voor de kaart instellen, alle instellingen voor basisprofielen wijzigen en ze terugzetten naar de standaardinstellingen
\n \n
\n • Exitnummer toegevoegd in de navigatie \n • Exitnummer toegevoegd in de navigatie
\n \n
@ -3758,23 +3758,23 @@
\n \n
\n • Herwerkt instellingenscherm voor snelle toegang tot alle profielen \n • Herwerkt instellingenscherm voor snelle toegang tot alle profielen
\n \n
\n • Optie toegevoegd om instellingen van een ander profiel te kopiëren \n • Optie toegevoegd om instellingen van een ander profiel te kopiëren
\n \n
\n • Mogelijkheid toegevoegd om een volgorde te wijzigen of POI-categorieën in Zoeken te verbergen \n • Mogelijkheid toegevoegd om een volgorde te wijzigen of POI-categorieën in Zoeken te verbergen
\n \n
\n • Correct uitgelijnde POI-pictogrammen op de kaart \n • Correct uitgelijnde POI-pictogrammen op de kaart
\n \n
\n • Zonsondergang / zonsopganggegevens toegevoegd om de kaart te configureren \n • Zonsondergang / zonsopganggegevens toegevoegd om de kaart te configureren
\n \n
\n • Thuis/werk-pictogrammen toegevoegd op de kaart \n • Thuis/werk-pictogrammen toegevoegd op de kaart
\n \n
\n • Ondersteuning toegevoegd voor meerdere regels beschrijving bij Instellingen \n • Ondersteuning toegevoegd voor meerdere regels beschrijving bij Instellingen
\n \n
\n • Correcte transliteratie toegevoegd aan de kaart van Japan \n • Correcte transliteratie toegevoegd aan de kaart van Japan
\n \n
\n • Antarctica-kaart toegevoegd \n • Antarctica-kaart toegevoegd
\n \n
\n"</string> \n</string>
<string name="what_is_new">Wat is er nieuw</string> <string name="what_is_new">Wat is er nieuw</string>
<string name="snowmobile_render_descr">Voor sneeuwscooter, rijden met speciale wegen en tracks.</string> <string name="snowmobile_render_descr">Voor sneeuwscooter, rijden met speciale wegen en tracks.</string>
<string name="set_working_days_to_continue">Stel aantal werkdagen in om door te gaan</string> <string name="set_working_days_to_continue">Stel aantal werkdagen in om door te gaan</string>
@ -3837,7 +3837,7 @@
<string name="osm_edit_logout_success">Uitloggen gelukt</string> <string name="osm_edit_logout_success">Uitloggen gelukt</string>
<string name="file_already_imported">Bestand is reeds geïmporteerd in OsmAnd</string> <string name="file_already_imported">Bestand is reeds geïmporteerd in OsmAnd</string>
<string name="shared_string_local_maps">Lokale kaarten</string> <string name="shared_string_local_maps">Lokale kaarten</string>
<string name="icon_group_amenity">Aangenaam</string> <string name="icon_group_amenity">Voorziening</string>
<string name="icon_group_special">Speciaal</string> <string name="icon_group_special">Speciaal</string>
<string name="icon_group_transport">Transport</string> <string name="icon_group_transport">Transport</string>
<string name="icon_group_service">Onderhoud</string> <string name="icon_group_service">Onderhoud</string>
@ -3856,7 +3856,7 @@
<string name="open_street_map_login_mode">U moet inloggen om wijzigingen te uploaden. <string name="open_street_map_login_mode">U moet inloggen om wijzigingen te uploaden.
\n \n
\nU kunt inloggen met de veilige OAuth-methode of uw loginnaam en wachtwoord gebruiken.</string> \nU kunt inloggen met de veilige OAuth-methode of uw loginnaam en wachtwoord gebruiken.</string>
<string name="use_login_password">Inloggen met gebruikersnaam en wachtwoord.</string> <string name="use_login_password">Inloggen met gebruikersnaam en wachtwoord</string>
<string name="login_account">Account</string> <string name="login_account">Account</string>
<string name="user_login">Gebruikersnaam</string> <string name="user_login">Gebruikersnaam</string>
<string name="manage_subscription">Abonnement beheren</string> <string name="manage_subscription">Abonnement beheren</string>
@ -3993,4 +3993,9 @@
<string name="delete_waypoints">Waypoints verwijderen</string> <string name="delete_waypoints">Waypoints verwijderen</string>
<string name="copy_to_map_markers">Kopiëren naar Markeervlaggetjes</string> <string name="copy_to_map_markers">Kopiëren naar Markeervlaggetjes</string>
<string name="copy_to_map_favorites">Kopiëren naar Favorieten</string> <string name="copy_to_map_favorites">Kopiëren naar Favorieten</string>
<string name="upload_photo">Opladen</string>
<string name="upload_photo_completed">Opladen voltooid</string>
<string name="uploading_count">Aan het opladen %1$d van %2$d</string>
<string name="uploaded_count">Opgeladen %1$d van %2$d</string>
<string name="toast_select_edits_for_upload">Selecteer de op te laden wijzigingen</string>
</resources> </resources>

View file

@ -3986,4 +3986,10 @@
<string name="context_menu_read_full">Читать полностью</string> <string name="context_menu_read_full">Читать полностью</string>
<string name="context_menu_edit_descr">Редактировать описание</string> <string name="context_menu_edit_descr">Редактировать описание</string>
<string name="delete_waypoints">Удалить путевые точки</string> <string name="delete_waypoints">Удалить путевые точки</string>
<string name="routing_engine_vehicle_type_hgv">HGV</string>
<string name="upload_photo">Отправка</string>
<string name="upload_photo_completed">Отправка завершена</string>
<string name="uploading_count">Отправка %1$d из %2$d</string>
<string name="uploaded_count">Отправлено %1$d из %2$d</string>
<string name="toast_select_edits_for_upload">Выберите правки для отправки</string>
</resources> </resources>

View file

@ -3275,14 +3275,14 @@
<string name="select_folder">Izberi mapo</string> <string name="select_folder">Izberi mapo</string>
<string name="select_folder_descr">Izberi mapo ali dodaj novo</string> <string name="select_folder_descr">Izberi mapo ali dodaj novo</string>
<string name="shared_string_empty">Prazno</string> <string name="shared_string_empty">Prazno</string>
<string name="analyze_by_intervals">Analiziraj po intervalih (razdelitveni interval)</string> <string name="analyze_by_intervals">Preuči po intervalih (razdelitveni interval)</string>
<string name="upload_to_openstreetmap">Naloži v OpenStreetMap</string> <string name="upload_to_openstreetmap">Naloži v OpenStreetMap</string>
<string name="edit_track">Uredi sled</string> <string name="edit_track">Uredi sled</string>
<string name="rename_track">Preimenuj sled</string> <string name="rename_track">Preimenuj sled</string>
<string name="change_folder">Spremeni mapo</string> <string name="change_folder">Spremeni mapo</string>
<string name="shared_string_sec">sek</string> <string name="shared_string_sec">sek</string>
<string name="announcement_time_approach">Pristop</string> <string name="announcement_time_approach">Pristop</string>
<string name="announcement_time_prepare">Pripravi se</string> <string name="announcement_time_prepare">Pripravljanje</string>
<string name="announcement_time_off_route">Izven poti</string> <string name="announcement_time_off_route">Izven poti</string>
<string name="announcement_time_arrive">Prihod na cilj</string> <string name="announcement_time_arrive">Prihod na cilj</string>
<string name="shared_string_turn">Zavoj</string> <string name="shared_string_turn">Zavoj</string>
@ -3296,7 +3296,7 @@
<string name="routing_engine_vehicle_type_cycling_electric">Električno kolesarjenje</string> <string name="routing_engine_vehicle_type_cycling_electric">Električno kolesarjenje</string>
<string name="routing_engine_vehicle_type_cycling_mountain">Gorsko kolesarjenje</string> <string name="routing_engine_vehicle_type_cycling_mountain">Gorsko kolesarjenje</string>
<string name="routing_engine_vehicle_type_cycling_road">Cestno kolesarjenje</string> <string name="routing_engine_vehicle_type_cycling_road">Cestno kolesarjenje</string>
<string name="routing_engine_vehicle_type_cycling_regular">Redno kolesarjenje</string> <string name="routing_engine_vehicle_type_cycling_regular">Mestno kolesarjenje</string>
<string name="routing_engine_vehicle_type_hgv">Težko tovorno vozilo</string> <string name="routing_engine_vehicle_type_hgv">Težko tovorno vozilo</string>
<string name="routing_engine_vehicle_type_small_truck">Majhno tovorno vozilo</string> <string name="routing_engine_vehicle_type_small_truck">Majhno tovorno vozilo</string>
<string name="routing_engine_vehicle_type_truck">Tovorno vozilo</string> <string name="routing_engine_vehicle_type_truck">Tovorno vozilo</string>
@ -3309,4 +3309,51 @@
<string name="context_menu_edit_descr">Uredi opis</string> <string name="context_menu_edit_descr">Uredi opis</string>
<string name="delete_waypoints">Brisanje točk</string> <string name="delete_waypoints">Brisanje točk</string>
<string name="copy_to_map_markers">Kopiraj na oznake na zemljevidu</string> <string name="copy_to_map_markers">Kopiraj na oznake na zemljevidu</string>
<string name="export_not_enough_space">Na napravi ni dovolj prostora.</string>
<string name="select_groups_for_import">Izbor skupin za uvoz.</string>
<string name="select_items_for_import">Izbor predmetov za uvoz.</string>
<string name="add_to_mapillary">Dodaj na Mapillary</string>
<string name="add_to_opr">Dodaj na OpenPlaceReviews</string>
<string name="use_dev_url_descr">Za preizkušanje pošiljanja sporočil, točk in sledi GPX preklopi iz openstreetmap.org na preizkusni dev.openstreetmap.org.</string>
<string name="use_dev_url">Uporabi dev.openstreetmap.org</string>
<string name="add_photos_descr">Program podpira prikaz fotografij različnih virov:
\nOpenPlaceReviews fotografije točk POI;
\nMapillary ulična fotografija;
\nSplet / Wikimedia fotografije točk POI in OpenStreetMap.</string>
<string name="ltr_or_rtl_combine_via_star">%1$s * %2$s</string>
<string name="plan_route_add_new_segment">Dodaj nov del poti</string>
<string name="app_mode_light_aircraft">Lahko letalo</string>
<string name="plan_route_join_segments">Združi dele poti</string>
<string name="plan_route_split_before">Razdeli pred</string>
<string name="plan_route_split_after">Razdeli po</string>
<string name="profile_type_osmand_string">Profil OsmAnd</string>
<string name="profile_type_user_string">Uporabniški profil</string>
<string name="reverse_all_points">Obrni vse točke</string>
<string name="profile_by_default_description">Izbor profila, ki bo prikazan ob zagonu programa.</string>
<string name="shared_string_last_used">Nazadnje uporabljeno</string>
<string name="shared_string_subtype">Podvrsta</string>
<string name="shared_string_vehicle">Vozilo</string>
<string name="shared_string_api_key">Ključ API</string>
<string name="shared_string_server_url">Naslov URL strežnika</string>
<string name="shared_string_enter_param">Vpis parametrov</string>
<string name="online_routing_example_hint">Naslov URL z vsemi parametri bo zapisan kot:</string>
<string name="test_route_calculation">Preizkusi izračun poti</string>
<string name="routing_engine_vehicle_type_driving">Vožnja</string>
<string name="routing_engine_vehicle_type_foot">Hoja</string>
<string name="routing_engine_vehicle_type_bike">Kolo</string>
<string name="routing_engine_vehicle_type_car">Avto</string>
<string name="copy_address">Kopiraj naslov</string>
<string name="announcement_time_prepare_long">Dolgo pripravljanje</string>
<string name="show_track_on_map">Pokaži sled na zemljevidu</string>
<string name="shared_string_zoom_levels">Raven približanja</string>
<string name="shared_string_transparency">Prosojnost</string>
<string name="shared_string_legend">Legenda</string>
<string name="terrain_empty_state_text">Prikaz višinskega senčenja na zemljevidu. Več o tem je mogoče prebrati na spletni strani programa.</string>
<string name="shared_string_hillshade">Senčenje</string>
<string name="copy_to_map_favorites">Kopiraj med priljubljene</string>
<string name="upload_photo">Poteka pošiljanje</string>
<string name="upload_photo_completed">Pošiljanje je končano</string>
<string name="uploading_count">Poteka pošiljanje %1$d od %2$d</string>
<string name="uploaded_count">Poslano %1$d od %2$d</string>
<string name="toast_select_edits_for_upload">Izbor sprememb za pošiljanje</string>
</resources> </resources>

View file

@ -1219,7 +1219,7 @@
<string name="display_zoom_level">显示缩放等级:%1$s</string> <string name="display_zoom_level">显示缩放等级:%1$s</string>
<string name="online_map">在线地图</string> <string name="online_map">在线地图</string>
<string name="roads_only">仅道路</string> <string name="roads_only">仅道路</string>
<string name="device_memory">设备</string> <string name="device_memory">设备</string>
<string name="first_usage_item">初次使用</string> <string name="first_usage_item">初次使用</string>
<string name="tips_and_tricks_descr">常见问题、最近修改和其它内容。</string> <string name="tips_and_tricks_descr">常见问题、最近修改和其它内容。</string>
<string name="faq_item_description">常见问题</string> <string name="faq_item_description">常见问题</string>

View file

@ -12,6 +12,11 @@
--> -->
<string name="login_open_place_reviews">Login to OpenPlaceReviews</string>
<string name="opr_use_dev_url">Use test.openplacereviews.org</string>
<string name="open_place_reviews">OpenPlaceReviews</string>
<string name="open_place_reviews_plugin_description">OpenPlaceReviews is a community-driven project about public places such as restaurants, hotels, museums, waypoints. It collects all public information about them such as photos, reviews, links to other systems link OpenStreetMap, Wikipedia.\n\nAll OpenPlaceReview data is open and available to everyone: http://openplacereviews.org/data.\n\nYou can read more at: http://openplacereviews.org</string>
<string name="hillshade_slope_contour_lines">Hillshade / Slope / Contour lines</string>
<string name="toast_select_edits_for_upload">Select edits for upload</string> <string name="toast_select_edits_for_upload">Select edits for upload</string>
<string name="uploaded_count">Uploaded %1$d of %2$d</string> <string name="uploaded_count">Uploaded %1$d of %2$d</string>
<string name="uploading_count">Uploading %1$d of %2$d</string> <string name="uploading_count">Uploading %1$d of %2$d</string>

View file

@ -14,10 +14,10 @@
android:title="@string/shared_string_maps"/> android:title="@string/shared_string_maps"/>
<Preference <Preference
android:key="contour_lines_and_hillshade_memory" android:key="terrain_memory_used"
android:layout="@layout/data_storage_memory_used_item" android:layout="@layout/data_storage_memory_used_item"
android:icon="@drawable/ic_map" android:icon="@drawable/ic_map"
android:title="@string/contour_lines_and_hillshade"/> android:title="@string/hillshade_slope_contour_lines"/>
<Preference <Preference
android:key="tracks_memory_used" android:key="tracks_memory_used"

View file

@ -22,7 +22,7 @@
android:layout="@layout/preference_with_descr" android:layout="@layout/preference_with_descr"
android:persistent="false" android:persistent="false"
android:title="@string/application_dir" android:title="@string/application_dir"
app:fragment="net.osmand.plus.settings.fragments.DataStorageFragment" app:fragment="net.osmand.plus.settings.datastorage.DataStorageFragment"
tools:icon="@drawable/ic_action_folder" /> tools:icon="@drawable/ic_action_folder" />
<Preference <Preference

View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:title="@string/open_place_reviews">
<Preference
android:key="opr_settings_info"
android:layout="@layout/preference_info"
android:persistent="false"
android:selectable="false"
android:title="@string/plugin_global_prefs_info" />
<Preference
android:key="opr_login_data"
android:layout="@layout/preference_with_descr"
android:persistent="false"
android:title="@string/login_open_place_reviews" />
<Preference
android:key="opr_logout"
android:layout="@layout/preference_login"
android:persistent="false"
android:title="@string/login_account" />
<net.osmand.plus.settings.preferences.SwitchPreferenceEx
android:key="opr_use_dev_url"
android:layout="@layout/preference_with_descr_dialog_and_switch"
android:title="@string/opr_use_dev_url"
tools:icon="@drawable/ic_plugin_developer" />
</PreferenceScreen>

View file

@ -28,7 +28,6 @@ import net.osmand.map.OsmandRegions.RegionTranslation;
import net.osmand.map.WorldRegion; import net.osmand.map.WorldRegion;
import net.osmand.osm.AbstractPoiType; import net.osmand.osm.AbstractPoiType;
import net.osmand.osm.MapPoiTypes; import net.osmand.osm.MapPoiTypes;
import net.osmand.plus.helpers.DayNightHelper;
import net.osmand.plus.activities.LocalIndexHelper; import net.osmand.plus.activities.LocalIndexHelper;
import net.osmand.plus.activities.LocalIndexInfo; import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.activities.SavingTrackHelper; import net.osmand.plus.activities.SavingTrackHelper;
@ -36,6 +35,7 @@ import net.osmand.plus.base.MapViewTrackingUtilities;
import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask; import net.osmand.plus.download.ui.AbstractLoadLocalIndexTask;
import net.osmand.plus.helpers.AvoidSpecificRoads; import net.osmand.plus.helpers.AvoidSpecificRoads;
import net.osmand.plus.helpers.DayNightHelper;
import net.osmand.plus.helpers.LockHelper; import net.osmand.plus.helpers.LockHelper;
import net.osmand.plus.helpers.WaypointHelper; import net.osmand.plus.helpers.WaypointHelper;
import net.osmand.plus.inapp.InAppPurchaseHelperImpl; import net.osmand.plus.inapp.InAppPurchaseHelperImpl;
@ -45,6 +45,7 @@ import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.monitoring.LiveMonitoringHelper; import net.osmand.plus.monitoring.LiveMonitoringHelper;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin; import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import net.osmand.plus.openplacereviews.OprAuthHelper;
import net.osmand.plus.osmedit.oauth.OsmOAuthHelper; import net.osmand.plus.osmedit.oauth.OsmOAuthHelper;
import net.osmand.plus.poi.PoiFiltersHelper; import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.quickaction.QuickActionRegistry; import net.osmand.plus.quickaction.QuickActionRegistry;
@ -468,6 +469,7 @@ public class AppInitializer implements IProgress {
app.settingsHelper = startupInit(new SettingsHelper(app), SettingsHelper.class); app.settingsHelper = startupInit(new SettingsHelper(app), SettingsHelper.class);
app.quickActionRegistry = startupInit(new QuickActionRegistry(app.getSettings()), QuickActionRegistry.class); app.quickActionRegistry = startupInit(new QuickActionRegistry(app.getSettings()), QuickActionRegistry.class);
app.osmOAuthHelper = startupInit(new OsmOAuthHelper(app), OsmOAuthHelper.class); app.osmOAuthHelper = startupInit(new OsmOAuthHelper(app), OsmOAuthHelper.class);
app.oprAuthHelper = startupInit(new OprAuthHelper(app), OprAuthHelper.class);
app.onlineRoutingHelper = startupInit(new OnlineRoutingHelper(app), OnlineRoutingHelper.class); app.onlineRoutingHelper = startupInit(new OnlineRoutingHelper(app), OnlineRoutingHelper.class);
initOpeningHoursParser(); initOpeningHoursParser();

View file

@ -344,8 +344,8 @@ public class OsmAndFormatter {
if (minperkm >= 10) { if (minperkm >= 10) {
return ((int) Math.round(minperkm)) + " " + mc.toShortString(ctx); return ((int) Math.round(minperkm)) + " " + mc.toShortString(ctx);
} else { } else {
int mph10 = (int) Math.round(minperkm * 10f); int seconds = Math.round(minperkm * 60);
return (mph10 / 10f) + " " + mc.toShortString(ctx); return Algorithms.formatDuration(seconds, false) + " " + mc.toShortString(ctx);
} }
} else if (mc == SpeedConstants.MINUTES_PER_MILE) { } else if (mc == SpeedConstants.MINUTES_PER_MILE) {
if (metersperseconds < 0.111111111) { if (metersperseconds < 0.111111111) {

View file

@ -24,6 +24,8 @@ import android.view.View;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatDelegate; import androidx.appcompat.app.AppCompatDelegate;
import androidx.multidex.MultiDex; import androidx.multidex.MultiDex;
@ -68,6 +70,7 @@ import net.osmand.plus.mapmarkers.MapMarkersHelper;
import net.osmand.plus.measurementtool.MeasurementEditingContext; import net.osmand.plus.measurementtool.MeasurementEditingContext;
import net.osmand.plus.monitoring.LiveMonitoringHelper; import net.osmand.plus.monitoring.LiveMonitoringHelper;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import net.osmand.plus.openplacereviews.OprAuthHelper;
import net.osmand.plus.osmedit.oauth.OsmOAuthHelper; import net.osmand.plus.osmedit.oauth.OsmOAuthHelper;
import net.osmand.plus.poi.PoiFiltersHelper; import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.quickaction.QuickActionRegistry; import net.osmand.plus.quickaction.QuickActionRegistry;
@ -159,6 +162,7 @@ public class OsmandApplication extends MultiDexApplication {
GpxDbHelper gpxDbHelper; GpxDbHelper gpxDbHelper;
QuickActionRegistry quickActionRegistry; QuickActionRegistry quickActionRegistry;
OsmOAuthHelper osmOAuthHelper; OsmOAuthHelper osmOAuthHelper;
OprAuthHelper oprAuthHelper;
MeasurementEditingContext measurementEditingContext; MeasurementEditingContext measurementEditingContext;
OnlineRoutingHelper onlineRoutingHelper; OnlineRoutingHelper onlineRoutingHelper;
@ -394,6 +398,10 @@ public class OsmandApplication extends MultiDexApplication {
return osmOAuthHelper; return osmOAuthHelper;
} }
public OprAuthHelper getOprAuthHelper() {
return oprAuthHelper;
}
public synchronized DownloadIndexesThread getDownloadThread() { public synchronized DownloadIndexesThread getDownloadThread() {
if (downloadIndexesThread == null) { if (downloadIndexesThread == null) {
downloadIndexesThread = new DownloadIndexesThread(this); downloadIndexesThread = new DownloadIndexesThread(this);
@ -910,6 +918,7 @@ public class OsmandApplication extends MultiDexApplication {
return customRoutingConfigs.get(key); return customRoutingConfigs.get(key);
} }
@NonNull
public RoutingConfiguration.Builder getRoutingConfigForMode(ApplicationMode mode) { public RoutingConfiguration.Builder getRoutingConfigForMode(ApplicationMode mode) {
RoutingConfiguration.Builder builder = null; RoutingConfiguration.Builder builder = null;
String routingProfileKey = mode.getRoutingProfile(); String routingProfileKey = mode.getRoutingProfile();
@ -923,11 +932,13 @@ public class OsmandApplication extends MultiDexApplication {
return builder != null ? builder : getDefaultRoutingConfig(); return builder != null ? builder : getDefaultRoutingConfig();
} }
@Nullable
public GeneralRouter getRouter(ApplicationMode mode) { public GeneralRouter getRouter(ApplicationMode mode) {
Builder builder = getRoutingConfigForMode(mode); Builder builder = getRoutingConfigForMode(mode);
return getRouter(builder, mode); return getRouter(builder, mode);
} }
@Nullable
public GeneralRouter getRouter(Builder builder, ApplicationMode am) { public GeneralRouter getRouter(Builder builder, ApplicationMode am) {
GeneralRouter router = builder.getRouter(am.getRoutingProfile()); GeneralRouter router = builder.getRouter(am.getRoutingProfile());
if (router == null && am.getParent() != null) { if (router == null && am.getParent() != null) {

View file

@ -35,9 +35,12 @@ import net.osmand.plus.dialogs.PluginInstalledBottomSheetDialog;
import net.osmand.plus.download.IndexItem; import net.osmand.plus.download.IndexItem;
import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.mapcontextmenu.MenuBuilder;
import net.osmand.plus.mapcontextmenu.MenuController; import net.osmand.plus.mapcontextmenu.MenuController;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener;
import net.osmand.plus.mapillary.MapillaryPlugin; import net.osmand.plus.mapillary.MapillaryPlugin;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin; import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
import net.osmand.plus.myplaces.FavoritesActivity; import net.osmand.plus.myplaces.FavoritesActivity;
import net.osmand.plus.openplacereviews.OpenPlaceReviewsPlugin;
import net.osmand.plus.openseamapsplugin.NauticalMapsPlugin; import net.osmand.plus.openseamapsplugin.NauticalMapsPlugin;
import net.osmand.plus.osmedit.OsmEditingPlugin; import net.osmand.plus.osmedit.OsmEditingPlugin;
import net.osmand.plus.parkingpoint.ParkingPositionPlugin; import net.osmand.plus.parkingpoint.ParkingPositionPlugin;
@ -66,6 +69,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
public abstract class OsmandPlugin { public abstract class OsmandPlugin {
@ -133,7 +137,7 @@ public abstract class OsmandPlugin {
public boolean init(@NonNull OsmandApplication app, @Nullable Activity activity) { public boolean init(@NonNull OsmandApplication app, @Nullable Activity activity) {
if (activity != null) { if (activity != null) {
// called from UI // called from UI
for (ApplicationMode appMode: getAddedAppModes()) { for (ApplicationMode appMode : getAddedAppModes()) {
ApplicationMode.changeProfileAvailability(appMode, true, app); ApplicationMode.changeProfileAvailability(appMode, true, app);
} }
} }
@ -208,6 +212,16 @@ public abstract class OsmandPlugin {
return Collections.emptyList(); return Collections.emptyList();
} }
protected List<ImageCard> getContextMenuImageCards(@NonNull Map<String, String> params,
@Nullable Map<String, String> additionalParams,
@Nullable GetImageCardsListener listener) {
return Collections.emptyList();
}
protected ImageCard createContextMenuImageCard(@NonNull JSONObject imageObject) {
return null;
}
/** /**
* Plugin was installed * Plugin was installed
*/ */
@ -263,25 +277,19 @@ public abstract class OsmandPlugin {
public static void initPlugins(@NonNull OsmandApplication app) { public static void initPlugins(@NonNull OsmandApplication app) {
Set<String> enabledPlugins = app.getSettings().getEnabledPlugins(); Set<String> enabledPlugins = app.getSettings().getEnabledPlugins();
allPlugins.clear(); allPlugins.clear();
enablePluginByDefault(app, enabledPlugins, new WikipediaPlugin(app));
enableHiddenPlugin(app, enabledPlugins, new MapillaryPlugin(app));
enableHiddenPlugin(app, enabledPlugins, new WikipediaPlugin(app));
allPlugins.add(new OsmandRasterMapsPlugin(app)); allPlugins.add(new OsmandRasterMapsPlugin(app));
allPlugins.add(new OsmandMonitoringPlugin(app)); allPlugins.add(new OsmandMonitoringPlugin(app));
checkMarketPlugin(app, enabledPlugins, new SRTMPlugin(app)); checkMarketPlugin(app, enabledPlugins, new SRTMPlugin(app));
// ? questionable - definitely not market plugin
// checkMarketPlugin(app, enabledPlugins, new TouringViewPlugin(app), false, TouringViewPlugin.COMPONENT, null);
checkMarketPlugin(app, enabledPlugins, new NauticalMapsPlugin(app)); checkMarketPlugin(app, enabledPlugins, new NauticalMapsPlugin(app));
checkMarketPlugin(app, enabledPlugins, new SkiMapsPlugin(app)); checkMarketPlugin(app, enabledPlugins, new SkiMapsPlugin(app));
allPlugins.add(new AudioVideoNotesPlugin(app)); allPlugins.add(new AudioVideoNotesPlugin(app));
checkMarketPlugin(app, enabledPlugins, new ParkingPositionPlugin(app)); checkMarketPlugin(app, enabledPlugins, new ParkingPositionPlugin(app));
allPlugins.add(new AccessibilityPlugin(app));
allPlugins.add(new OsmEditingPlugin(app)); allPlugins.add(new OsmEditingPlugin(app));
enablePluginByDefault(app, enabledPlugins, new OpenPlaceReviewsPlugin(app));
enablePluginByDefault(app, enabledPlugins, new MapillaryPlugin(app));
allPlugins.add(new AccessibilityPlugin(app));
allPlugins.add(new OsmandDevelopmentPlugin(app)); allPlugins.add(new OsmandDevelopmentPlugin(app));
loadCustomPlugins(app); loadCustomPlugins(app);
@ -373,7 +381,7 @@ public abstract class OsmandPlugin {
} }
} }
private static void enableHiddenPlugin(@NonNull OsmandApplication app, @NonNull Set<String> enabledPlugins, @NonNull OsmandPlugin plugin) { private static void enablePluginByDefault(@NonNull OsmandApplication app, @NonNull Set<String> enabledPlugins, @NonNull OsmandPlugin plugin) {
allPlugins.add(plugin); allPlugins.add(plugin);
if (!enabledPlugins.contains(plugin.getId()) && !app.getSettings().getPlugins().contains("-" + plugin.getId())) { if (!enabledPlugins.contains(plugin.getId()) && !app.getSettings().getPlugins().contains("-" + plugin.getId())) {
enabledPlugins.add(plugin.getId()); enabledPlugins.add(plugin.getId());
@ -734,7 +742,6 @@ public abstract class OsmandPlugin {
return l; return l;
} }
public static void onMapActivityCreate(MapActivity activity) { public static void onMapActivityCreate(MapActivity activity) {
for (OsmandPlugin plugin : getEnabledPlugins()) { for (OsmandPlugin plugin : getEnabledPlugins()) {
plugin.mapActivityCreate(activity); plugin.mapActivityCreate(activity);
@ -868,6 +875,23 @@ public abstract class OsmandPlugin {
return collection; return collection;
} }
public static void populateContextMenuImageCards(@NonNull List<ImageCard> imageCards, @NonNull Map<String, String> params,
@Nullable Map<String, String> additionalParams, @Nullable GetImageCardsListener listener) {
for (OsmandPlugin plugin : getEnabledPlugins()) {
imageCards.addAll(plugin.getContextMenuImageCards(params, additionalParams, listener));
}
}
public static ImageCard createImageCardForJson(@NonNull JSONObject imageObject) {
for (OsmandPlugin plugin : getEnabledPlugins()) {
ImageCard imageCard = plugin.createContextMenuImageCard(imageObject);
if (imageCard != null) {
return imageCard;
}
}
return null;
}
public static boolean isPackageInstalled(String packageInfo, Context ctx) { public static boolean isPackageInstalled(String packageInfo, Context ctx) {
if (packageInfo == null) { if (packageInfo == null) {
return false; return false;

View file

@ -51,6 +51,7 @@ import net.osmand.AndroidUtils;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.views.DirectionDrawable; import net.osmand.plus.views.DirectionDrawable;
import net.osmand.plus.widgets.TextViewEx; import net.osmand.plus.widgets.TextViewEx;
@ -468,8 +469,8 @@ public class UiUtilities {
} else { } else {
background.setCornerRadii(new float[]{radius, radius, 0, 0, 0, 0, radius, radius}); background.setCornerRadii(new float[]{radius, radius, 0, 0, 0, 0, radius, radius});
} }
TextView startButtonText = startButtonContainer.findViewById(R.id.tab_title); TextView startButtonText = startButtonContainer.findViewById(R.id.left_button);
TextView endButtonText = endButtonContainer.findViewById(R.id.tab_title); TextView endButtonText = endButtonContainer.findViewById(R.id.right_button);
endButtonContainer.setBackgroundColor(Color.TRANSPARENT); endButtonContainer.setBackgroundColor(Color.TRANSPARENT);
endButtonText.setTextColor(activeColor); endButtonText.setTextColor(activeColor);
@ -477,23 +478,25 @@ public class UiUtilities {
startButtonText.setTextColor(textColor); startButtonText.setTextColor(textColor);
if (centerButtonContainer != null) { if (centerButtonContainer != null) {
TextView centerButtonText = centerButtonContainer.findViewById(R.id.tab_title); TextView centerButtonText = centerButtonContainer.findViewById(R.id.center_button);
centerButtonText.setTextColor(activeColor); centerButtonText.setTextColor(activeColor);
centerButtonContainer.setBackgroundColor(Color.TRANSPARENT); centerButtonContainer.setBackgroundColor(Color.TRANSPARENT);
} }
} else if (buttonType == CustomRadioButtonType.CENTER) { } else if (buttonType == CustomRadioButtonType.CENTER) {
background.setCornerRadii(new float[] {0, 0, 0, 0, 0, 0, 0, 0}); background.setCornerRadii(new float[] {0, 0, 0, 0, 0, 0, 0, 0});
centerButtonContainer.setBackgroundDrawable(background); centerButtonContainer.setBackgroundDrawable(background);
TextView centerButtonText = centerButtonContainer.findViewById(R.id.tab_title); AndroidUiHelper.updateVisibility(centerButtonContainer, true);
TextView centerButtonText = centerButtonContainer.findViewById(R.id.center_button);
centerButtonText.setTextColor(textColor); centerButtonText.setTextColor(textColor);
if (endButtonContainer != null) { if (endButtonContainer != null) {
TextView endButtonText = endButtonContainer.findViewById(R.id.tab_title); TextView endButtonText = endButtonContainer.findViewById(R.id.right_button);
endButtonText.setTextColor(activeColor); endButtonText.setTextColor(activeColor);
endButtonContainer.setBackgroundColor(Color.TRANSPARENT); endButtonContainer.setBackgroundColor(Color.TRANSPARENT);
} }
if (startButtonContainer != null) { if (startButtonContainer != null) {
TextView startButtonText = startButtonContainer.findViewById(R.id.tab_title); TextView startButtonText = startButtonContainer.findViewById(R.id.left_button);
startButtonText.setTextColor(activeColor); startButtonText.setTextColor(activeColor);
startButtonContainer.setBackgroundColor(Color.TRANSPARENT); startButtonContainer.setBackgroundColor(Color.TRANSPARENT);
} }
@ -503,8 +506,8 @@ public class UiUtilities {
} else { } else {
background.setCornerRadii(new float[]{0, 0, radius, radius, radius, radius, 0, 0}); background.setCornerRadii(new float[]{0, 0, radius, radius, radius, radius, 0, 0});
} }
TextView startButtonText = startButtonContainer.findViewById(R.id.tab_title); TextView startButtonText = startButtonContainer.findViewById(R.id.left_button);
TextView endButtonText = endButtonContainer.findViewById(R.id.tab_title); TextView endButtonText = endButtonContainer.findViewById(R.id.right_button);
endButtonContainer.setBackgroundDrawable(background); endButtonContainer.setBackgroundDrawable(background);
endButtonText.setTextColor(textColor); endButtonText.setTextColor(textColor);
@ -512,7 +515,7 @@ public class UiUtilities {
startButtonText.setTextColor(activeColor); startButtonText.setTextColor(activeColor);
if (centerButtonContainer != null) { if (centerButtonContainer != null) {
TextView centerButtonText = centerButtonContainer.findViewById(R.id.tab_title); TextView centerButtonText = centerButtonContainer.findViewById(R.id.center_button);
centerButtonText.setTextColor(activeColor); centerButtonText.setTextColor(activeColor);
centerButtonContainer.setBackgroundColor(Color.TRANSPARENT); centerButtonContainer.setBackgroundColor(Color.TRANSPARENT);
} }

View file

@ -10,6 +10,7 @@ import android.os.AsyncTask;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.Html; import android.text.Html;
import android.text.Spanned;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -88,6 +89,8 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen
public static final int IMPORT_FAVOURITES_ID = 7; public static final int IMPORT_FAVOURITES_ID = 7;
public static final String GROUP_EXPANDED_POSTFIX = "_group_expanded"; public static final String GROUP_EXPANDED_POSTFIX = "_group_expanded";
private static final int MAX_POINTS_IN_DESCRIPTION = 100;
private FavouritesAdapter favouritesAdapter; private FavouritesAdapter favouritesAdapter;
private FavouritesDbHelper helper; private FavouritesDbHelper helper;
@ -606,29 +609,39 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen
} }
} }
private StringBuilder generateHtmlPrint(List<FavoriteGroup> groups) { private String generateHtmlPrint(List<FavoriteGroup> groups) {
StringBuilder html = new StringBuilder(); StringBuilder html = new StringBuilder();
html.append("<h1>My Favorites</h1>"); html.append("<h1>My Favorites</h1>");
int addedPoints = 0;
for (FavoriteGroup group : groups) { for (FavoriteGroup group : groups) {
html.append("<h3>" + group.getDisplayName(app) + "</h3>"); html.append("<h3>").append(group.getDisplayName(app)).append("</h3>");
for (FavouritePoint fp : group.getPoints()) { for (FavouritePoint fp : group.getPoints()) {
String url = "geo:" + ((float) fp.getLatitude()) + "," + ((float) fp.getLongitude()) + "?m=" + fp.getName(); if (addedPoints >= MAX_POINTS_IN_DESCRIPTION) {
html.append("<p>" + fp.getDisplayName(app) + " - " + "<a href=\"" + url + "\">geo:" break;
+ ((float) fp.getLatitude()) + "," + ((float) fp.getLongitude()) + "</a><br>");
if (fp.isAddressSpecified()) {
html.append(": " + fp.getAddress());
html.append("<br>");
} }
if (!Algorithms.isEmpty(fp.getDescription())) {
html.append(": " + fp.getDescription()); float lat = (float) fp.getLatitude();
} float lon = (float) fp.getLongitude();
html.append("</p>"); String url = "geo:" + lat + "," + lon + "?m=" + fp.getName();
html.append("<p>")
.append(fp.getDisplayName(app))
.append(" - <a href=\"")
.append(url)
.append("\">geo:")
.append(lat).append(",").append(lon)
.append("</a><br></p>");
addedPoints++;
}
if (addedPoints >= MAX_POINTS_IN_DESCRIPTION) {
html.append("<p>...</p>");
break;
} }
} }
return html; return html.toString();
} }
private void shareFavourites() { private void shareFavourites() {
if (favouritesAdapter.isEmpty()) { if (favouritesAdapter.isEmpty()) {
Toast.makeText(getActivity(), R.string.no_fav_to_save, Toast.LENGTH_LONG).show(); Toast.makeText(getActivity(), R.string.no_fav_to_save, Toast.LENGTH_LONG).show();
@ -646,6 +659,7 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen
File src = null; File src = null;
File dst = null; File dst = null;
Spanned descriptionOfPoints;
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
@ -662,9 +676,15 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen
@Override @Override
protected Void doInBackground(Void... params) { protected Void doInBackground(Void... params) {
List<FavoriteGroup> groups;
if (group != null) { if (group != null) {
helper.saveFile(group.getPoints(), dst); helper.saveFile(group.getPoints(), dst);
groups = new ArrayList<>();
groups.add(group);
} else {
groups = getMyApplication().getFavorites().getFavoriteGroups();
} }
descriptionOfPoints = Html.fromHtml(generateHtmlPrint(groups));
return null; return null;
} }
@ -680,19 +700,12 @@ public class FavoritesTreeFragment extends OsmandExpandableListFragment implemen
Algorithms.fileCopy(src, dst); Algorithms.fileCopy(src, dst);
} }
final Intent sendIntent = new Intent(); final Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND); sendIntent.setAction(Intent.ACTION_SEND)
List<FavoriteGroup> groups; .putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_fav_subject))
if (group != null) { .putExtra(Intent.EXTRA_TEXT, descriptionOfPoints)
groups = new ArrayList<>(); .putExtra(Intent.EXTRA_STREAM, AndroidUtils.getUriForFile(getMyApplication(), dst))
groups.add(group); .setType("text/plain")
} else { .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
groups = getMyApplication().getFavorites().getFavoriteGroups();
}
sendIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(generateHtmlPrint(groups).toString()));
sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_fav_subject));
sendIntent.putExtra(Intent.EXTRA_STREAM, AndroidUtils.getUriForFile(getMyApplication(), dst));
sendIntent.setType("text/plain");
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(sendIntent); startActivity(sendIntent);
} catch (IOException e) { } catch (IOException e) {
Toast.makeText(getActivity(), "Error sharing favorites: " + e.getMessage(), Toast.LENGTH_SHORT).show(); Toast.makeText(getActivity(), "Error sharing favorites: " + e.getMessage(), Toast.LENGTH_SHORT).show();

View file

@ -139,7 +139,7 @@ import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.fragments.BaseSettingsFragment; import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType; import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
import net.osmand.plus.settings.fragments.ConfigureProfileFragment; import net.osmand.plus.settings.fragments.ConfigureProfileFragment;
import net.osmand.plus.settings.fragments.DataStorageFragment; import net.osmand.plus.settings.datastorage.DataStorageFragment;
import net.osmand.plus.track.TrackAppearanceFragment; import net.osmand.plus.track.TrackAppearanceFragment;
import net.osmand.plus.track.TrackMenuFragment; import net.osmand.plus.track.TrackMenuFragment;
import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint; import net.osmand.plus.views.AddGpxPointBottomSheetHelper.NewGpxPoint;

View file

@ -143,8 +143,8 @@ public class OsmandDevelopmentPlugin extends OsmandPlugin {
@Override @Override
public void disable(OsmandApplication app) { public void disable(OsmandApplication app) {
if (app.getSettings().USE_DEV_URL.get()) { if (app.getSettings().OSM_USE_DEV_URL.get()) {
app.getSettings().USE_DEV_URL.set(false); app.getSettings().OSM_USE_DEV_URL.set(false);
app.getOsmOAuthHelper().resetAuthorization(); app.getOsmOAuthHelper().resetAuthorization();
} }
super.disable(app); super.disable(app);

View file

@ -19,9 +19,9 @@ import net.osmand.plus.base.MenuBottomSheetDialogFragment;
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem; import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.DividerSpaceItem;
import net.osmand.plus.mapcontextmenu.UploadPhotosAsyncTask.UploadPhotosListener; import net.osmand.plus.mapcontextmenu.UploadPhotosAsyncTask.UploadPhotosProgressListener;
public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragment implements UploadPhotosListener { public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragment implements UploadPhotosProgressListener {
public static final String TAG = UploadPhotoProgressBottomSheet.class.getSimpleName(); public static final String TAG = UploadPhotoProgressBottomSheet.class.getSimpleName();
@ -103,7 +103,7 @@ public class UploadPhotoProgressBottomSheet extends MenuBottomSheetDialogFragmen
return uploadingFinished ? R.string.shared_string_close : R.string.shared_string_cancel; return uploadingFinished ? R.string.shared_string_close : R.string.shared_string_cancel;
} }
public static UploadPhotosListener showInstance(@NonNull FragmentManager fragmentManager, int maxProgress, OnDismissListener listener) { public static UploadPhotosProgressListener showInstance(@NonNull FragmentManager fragmentManager, int maxProgress, OnDismissListener listener) {
UploadPhotoProgressBottomSheet fragment = new UploadPhotoProgressBottomSheet(); UploadPhotoProgressBottomSheet fragment = new UploadPhotoProgressBottomSheet();
fragment.setRetainInstance(true); fragment.setRetainInstance(true);
fragment.setMaxProgress(maxProgress); fragment.setMaxProgress(maxProgress);

View file

@ -22,6 +22,7 @@ import net.osmand.plus.mapmarkers.MapMarkersDialogFragment;
import net.osmand.plus.mapmarkers.MapMarkersGroup; import net.osmand.plus.mapmarkers.MapMarkersGroup;
import net.osmand.plus.mapsource.EditMapSourceDialogFragment; import net.osmand.plus.mapsource.EditMapSourceDialogFragment;
import net.osmand.plus.openplacereviews.OPRConstants; import net.osmand.plus.openplacereviews.OPRConstants;
import net.osmand.plus.openplacereviews.OprAuthHelper.OprAuthorizationListener;
import net.osmand.plus.search.QuickSearchDialogFragment; import net.osmand.plus.search.QuickSearchDialogFragment;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
@ -326,8 +327,8 @@ public class IntentHelper {
if (uri.toString().startsWith(OPRConstants.OPR_OAUTH_PREFIX)) { if (uri.toString().startsWith(OPRConstants.OPR_OAUTH_PREFIX)) {
String token = uri.getQueryParameter("opr-token"); String token = uri.getQueryParameter("opr-token");
String username = uri.getQueryParameter("opr-nickname"); String username = uri.getQueryParameter("opr-nickname");
app.getSettings().OPR_ACCESS_TOKEN.set(token); app.getOprAuthHelper().addListener(getOprAuthorizationListener());
app.getSettings().OPR_USERNAME.set(username); app.getOprAuthHelper().authorize(token, username);
mapActivity.setIntent(null); mapActivity.setIntent(null);
return true; return true;
} }
@ -348,6 +349,19 @@ public class IntentHelper {
}; };
} }
private OprAuthorizationListener getOprAuthorizationListener() {
return new OprAuthorizationListener() {
@Override
public void authorizationCompleted() {
for (Fragment fragment : mapActivity.getSupportFragmentManager().getFragments()) {
if (fragment instanceof OprAuthorizationListener) {
((OprAuthorizationListener) fragment).authorizationCompleted();
}
}
}
};
}
private boolean handleSendText(Intent intent) { private boolean handleSendText(Intent intent) {
String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT); String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
if (!Algorithms.isEmpty(sharedText)) { if (!Algorithms.isEmpty(sharedText)) {

View file

@ -63,7 +63,7 @@ class GpxOrFavouritesImportTask extends BaseLoadAsyncTask<Void, Void, GPXFile> {
ZipEntry entry; ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) { while ((entry = zis.getNextEntry()) != null) {
if (entry.getName().endsWith(ImportHelper.KML_SUFFIX)) { if (entry.getName().endsWith(ImportHelper.KML_SUFFIX)) {
InputStream gpxStream = convertKmlToGpxStream(is); InputStream gpxStream = convertKmlToGpxStream(zis);
if (gpxStream != null) { if (gpxStream != null) {
fileSize = gpxStream.available(); fileSize = gpxStream.available();
return GPXUtilities.loadGPXFile(gpxStream); return GPXUtilities.loadGPXFile(gpxStream);

View file

@ -49,7 +49,7 @@ class KmzImportTask extends BaseLoadAsyncTask<Void, Void, GPXFile> {
ZipEntry entry; ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) { while ((entry = zis.getNextEntry()) != null) {
if (entry.getName().endsWith(KML_SUFFIX)) { if (entry.getName().endsWith(KML_SUFFIX)) {
InputStream gpxStream = convertKmlToGpxStream(is); InputStream gpxStream = convertKmlToGpxStream(zis);
if (gpxStream != null) { if (gpxStream != null) {
fileSize = gpxStream.available(); fileSize = gpxStream.available();
return GPXUtilities.loadGPXFile(gpxStream); return GPXUtilities.loadGPXFile(gpxStream);

View file

@ -58,6 +58,7 @@ import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.LockableScrollView; import net.osmand.plus.LockableScrollView;
import net.osmand.plus.OsmAndFormatter; import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.settings.backend.MainContextMenuItemsSettings; import net.osmand.plus.settings.backend.MainContextMenuItemsSettings;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
@ -1674,6 +1675,12 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
line2MeasuredHeight = line2.getMeasuredHeight(); line2MeasuredHeight = line2.getMeasuredHeight();
} }
int customAddressLineHeight = 0;
View customAddressLine = view.findViewById(R.id.context_menu_custom_address_line);
if (customAddressLine.getVisibility() == View.VISIBLE) {
customAddressLineHeight = customAddressLine.getMeasuredHeight();
}
int line3Height = 0; int line3Height = 0;
View line3Container = view.findViewById(R.id.additional_info_row_container); View line3Container = view.findViewById(R.id.additional_info_row_container);
if (line3Container.getVisibility() == View.VISIBLE) { if (line3Container.getVisibility() == View.VISIBLE) {
@ -1717,12 +1724,12 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
titleHeight = line1.getMeasuredHeight() + line2MeasuredHeight; titleHeight = line1.getMeasuredHeight() + line2MeasuredHeight;
} }
newMenuTopViewHeight = menuTopViewHeightExcludingTitle + titleHeight newMenuTopViewHeight = menuTopViewHeightExcludingTitle + titleHeight
+ titleButtonHeight + downloadButtonsHeight + titleButtonHeight + customAddressLineHeight + downloadButtonsHeight
+ titleBottomButtonHeight + additionalButtonsHeight + titleProgressHeight + line3Height; + titleBottomButtonHeight + additionalButtonsHeight + titleProgressHeight + line3Height;
dy = Math.max(0, newMenuTopViewHeight - menuTopViewHeight dy = Math.max(0, newMenuTopViewHeight - menuTopViewHeight
- (newMenuTopShadowAllHeight - menuTopShadowAllHeight)); - (newMenuTopShadowAllHeight - menuTopShadowAllHeight));
} else { } else {
menuTopViewHeightExcludingTitle = newMenuTopViewHeight - line1.getMeasuredHeight() - line2MeasuredHeight menuTopViewHeightExcludingTitle = newMenuTopViewHeight - line1.getMeasuredHeight() - line2MeasuredHeight - customAddressLineHeight
- titleButtonHeight - downloadButtonsHeight - titleBottomButtonHeight - additionalButtonsHeight - titleProgressHeight - line3Height; - titleButtonHeight - downloadButtonsHeight - titleBottomButtonHeight - additionalButtonsHeight - titleProgressHeight - line3Height;
menuTitleTopBottomPadding = (line1.getMeasuredHeight() - line1.getLineCount() * line1.getLineHeight()) menuTitleTopBottomPadding = (line1.getMeasuredHeight() - line1.getLineCount() * line1.getLineHeight())
+ (line2MeasuredHeight - line2LineCount * line2LineHeight); + (line2MeasuredHeight - line2LineCount * line2LineHeight);
@ -1818,12 +1825,16 @@ public class MapContextMenuFragment extends BaseOsmAndFragment implements Downlo
line1.setText(menu.getTitleStr()); line1.setText(menu.getTitleStr());
toolbarTextView.setText(menu.getTitleStr()); toolbarTextView.setText(menu.getTitleStr());
// Text line 2 // Text line 2
LinearLayout line2layout = view.findViewById(R.id.context_menu_line2_layout);
TextView line2 = view.findViewById(R.id.context_menu_line2); TextView line2 = view.findViewById(R.id.context_menu_line2);
LinearLayout customAddressLine = view.findViewById(R.id.context_menu_custom_address_line);
customAddressLine.removeAllViews();
if (menu.hasCustomAddressLine()) { if (menu.hasCustomAddressLine()) {
line2layout.removeAllViews(); menu.buildCustomAddressLine(customAddressLine);
menu.buildCustomAddressLine(line2layout); AndroidUiHelper.updateVisibility(line2, false);
AndroidUiHelper.updateVisibility(customAddressLine, true);
} else { } else {
AndroidUiHelper.updateVisibility(line2, true);
AndroidUiHelper.updateVisibility(customAddressLine, false);
String typeStr = menu.getTypeStr(); String typeStr = menu.getTypeStr();
String streetStr = menu.getStreetStr(); String streetStr = menu.getStreetStr();
StringBuilder line2Str = new StringBuilder(); StringBuilder line2Str = new StringBuilder();

View file

@ -36,6 +36,7 @@ import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.graphics.drawable.DrawableCompat;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.data.Amenity; import net.osmand.data.Amenity;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
@ -47,11 +48,12 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.Version;
import net.osmand.plus.activities.ActivityResultListener; import net.osmand.plus.activities.ActivityResultListener;
import net.osmand.plus.activities.ActivityResultListener.OnActivityResultListener; import net.osmand.plus.activities.ActivityResultListener.OnActivityResultListener;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.FontCache; import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.mapcontextmenu.UploadPhotosAsyncTask.UploadPhotosListener;
import net.osmand.plus.mapcontextmenu.builders.cards.AbstractCard; import net.osmand.plus.mapcontextmenu.builders.cards.AbstractCard;
import net.osmand.plus.mapcontextmenu.builders.cards.CardsRowBuilder; import net.osmand.plus.mapcontextmenu.builders.cards.CardsRowBuilder;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard;
@ -75,6 +77,10 @@ import net.osmand.plus.widgets.tools.ClickableSpanTouchListener;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils; import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -87,6 +93,7 @@ import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCa
public class MenuBuilder { public class MenuBuilder {
private static final Log LOG = PlatformUtil.getLog(MenuBuilder.class);
private static final int PICK_IMAGE = 1231; private static final int PICK_IMAGE = 1231;
public static final float SHADOW_HEIGHT_TOP_DP = 17f; public static final float SHADOW_HEIGHT_TOP_DP = 17f;
public static final int TITLE_LIMIT = 60; public static final int TITLE_LIMIT = 60;
@ -131,16 +138,14 @@ public class MenuBuilder {
} }
@Override @Override
public void onPlaceIdAcquired(String[] placeId) { public void onPlaceIdAcquired(final String[] placeId) {
MenuBuilder.this.placeId = placeId; MenuBuilder.this.placeId = placeId;
if (placeId.length < 2) { app.runInUIThread(new Runnable() {
app.runInUIThread(new Runnable() { @Override
@Override public void run() {
public void run() { AndroidUiHelper.updateVisibility(photoButton, placeId.length >= 2);
photoButton.setVisibility(View.GONE); }
} });
});
}
} }
@Override @Override
@ -158,6 +163,16 @@ public class MenuBuilder {
} }
}; };
public void addImageCard(ImageCard card) {
if (onlinePhotoCards.size() == 1 && onlinePhotoCards.get(0) instanceof NoImagesCard) {
onlinePhotoCards.clear();
}
onlinePhotoCards.add(0, card);
if (onlinePhotoCardsRow != null) {
onlinePhotoCardsRow.setCards(onlinePhotoCards);
}
}
public interface CollapseExpandListener { public interface CollapseExpandListener {
void onCollapseExpand(boolean collapsed); void onCollapseExpand(boolean collapsed);
} }
@ -443,10 +458,7 @@ public class MenuBuilder {
} }
} }
}); });
//TODO This feature is under development AndroidUiHelper.updateVisibility(view, false);
if (!Version.isDeveloperVersion(app)) {
view.setVisibility(View.GONE);
}
photoButton = view; photoButton = view;
return view; return view;
} }
@ -481,7 +493,27 @@ public class MenuBuilder {
} }
} }
} }
execute(new UploadPhotosAsyncTask(mapActivity, imagesUri, getLatLon(), placeId, getAdditionalCardParams(), imageCardListener)); UploadPhotosListener listener = new UploadPhotosListener() {
@Override
public void uploadPhotosSuccess(final String response) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
if (AndroidUtils.isActivityNotDestroyed(mapActivity)) {
try {
ImageCard imageCard = OsmandPlugin.createImageCardForJson(new JSONObject(response));
if (imageCard != null) {
addImageCard(imageCard);
}
} catch (JSONException e) {
LOG.error(e);
}
}
}
});
}
};
execute(new UploadPhotosAsyncTask(mapActivity, imagesUri, placeId, listener));
} }
} }
})); }));

View file

@ -13,14 +13,11 @@ import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.data.LatLon;
import net.osmand.osm.io.NetworkUtils; import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dialogs.UploadPhotoProgressBottomSheet; import net.osmand.plus.dialogs.UploadPhotoProgressBottomSheet;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener;
import net.osmand.plus.openplacereviews.OPRConstants; import net.osmand.plus.openplacereviews.OPRConstants;
import net.osmand.plus.openplacereviews.OprStartFragment; import net.osmand.plus.openplacereviews.OprStartFragment;
import net.osmand.plus.osmedit.opr.OpenDBAPI; import net.osmand.plus.osmedit.opr.OpenDBAPI;
@ -36,7 +33,6 @@ import java.io.InputStream;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
public class UploadPhotosAsyncTask extends AsyncTask<Void, Integer, Void> { public class UploadPhotosAsyncTask extends AsyncTask<Void, Integer, Void> {
@ -47,22 +43,17 @@ public class UploadPhotosAsyncTask extends AsyncTask<Void, Integer, Void> {
private final OsmandApplication app; private final OsmandApplication app;
private final WeakReference<MapActivity> activityRef; private final WeakReference<MapActivity> activityRef;
private final OpenDBAPI openDBAPI = new OpenDBAPI(); private final OpenDBAPI openDBAPI = new OpenDBAPI();
private final LatLon latLon;
private final List<Uri> data; private final List<Uri> data;
private final String[] placeId; private final String[] placeId;
private final Map<String, String> params; private final UploadPhotosListener listener;
private final GetImageCardsListener imageCardListener; private UploadPhotosProgressListener progressListener;
private UploadPhotosListener listener;
public UploadPhotosAsyncTask(MapActivity activity, List<Uri> data, LatLon latLon, String[] placeId, public UploadPhotosAsyncTask(MapActivity activity, List<Uri> data, String[] placeId, UploadPhotosListener listener) {
Map<String, String> params, GetImageCardsListener imageCardListener) {
app = (OsmandApplication) activity.getApplicationContext(); app = (OsmandApplication) activity.getApplicationContext();
activityRef = new WeakReference<>(activity); activityRef = new WeakReference<>(activity);
this.data = data; this.data = data;
this.latLon = latLon;
this.params = params;
this.placeId = placeId; this.placeId = placeId;
this.imageCardListener = imageCardListener; this.listener = listener;
} }
@Override @Override
@ -70,7 +61,7 @@ public class UploadPhotosAsyncTask extends AsyncTask<Void, Integer, Void> {
FragmentActivity activity = activityRef.get(); FragmentActivity activity = activityRef.get();
if (AndroidUtils.isActivityNotDestroyed(activity)) { if (AndroidUtils.isActivityNotDestroyed(activity)) {
FragmentManager manager = activity.getSupportFragmentManager(); FragmentManager manager = activity.getSupportFragmentManager();
listener = UploadPhotoProgressBottomSheet.showInstance(manager, data.size(), new OnDismissListener() { progressListener = UploadPhotoProgressBottomSheet.showInstance(manager, data.size(), new OnDismissListener() {
@Override @Override
public void onDismiss(DialogInterface dialog) { public void onDismiss(DialogInterface dialog) {
cancel(false); cancel(false);
@ -81,8 +72,8 @@ public class UploadPhotosAsyncTask extends AsyncTask<Void, Integer, Void> {
@Override @Override
protected void onProgressUpdate(Integer... values) { protected void onProgressUpdate(Integer... values) {
if (listener != null) { if (progressListener != null) {
listener.uploadPhotosProgressUpdate(values[0]); progressListener.uploadPhotosProgressUpdate(values[0]);
} }
} }
@ -103,8 +94,8 @@ public class UploadPhotosAsyncTask extends AsyncTask<Void, Integer, Void> {
@Override @Override
protected void onPostExecute(Void aVoid) { protected void onPostExecute(Void aVoid) {
if (listener != null) { if (progressListener != null) {
listener.uploadPhotosFinished(); progressListener.uploadPhotosFinished();
} }
} }
@ -156,13 +147,9 @@ public class UploadPhotosAsyncTask extends AsyncTask<Void, Integer, Void> {
checkTokenAndShowScreen(); checkTokenAndShowScreen();
} else { } else {
success = true; success = true;
String str = app.getString(R.string.successfully_uploaded_pattern, 1, 1);
app.showToastMessage(str);
//refresh the image //refresh the image
if (listener != null) {
MapActivity activity = activityRef.get(); listener.uploadPhotosSuccess(response);
if (activity != null) {
MenuBuilder.execute(new GetImageCardsTask(activity, latLon, params, imageCardListener));
} }
} }
} else { } else {
@ -193,7 +180,9 @@ public class UploadPhotosAsyncTask extends AsyncTask<Void, Integer, Void> {
private byte[] compressImageToJpeg(InputStream image) { private byte[] compressImageToJpeg(InputStream image) {
BufferedInputStream bufferedInputStream = new BufferedInputStream(image); BufferedInputStream bufferedInputStream = new BufferedInputStream(image);
Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream); BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 4;
Bitmap bmp = BitmapFactory.decodeStream(bufferedInputStream, null, opts);
ByteArrayOutputStream os = new ByteArrayOutputStream(); ByteArrayOutputStream os = new ByteArrayOutputStream();
int h = bmp.getHeight(); int h = bmp.getHeight();
int w = bmp.getWidth(); int w = bmp.getWidth();
@ -215,12 +204,17 @@ public class UploadPhotosAsyncTask extends AsyncTask<Void, Integer, Void> {
return os.toByteArray(); return os.toByteArray();
} }
public interface UploadPhotosProgressListener {
public interface UploadPhotosListener {
void uploadPhotosProgressUpdate(int progress); void uploadPhotosProgressUpdate(int progress);
void uploadPhotosFinished(); void uploadPhotosFinished();
} }
public interface UploadPhotosListener {
void uploadPhotosSuccess(String response);
}
} }

View file

@ -19,17 +19,13 @@ import net.osmand.AndroidNetworkUtils;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.Location; import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.data.Amenity;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapcontextmenu.MenuBuilder; import net.osmand.plus.mapcontextmenu.MenuBuilder;
import net.osmand.plus.mapillary.MapillaryContributeCard;
import net.osmand.plus.mapillary.MapillaryImageCard;
import net.osmand.plus.openplacereviews.OPRConstants;
import net.osmand.plus.wikimedia.WikiImageHelper;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -41,18 +37,17 @@ import java.text.DateFormat;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import static net.osmand.plus.mapillary.MapillaryPlugin.TYPE_MAPILLARY_CONTRIBUTE;
import static net.osmand.plus.mapillary.MapillaryPlugin.TYPE_MAPILLARY_PHOTO;
public abstract class ImageCard extends AbstractCard { public abstract class ImageCard extends AbstractCard {
public static String TYPE_MAPILLARY_PHOTO = "mapillary-photo";
public static String TYPE_MAPILLARY_CONTRIBUTE = "mapillary-contribute";
private static final Log LOG = PlatformUtil.getLog(ImageCard.class); private static final Log LOG = PlatformUtil.getLog(ImageCard.class);
protected String type; protected String type;
@ -184,11 +179,7 @@ public abstract class ImageCard extends AbstractCard {
try { try {
if (imageObject.has("type")) { if (imageObject.has("type")) {
String type = imageObject.getString("type"); String type = imageObject.getString("type");
if (TYPE_MAPILLARY_PHOTO.equals(type)) { if (!TYPE_MAPILLARY_CONTRIBUTE.equals(type) && !TYPE_MAPILLARY_PHOTO.equals(type)) {
imageCard = new MapillaryImageCard(mapActivity, imageObject);
} else if (TYPE_MAPILLARY_CONTRIBUTE.equals(type)) {
imageCard = new MapillaryContributeCard(mapActivity, imageObject);
} else {
imageCard = new UrlImageCard(mapActivity, imageObject); imageCard = new UrlImageCard(mapActivity, imageObject);
} }
} }
@ -198,14 +189,6 @@ public abstract class ImageCard extends AbstractCard {
return imageCard; return imageCard;
} }
private static ImageCard createCardOpr(MapActivity mapActivity, JSONObject imageObject) {
ImageCard imageCard = null;
if (imageObject.has("cid")) {
imageCard = new IPFSImageCard(mapActivity, imageObject);
}
return imageCard;
}
public double getCa() { public double getCa() {
return ca; return ca;
} }
@ -410,28 +393,6 @@ public abstract class ImageCard extends AbstractCard {
} }
} }
private static String[] getIdFromResponse(String response) {
try {
JSONArray obj = new JSONObject(response).getJSONArray("objects");
JSONArray images = (JSONArray) ((JSONObject) obj.get(0)).get("id");
return toStringArray(images);
} catch (JSONException e) {
e.printStackTrace();
}
return new String[0];
}
private static String[] toStringArray(JSONArray array) {
if (array == null)
return null;
String[] arr = new String[array.length()];
for (int i = 0; i < arr.length; i++) {
arr[i] = array.optString(i);
}
return arr;
}
public static class GetImageCardsTask extends AsyncTask<Void, Void, List<ImageCard>> { public static class GetImageCardsTask extends AsyncTask<Void, Void, List<ImageCard>> {
private MapActivity mapActivity; private MapActivity mapActivity;
@ -451,7 +412,7 @@ public abstract class ImageCard extends AbstractCard {
} }
public GetImageCardsTask(@NonNull MapActivity mapActivity, LatLon latLon, public GetImageCardsTask(@NonNull MapActivity mapActivity, LatLon latLon,
@Nullable Map<String, String> params, GetImageCardsListener listener) { @Nullable Map<String, String> params, GetImageCardsListener listener) {
this.mapActivity = mapActivity; this.mapActivity = mapActivity;
this.app = mapActivity.getMyApplication(); this.app = mapActivity.getMyApplication();
this.latLon = latLon; this.latLon = latLon;
@ -460,23 +421,9 @@ public abstract class ImageCard extends AbstractCard {
} }
@Override @Override
protected List<ImageCard> doInBackground(Void... params) { protected List<ImageCard> doInBackground(Void... voids) {
TrafficStats.setThreadStatsTag(GET_IMAGE_CARD_THREAD_ID); TrafficStats.setThreadStatsTag(GET_IMAGE_CARD_THREAD_ID);
List<ImageCard> result = new ArrayList<>(); List<ImageCard> result = new ArrayList<>();
Object o = mapActivity.getMapLayers().getContextMenuLayer().getSelectedObject();
if (o instanceof Amenity) {
Amenity am = (Amenity) o;
long amenityId = am.getId() >> 1;
String baseUrl = OPRConstants.getBaseUrl(app);
String url = baseUrl + "api/objects-by-index?type=opr.place&index=osmid&key=" + amenityId;
String response = AndroidNetworkUtils.sendRequest(app, url, Collections.<String, String>emptyMap(),
"Requesting location images...", false, false);
if (response != null) {
getPicturesForPlace(result, response);
String[] id = getIdFromResponse(response);
listener.onPlaceIdAcquired(id);
}
}
try { try {
final Map<String, String> pms = new LinkedHashMap<>(); final Map<String, String> pms = new LinkedHashMap<>();
pms.put("lat", "" + (float) latLon.getLatitude()); pms.put("lat", "" + (float) latLon.getLatitude());
@ -493,19 +440,8 @@ public abstract class ImageCard extends AbstractCard {
if (!Algorithms.isEmpty(preferredLang)) { if (!Algorithms.isEmpty(preferredLang)) {
pms.put("lang", preferredLang); pms.put("lang", preferredLang);
} }
if (this.params != null) { OsmandPlugin.populateContextMenuImageCards(result, pms, params, listener);
String wikidataId = this.params.get(Amenity.WIKIDATA);
if (wikidataId != null) {
this.params.remove(Amenity.WIKIDATA);
WikiImageHelper.addWikidataImageCards(mapActivity, wikidataId, result);
}
String wikimediaContent = this.params.get(Amenity.WIKIMEDIA_COMMONS);
if (wikimediaContent != null) {
this.params.remove(Amenity.WIKIMEDIA_COMMONS);
WikiImageHelper.addWikimediaImageCards(mapActivity, wikimediaContent, result);
}
pms.putAll(this.params);
}
String response = AndroidNetworkUtils.sendRequest(app, "https://osmand.net/api/cm_place", pms, String response = AndroidNetworkUtils.sendRequest(app, "https://osmand.net/api/cm_place", pms,
"Requesting location images...", false, false); "Requesting location images...", false, false);
@ -517,7 +453,10 @@ public abstract class ImageCard extends AbstractCard {
try { try {
JSONObject imageObject = (JSONObject) images.get(i); JSONObject imageObject = (JSONObject) images.get(i);
if (imageObject != JSONObject.NULL) { if (imageObject != JSONObject.NULL) {
ImageCard imageCard = ImageCard.createCard(mapActivity, imageObject); ImageCard imageCard = OsmandPlugin.createImageCardForJson(imageObject);
if (imageCard == null) {
imageCard = ImageCard.createCard(mapActivity, imageObject);
}
if (imageCard != null) { if (imageCard != null) {
result.add(imageCard); result.add(imageCard);
} }
@ -537,36 +476,6 @@ public abstract class ImageCard extends AbstractCard {
return result; return result;
} }
private void getPicturesForPlace(List<ImageCard> result, String response) {
try {
if (!Algorithms.isEmpty(response)) {
JSONArray obj = new JSONObject(response).getJSONArray("objects");
JSONObject imagesWrapper = ((JSONObject) ((JSONObject) obj.get(0)).get("images"));
Iterator<String> it = imagesWrapper.keys();
while (it.hasNext()) {
JSONArray images = imagesWrapper.getJSONArray(it.next());
if (images.length() > 0) {
for (int i = 0; i < images.length(); i++) {
try {
JSONObject imageObject = (JSONObject) images.get(i);
if (imageObject != JSONObject.NULL) {
ImageCard imageCard = ImageCard.createCardOpr(mapActivity, imageObject);
if (imageCard != null) {
result.add(imageCard);
}
}
} catch (JSONException e) {
LOG.error(e);
}
}
}
}
}
} catch (Exception e) {
LOG.error(e);
}
}
@Override @Override
protected void onPostExecute(List<ImageCard> cardList) { protected void onPostExecute(List<ImageCard> cardList) {
result = cardList; result = cardList;

View file

@ -17,27 +17,34 @@ import androidx.appcompat.widget.SwitchCompat;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.map.ITileSource; import net.osmand.map.ITileSource;
import net.osmand.map.TileSourceManager; import net.osmand.map.TileSourceManager;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.ContextMenuAdapter; import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuItem; import net.osmand.plus.ContextMenuItem;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin; import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.MapActivityLayers; import net.osmand.plus.activities.MapActivityLayers;
import net.osmand.plus.base.BottomSheetDialogFragment; import net.osmand.plus.base.BottomSheetDialogFragment;
import net.osmand.plus.dashboard.DashboardOnMap; import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.views.layers.MapInfoLayer; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard;
import net.osmand.plus.openplacereviews.OpenPlaceReviewsPlugin;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.views.MapTileLayer; import net.osmand.plus.views.MapTileLayer;
import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.layers.MapInfoLayer;
import net.osmand.plus.views.mapwidgets.MapWidgetRegistry.MapWidgetRegInfo; import net.osmand.plus.views.mapwidgets.MapWidgetRegistry.MapWidgetRegInfo;
import net.osmand.plus.views.mapwidgets.widgets.TextInfoWidget; import net.osmand.plus.views.mapwidgets.widgets.TextInfoWidget;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.List; import java.util.List;
@ -47,11 +54,18 @@ import static net.osmand.plus.ContextMenuAdapter.makeDeleteAction;
public class MapillaryPlugin extends OsmandPlugin { public class MapillaryPlugin extends OsmandPlugin {
public static String TYPE_MAPILLARY_PHOTO = "mapillary-photo";
public static String TYPE_MAPILLARY_CONTRIBUTE = "mapillary-contribute";
public static final String ID = "osmand.mapillary"; public static final String ID = "osmand.mapillary";
private static final String MAPILLARY_PACKAGE_ID = "app.mapillary"; private static final String MAPILLARY_PACKAGE_ID = "app.mapillary";
private static final Log LOG = PlatformUtil.getLog(OpenPlaceReviewsPlugin.class);
private OsmandSettings settings; private OsmandSettings settings;
private MapActivity mapActivity;
private MapillaryRasterLayer rasterLayer; private MapillaryRasterLayer rasterLayer;
private MapillaryVectorLayer vectorLayer; private MapillaryVectorLayer vectorLayer;
private TextInfoWidget mapillaryControl; private TextInfoWidget mapillaryControl;
@ -62,11 +76,6 @@ public class MapillaryPlugin extends OsmandPlugin {
settings = app.getSettings(); settings = app.getSettings();
} }
@Override
public boolean isVisible() {
return false;
}
@Override @Override
public int getLogoResourceId() { public int getLogoResourceId() {
return R.drawable.ic_action_mapillary; return R.drawable.ic_action_mapillary;
@ -92,6 +101,14 @@ public class MapillaryPlugin extends OsmandPlugin {
return app.getString(R.string.mapillary); return app.getString(R.string.mapillary);
} }
@Override
public boolean init(@NonNull OsmandApplication app, Activity activity) {
if (activity instanceof MapActivity) {
mapActivity = (MapActivity) activity;
}
return true;
}
@Override @Override
public void registerLayers(MapActivity activity) { public void registerLayers(MapActivity activity) {
createLayers(); createLayers();
@ -228,6 +245,41 @@ public class MapillaryPlugin extends OsmandPlugin {
} }
} }
@Override
protected ImageCard createContextMenuImageCard(@NonNull JSONObject imageObject) {
ImageCard imageCard = null;
if (mapActivity != null) {
try {
if (imageObject.has("type")) {
String type = imageObject.getString("type");
if (TYPE_MAPILLARY_PHOTO.equals(type)) {
imageCard = new MapillaryImageCard(mapActivity, imageObject);
} else if (TYPE_MAPILLARY_CONTRIBUTE.equals(type)) {
imageCard = new MapillaryContributeCard(mapActivity, imageObject);
}
}
} catch (JSONException e) {
LOG.error(e);
}
}
return imageCard;
}
@Override
public void mapActivityResume(MapActivity activity) {
this.mapActivity = activity;
}
@Override
public void mapActivityResumeOnTop(MapActivity activity) {
this.mapActivity = activity;
}
@Override
public void mapActivityPause(MapActivity activity) {
this.mapActivity = null;
}
public static boolean openMapillary(FragmentActivity activity, String imageKey) { public static boolean openMapillary(FragmentActivity activity, String imageKey) {
boolean success = false; boolean success = false;
OsmandApplication app = (OsmandApplication) activity.getApplication(); OsmandApplication app = (OsmandApplication) activity.getApplication();

View file

@ -573,8 +573,12 @@ public class GPXItemPagerAdapter extends PagerAdapter implements CustomTabProvid
} else { } else {
layoutId = tripleTabsLayoutIds[position]; layoutId = tripleTabsLayoutIds[position];
} }
View tab = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false); ViewGroup tab = (ViewGroup) UiUtilities.getInflater(parent.getContext(), nightMode).inflate(layoutId, parent, false);
tab.setTag(tabTypes[position].name()); tab.setTag(tabTypes[position].name());
TextView title = (TextView) tab.getChildAt(0);
if (title != null) {
title.setText(getPageTitle(position));
}
return tab; return tab;
} }

View file

@ -9,6 +9,7 @@ import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.Version; import net.osmand.plus.Version;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine;
import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;

View file

@ -1,24 +0,0 @@
package net.osmand.plus.onlinerouting;
import net.osmand.Location;
import net.osmand.plus.routing.RouteDirectionInfo;
import java.util.List;
public class OnlineRoutingResponse {
private List<Location> route;
private List<RouteDirectionInfo> directions;
public OnlineRoutingResponse(List<Location> route, List<RouteDirectionInfo> directions) {
this.route = route;
this.directions = directions;
}
public List<Location> getRoute() {
return route;
}
public List<RouteDirectionInfo> getDirections() {
return directions;
}
}

View file

@ -8,7 +8,6 @@ import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.OnlineRoutingResponse;
import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.plus.onlinerouting.VehicleType;
import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RouteDirectionInfo;
import net.osmand.router.TurnType; import net.osmand.router.TurnType;
@ -84,12 +83,9 @@ public class GraphhopperEngine extends OnlineRoutingEngine {
@Nullable @Nullable
@Override @Override
public OnlineRoutingResponse parseServerResponse(@NonNull String content, public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root,
@NonNull OsmandApplication app, @NonNull OsmandApplication app,
boolean leftSideNavigation) throws JSONException { boolean leftSideNavigation) throws JSONException {
JSONObject obj = new JSONObject(content);
JSONObject root = obj.getJSONArray("paths").getJSONObject(0);
String encoded = root.getString("points"); String encoded = root.getString("points");
List<LatLon> points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5); List<LatLon> points = GeoPolylineParserUtil.parse(encoded, GeoPolylineParserUtil.PRECISION_5);
if (isEmpty(points)) return null; if (isEmpty(points)) return null;
@ -216,14 +212,15 @@ public class GraphhopperEngine extends OnlineRoutingEngine {
return id != null ? TurnType.valueOf(id, leftSide) : null; return id != null ? TurnType.valueOf(id, leftSide) : null;
} }
@NonNull
@Override @Override
public boolean parseServerMessage(@NonNull StringBuilder sb, protected String getErrorMessageKey() {
@NonNull String content) throws JSONException { return "message";
JSONObject obj = new JSONObject(content); }
if (obj.has("message")) {
String message = obj.getString("message"); @NonNull
sb.append(message); @Override
} protected String getRootArrayKey() {
return obj.has("paths"); return "paths";
} }
} }

View file

@ -12,12 +12,14 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.OnlineRoutingFactory; import net.osmand.plus.onlinerouting.OnlineRoutingFactory;
import net.osmand.plus.onlinerouting.OnlineRoutingResponse;
import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.plus.onlinerouting.VehicleType;
import net.osmand.plus.routing.RouteDirectionInfo;
import net.osmand.plus.routing.RouteProvider; import net.osmand.plus.routing.RouteProvider;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -98,10 +100,31 @@ public abstract class OnlineRoutingEngine implements Cloneable {
@NonNull @NonNull
public abstract String getStandardUrl(); public abstract String getStandardUrl();
public OnlineRoutingResponse parseServerResponse(@NonNull String content,
@NonNull OsmandApplication app,
boolean leftSideNavigation) throws JSONException {
JSONObject root = parseRootResponseObject(content);
return root != null ? parseServerResponse(root, app, leftSideNavigation) : null;
}
@Nullable @Nullable
public abstract OnlineRoutingResponse parseServerResponse(@NonNull String content, protected abstract OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root,
@NonNull OsmandApplication app, @NonNull OsmandApplication app,
boolean leftSideNavigation) throws JSONException; boolean leftSideNavigation) throws JSONException;
@Nullable
protected JSONObject parseRootResponseObject(@NonNull String content) throws JSONException {
JSONObject fullJSON = new JSONObject(content);
String responseArrayKey = getRootArrayKey();
JSONArray array = null;
if (fullJSON.has(responseArrayKey)) {
array = fullJSON.getJSONArray(responseArrayKey);
}
return array != null && array.length() > 0 ? array.getJSONObject(0) : null;
}
@NonNull
protected abstract String getRootArrayKey();
@NonNull @NonNull
protected List<Location> convertRouteToLocationsList(@NonNull List<LatLon> route) { protected List<Location> convertRouteToLocationsList(@NonNull List<LatLon> route) {
@ -161,7 +184,7 @@ public abstract class OnlineRoutingEngine implements Cloneable {
return allowedParameters.contains(key); return allowedParameters.contains(key);
} }
protected void allowParameters(@NonNull EngineParameter ... allowedParams) { protected void allowParameters(@NonNull EngineParameter... allowedParams) {
allowedParameters.addAll(Arrays.asList(allowedParams)); allowedParameters.addAll(Arrays.asList(allowedParams));
} }
@ -193,8 +216,19 @@ public abstract class OnlineRoutingEngine implements Cloneable {
return CUSTOM_VEHICLE; return CUSTOM_VEHICLE;
} }
public abstract boolean parseServerMessage(@NonNull StringBuilder sb, public boolean checkServerResponse(@NonNull StringBuilder errorMessage,
@NonNull String content) throws JSONException; @NonNull String content) throws JSONException {
JSONObject obj = new JSONObject(content);
String messageKey = getErrorMessageKey();
if (obj.has(messageKey)) {
String message = obj.getString(messageKey);
errorMessage.append(message);
}
return obj.has(getRootArrayKey());
}
@NonNull
protected abstract String getErrorMessageKey();
@NonNull @NonNull
@Override @Override
@ -202,11 +236,6 @@ public abstract class OnlineRoutingEngine implements Cloneable {
return OnlineRoutingFactory.createEngine(getType(), getParams()); return OnlineRoutingFactory.createEngine(getType(), getParams());
} }
@NonNull
public static String generateKey() {
return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis();
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
@ -216,4 +245,27 @@ public abstract class OnlineRoutingEngine implements Cloneable {
if (getType() != engine.getType()) return false; if (getType() != engine.getType()) return false;
return Algorithms.objectEquals(getParams(), engine.getParams()); return Algorithms.objectEquals(getParams(), engine.getParams());
} }
@NonNull
public static String generateKey() {
return ONLINE_ROUTING_ENGINE_PREFIX + System.currentTimeMillis();
}
public static class OnlineRoutingResponse {
private List<Location> route;
private List<RouteDirectionInfo> directions;
public OnlineRoutingResponse(List<Location> route, List<RouteDirectionInfo> directions) {
this.route = route;
this.directions = directions;
}
public List<Location> getRoute() {
return route;
}
public List<RouteDirectionInfo> getDirections() {
return directions;
}
}
} }

View file

@ -8,7 +8,6 @@ import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.OnlineRoutingResponse;
import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.plus.onlinerouting.VehicleType;
import org.json.JSONArray; import org.json.JSONArray;
@ -81,12 +80,10 @@ public class OrsEngine extends OnlineRoutingEngine {
@Nullable @Nullable
@Override @Override
public OnlineRoutingResponse parseServerResponse(@NonNull String content, public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root,
@NonNull OsmandApplication app, @NonNull OsmandApplication app,
boolean leftSideNavigation) throws JSONException { boolean leftSideNavigation) throws JSONException {
JSONObject obj = new JSONObject(content); JSONArray array = root.getJSONObject("geometry").getJSONArray("coordinates");
JSONArray array = obj.getJSONArray("features").getJSONObject(0)
.getJSONObject("geometry").getJSONArray("coordinates");
List<LatLon> points = new ArrayList<>(); List<LatLon> points = new ArrayList<>();
for (int i = 0; i < array.length(); i++) { for (int i = 0; i < array.length(); i++) {
JSONArray point = array.getJSONArray(i); JSONArray point = array.getJSONArray(i);
@ -101,14 +98,15 @@ public class OrsEngine extends OnlineRoutingEngine {
return null; return null;
} }
@NonNull
@Override @Override
public boolean parseServerMessage(@NonNull StringBuilder sb, protected String getErrorMessageKey() {
@NonNull String content) throws JSONException { return "error";
JSONObject obj = new JSONObject(content); }
if (obj.has("error")) {
String message = obj.getString("error"); @NonNull
sb.append(message); @Override
} protected String getRootArrayKey() {
return obj.has("features"); return "features";
} }
} }

View file

@ -8,7 +8,6 @@ import net.osmand.data.LatLon;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.onlinerouting.EngineParameter; import net.osmand.plus.onlinerouting.EngineParameter;
import net.osmand.plus.onlinerouting.OnlineRoutingResponse;
import net.osmand.plus.onlinerouting.VehicleType; import net.osmand.plus.onlinerouting.VehicleType;
import net.osmand.plus.routing.RouteCalculationResult; import net.osmand.plus.routing.RouteCalculationResult;
import net.osmand.plus.routing.RouteDirectionInfo; import net.osmand.plus.routing.RouteDirectionInfo;
@ -77,19 +76,17 @@ public class OsrmEngine extends OnlineRoutingEngine {
@Nullable @Nullable
@Override @Override
public OnlineRoutingResponse parseServerResponse(@NonNull String content, public OnlineRoutingResponse parseServerResponse(@NonNull JSONObject root,
@NonNull OsmandApplication app, @NonNull OsmandApplication app,
boolean leftSideNavigation) throws JSONException { boolean leftSideNavigation) throws JSONException {
JSONObject obj = new JSONObject(content); String encodedPoints = root.getString("geometry");
JSONObject routeInfo = obj.getJSONArray("routes").getJSONObject(0);
String encodedPoints = routeInfo.getString("geometry");
List<LatLon> points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5); List<LatLon> points = GeoPolylineParserUtil.parse(encodedPoints, GeoPolylineParserUtil.PRECISION_5);
if (isEmpty(points)) return null; if (isEmpty(points)) return null;
List<Location> route = convertRouteToLocationsList(points); List<Location> route = convertRouteToLocationsList(points);
List<RouteDirectionInfo> directions = new ArrayList<>(); List<RouteDirectionInfo> directions = new ArrayList<>();
int startSearchingId = 0; int startSearchingId = 0;
JSONArray legs = routeInfo.getJSONArray("legs"); JSONArray legs = root.getJSONArray("legs");
for (int i = 0; i < legs.length(); i++) { for (int i = 0; i < legs.length(); i++) {
JSONObject leg = legs.getJSONObject(i); JSONObject leg = legs.getJSONObject(i);
if (!leg.has("steps")) continue; if (!leg.has("steps")) continue;
@ -226,14 +223,15 @@ public class OsrmEngine extends OnlineRoutingEngine {
return id != null ? TurnType.valueOf(id, leftSide) : null; return id != null ? TurnType.valueOf(id, leftSide) : null;
} }
@NonNull
@Override @Override
public boolean parseServerMessage(@NonNull StringBuilder sb, protected String getErrorMessageKey() {
@NonNull String content) throws JSONException { return "message";
JSONObject obj = new JSONObject(content); }
if (obj.has("message")) {
String message = obj.getString("message"); @NonNull
sb.append(message); @Override
} protected String getRootArrayKey() {
return obj.has("routes"); return "routes";
} }
} }

View file

@ -458,15 +458,15 @@ public class OnlineRoutingEngineFragment extends BaseOsmAndFragment {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
StringBuilder message = new StringBuilder(); StringBuilder errorMessage = new StringBuilder();
boolean resultOk = false; boolean resultOk = false;
try { try {
String response = helper.makeRequest(exampleCard.getEditedText()); String response = helper.makeRequest(exampleCard.getEditedText());
resultOk = requestedEngine.parseServerMessage(message, response); resultOk = requestedEngine.checkServerResponse(errorMessage, response);
} catch (IOException | JSONException e) { } catch (IOException | JSONException e) {
message.append(e.toString()); errorMessage.append(e.toString());
} }
showTestResults(resultOk, message.toString(), location); showTestResults(resultOk, errorMessage.toString(), location);
} }
}).start(); }).start();
} }

View file

@ -1,12 +1,16 @@
package net.osmand.plus.mapcontextmenu.builders.cards; package net.osmand.plus.openplacereviews;
import android.view.View; import android.view.View;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -16,16 +20,17 @@ public class IPFSImageCard extends ImageCard {
public IPFSImageCard(MapActivity mapActivity, JSONObject imageObject) { public IPFSImageCard(MapActivity mapActivity, JSONObject imageObject) {
super(mapActivity, imageObject); super(mapActivity, imageObject);
String cid = "";
try { try {
cid = (String) imageObject.get("cid"); String calcImageUrl = mapActivity.getString(R.string.opr_base_url) + "api/ipfs/image?";
calcImageUrl += "cid=" + (String) imageObject.getString("cid");
calcImageUrl += "&hash=" + (String) imageObject.getString("hash");
calcImageUrl += "&ext=" + (String) imageObject.getString("extension");
url = calcImageUrl;
imageHiresUrl = url;
imageUrl = url;
} catch (JSONException e) { } catch (JSONException e) {
LOG.error(e); LOG.error(e);
} }
String BASE_URL = mapActivity.getString(R.string.opr_base_url) + "api/ipfs/image-ipfs?cid=";
url = BASE_URL + cid;
imageHiresUrl = BASE_URL + cid;
imageUrl = BASE_URL + cid;
icon = ContextCompat.getDrawable(getMyApplication(), R.drawable.ic_logo_openplacereview); icon = ContextCompat.getDrawable(getMyApplication(), R.drawable.ic_logo_openplacereview);
if (!Algorithms.isEmpty(getUrl())) { if (!Algorithms.isEmpty(getUrl())) {
View.OnClickListener onClickListener = new View.OnClickListener() { View.OnClickListener onClickListener = new View.OnClickListener() {

View file

@ -1,9 +1,9 @@
package net.osmand.plus.openplacereviews; package net.osmand.plus.openplacereviews;
import android.content.Context; import androidx.annotation.NonNull;
import net.osmand.plus.R; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.osmedit.opr.OpenDBAPI; import net.osmand.plus.osmedit.opr.OpenDBAPI;
public class OPRConstants { public class OPRConstants {
@ -11,28 +11,27 @@ public class OPRConstants {
private static final String PURPOSE = OpenDBAPI.PURPOSE; private static final String PURPOSE = OpenDBAPI.PURPOSE;
private static final String CALLBACK_URL = OPR_OAUTH_PREFIX + "://osmand_opr_auth"; private static final String CALLBACK_URL = OPR_OAUTH_PREFIX + "://osmand_opr_auth";
public static String getBaseUrl(Context ctx) { public static String getBaseUrl(@NonNull OsmandApplication app) {
return ctx.getString(R.string.opr_base_url); return app.getSettings().getOprUrl();
} }
public static String getLoginUrl(@NonNull OsmandApplication app) {
public static String getLoginUrl(Context ctx) { return getBaseUrl(app) + "login" + getQueryString();
return getBaseUrl(ctx) + "login" + getQueryString(ctx);
} }
public static String getRegisterUrl(Context ctx) { public static String getRegisterUrl(@NonNull OsmandApplication app) {
return getBaseUrl(ctx) + "signup" + getQueryString(ctx); return getBaseUrl(app) + "signup" + getQueryString();
} }
public static String getQueryString(Context ctx) { public static String getQueryString() {
return "?" + getPurposeParam(ctx) + "&" + getCallbackParam(ctx); return "?" + getPurposeParam() + "&" + getCallbackParam();
} }
public static String getPurposeParam(Context ctx) { public static String getPurposeParam() {
return "purpose=" + PURPOSE; return "purpose=" + PURPOSE;
} }
public static String getCallbackParam(Context ctx) { public static String getCallbackParam() {
return "callback=" + CALLBACK_URL; return "callback=" + CALLBACK_URL;
} }
} }

View file

@ -0,0 +1,199 @@
package net.osmand.plus.openplacereviews;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.osmand.AndroidNetworkUtils;
import net.osmand.PlatformUtil;
import net.osmand.data.Amenity;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener;
import net.osmand.plus.settings.fragments.BaseSettingsFragment.SettingsScreenType;
import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class OpenPlaceReviewsPlugin extends OsmandPlugin {
private static final Log LOG = PlatformUtil.getLog(OpenPlaceReviewsPlugin.class);
public static final String ID = "osmand.openplacereviews";
private MapActivity mapActivity;
public OpenPlaceReviewsPlugin(OsmandApplication app) {
super(app);
}
@Override
public String getId() {
return ID;
}
@Override
public String getName() {
return app.getString(R.string.open_place_reviews);
}
@Override
public CharSequence getDescription() {
return app.getString(R.string.open_place_reviews_plugin_description);
}
@Override
public SettingsScreenType getSettingsScreenType() {
return SettingsScreenType.OPEN_PLACE_REVIEWS;
}
@Override
public int getLogoResourceId() {
return R.drawable.ic_img_logo_openplacereview;
}
@Override
public Drawable getAssetResourceImage() {
return app.getUIUtilities().getIcon(R.drawable.img_plugin_openplacereviews);
}
@Override
public void mapActivityResume(MapActivity activity) {
this.mapActivity = activity;
}
@Override
public void mapActivityResumeOnTop(MapActivity activity) {
this.mapActivity = activity;
}
@Override
public void mapActivityPause(MapActivity activity) {
this.mapActivity = null;
}
@Override
protected List<ImageCard> getContextMenuImageCards(@NonNull Map<String, String> params,
@Nullable Map<String, String> additionalParams,
@Nullable GetImageCardsListener listener) {
List<ImageCard> imageCards = new ArrayList<>();
if (mapActivity != null) {
Object object = mapActivity.getMapLayers().getContextMenuLayer().getSelectedObject();
if (object instanceof Amenity) {
Amenity am = (Amenity) object;
long amenityId = am.getId() >> 1;
String baseUrl = OPRConstants.getBaseUrl(app);
String url = baseUrl + "api/objects-by-index?type=opr.place&index=osmid&key=" + amenityId;
String response = AndroidNetworkUtils.sendRequest(app, url, Collections.<String, String>emptyMap(),
"Requesting location images...", false, false);
if (response != null) {
getPicturesForPlace(imageCards, response);
if (listener != null) {
listener.onPlaceIdAcquired(getIdFromResponse(response));
}
}
}
}
return imageCards;
}
@Override
protected ImageCard createContextMenuImageCard(@NonNull JSONObject imageObject) {
ImageCard imageCard = null;
if (mapActivity != null && imageObject != JSONObject.NULL) {
imageCard = createCardOpr(mapActivity, imageObject);
}
return imageCard;
}
private void getPicturesForPlace(List<ImageCard> result, String response) {
try {
if (!Algorithms.isEmpty(response)) {
JSONArray obj = new JSONObject(response).getJSONArray("objects");
JSONObject imagesWrapper = ((JSONObject) ((JSONObject) obj.get(0)).get("images"));
Iterator<String> it = imagesWrapper.keys();
while (it.hasNext()) {
JSONArray images = imagesWrapper.getJSONArray(it.next());
if (images.length() > 0) {
for (int i = 0; i < images.length(); i++) {
try {
JSONObject imageObject = (JSONObject) images.get(i);
if (imageObject != JSONObject.NULL) {
ImageCard imageCard = createCardOpr(mapActivity, imageObject);
if (imageCard != null) {
result.add(imageCard);
}
}
} catch (JSONException e) {
LOG.error(e);
}
}
}
}
}
} catch (Exception e) {
LOG.error(e);
}
}
public static ImageCard createCardOpr(MapActivity mapActivity, JSONObject imageObject) {
ImageCard imageCard = null;
if (imageObject.has("cid")) {
imageCard = new IPFSImageCard(mapActivity, imageObject);
}
return imageCard;
}
private static String[] getIdFromResponse(String response) {
try {
JSONArray obj = new JSONObject(response).getJSONArray("objects");
JSONArray images = (JSONArray) ((JSONObject) obj.get(0)).get("id");
return toStringArray(images);
} catch (JSONException e) {
e.printStackTrace();
}
return new String[0];
}
private static String[] toStringArray(JSONArray array) {
if (array == null)
return null;
String[] arr = new String[array.length()];
for (int i = 0; i < arr.length; i++) {
arr[i] = array.optString(i);
}
return arr;
}
@Override
public boolean init(@NonNull OsmandApplication app, Activity activity) {
if (activity instanceof MapActivity) {
mapActivity = (MapActivity) activity;
}
return true;
}
@Override
public void disable(OsmandApplication app) {
if (app.getSettings().OPR_USE_DEV_URL.get()) {
app.getSettings().OPR_USE_DEV_URL.set(false);
app.getOprAuthHelper().resetAuthorization();
}
super.disable(app);
}
}

View file

@ -0,0 +1,95 @@
package net.osmand.plus.openplacereviews;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.osmedit.opr.OpenDBAPI;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.util.Algorithms;
import java.util.HashSet;
import java.util.Set;
public class OprAuthHelper {
private final OsmandApplication app;
private final OsmandSettings settings;
private final Set<OprAuthorizationListener> listeners = new HashSet<>();
public OprAuthHelper(@NonNull OsmandApplication app) {
this.app = app;
settings = app.getSettings();
}
public void addListener(OprAuthorizationListener listener) {
listeners.add(listener);
}
public void removeListener(OprAuthorizationListener listener) {
listeners.remove(listener);
}
public void resetAuthorization() {
if (isLoginExists()) {
settings.OPR_USERNAME.resetToDefault();
settings.OPR_ACCESS_TOKEN.resetToDefault();
settings.OPR_BLOCKCHAIN_NAME.resetToDefault();
}
}
public boolean isLoginExists() {
return !Algorithms.isEmpty(settings.OPR_USERNAME.get())
&& !Algorithms.isEmpty(settings.OPR_BLOCKCHAIN_NAME.get())
&& !Algorithms.isEmpty(settings.OPR_ACCESS_TOKEN.get());
}
private void notifyAndRemoveListeners() {
for (OprAuthorizationListener listener : listeners) {
listener.authorizationCompleted();
}
listeners.clear();
}
public void authorize(final String token, final String username) {
CheckOprAuthTask checkOprAuthTask = new CheckOprAuthTask(app, token, username);
checkOprAuthTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
}
private static class CheckOprAuthTask extends AsyncTask<Void, Void, Boolean> {
private final OsmandApplication app;
private final OpenDBAPI openDBAPI = new OpenDBAPI();
private final String token;
private final String username;
private CheckOprAuthTask(@NonNull OsmandApplication app, String token, String username) {
this.app = app;
this.token = token;
this.username = username;
}
@Override
protected Boolean doInBackground(Void... params) {
String baseUrl = OPRConstants.getBaseUrl(app);
return openDBAPI.checkPrivateKeyValid(app, baseUrl, username, token);
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
app.getSettings().OPR_ACCESS_TOKEN.set(token);
app.getSettings().OPR_USERNAME.set(username);
} else {
app.getOprAuthHelper().resetAuthorization();
}
app.getOprAuthHelper().notifyAndRemoveListeners();
}
}
public interface OprAuthorizationListener {
void authorizationCompleted();
}
}

View file

@ -0,0 +1,119 @@
package net.osmand.plus.openplacereviews;
import android.os.Bundle;
import androidx.activity.OnBackPressedCallback;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.openplacereviews.OprAuthHelper.OprAuthorizationListener;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.OnPreferenceChanged;
import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
public class OprSettingsFragment extends BaseSettingsFragment implements OnPreferenceChanged, OprAuthorizationListener {
private static final String OPR_LOGOUT = "opr_logout";
public static final String OPR_LOGIN_DATA = "opr_login_data";
private OprAuthHelper authHelper;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
authHelper = app.getOprAuthHelper();
FragmentActivity activity = requireMyActivity();
activity.getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
public void handleOnBackPressed() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
mapActivity.launchPrevActivityIntent();
}
dismiss();
}
});
}
@Override
protected void setupPreferences() {
Preference oprSettingsInfo = findPreference("opr_settings_info");
oprSettingsInfo.setIconSpaceReserved(false);
setupLoginPref();
setupLogoutPref();
setupUseDevUrlPref();
}
private void setupLoginPref() {
Preference nameAndPasswordPref = findPreference(OPR_LOGIN_DATA);
nameAndPasswordPref.setVisible(!authHelper.isLoginExists());
nameAndPasswordPref.setIcon(getContentIcon(R.drawable.ic_action_user_account));
}
private void setupLogoutPref() {
Preference nameAndPasswordPref = findPreference(OPR_LOGOUT);
nameAndPasswordPref.setVisible(authHelper.isLoginExists());
nameAndPasswordPref.setSummary(settings.OPR_USERNAME.get());
nameAndPasswordPref.setIcon(getContentIcon(R.drawable.ic_action_user_account));
}
private void setupUseDevUrlPref() {
SwitchPreferenceEx useDevUrlPref = findPreference(settings.OPR_USE_DEV_URL.getId());
useDevUrlPref.setVisible(OsmandPlugin.isDevelopment());
useDevUrlPref.setIcon(getPersistentPrefIcon(R.drawable.ic_plugin_developer));
}
@Override
public boolean onPreferenceClick(Preference preference) {
String prefId = preference.getKey();
if (OPR_LOGIN_DATA.equals(prefId)) {
FragmentManager fragmentManager = getFragmentManager();
if (fragmentManager != null) {
OprStartFragment.showInstance(fragmentManager);
return true;
}
} else if (OPR_LOGOUT.equals(prefId)) {
oprLogout();
return true;
}
return super.onPreferenceClick(preference);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String prefId = preference.getKey();
if (settings.OPR_USE_DEV_URL.getId().equals(prefId) && newValue instanceof Boolean) {
settings.OPR_USE_DEV_URL.set((Boolean) newValue);
oprLogout();
return true;
}
return super.onPreferenceChange(preference, newValue);
}
public void oprLogout() {
authHelper.resetAuthorization();
app.showShortToastMessage(R.string.osm_edit_logout_success);
updateAllSettings();
}
@Override
public void onPreferenceChanged(String prefId) {
if (settings.OPR_USE_DEV_URL.getId().equals(prefId)) {
oprLogout();
}
updateAllSettings();
}
@Override
public void authorizationCompleted() {
if (getContext() != null) {
updateAllSettings();
}
}
}

View file

@ -16,18 +16,21 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.browser.customtabs.CustomTabsIntent; import androidx.browser.customtabs.CustomTabsIntent;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.BaseOsmAndFragment; import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.openplacereviews.OprAuthHelper.OprAuthorizationListener;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
public class OprStartFragment extends BaseOsmAndFragment { public class OprStartFragment extends BaseOsmAndFragment implements OprAuthorizationListener {
private static final String TAG = OprStartFragment.class.getSimpleName(); private static final String TAG = OprStartFragment.class.getSimpleName();
private static final Log LOG = PlatformUtil.getLog(OprStartFragment.class); private static final Log LOG = PlatformUtil.getLog(OprStartFragment.class);
private static final String openPlaceReviewsUrl = "OpenPlaceReviews.org"; private static final String openPlaceReviewsUrl = "OpenPlaceReviews.org";
@ -36,18 +39,22 @@ public class OprStartFragment extends BaseOsmAndFragment {
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls(); nightMode = getMyApplication().getDaynightHelper().isNightModeForMapControls();
View v = UiUtilities.getInflater(requireMyActivity(), nightMode).inflate(R.layout.fragment_opr_login, container,
false); View v = UiUtilities.getInflater(requireMyActivity(), nightMode).inflate(R.layout.fragment_opr_login, container, false);
View createAccount = v.findViewById(R.id.register_opr_create_account); AndroidUtils.addStatusBarPadding21v(requireMyActivity(), v);
v.findViewById(R.id.back_button).setOnClickListener(new View.OnClickListener() {
Toolbar toolbar = (Toolbar) v.findViewById(R.id.toolbar);
int icBackResId = AndroidUtils.getNavigationIconResId(v.getContext());
toolbar.setNavigationIcon(getContentIcon(icBackResId));
toolbar.setNavigationContentDescription(R.string.access_shared_string_navigate_up);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View v) {
FragmentActivity activity = getActivity(); dismiss();
if (activity != null) {
activity.getSupportFragmentManager().popBackStack();
}
} }
}); });
View createAccount = v.findViewById(R.id.register_opr_create_account);
UiUtilities.setupDialogButton(nightMode, createAccount, UiUtilities.DialogButtonType.PRIMARY, UiUtilities.setupDialogButton(nightMode, createAccount, UiUtilities.DialogButtonType.PRIMARY,
R.string.register_opr_create_new_account); R.string.register_opr_create_new_account);
createAccount.setOnClickListener(new View.OnClickListener() { createAccount.setOnClickListener(new View.OnClickListener() {
@ -70,14 +77,14 @@ public class OprStartFragment extends BaseOsmAndFragment {
} }
private void handleHaveAccount() { private void handleHaveAccount() {
String url = OPRConstants.getLoginUrl(requireContext()); String url = OPRConstants.getLoginUrl(requireMyApplication());
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build(); CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(requireContext(), Uri.parse(url)); customTabsIntent.launchUrl(requireContext(), Uri.parse(url));
} }
private void handleCreateAccount() { private void handleCreateAccount() {
String url = OPRConstants.getRegisterUrl(requireContext()); String url = OPRConstants.getRegisterUrl(requireMyApplication());
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build(); CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(requireContext(), Uri.parse(url)); customTabsIntent.launchUrl(requireContext(), Uri.parse(url));
@ -114,6 +121,17 @@ public class OprStartFragment extends BaseOsmAndFragment {
} }
} }
@Override
public void authorizationCompleted() {
dismiss();
}
protected void dismiss() {
FragmentActivity activity = getActivity();
if (activity != null) {
activity.getSupportFragmentManager().popBackStack();
}
}
public static void showInstance(@NonNull FragmentManager fm) { public static void showInstance(@NonNull FragmentManager fm) {
try { try {

View file

@ -28,7 +28,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static net.osmand.plus.osmedit.oauth.OsmOAuthHelper.*; import static net.osmand.plus.osmedit.oauth.OsmOAuthHelper.OsmAuthorizationListener;
/** /**
* Created by Denis * Created by Denis
@ -149,7 +149,9 @@ public class DashOsmEditsFragment extends DashBaseFragment
@Override @Override
public void authorizationCompleted() { public void authorizationCompleted() {
SendPoiBottomSheetFragment.showInstance(getChildFragmentManager(), new OsmPoint[]{selectedPoint}); if (selectedPoint != null) {
SendPoiBottomSheetFragment.showInstance(getChildFragmentManager(), new OsmPoint[] {selectedPoint});
}
} }
@Override @Override

View file

@ -5,6 +5,7 @@ import android.graphics.drawable.Drawable;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentManager;
import net.osmand.data.PointDescription; import net.osmand.data.PointDescription;
import net.osmand.osm.PoiType; import net.osmand.osm.PoiType;
@ -51,19 +52,18 @@ public class EditPOIMenuController extends MenuController {
OsmandSettings settings = app.getSettings(); OsmandSettings settings = app.getSettings();
OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(app); OsmOAuthAuthorizationAdapter client = new OsmOAuthAuthorizationAdapter(app);
boolean isLogged = client.isValidToken() boolean isLogged = client.isValidToken()
|| !Algorithms.isEmpty(settings.USER_NAME.get()) || !Algorithms.isEmpty(settings.OSM_USER_NAME.get())
&& !Algorithms.isEmpty(settings.USER_PASSWORD.get()); && !Algorithms.isEmpty(settings.OSM_USER_PASSWORD.get());
FragmentManager fragmentManager = activity.getSupportFragmentManager();
if (point instanceof OpenstreetmapPoint) { if (point instanceof OpenstreetmapPoint) {
if (isLogged) { if (isLogged) {
SendPoiBottomSheetFragment.showInstance(activity.getSupportFragmentManager(), SendPoiBottomSheetFragment.showInstance(fragmentManager, new OsmPoint[] {point});
new OsmPoint[]{getOsmPoint()});
} else { } else {
LoginBottomSheetFragment.showInstance(activity.getSupportFragmentManager(), null); LoginBottomSheetFragment.showInstance(fragmentManager, null);
} }
} else if (point instanceof OsmNotesPoint) { } else if (point instanceof OsmNotesPoint) {
SendOsmNoteBottomSheetFragment.showInstance(activity.getSupportFragmentManager(), SendOsmNoteBottomSheetFragment.showInstance(fragmentManager, new OsmPoint[] {point});
new OsmPoint[]{getOsmPoint()});
} }
} }
} }

View file

@ -84,7 +84,7 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
additionalData.put("tags", tagstring); additionalData.put("tags", tagstring);
additionalData.put("visibility", visibility); additionalData.put("visibility", visibility);
return NetworkUtils.uploadFile(url, f, return NetworkUtils.uploadFile(url, f,
settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(), settings.OSM_USER_NAME.get() + ":" + settings.OSM_USER_PASSWORD.get(),
adapter.getClient(), adapter.getClient(),
"file", "file",
true, additionalData); true, additionalData);
@ -138,7 +138,7 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
connection.setRequestMethod(requestMethod); connection.setRequestMethod(requestMethod);
connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx)); //$NON-NLS-1$ connection.setRequestProperty("User-Agent", Version.getFullVersion(ctx)); //$NON-NLS-1$
StringBuilder responseBody = new StringBuilder(); StringBuilder responseBody = new StringBuilder();
String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); //$NON-NLS-1$ String token = settings.OSM_USER_NAME.get() + ":" + settings.OSM_USER_PASSWORD.get(); //$NON-NLS-1$
connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
connection.setDoInput(true); connection.setDoInput(true);
if (requestMethod.equals("PUT") || requestMethod.equals("POST") || requestMethod.equals("DELETE")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if (requestMethod.equals("PUT") || requestMethod.equals("POST") || requestMethod.equals("DELETE")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
@ -322,9 +322,9 @@ public class OpenstreetmapRemoteUtil implements OpenstreetmapUtil {
ser.attribute(null, "version", "0.6"); //$NON-NLS-1$ //$NON-NLS-2$ ser.attribute(null, "version", "0.6"); //$NON-NLS-1$ //$NON-NLS-2$
ser.attribute(null, "generator", Version.getAppName(ctx)); //$NON-NLS-1$ ser.attribute(null, "generator", Version.getAppName(ctx)); //$NON-NLS-1$
if (n instanceof Node) { if (n instanceof Node) {
writeNode((Node) n, info, ser, changeSetId, settings.USER_NAME.get()); writeNode((Node) n, info, ser, changeSetId, settings.OSM_USER_NAME.get());
} else if (n instanceof Way) { } else if (n instanceof Way) {
writeWay((Way) n, info, ser, changeSetId, settings.USER_NAME.get()); writeWay((Way) n, info, ser, changeSetId, settings.OSM_USER_NAME.get());
} }
ser.endTag(null, OsmPoint.stringAction.get(action)); ser.endTag(null, OsmPoint.stringAction.get(action));
ser.endTag(null, "osmChange"); //$NON-NLS-1$ ser.endTag(null, "osmChange"); //$NON-NLS-1$

View file

@ -141,7 +141,7 @@ public class OsmBugsRemoteUtil implements OsmBugsUtil {
connection.setRequestMethod(requestMethod); connection.setRequestMethod(requestMethod);
connection.setRequestProperty("User-Agent", Version.getFullVersion(app)); connection.setRequestProperty("User-Agent", Version.getFullVersion(app));
if (!anonymous) { if (!anonymous) {
String token = settings.USER_NAME.get() + ":" + settings.USER_PASSWORD.get(); String token = settings.OSM_USER_NAME.get() + ":" + settings.OSM_USER_PASSWORD.get();
connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes(StandardCharsets.UTF_8))); connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes(StandardCharsets.UTF_8)));
} }
connection.setDoInput(true); connection.setDoInput(true);

View file

@ -112,7 +112,7 @@ public class OsmEditingFragment extends BaseSettingsFragment implements OnPrefer
boolean validToken = isValidToken(); boolean validToken = isValidToken();
Preference nameAndPasswordPref = findPreference(OSM_LOGOUT); Preference nameAndPasswordPref = findPreference(OSM_LOGOUT);
if (validToken || isLoginExists()) { if (validToken || isLoginExists()) {
String userName = validToken ? settings.USER_DISPLAY_NAME.get() : settings.USER_NAME.get(); String userName = validToken ? settings.OSM_USER_DISPLAY_NAME.get() : settings.OSM_USER_NAME.get();
nameAndPasswordPref.setVisible(true); nameAndPasswordPref.setVisible(true);
nameAndPasswordPref.setSummary(userName); nameAndPasswordPref.setSummary(userName);
nameAndPasswordPref.setIcon(getContentIcon(R.drawable.ic_action_user_account)); nameAndPasswordPref.setIcon(getContentIcon(R.drawable.ic_action_user_account));
@ -126,7 +126,7 @@ public class OsmEditingFragment extends BaseSettingsFragment implements OnPrefer
} }
private boolean isLoginExists() { private boolean isLoginExists() {
return !Algorithms.isEmpty(settings.USER_NAME.get()) && !Algorithms.isEmpty(settings.USER_PASSWORD.get()); return !Algorithms.isEmpty(settings.OSM_USER_NAME.get()) && !Algorithms.isEmpty(settings.OSM_USER_PASSWORD.get());
} }
private void setupOfflineEditingPref() { private void setupOfflineEditingPref() {
@ -140,7 +140,7 @@ public class OsmEditingFragment extends BaseSettingsFragment implements OnPrefer
} }
private void setupUseDevUrlPref() { private void setupUseDevUrlPref() {
SwitchPreferenceEx useDevUrlPref = findPreference(settings.USE_DEV_URL.getId()); SwitchPreferenceEx useDevUrlPref = findPreference(settings.OSM_USE_DEV_URL.getId());
if (OsmandPlugin.isDevelopment()) { if (OsmandPlugin.isDevelopment()) {
Drawable icon = getPersistentPrefIcon(R.drawable.ic_action_laptop); Drawable icon = getPersistentPrefIcon(R.drawable.ic_action_laptop);
useDevUrlPref.setDescription(getString(R.string.use_dev_url_descr)); useDevUrlPref.setDescription(getString(R.string.use_dev_url_descr));
@ -176,8 +176,8 @@ public class OsmEditingFragment extends BaseSettingsFragment implements OnPrefer
@Override @Override
public boolean onPreferenceChange(Preference preference, Object newValue) { public boolean onPreferenceChange(Preference preference, Object newValue) {
String prefId = preference.getKey(); String prefId = preference.getKey();
if (settings.USE_DEV_URL.getId().equals(prefId) && newValue instanceof Boolean) { if (settings.OSM_USE_DEV_URL.getId().equals(prefId) && newValue instanceof Boolean) {
settings.USE_DEV_URL.set((Boolean) newValue); settings.OSM_USE_DEV_URL.set((Boolean) newValue);
osmLogout(); osmLogout();
return true; return true;
} }
@ -220,7 +220,7 @@ public class OsmEditingFragment extends BaseSettingsFragment implements OnPrefer
@Override @Override
public void onPreferenceChanged(String prefId) { public void onPreferenceChanged(String prefId) {
if (settings.USE_DEV_URL.getId().equals(prefId)) { if (settings.OSM_USE_DEV_URL.getId().equals(prefId)) {
osmLogout(); osmLogout();
} }
updateAllSettings(); updateAllSettings();

View file

@ -457,9 +457,9 @@ public class OsmEditingPlugin extends OsmandPlugin {
} }
public boolean sendGPXFiles(final FragmentActivity activity, Fragment fragment, final GpxInfo... info) { public boolean sendGPXFiles(final FragmentActivity activity, Fragment fragment, final GpxInfo... info) {
String name = settings.USER_NAME.get(); String name = settings.OSM_USER_NAME.get();
String pwd = settings.USER_PASSWORD.get(); String pwd = settings.OSM_USER_PASSWORD.get();
String authToken = settings.USER_ACCESS_TOKEN.get(); String authToken = settings.OSM_USER_ACCESS_TOKEN.get();
if ((Algorithms.isEmpty(name) || Algorithms.isEmpty(pwd)) && Algorithms.isEmpty(authToken)) { if ((Algorithms.isEmpty(name) || Algorithms.isEmpty(pwd)) && Algorithms.isEmpty(authToken)) {
LoginBottomSheetFragment.showInstance(activity.getSupportFragmentManager(), fragment); LoginBottomSheetFragment.showInstance(activity.getSupportFragmentManager(), fragment);
return false; return false;

View file

@ -30,8 +30,8 @@ public class ValidateOsmLoginDetailsTask extends AsyncTask<Void, Void, OsmBugRes
@Override @Override
protected void onPostExecute(OsmBugResult osmBugResult) { protected void onPostExecute(OsmBugResult osmBugResult) {
if (osmBugResult.warning != null) { if (osmBugResult.warning != null) {
app.getSettings().USER_NAME.resetToDefault(); app.getSettings().OSM_USER_NAME.resetToDefault();
app.getSettings().USER_PASSWORD.resetToDefault(); app.getSettings().OSM_USER_PASSWORD.resetToDefault();
app.showToastMessage(osmBugResult.warning); app.showToastMessage(osmBugResult.warning);
} else { } else {
app.showToastMessage(R.string.osm_authorization_success); app.showToastMessage(R.string.osm_authorization_success);

View file

@ -69,10 +69,10 @@ public class SendGpxBottomSheetFragment extends MenuBottomSheetDialogFragment {
messageField = sendGpxView.findViewById(R.id.message_field); messageField = sendGpxView.findViewById(R.id.message_field);
TextView accountName = sendGpxView.findViewById(R.id.user_name); TextView accountName = sendGpxView.findViewById(R.id.user_name);
if (!Algorithms.isEmpty(settings.USER_DISPLAY_NAME.get())) { if (!Algorithms.isEmpty(settings.OSM_USER_DISPLAY_NAME.get())) {
accountName.setText(settings.USER_DISPLAY_NAME.get()); accountName.setText(settings.OSM_USER_DISPLAY_NAME.get());
} else { } else {
accountName.setText(settings.USER_NAME.get()); accountName.setText(settings.OSM_USER_NAME.get());
} }
String fileName = gpxInfos[0].getFileName(); String fileName = gpxInfos[0].getFileName();

View file

@ -61,7 +61,7 @@ public class SendOsmNoteBottomSheetFragment extends MenuBottomSheetDialogFragmen
private EditText noteText; private EditText noteText;
private boolean isLoginOAuth() { private boolean isLoginOAuth() {
return !Algorithms.isEmpty(settings.USER_DISPLAY_NAME.get()); return !Algorithms.isEmpty(settings.OSM_USER_DISPLAY_NAME.get());
} }
@Override @Override
@ -150,8 +150,8 @@ public class SendOsmNoteBottomSheetFragment extends MenuBottomSheetDialogFragmen
} }
private void updateAccountName() { private void updateAccountName() {
String userNameOAuth = settings.USER_DISPLAY_NAME.get(); String userNameOAuth = settings.OSM_USER_DISPLAY_NAME.get();
String userNameOpenID = settings.USER_NAME.get(); String userNameOpenID = settings.OSM_USER_NAME.get();
String userName = isLoginOAuth() ? userNameOAuth : userNameOpenID; String userName = isLoginOAuth() ? userNameOAuth : userNameOpenID;
accountName.setText(userName); accountName.setText(userName);
updateSignIn(uploadAnonymously.isChecked()); updateSignIn(uploadAnonymously.isChecked());
@ -230,7 +230,7 @@ public class SendOsmNoteBottomSheetFragment extends MenuBottomSheetDialogFragmen
private boolean isLogged() { private boolean isLogged() {
OsmOAuthAuthorizationAdapter adapter = app.getOsmOAuthHelper().getAuthorizationAdapter(); OsmOAuthAuthorizationAdapter adapter = app.getOsmOAuthHelper().getAuthorizationAdapter();
return adapter.isValidToken() return adapter.isValidToken()
|| !Algorithms.isEmpty(settings.USER_NAME.get()) || !Algorithms.isEmpty(settings.OSM_USER_NAME.get())
&& !Algorithms.isEmpty(settings.USER_PASSWORD.get()); && !Algorithms.isEmpty(settings.OSM_USER_PASSWORD.get());
} }
} }

View file

@ -47,7 +47,7 @@ public class SendPoiBottomSheetFragment extends MenuBottomSheetDialogFragment {
private boolean isLoginOAuth(OsmandSettings settings) { private boolean isLoginOAuth(OsmandSettings settings) {
return !Algorithms.isEmpty(settings.USER_DISPLAY_NAME.get()); return !Algorithms.isEmpty(settings.OSM_USER_DISPLAY_NAME.get());
} }
@Override @Override
@ -68,8 +68,8 @@ public class SendPoiBottomSheetFragment extends MenuBottomSheetDialogFragment {
messageEditText.setSelection(messageEditText.getText().length()); messageEditText.setSelection(messageEditText.getText().length());
final TextView accountName = sendOsmPoiView.findViewById(R.id.user_name); final TextView accountName = sendOsmPoiView.findViewById(R.id.user_name);
OsmandSettings settings = app.getSettings(); OsmandSettings settings = app.getSettings();
String userNameOAuth = settings.USER_DISPLAY_NAME.get(); String userNameOAuth = settings.OSM_USER_DISPLAY_NAME.get();
String userNameOpenID = settings.USER_NAME.get(); String userNameOpenID = settings.OSM_USER_NAME.get();
String userName = isLoginOAuth(settings) ? userNameOAuth : userNameOpenID; String userName = isLoginOAuth(settings) ? userNameOAuth : userNameOpenID;
accountName.setText(userName); accountName.setText(userName);
final int paddingSmall = app.getResources().getDimensionPixelSize(R.dimen.content_padding_small); final int paddingSmall = app.getResources().getDimensionPixelSize(R.dimen.content_padding_small);

View file

@ -1,19 +1,10 @@
package net.osmand.plus.osmedit.oauth; package net.osmand.plus.osmedit.oauth;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.net.TrafficStats; import android.net.TrafficStats;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.annotation.NonNull;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.core.content.ContextCompat;
import com.github.scribejava.core.builder.api.DefaultApi10a; import com.github.scribejava.core.builder.api.DefaultApi10a;
import com.github.scribejava.core.model.OAuth1AccessToken; import com.github.scribejava.core.model.OAuth1AccessToken;
@ -24,7 +15,6 @@ import com.github.scribejava.core.model.Verb;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.osm.oauth.OsmOAuthAuthorizationClient; import net.osmand.osm.oauth.OsmOAuthAuthorizationClient;
import net.osmand.plus.OsmAndConstants;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.wikipedia.WikipediaDialogFragment; import net.osmand.plus.wikipedia.WikipediaDialogFragment;
@ -52,7 +42,7 @@ public class OsmOAuthAuthorizationAdapter {
DefaultApi10a api10a; DefaultApi10a api10a;
String key; String key;
String secret; String secret;
if (app.getSettings().USE_DEV_URL.get()) { if (app.getSettings().OSM_USE_DEV_URL.get()) {
api10a = new OsmOAuthAuthorizationClient.OsmDevApi(); api10a = new OsmOAuthAuthorizationClient.OsmDevApi();
key = app.getString(R.string.osm_oauth_developer_key); key = app.getString(R.string.osm_oauth_developer_key);
secret = app.getString(R.string.osm_oauth_developer_secret); secret = app.getString(R.string.osm_oauth_developer_secret);
@ -78,8 +68,8 @@ public class OsmOAuthAuthorizationAdapter {
} }
public void restoreToken() { public void restoreToken() {
String token = app.getSettings().USER_ACCESS_TOKEN.get(); String token = app.getSettings().OSM_USER_ACCESS_TOKEN.get();
String tokenSecret = app.getSettings().USER_ACCESS_TOKEN_SECRET.get(); String tokenSecret = app.getSettings().OSM_USER_ACCESS_TOKEN_SECRET.get();
if (!(token.isEmpty() || tokenSecret.isEmpty())) { if (!(token.isEmpty() || tokenSecret.isEmpty())) {
client.setAccessToken(new OAuth1AccessToken(token, tokenSecret)); client.setAccessToken(new OAuth1AccessToken(token, tokenSecret));
} else { } else {
@ -93,8 +83,8 @@ public class OsmOAuthAuthorizationAdapter {
private void saveToken() { private void saveToken() {
OAuth1AccessToken accessToken = client.getAccessToken(); OAuth1AccessToken accessToken = client.getAccessToken();
app.getSettings().USER_ACCESS_TOKEN.set(accessToken.getToken()); app.getSettings().OSM_USER_ACCESS_TOKEN.set(accessToken.getToken());
app.getSettings().USER_ACCESS_TOKEN_SECRET.set(accessToken.getTokenSecret()); app.getSettings().OSM_USER_ACCESS_TOKEN_SECRET.set(accessToken.getTokenSecret());
} }
private void loadWebView(ViewGroup root, boolean nightMode, String url) { private void loadWebView(ViewGroup root, boolean nightMode, String url) {
@ -137,7 +127,7 @@ public class OsmOAuthAuthorizationAdapter {
} }
@Override @Override
protected void onPostExecute(@NonNull OAuth1RequestToken requestToken) { protected void onPostExecute(OAuth1RequestToken requestToken) {
if (requestToken != null) { if (requestToken != null) {
loadWebView(rootLayout, nightMode, client.getService().getAuthorizationUrl(requestToken)); loadWebView(rootLayout, nightMode, client.getService().getAuthorizationUrl(requestToken));
} else { } else {
@ -156,9 +146,11 @@ public class OsmOAuthAuthorizationAdapter {
@Override @Override
protected Void doInBackground(String... oauthVerifier) { protected Void doInBackground(String... oauthVerifier) {
client.authorize(oauthVerifier[0]); if (client.getRequestToken() != null) {
saveToken(); client.authorize(oauthVerifier[0]);
updateUserName(); saveToken();
updateUserName();
}
return null; return null;
} }
@ -180,7 +172,7 @@ public class OsmOAuthAuthorizationAdapter {
} catch (XmlPullParserException e) { } catch (XmlPullParserException e) {
log.error(e); log.error(e);
} }
app.getSettings().USER_DISPLAY_NAME.set(userName); app.getSettings().OSM_USER_DISPLAY_NAME.set(userName);
} }
public String getUserName() throws InterruptedException, ExecutionException, IOException, XmlPullParserException { public String getUserName() throws InterruptedException, ExecutionException, IOException, XmlPullParserException {

View file

@ -54,18 +54,18 @@ public class OsmOAuthHelper {
public void resetAuthorization() { public void resetAuthorization() {
if (isValidToken()) { if (isValidToken()) {
settings.USER_ACCESS_TOKEN.resetToDefault(); settings.OSM_USER_ACCESS_TOKEN.resetToDefault();
settings.USER_ACCESS_TOKEN_SECRET.resetToDefault(); settings.OSM_USER_ACCESS_TOKEN_SECRET.resetToDefault();
authorizationAdapter.resetToken(); authorizationAdapter.resetToken();
} else if (isLoginExists()) { } else if (isLoginExists()) {
settings.USER_NAME.resetToDefault(); settings.OSM_USER_NAME.resetToDefault();
settings.USER_PASSWORD.resetToDefault(); settings.OSM_USER_PASSWORD.resetToDefault();
} }
updateAdapter(); updateAdapter();
} }
private boolean isLoginExists() { private boolean isLoginExists() {
return !Algorithms.isEmpty(settings.USER_NAME.get()) && !Algorithms.isEmpty(settings.USER_PASSWORD.get()); return !Algorithms.isEmpty(settings.OSM_USER_NAME.get()) && !Algorithms.isEmpty(settings.OSM_USER_PASSWORD.get());
} }
public void notifyAndRemoveListeners() { public void notifyAndRemoveListeners() {

View file

@ -1,7 +1,11 @@
package net.osmand.plus.profiles; package net.osmand.plus.profiles;
import net.osmand.plus.settings.backend.ApplicationMode; import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentManager;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.profiles.ConfigureProfileMenuAdapter.ProfileSelectedListener;
import net.osmand.plus.settings.backend.ApplicationMode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@ -9,8 +13,8 @@ import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
public class ConfigureAppModesBottomSheetDialogFragment extends AppModesBottomSheetDialogFragment<ConfigureProfileMenuAdapter> public class ConfigureAppModesBottomSheetDialogFragment extends AppModesBottomSheetDialogFragment<ConfigureProfileMenuAdapter>
implements ConfigureProfileMenuAdapter.ProfileSelectedListener { implements ProfileSelectedListener {
public static final String TAG = "ConfigureAppModesBottomSheetDialogFragment"; public static final String TAG = "ConfigureAppModesBottomSheetDialogFragment";
@ -56,4 +60,15 @@ public class ConfigureAppModesBottomSheetDialogFragment extends AppModesBottomSh
} }
ApplicationMode.changeProfileAvailability(item, isChecked, getMyApplication()); ApplicationMode.changeProfileAvailability(item, isChecked, getMyApplication());
} }
public static void showInstance(@NonNull FragmentManager fragmentManager, boolean usedOnMap, UpdateMapRouteMenuListener listener) {
if (fragmentManager.findFragmentByTag(TAG) == null) {
ConfigureAppModesBottomSheetDialogFragment fragment = new ConfigureAppModesBottomSheetDialogFragment();
fragment.setUsedOnMap(usedOnMap);
fragment.setUpdateMapRouteMenuListener(listener);
fragmentManager.beginTransaction()
.add(fragment, TAG)
.commitAllowingStateLoss();
}
}
} }

View file

@ -29,6 +29,8 @@ import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.AppCompatImageView;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.transition.AutoTransition; import androidx.transition.AutoTransition;
import androidx.transition.Scene; import androidx.transition.Scene;
import androidx.transition.Transition; import androidx.transition.Transition;
@ -71,7 +73,7 @@ import net.osmand.plus.mapcontextmenu.other.TrackDetailsMenuFragment;
import net.osmand.plus.mapmarkers.MapMarker; import net.osmand.plus.mapmarkers.MapMarker;
import net.osmand.plus.mapmarkers.MapMarkerSelectionFragment; import net.osmand.plus.mapmarkers.MapMarkerSelectionFragment;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.profiles.AppModesBottomSheetDialogFragment; import net.osmand.plus.profiles.AppModesBottomSheetDialogFragment.UpdateMapRouteMenuListener;
import net.osmand.plus.profiles.ConfigureAppModesBottomSheetDialogFragment; import net.osmand.plus.profiles.ConfigureAppModesBottomSheetDialogFragment;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.AvoidPTTypesRoutingParameter; import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.AvoidPTTypesRoutingParameter;
import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.AvoidRoadsRoutingParameter; import net.osmand.plus.routepreparationmenu.RoutingOptionsHelper.AvoidRoadsRoutingParameter;
@ -870,16 +872,16 @@ public class MapRouteInfoMenu implements IRouteInformationListener, CardListener
} }
private void showProfileBottomSheetDialog() { private void showProfileBottomSheetDialog() {
final AppModesBottomSheetDialogFragment fragment = new ConfigureAppModesBottomSheetDialogFragment(); FragmentActivity activity = getMapActivity();
fragment.setUsedOnMap(true); if (activity != null) {
fragment.setUpdateMapRouteMenuListener(new AppModesBottomSheetDialogFragment.UpdateMapRouteMenuListener() { FragmentManager manager = activity.getSupportFragmentManager();
@Override ConfigureAppModesBottomSheetDialogFragment.showInstance(manager, true, new UpdateMapRouteMenuListener() {
public void updateAppModeMenu() { @Override
updateApplicationModes(); public void updateAppModeMenu() {
} updateApplicationModes();
}); }
getMapActivity().getSupportFragmentManager().beginTransaction() });
.add(fragment, ConfigureAppModesBottomSheetDialogFragment.TAG).commitAllowingStateLoss(); }
} }
private void updateApplicationMode(ApplicationMode mode, ApplicationMode next) { private void updateApplicationMode(ApplicationMode mode, ApplicationMode next) {

View file

@ -625,11 +625,14 @@ public class RouteOptionsBottomSheet extends MenuBottomSheetDialogFragment {
private List<RoutingParameter> getReliefParameters() { private List<RoutingParameter> getReliefParameters() {
List<RoutingParameter> reliefFactorParameters = new ArrayList<>(); List<RoutingParameter> reliefFactorParameters = new ArrayList<>();
Map<String, RoutingParameter> parameters = app.getRouter(applicationMode).getParameters(); GeneralRouter router = app.getRouter(applicationMode);
for (Map.Entry<String, RoutingParameter> entry : parameters.entrySet()) { if (router != null) {
RoutingParameter routingParameter = entry.getValue(); Map<String, RoutingParameter> parameters = router.getParameters();
if (RELIEF_SMOOTHNESS_FACTOR.equals(routingParameter.getGroup())) { for (Map.Entry<String, RoutingParameter> entry : parameters.entrySet()) {
reliefFactorParameters.add(routingParameter); RoutingParameter routingParameter = entry.getValue();
if (RELIEF_SMOOTHNESS_FACTOR.equals(routingParameter.getGroup())) {
reliefFactorParameters.add(routingParameter);
}
} }
} }
return reliefFactorParameters; return reliefFactorParameters;

View file

@ -21,7 +21,7 @@ import net.osmand.data.LocationPoint;
import net.osmand.data.WptLocationPoint; import net.osmand.data.WptLocationPoint;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.onlinerouting.OnlineRoutingHelper; import net.osmand.plus.onlinerouting.OnlineRoutingHelper;
import net.osmand.plus.onlinerouting.OnlineRoutingResponse; import net.osmand.plus.onlinerouting.engine.OnlineRoutingEngine.OnlineRoutingResponse;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.backend.CommonPreference; import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.R; import net.osmand.plus.R;

View file

@ -301,7 +301,12 @@ public class ApplicationMode {
} }
public boolean isCustomProfile() { public boolean isCustomProfile() {
return !defaultValues.contains(this); for (ApplicationMode mode : defaultValues) {
if (Algorithms.stringsEqual(mode.getStringKey(), getStringKey())) {
return false;
}
}
return true;
} }
public boolean isDerivedRoutingFrom(ApplicationMode mode) { public boolean isDerivedRoutingFrom(ApplicationMode mode) {

View file

@ -48,6 +48,7 @@ import net.osmand.plus.helpers.enums.TracksSortByMode;
import net.osmand.plus.mapillary.MapillaryPlugin; import net.osmand.plus.mapillary.MapillaryPlugin;
import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format; import net.osmand.plus.mapmarkers.CoordinateInputFormats.Format;
import net.osmand.plus.mapmarkers.MapMarkersMode; import net.osmand.plus.mapmarkers.MapMarkersMode;
import net.osmand.plus.openplacereviews.OpenPlaceReviewsPlugin;
import net.osmand.plus.profiles.LocationIcon; import net.osmand.plus.profiles.LocationIcon;
import net.osmand.plus.profiles.NavigationIcon; import net.osmand.plus.profiles.NavigationIcon;
import net.osmand.plus.profiles.ProfileIconColors; import net.osmand.plus.profiles.ProfileIconColors;
@ -653,7 +654,7 @@ public class OsmandSettings {
public static final String NUMBER_OF_FREE_DOWNLOADS_ID = "free_downloads_v3"; public static final String NUMBER_OF_FREE_DOWNLOADS_ID = "free_downloads_v3";
// this value string is synchronized with settings_pref.xml preference name // this value string is synchronized with settings_pref.xml preference name
private final OsmandPreference<String> PLUGINS = new StringPreference(this, "enabled_plugins", MapillaryPlugin.ID).makeGlobal().makeShared(); private final OsmandPreference<String> PLUGINS = new StringPreference(this, "enabled_plugins", "").makeGlobal().makeShared();
public Set<String> getEnabledPlugins() { public Set<String> getEnabledPlugins() {
String plugs = PLUGINS.get(); String plugs = PLUGINS.get();
@ -1121,8 +1122,8 @@ public class OsmandSettings {
} }
// this value string is synchronized with settings_pref.xml preference name // this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference<String> USER_NAME = new StringPreference(this, "user_name", "").makeGlobal().makeShared(); public final OsmandPreference<String> OSM_USER_NAME = new StringPreference(this, "user_name", "").makeGlobal().makeShared();
public final OsmandPreference<String> USER_DISPLAY_NAME = new StringPreference(this, "user_display_name", "").makeGlobal().makeShared(); public final OsmandPreference<String> OSM_USER_DISPLAY_NAME = new StringPreference(this, "user_display_name", "").makeGlobal().makeShared();
public static final String BILLING_USER_DONATION_WORLD_PARAMETER = ""; public static final String BILLING_USER_DONATION_WORLD_PARAMETER = "";
public static final String BILLING_USER_DONATION_NONE_PARAMETER = "none"; public static final String BILLING_USER_DONATION_NONE_PARAMETER = "none";
@ -1156,13 +1157,13 @@ public class OsmandSettings {
new StringPreference(this, "user_osm_bug_name", "NoName/OsmAnd").makeGlobal().makeShared(); new StringPreference(this, "user_osm_bug_name", "NoName/OsmAnd").makeGlobal().makeShared();
// this value string is synchronized with settings_pref.xml preference name // this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference<String> USER_PASSWORD = public final OsmandPreference<String> OSM_USER_PASSWORD =
new StringPreference(this, "user_password", "").makeGlobal().makeShared(); new StringPreference(this, "user_password", "").makeGlobal().makeShared();
public final OsmandPreference<String> USER_ACCESS_TOKEN = public final OsmandPreference<String> OSM_USER_ACCESS_TOKEN =
new StringPreference(this, "user_access_token", "").makeGlobal(); new StringPreference(this, "user_access_token", "").makeGlobal();
public final OsmandPreference<String> USER_ACCESS_TOKEN_SECRET = public final OsmandPreference<String> OSM_USER_ACCESS_TOKEN_SECRET =
new StringPreference(this, "user_access_token_secret", "").makeGlobal(); new StringPreference(this, "user_access_token_secret", "").makeGlobal();
public final OsmandPreference<String> OPR_ACCESS_TOKEN = public final OsmandPreference<String> OPR_ACCESS_TOKEN =
@ -1174,13 +1175,15 @@ public class OsmandSettings {
public final OsmandPreference<String> OPR_BLOCKCHAIN_NAME = public final OsmandPreference<String> OPR_BLOCKCHAIN_NAME =
new StringPreference(this, "opr_blockchain_name", "").makeGlobal(); new StringPreference(this, "opr_blockchain_name", "").makeGlobal();
public final OsmandPreference<Boolean> OPR_USE_DEV_URL = new BooleanPreference(this, "opr_use_dev_url", false).makeGlobal().makeShared();
// this value boolean is synchronized with settings_pref.xml preference offline POI/Bugs edition // this value boolean is synchronized with settings_pref.xml preference offline POI/Bugs edition
public final OsmandPreference<Boolean> OFFLINE_EDITION = new BooleanPreference(this, "offline_osm_editing", true).makeGlobal().makeShared(); public final OsmandPreference<Boolean> OFFLINE_EDITION = new BooleanPreference(this, "offline_osm_editing", true).makeGlobal().makeShared();
public final OsmandPreference<Boolean> USE_DEV_URL = new BooleanPreference(this, "use_dev_url", false).makeGlobal().makeShared(); public final OsmandPreference<Boolean> OSM_USE_DEV_URL = new BooleanPreference(this, "use_dev_url", false).makeGlobal().makeShared();
public String getOsmUrl() { public String getOsmUrl() {
String osmUrl; String osmUrl;
if (USE_DEV_URL.get()) { if (OSM_USE_DEV_URL.get()) {
osmUrl = "https://master.apis.dev.openstreetmap.org/"; osmUrl = "https://master.apis.dev.openstreetmap.org/";
} else { } else {
osmUrl = "https://api.openstreetmap.org/"; osmUrl = "https://api.openstreetmap.org/";
@ -1188,6 +1191,10 @@ public class OsmandSettings {
return osmUrl; return osmUrl;
} }
public String getOprUrl() {
return ctx.getString(OPR_USE_DEV_URL.get() ? R.string.dev_opr_base_url : R.string.opr_base_url);
}
// this value string is synchronized with settings_pref.xml preference name // this value string is synchronized with settings_pref.xml preference name
public final CommonPreference<DayNightMode> DAYNIGHT_MODE = public final CommonPreference<DayNightMode> DAYNIGHT_MODE =
new EnumStringPreference<DayNightMode>(this, "daynight_mode", DayNightMode.DAY, DayNightMode.values()); new EnumStringPreference<DayNightMode>(this, "daynight_mode", DayNightMode.DAY, DayNightMode.values());

View file

@ -124,7 +124,7 @@ public class ProfileSettingsItem extends OsmandSettingsItem {
if (Algorithms.isEmpty(modeBean.userProfileName)) { if (Algorithms.isEmpty(modeBean.userProfileName)) {
ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null); ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null);
if (appMode != null) { if (appMode != null) {
modeBean.userProfileName = app.getString(appMode.getNameKeyResource()); modeBean.userProfileName = appMode.toHumanString();
} }
} }
int number = 0; int number = 0;

View file

@ -19,13 +19,13 @@ import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription; import net.osmand.plus.base.bottomsheetmenu.BottomSheetItemWithDescription;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem; import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.settings.fragments.BaseSettingsFragment; import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import net.osmand.plus.settings.fragments.DataStorageMenuItem; import net.osmand.plus.settings.datastorage.item.StorageItem;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import java.io.File; import java.io.File;
import static net.osmand.plus.settings.fragments.DataStorageHelper.MANUALLY_SPECIFIED; import static net.osmand.plus.settings.datastorage.DataStorageHelper.MANUALLY_SPECIFIED;
public class ChangeDataStorageBottomSheet extends BasePreferenceBottomSheet { public class ChangeDataStorageBottomSheet extends BasePreferenceBottomSheet {
@ -39,8 +39,8 @@ public class ChangeDataStorageBottomSheet extends BasePreferenceBottomSheet {
public final static String MOVE_DATA = "move_data"; public final static String MOVE_DATA = "move_data";
public final static String CHOSEN_DIRECTORY = "chosen_storage"; public final static String CHOSEN_DIRECTORY = "chosen_storage";
private DataStorageMenuItem currentDirectory; private StorageItem currentDirectory;
private DataStorageMenuItem newDirectory; private StorageItem newDirectory;
@Override @Override
public void createMenuItems(Bundle savedInstanceState) { public void createMenuItems(Bundle savedInstanceState) {
@ -126,11 +126,11 @@ public class ChangeDataStorageBottomSheet extends BasePreferenceBottomSheet {
items.add(baseItem); items.add(baseItem);
} }
public void setCurrentDirectory(DataStorageMenuItem currentDirectory) { public void setCurrentDirectory(StorageItem currentDirectory) {
this.currentDirectory = currentDirectory; this.currentDirectory = currentDirectory;
} }
public void setNewDirectory(DataStorageMenuItem newDirectory) { public void setNewDirectory(StorageItem newDirectory) {
this.newDirectory = newDirectory; this.newDirectory = newDirectory;
} }
@ -158,8 +158,8 @@ public class ChangeDataStorageBottomSheet extends BasePreferenceBottomSheet {
return true; return true;
} }
public static boolean showInstance(FragmentManager fm, String prefId, DataStorageMenuItem currentDirectory, public static boolean showInstance(FragmentManager fm, String prefId, StorageItem currentDirectory,
DataStorageMenuItem newDirectory, Fragment target, boolean usedOnMap) { StorageItem newDirectory, Fragment target, boolean usedOnMap) {
try { try {
if (fm.findFragmentByTag(TAG) == null) { if (fm.findFragmentByTag(TAG) == null) {
Bundle args = new Bundle(); Bundle args = new Bundle();

View file

@ -6,7 +6,6 @@ import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ScrollView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -49,8 +48,8 @@ public class OsmLoginDataBottomSheet extends BasePreferenceBottomSheet {
userNameEditText = view.findViewById(R.id.name_edit_text); userNameEditText = view.findViewById(R.id.name_edit_text);
passwordEditText = view.findViewById(R.id.password_edit_text); passwordEditText = view.findViewById(R.id.password_edit_text);
String name = app.getSettings().USER_NAME.get(); String name = app.getSettings().OSM_USER_NAME.get();
String password = app.getSettings().USER_PASSWORD.get(); String password = app.getSettings().OSM_USER_PASSWORD.get();
if (savedInstanceState != null) { if (savedInstanceState != null) {
name = savedInstanceState.getString(USER_NAME_KEY, null); name = savedInstanceState.getString(USER_NAME_KEY, null);
@ -96,8 +95,8 @@ public class OsmLoginDataBottomSheet extends BasePreferenceBottomSheet {
protected void onRightBottomButtonClick() { protected void onRightBottomButtonClick() {
OsmandApplication app = requiredMyApplication(); OsmandApplication app = requiredMyApplication();
app.getSettings().USER_NAME.set(userNameEditText.getText().toString()); app.getSettings().OSM_USER_NAME.set(userNameEditText.getText().toString());
app.getSettings().USER_PASSWORD.set(passwordEditText.getText().toString()); app.getSettings().OSM_USER_PASSWORD.set(passwordEditText.getText().toString());
Fragment targetFragment = getTargetFragment(); Fragment targetFragment = getTargetFragment();
if (targetFragment instanceof ValidateOsmLoginListener) { if (targetFragment instanceof ValidateOsmLoginListener) {

View file

@ -1,8 +1,7 @@
package net.osmand.plus.settings.fragments; package net.osmand.plus.settings.datastorage;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@ -26,7 +25,6 @@ import net.osmand.AndroidUtils;
import net.osmand.FileUtils; import net.osmand.FileUtils;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.ProgressImplementation;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.MapActivity;
@ -34,20 +32,21 @@ import net.osmand.plus.activities.OsmandActionBarActivity;
import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet; import net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet;
import net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet; import net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet;
import net.osmand.util.Algorithms; import net.osmand.plus.settings.datastorage.item.MemoryItem;
import net.osmand.plus.settings.datastorage.item.StorageItem;
import net.osmand.plus.settings.datastorage.task.MoveFilesTask;
import net.osmand.plus.settings.datastorage.task.RefreshUsedMemoryTask;
import net.osmand.plus.settings.datastorage.task.ReloadDataTask;
import net.osmand.plus.settings.fragments.BaseSettingsFragment;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import static net.osmand.plus.settings.fragments.DataStorageHelper.INTERNAL_STORAGE; import static net.osmand.plus.settings.datastorage.DataStorageHelper.INTERNAL_STORAGE;
import static net.osmand.plus.settings.fragments.DataStorageHelper.MANUALLY_SPECIFIED; import static net.osmand.plus.settings.datastorage.DataStorageHelper.MANUALLY_SPECIFIED;
import static net.osmand.plus.settings.fragments.DataStorageHelper.OTHER_MEMORY; import static net.osmand.plus.settings.datastorage.DataStorageHelper.OTHER_MEMORY;
import static net.osmand.plus.settings.fragments.DataStorageHelper.TILES_MEMORY; import static net.osmand.plus.settings.datastorage.DataStorageHelper.TILES_MEMORY;
import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.CHOSEN_DIRECTORY; import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.CHOSEN_DIRECTORY;
import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.MOVE_DATA; import static net.osmand.plus.settings.bottomsheets.ChangeDataStorageBottomSheet.MOVE_DATA;
import static net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet.NEW_PATH; import static net.osmand.plus.settings.bottomsheets.SelectFolderBottomSheet.NEW_PATH;
@ -60,17 +59,17 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
private final static String CHANGE_DIRECTORY_BUTTON = "change_directory"; private final static String CHANGE_DIRECTORY_BUTTON = "change_directory";
private final static String OSMAND_USAGE = "osmand_usage"; private final static String OSMAND_USAGE = "osmand_usage";
private ArrayList<DataStorageMenuItem> menuItems; private ArrayList<StorageItem> storageItems;
private ArrayList<DataStorageMemoryItem> memoryItems; private ArrayList<MemoryItem> memoryItems;
private ArrayList<CheckBoxPreference> dataStorageRadioButtonsGroup; private ArrayList<CheckBoxPreference> dataStorageRadioButtonsGroup;
private Preference changeButton; private Preference changeButton;
private DataStorageMenuItem currentDataStorage; private StorageItem currentDataStorage;
private String tmpManuallySpecifiedPath; private String tmpManuallySpecifiedPath;
private DataStorageHelper dataStorageHelper; private DataStorageHelper dataStorageHelper;
private boolean calculateTilesBtnPressed; private boolean calculateTilesBtnPressed;
private DataStorageHelper.RefreshMemoryUsedInfo calculateMemoryTask; private RefreshUsedMemoryTask calculateMemoryTask;
private DataStorageHelper.RefreshMemoryUsedInfo calculateTilesMemoryTask; private RefreshUsedMemoryTask calculateTilesMemoryTask;
private OsmandApplication app; private OsmandApplication app;
private OsmandActionBarActivity activity; private OsmandActionBarActivity activity;
@ -95,11 +94,11 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
return; return;
} }
menuItems = dataStorageHelper.getStorageItems(); storageItems = dataStorageHelper.getStorageItems();
memoryItems = dataStorageHelper.getMemoryInfoItems(); memoryItems = dataStorageHelper.getMemoryInfoItems();
dataStorageRadioButtonsGroup = new ArrayList<>(); dataStorageRadioButtonsGroup = new ArrayList<>();
for (DataStorageMenuItem item : menuItems) { for (StorageItem item : storageItems) {
CheckBoxPreference preference = new CheckBoxPreference(activity); CheckBoxPreference preference = new CheckBoxPreference(activity);
preference.setKey(item.getKey()); preference.setKey(item.getKey());
preference.setTitle(item.getTitle()); preference.setTitle(item.getTitle());
@ -136,7 +135,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
Bundle resultData = (Bundle) newValue; Bundle resultData = (Bundle) newValue;
if (resultData.containsKey(ChangeDataStorageBottomSheet.TAG)) { if (resultData.containsKey(ChangeDataStorageBottomSheet.TAG)) {
boolean moveMaps = resultData.getBoolean(MOVE_DATA); boolean moveMaps = resultData.getBoolean(MOVE_DATA);
DataStorageMenuItem newDataStorage = resultData.getParcelable(CHOSEN_DIRECTORY); StorageItem newDataStorage = resultData.getParcelable(CHOSEN_DIRECTORY);
if (newDataStorage != null) { if (newDataStorage != null) {
if (tmpManuallySpecifiedPath != null) { if (tmpManuallySpecifiedPath != null) {
String directory = tmpManuallySpecifiedPath; String directory = tmpManuallySpecifiedPath;
@ -154,9 +153,9 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
if (pathChanged) { if (pathChanged) {
tmpManuallySpecifiedPath = resultData.getString(NEW_PATH); tmpManuallySpecifiedPath = resultData.getString(NEW_PATH);
if (tmpManuallySpecifiedPath != null) { if (tmpManuallySpecifiedPath != null) {
DataStorageMenuItem manuallySpecified = null; StorageItem manuallySpecified = null;
try { try {
manuallySpecified = (DataStorageMenuItem) dataStorageHelper.getManuallySpecified().clone(); manuallySpecified = (StorageItem) dataStorageHelper.getManuallySpecified().clone();
manuallySpecified.setDirectory(tmpManuallySpecifiedPath); manuallySpecified.setDirectory(tmpManuallySpecifiedPath);
} catch (CloneNotSupportedException e) { } catch (CloneNotSupportedException e) {
return false; return false;
@ -170,7 +169,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
//show necessary dialog //show necessary dialog
String key = preference.getKey(); String key = preference.getKey();
if (key != null) { if (key != null) {
DataStorageMenuItem newDataStorage = dataStorageHelper.getStorage(key); StorageItem newDataStorage = dataStorageHelper.getStorage(key);
if (newDataStorage != null) { if (newDataStorage != null) {
if (!currentDataStorage.getKey().equals(newDataStorage.getKey())) { if (!currentDataStorage.getKey().equals(newDataStorage.getKey())) {
if (newDataStorage.getType() == OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT if (newDataStorage.getType() == OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT
@ -212,7 +211,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
final View itemView = holder.itemView; final View itemView = holder.itemView;
if (preference instanceof CheckBoxPreference) { if (preference instanceof CheckBoxPreference) {
DataStorageMenuItem item = dataStorageHelper.getStorage(key); StorageItem item = dataStorageHelper.getStorage(key);
if (item != null) { if (item != null) {
TextView tvTitle = itemView.findViewById(android.R.id.title); TextView tvTitle = itemView.findViewById(android.R.id.title);
TextView tvSummary = itemView.findViewById(R.id.summary); TextView tvSummary = itemView.findViewById(R.id.summary);
@ -267,7 +266,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
TextView tvSummary = itemView.findViewById(R.id.summary); TextView tvSummary = itemView.findViewById(R.id.summary);
tvSummary.setText(DataStorageHelper.getFormattedMemoryInfo(totalUsageBytes, memoryUnitsFormats)); tvSummary.setText(DataStorageHelper.getFormattedMemoryInfo(totalUsageBytes, memoryUnitsFormats));
} else { } else {
for (DataStorageMemoryItem mi : memoryItems) { for (MemoryItem mi : memoryItems) {
if (key.equals(mi.getKey())) { if (key.equals(mi.getKey())) {
TextView tvMemory = itemView.findViewById(R.id.memory); TextView tvMemory = itemView.findViewById(R.id.memory);
String summary = ""; String summary = "";
@ -326,7 +325,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
} }
private void showFolderSelectionDialog() { private void showFolderSelectionDialog() {
DataStorageMenuItem manuallySpecified = dataStorageHelper.getManuallySpecified(); StorageItem manuallySpecified = dataStorageHelper.getManuallySpecified();
if (manuallySpecified != null) { if (manuallySpecified != null) {
SelectFolderBottomSheet.showInstance(getFragmentManager(), manuallySpecified.getKey(), SelectFolderBottomSheet.showInstance(getFragmentManager(), manuallySpecified.getKey(),
manuallySpecified.getDirectory(), DataStorageFragment.this, manuallySpecified.getDirectory(), DataStorageFragment.this,
@ -335,11 +334,11 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
} }
} }
private void moveData(final DataStorageMenuItem currentStorage, final DataStorageMenuItem newStorage) { private void moveData(final StorageItem currentStorage, final StorageItem newStorage) {
File fromDirectory = new File(currentStorage.getDirectory()); File fromDirectory = new File(currentStorage.getDirectory());
File toDirectory = new File(newStorage.getDirectory()); File toDirectory = new File(newStorage.getDirectory());
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
MoveFilesToDifferentDirectory task = new MoveFilesToDifferentDirectory(activity, fromDirectory, toDirectory) { MoveFilesTask task = new MoveFilesTask(activity, fromDirectory, toDirectory) {
@NonNull @NonNull
@ -405,7 +404,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} }
private void confirm(OsmandApplication app, OsmandActionBarActivity activity, DataStorageMenuItem newStorageDirectory, boolean silentRestart) { private void confirm(OsmandApplication app, OsmandActionBarActivity activity, StorageItem newStorageDirectory, boolean silentRestart) {
String newDirectory = newStorageDirectory.getDirectory(); String newDirectory = newStorageDirectory.getDirectory();
int type = newStorageDirectory.getType(); int type = newStorageDirectory.getType();
File newDirectoryFile = new File(newDirectory); File newDirectoryFile = new File(newDirectory);
@ -454,7 +453,7 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
} }
protected void reloadData() { protected void reloadData() {
new ReloadData(activity, app).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null); new ReloadDataTask(activity, app).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void) null);
} }
@Override @Override
@ -463,204 +462,10 @@ public class DataStorageFragment extends BaseSettingsFragment implements DataSto
} }
@Override @Override
public void onFinishUpdating(String taskKey) { public void onFinishUpdating(String tag) {
updateAllSettings(); updateAllSettings();
if (taskKey != null && taskKey.equals(TILES_MEMORY)) { if (tag != null && tag.equals(TILES_MEMORY)) {
app.getSettings().OSMAND_USAGE_SPACE.set(dataStorageHelper.getTotalUsedBytes()); app.getSettings().OSMAND_USAGE_SPACE.set(dataStorageHelper.getTotalUsedBytes());
} }
} }
public static class MoveFilesToDifferentDirectory extends AsyncTask<Void, Void, Boolean> {
protected WeakReference<OsmandActionBarActivity> activity;
private WeakReference<Context> context;
private File from;
private File to;
protected ProgressImplementation progress;
private Runnable runOnSuccess;
private int movedCount;
private long movedSize;
private int copiedCount;
private long copiedSize;
private int failedCount;
private long failedSize;
private String exceptionMessage;
public MoveFilesToDifferentDirectory(OsmandActionBarActivity activity, File from, File to) {
this.activity = new WeakReference<>(activity);
this.context = new WeakReference<>((Context) activity);
this.from = from;
this.to = to;
}
public void setRunOnSuccess(Runnable runOnSuccess) {
this.runOnSuccess = runOnSuccess;
}
public int getMovedCount() {
return movedCount;
}
public int getCopiedCount() {
return copiedCount;
}
public int getFailedCount() {
return failedCount;
}
public long getMovedSize() {
return movedSize;
}
public long getCopiedSize() {
return copiedSize;
}
public long getFailedSize() {
return failedSize;
}
@Override
protected void onPreExecute() {
Context ctx = context.get();
if (context == null) {
return;
}
movedCount = 0;
copiedCount = 0;
failedCount = 0;
progress = ProgressImplementation.createProgressDialog(
ctx, ctx.getString(R.string.copying_osmand_files),
ctx.getString(R.string.copying_osmand_files_descr, to.getPath()),
ProgressDialog.STYLE_HORIZONTAL);
}
@Override
protected void onPostExecute(Boolean result) {
Context ctx = context.get();
if (ctx == null) {
return;
}
if (result != null) {
if (result.booleanValue() && runOnSuccess != null) {
runOnSuccess.run();
} else if (!result.booleanValue()) {
Toast.makeText(ctx, ctx.getString(R.string.shared_string_io_error) + ": " + exceptionMessage, Toast.LENGTH_LONG).show();
}
}
try {
if (progress.getDialog().isShowing()) {
progress.getDialog().dismiss();
}
} catch (Exception e) {
//ignored
}
}
private void movingFiles(File f, File t, int depth) throws IOException {
Context ctx = context.get();
if (ctx == null) {
return;
}
if (depth <= 2) {
progress.startTask(ctx.getString(R.string.copying_osmand_one_file_descr, t.getName()), -1);
}
if (f.isDirectory()) {
t.mkdirs();
File[] lf = f.listFiles();
if (lf != null) {
for (int i = 0; i < lf.length; i++) {
if (lf[i] != null) {
movingFiles(lf[i], new File(t, lf[i].getName()), depth + 1);
}
}
}
f.delete();
} else if (f.isFile()) {
if (t.exists()) {
Algorithms.removeAllFiles(t);
}
boolean rnm = false;
long fileSize = f.length();
try {
rnm = f.renameTo(t);
movedCount++;
movedSize += fileSize;
} catch (RuntimeException e) {
}
if (!rnm) {
FileInputStream fin = new FileInputStream(f);
FileOutputStream fout = new FileOutputStream(t);
try {
progress.startTask(ctx.getString(R.string.copying_osmand_one_file_descr, t.getName()), (int) (f.length() / 1024));
Algorithms.streamCopy(fin, fout, progress, 1024);
copiedCount++;
copiedSize += fileSize;
} catch (IOException e) {
failedCount++;
failedSize += fileSize;
} finally {
fin.close();
fout.close();
}
f.delete();
}
}
if (depth <= 2) {
progress.finishTask();
}
}
@Override
protected Boolean doInBackground(Void... params) {
to.mkdirs();
try {
movingFiles(from, to, 0);
} catch (IOException e) {
exceptionMessage = e.getMessage();
return false;
}
return true;
}
}
public static class ReloadData extends AsyncTask<Void, Void, Boolean> {
private WeakReference<Context> ctx;
protected ProgressImplementation progress;
private OsmandApplication app;
public ReloadData(Context ctx, OsmandApplication app) {
this.ctx = new WeakReference<>(ctx);
this.app = app;
}
@Override
protected void onPreExecute() {
Context c = ctx.get();
if (c == null) {
return;
}
progress = ProgressImplementation.createProgressDialog(c, c.getString(R.string.loading_data),
c.getString(R.string.loading_data), ProgressDialog.STYLE_HORIZONTAL);
}
@Override
protected void onPostExecute(Boolean result) {
try {
if (progress.getDialog().isShowing()) {
progress.getDialog().dismiss();
}
} catch (Exception e) {
//ignored
}
}
@Override
protected Boolean doInBackground(Void... params) {
app.getResourceManager().reloadIndexes(progress, new ArrayList<String>());
return true;
}
}
} }

View file

@ -0,0 +1,321 @@
package net.osmand.plus.settings.datastorage;
import android.os.Build;
import androidx.annotation.NonNull;
import net.osmand.IndexConstants;
import net.osmand.ValueHolder;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.settings.datastorage.item.DirectoryItem;
import net.osmand.plus.settings.datastorage.item.DirectoryItem.CheckingType;
import net.osmand.plus.settings.datastorage.item.MemoryItem;
import net.osmand.plus.settings.datastorage.item.StorageItem;
import net.osmand.plus.settings.datastorage.task.RefreshUsedMemoryTask;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import static net.osmand.IndexConstants.AV_INDEX_DIR;
import static net.osmand.IndexConstants.BACKUP_INDEX_DIR;
import static net.osmand.IndexConstants.GPX_INDEX_DIR;
import static net.osmand.IndexConstants.MAPS_PATH;
import static net.osmand.IndexConstants.ROADS_INDEX_DIR;
import static net.osmand.IndexConstants.SRTM_INDEX_DIR;
import static net.osmand.IndexConstants.TILES_INDEX_DIR;
import static net.osmand.IndexConstants.WIKIVOYAGE_INDEX_DIR;
import static net.osmand.IndexConstants.WIKI_INDEX_DIR;
import static net.osmand.plus.settings.datastorage.item.DirectoryItem.CheckingType.EXTENSIONS;
import static net.osmand.plus.settings.datastorage.item.DirectoryItem.CheckingType.PREFIX;
public class DataStorageHelper {
public final static String INTERNAL_STORAGE = "internal_storage";
public final static String EXTERNAL_STORAGE = "external_storage";
public final static String SHARED_STORAGE = "shared_storage";
public final static String MULTIUSER_STORAGE = "multiuser_storage";
public final static String MANUALLY_SPECIFIED = "manually_specified";
public final static String MAPS_MEMORY = "maps_memory_used";
public final static String TERRAIN_MEMORY = "terrain_memory_used";
public final static String TRACKS_MEMORY = "tracks_memory_used";
public final static String NOTES_MEMORY = "notes_memory_used";
public final static String TILES_MEMORY = "tiles_memory_used";
public final static String OTHER_MEMORY = "other_memory_used";
private OsmandApplication app;
private ArrayList<StorageItem> storageItems = new ArrayList<>();
private StorageItem currentDataStorage;
private StorageItem manuallySpecified;
private ArrayList<MemoryItem> memoryItems = new ArrayList<>();
private MemoryItem mapsMemory;
private MemoryItem terrainMemory;
private MemoryItem tracksMemory;
private MemoryItem notesMemory;
private MemoryItem tilesMemory;
private MemoryItem otherMemory;
private int currentStorageType;
private String currentStoragePath;
public DataStorageHelper(@NonNull OsmandApplication app) {
this.app = app;
prepareData();
}
private void prepareData() {
initStorageItems();
initUsedMemoryItems();
}
private void initStorageItems() {
OsmandSettings settings = app.getSettings();
if (settings.getExternalStorageDirectoryTypeV19() >= 0) {
currentStorageType = settings.getExternalStorageDirectoryTypeV19();
} else {
ValueHolder<Integer> vh = new ValueHolder<Integer>();
if (vh.value != null && vh.value >= 0) {
currentStorageType = vh.value;
} else {
currentStorageType = 0;
}
}
currentStoragePath = settings.getExternalStorageDirectory().getAbsolutePath();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//internal storage
String path = settings.getInternalAppPath().getAbsolutePath();
File dir = new File(path);
int iconId = R.drawable.ic_action_phone;
StorageItem internalStorageItem = StorageItem.builder()
.setKey(INTERNAL_STORAGE)
.setTitle(app.getString(R.string.storage_directory_internal_app))
.setDirectory(path)
.setDescription(app.getString(R.string.internal_app_storage_description))
.setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_INTERNAL_FILE)
.setIconResId(iconId)
.createItem();
addItem(internalStorageItem);
//shared storage
dir = settings.getDefaultInternalStorage();
path = dir.getAbsolutePath();
iconId = R.drawable.ic_action_phone;
StorageItem sharedStorageItem = StorageItem.builder()
.setKey(SHARED_STORAGE)
.setTitle(app.getString(R.string.storage_directory_shared))
.setDirectory(path)
.setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT)
.setIconResId(iconId)
.createItem();
addItem(sharedStorageItem);
//external storage
File[] externals = app.getExternalFilesDirs(null);
if (externals != null) {
int i = 0;
for (File external : externals) {
if (external != null) {
++i;
dir = external;
path = dir.getAbsolutePath();
iconId = getIconForStorageType(dir);
StorageItem externalStorageItem = StorageItem.builder()
.setKey(EXTERNAL_STORAGE + i)
.setTitle(app.getString(R.string.storage_directory_external) + " " + i)
.setDirectory(path)
.setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE)
.setIconResId(iconId)
.createItem();
addItem(externalStorageItem);
}
}
}
//multi user storage
File[] obbDirs = app.getObbDirs();
if (obbDirs != null) {
int i = 0;
for (File obb : obbDirs) {
if (obb != null) {
++i;
dir = obb;
path = dir.getAbsolutePath();
iconId = getIconForStorageType(dir);
StorageItem multiuserStorageItem = StorageItem.builder()
.setKey(MULTIUSER_STORAGE + i)
.setTitle(app.getString(R.string.storage_directory_multiuser) + " " + i)
.setDirectory(path)
.setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_OBB)
.setIconResId(iconId)
.createItem();
addItem(multiuserStorageItem);
}
}
}
}
//manually specified storage
manuallySpecified = StorageItem.builder()
.setKey(MANUALLY_SPECIFIED)
.setTitle(app.getString(R.string.storage_directory_manual))
.setDirectory(currentStoragePath)
.setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED)
.setIconResId(R.drawable.ic_action_folder)
.createItem();
storageItems.add(manuallySpecified);
if (currentDataStorage == null) {
currentDataStorage = manuallySpecified;
}
}
private void initUsedMemoryItems() {
mapsMemory = MemoryItem.builder()
.setKey(MAPS_MEMORY)
.setExtensions(IndexConstants.BINARY_MAP_INDEX_EXT)
.setDirectories(
createDirectory(MAPS_PATH, false, EXTENSIONS, true),
createDirectory(ROADS_INDEX_DIR, true, EXTENSIONS, true),
createDirectory(WIKI_INDEX_DIR, true, EXTENSIONS, true),
createDirectory(WIKIVOYAGE_INDEX_DIR, true, EXTENSIONS, true),
createDirectory(BACKUP_INDEX_DIR, true, EXTENSIONS, true))
.createItem();
memoryItems.add(mapsMemory);
terrainMemory = MemoryItem.builder()
.setKey(TERRAIN_MEMORY)
.setExtensions(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)
.setDirectories(
createDirectory(SRTM_INDEX_DIR, true, EXTENSIONS, true),
createDirectory(TILES_INDEX_DIR, false, PREFIX, false))
.setPrefixes("Hillshade", "Slope")
.createItem();
memoryItems.add(terrainMemory);
tracksMemory = MemoryItem.builder()
.setKey(TRACKS_MEMORY)
// .setExtensions(IndexConstants.GPX_FILE_EXT, ".gpx.bz2")
.setDirectories(
createDirectory(GPX_INDEX_DIR, true, EXTENSIONS, true))
.createItem();
memoryItems.add(tracksMemory);
notesMemory = MemoryItem.builder()
.setKey(NOTES_MEMORY)
// .setExtensions("")
.setDirectories(
createDirectory(AV_INDEX_DIR, true, EXTENSIONS, true))
.createItem();
memoryItems.add(notesMemory);
tilesMemory = MemoryItem.builder()
.setKey(TILES_MEMORY)
// .setExtensions("")
.setDirectories(
createDirectory(TILES_INDEX_DIR, true, EXTENSIONS, true))
.createItem();
memoryItems.add(tilesMemory);
otherMemory = MemoryItem.builder()
.setKey(OTHER_MEMORY)
.createItem();
memoryItems.add(otherMemory);
}
public ArrayList<StorageItem> getStorageItems() {
return storageItems;
}
private int getIconForStorageType(File dir) {
return R.drawable.ic_action_folder;
}
public StorageItem getCurrentStorage() {
return currentDataStorage;
}
private void addItem(StorageItem item) {
if (currentStorageType == item.getType() && currentStoragePath.equals(item.getDirectory())) {
currentDataStorage = item;
}
storageItems.add(item);
}
public StorageItem getManuallySpecified() {
return manuallySpecified;
}
public StorageItem getStorage(String key) {
if (storageItems != null && key != null) {
for (StorageItem storageItem : storageItems) {
if (key.equals(storageItem.getKey())) {
return storageItem;
}
}
}
return null;
}
public ArrayList<MemoryItem> getMemoryInfoItems() {
return memoryItems;
}
public RefreshUsedMemoryTask calculateMemoryUsedInfo(UpdateMemoryInfoUIAdapter uiAdapter) {
File rootDir = new File(currentStoragePath);
RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(uiAdapter, otherMemory, rootDir, null, null, OTHER_MEMORY);
task.execute(mapsMemory, terrainMemory, tracksMemory, notesMemory);
return task;
}
public RefreshUsedMemoryTask calculateTilesMemoryUsed(UpdateMemoryInfoUIAdapter listener) {
File rootDir = new File(tilesMemory.getDirectories()[0].getAbsolutePath());
RefreshUsedMemoryTask task = new RefreshUsedMemoryTask(listener, otherMemory, rootDir, null, terrainMemory.getPrefixes(), TILES_MEMORY);
task.execute(tilesMemory);
return task;
}
public long getTotalUsedBytes() {
long total = 0;
if (memoryItems != null && memoryItems.size() > 0) {
for (MemoryItem mi : memoryItems) {
total += mi.getUsedMemoryBytes();
}
return total;
}
return -1;
}
public DirectoryItem createDirectory(@NonNull String relativePath,
boolean processInternalDirectories,
CheckingType checkingType,
boolean addUnmatchedToOtherMemory) {
String path = app.getAppPath(relativePath).getAbsolutePath();
return new DirectoryItem(path, processInternalDirectories, checkingType, addUnmatchedToOtherMemory);
}
public static String getFormattedMemoryInfo(long bytes, String[] formatStrings) {
int type = 0;
double memory = (double) bytes / 1024;
while (memory > 1024 && type < formatStrings.length) {
++type;
memory = memory / 1024;
}
String formattedUsed = new DecimalFormat("#.##").format(memory);
return String.format(formatStrings[type], formattedUsed);
}
public interface UpdateMemoryInfoUIAdapter {
void onMemoryInfoUpdate();
void onFinishUpdating(String tag);
}
}

View file

@ -0,0 +1,40 @@
package net.osmand.plus.settings.datastorage.item;
public class DirectoryItem {
private final String absolutePath;
private final boolean processInternalDirectories;
private final CheckingType checkingType;
private final boolean addUnmatchedToOtherMemory;
public enum CheckingType {
EXTENSIONS,
PREFIX
}
public DirectoryItem(String absolutePath,
boolean processInternalDirectories,
CheckingType checkingType,
boolean addUnmatchedToOtherMemory) {
this.absolutePath = absolutePath;
this.processInternalDirectories = processInternalDirectories;
this.checkingType = checkingType;
this.addUnmatchedToOtherMemory = addUnmatchedToOtherMemory;
}
public String getAbsolutePath() {
return absolutePath;
}
public boolean shouldProcessInternalDirectories() {
return processInternalDirectories;
}
public CheckingType getCheckingType() {
return checkingType;
}
public boolean shouldAddUnmatchedToOtherMemory() {
return addUnmatchedToOtherMemory;
}
}

View file

@ -1,16 +1,18 @@
package net.osmand.plus.settings.fragments; package net.osmand.plus.settings.datastorage.item;
public class MemoryItem {
public class DataStorageMemoryItem {
public final static int EXTENSIONS = 0;
public final static int PREFIX = 1;
private String key; private String key;
private String[] extensions; private final String[] extensions;
private String[] prefixes; private final String[] prefixes;
private Directory[] directories; private final DirectoryItem[] directories;
private long usedMemoryBytes; private long usedMemoryBytes;
private DataStorageMemoryItem(String key, String[] extensions, String[] prefixes, long usedMemoryBytes, Directory[] directories) { private MemoryItem(String key,
String[] extensions,
String[] prefixes,
long usedMemoryBytes,
DirectoryItem[] directories) {
this.key = key; this.key = key;
this.extensions = extensions; this.extensions = extensions;
this.prefixes = prefixes; this.prefixes = prefixes;
@ -42,7 +44,7 @@ public class DataStorageMemoryItem {
return prefixes; return prefixes;
} }
public Directory[] getDirectories() { public DirectoryItem[] getDirectories() {
return directories; return directories;
} }
@ -54,7 +56,7 @@ public class DataStorageMemoryItem {
private String key; private String key;
private String[] extensions; private String[] extensions;
private String[] prefixes; private String[] prefixes;
private Directory[] directories; private DirectoryItem[] directories;
private long usedMemoryBytes; private long usedMemoryBytes;
public DataStorageMemoryItemBuilder setKey(String key) { public DataStorageMemoryItemBuilder setKey(String key) {
@ -72,7 +74,7 @@ public class DataStorageMemoryItem {
return this; return this;
} }
public DataStorageMemoryItemBuilder setDirectories(Directory ... directories) { public DataStorageMemoryItemBuilder setDirectories(DirectoryItem... directories) {
this.directories = directories; this.directories = directories;
return this; return this;
} }
@ -82,38 +84,8 @@ public class DataStorageMemoryItem {
return this; return this;
} }
public DataStorageMemoryItem createItem() { public MemoryItem createItem() {
return new DataStorageMemoryItem(key, extensions, prefixes, usedMemoryBytes, directories); return new MemoryItem(key, extensions, prefixes, usedMemoryBytes, directories);
}
}
public static class Directory {
private String absolutePath;
private boolean goDeeper;
private int checkingType;
private boolean skipOther;
public Directory(String absolutePath, boolean goDeeper, int checkingType, boolean skipOther) {
this.absolutePath = absolutePath;
this.goDeeper = goDeeper;
this.checkingType = checkingType;
this.skipOther = skipOther;
}
public String getAbsolutePath() {
return absolutePath;
}
public boolean isGoDeeper() {
return goDeeper;
}
public int getCheckingType() {
return checkingType;
}
public boolean isSkipOther() {
return skipOther;
} }
} }
} }

View file

@ -1,11 +1,11 @@
package net.osmand.plus.settings.fragments; package net.osmand.plus.settings.datastorage.item;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.IdRes; import androidx.annotation.IdRes;
public class DataStorageMenuItem implements Parcelable, Cloneable { public class StorageItem implements Parcelable, Cloneable {
private String key; private String key;
private int type; private int type;
@ -15,8 +15,12 @@ public class DataStorageMenuItem implements Parcelable, Cloneable {
@IdRes @IdRes
private int iconResId; private int iconResId;
private DataStorageMenuItem(String key, int type, String title, String description, private StorageItem(String key,
String directory, int iconResId) { int type,
String title,
String description,
String directory,
int iconResId) {
this.key = key; this.key = key;
this.type = type; this.type = type;
this.title = title; this.title = title;
@ -25,7 +29,7 @@ public class DataStorageMenuItem implements Parcelable, Cloneable {
this.iconResId = iconResId; this.iconResId = iconResId;
} }
private DataStorageMenuItem(Parcel in) { private StorageItem(Parcel in) {
key = in.readString(); key = in.readString();
type = in.readInt(); type = in.readInt();
title = in.readString(); title = in.readString();
@ -99,16 +103,16 @@ public class DataStorageMenuItem implements Parcelable, Cloneable {
dest.writeString(directory); dest.writeString(directory);
} }
public static final Parcelable.Creator<DataStorageMenuItem> CREATOR = new Parcelable.Creator<DataStorageMenuItem>() { public static final Parcelable.Creator<StorageItem> CREATOR = new Parcelable.Creator<StorageItem>() {
@Override @Override
public DataStorageMenuItem createFromParcel(Parcel source) { public StorageItem createFromParcel(Parcel source) {
return new DataStorageMenuItem(source); return new StorageItem(source);
} }
@Override @Override
public DataStorageMenuItem[] newArray(int size) { public StorageItem[] newArray(int size) {
return new DataStorageMenuItem[size]; return new StorageItem[size];
} }
}; };
@ -151,14 +155,14 @@ public class DataStorageMenuItem implements Parcelable, Cloneable {
return this; return this;
} }
public DataStorageMenuItem createItem() { public StorageItem createItem() {
return new DataStorageMenuItem(key, type, title, description, directory, iconResId); return new StorageItem(key, type, title, description, directory, iconResId);
} }
} }
@Override @Override
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
return DataStorageMenuItem.builder() return StorageItem.builder()
.setKey(this.key) .setKey(this.key)
.setTitle(this.title) .setTitle(this.title)
.setDescription(this.description) .setDescription(this.description)

View file

@ -0,0 +1,173 @@
package net.osmand.plus.settings.datastorage.task;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
import net.osmand.plus.ProgressImplementation;
import net.osmand.plus.R;
import net.osmand.plus.activities.OsmandActionBarActivity;
import net.osmand.util.Algorithms;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
public class MoveFilesTask extends AsyncTask<Void, Void, Boolean> {
protected WeakReference<OsmandActionBarActivity> activity;
private WeakReference<Context> context;
private File from;
private File to;
protected ProgressImplementation progress;
private Runnable runOnSuccess;
private int movedCount;
private long movedSize;
private int copiedCount;
private long copiedSize;
private int failedCount;
private long failedSize;
private String exceptionMessage;
public MoveFilesTask(OsmandActionBarActivity activity, File from, File to) {
this.activity = new WeakReference<>(activity);
this.context = new WeakReference<>((Context) activity);
this.from = from;
this.to = to;
}
public void setRunOnSuccess(Runnable runOnSuccess) {
this.runOnSuccess = runOnSuccess;
}
public int getMovedCount() {
return movedCount;
}
public int getCopiedCount() {
return copiedCount;
}
public int getFailedCount() {
return failedCount;
}
public long getMovedSize() {
return movedSize;
}
public long getCopiedSize() {
return copiedSize;
}
public long getFailedSize() {
return failedSize;
}
@Override
protected void onPreExecute() {
Context ctx = context.get();
if (context == null) {
return;
}
movedCount = 0;
copiedCount = 0;
failedCount = 0;
progress = ProgressImplementation.createProgressDialog(
ctx, ctx.getString(R.string.copying_osmand_files),
ctx.getString(R.string.copying_osmand_files_descr, to.getPath()),
ProgressDialog.STYLE_HORIZONTAL);
}
@Override
protected void onPostExecute(Boolean result) {
Context ctx = context.get();
if (ctx == null) {
return;
}
if (result != null) {
if (result.booleanValue() && runOnSuccess != null) {
runOnSuccess.run();
} else if (!result.booleanValue()) {
Toast.makeText(ctx, ctx.getString(R.string.shared_string_io_error) + ": " + exceptionMessage, Toast.LENGTH_LONG).show();
}
}
try {
if (progress.getDialog().isShowing()) {
progress.getDialog().dismiss();
}
} catch (Exception e) {
//ignored
}
}
private void movingFiles(File f, File t, int depth) throws IOException {
Context ctx = context.get();
if (ctx == null) {
return;
}
if (depth <= 2) {
progress.startTask(ctx.getString(R.string.copying_osmand_one_file_descr, t.getName()), -1);
}
if (f.isDirectory()) {
t.mkdirs();
File[] lf = f.listFiles();
if (lf != null) {
for (int i = 0; i < lf.length; i++) {
if (lf[i] != null) {
movingFiles(lf[i], new File(t, lf[i].getName()), depth + 1);
}
}
}
f.delete();
} else if (f.isFile()) {
if (t.exists()) {
Algorithms.removeAllFiles(t);
}
boolean rnm = false;
long fileSize = f.length();
try {
rnm = f.renameTo(t);
movedCount++;
movedSize += fileSize;
} catch (RuntimeException e) {
}
if (!rnm) {
FileInputStream fin = new FileInputStream(f);
FileOutputStream fout = new FileOutputStream(t);
try {
progress.startTask(ctx.getString(R.string.copying_osmand_one_file_descr, t.getName()), (int) (f.length() / 1024));
Algorithms.streamCopy(fin, fout, progress, 1024);
copiedCount++;
copiedSize += fileSize;
} catch (IOException e) {
failedCount++;
failedSize += fileSize;
} finally {
fin.close();
fout.close();
}
f.delete();
}
}
if (depth <= 2) {
progress.finishTask();
}
}
@Override
protected Boolean doInBackground(Void... params) {
to.mkdirs();
try {
movingFiles(from, to, 0);
} catch (IOException e) {
exceptionMessage = e.getMessage();
return false;
}
return true;
}
}

View file

@ -0,0 +1,232 @@
package net.osmand.plus.settings.datastorage.task;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import net.osmand.plus.settings.datastorage.DataStorageHelper.UpdateMemoryInfoUIAdapter;
import net.osmand.plus.settings.datastorage.item.DirectoryItem;
import net.osmand.plus.settings.datastorage.item.DirectoryItem.CheckingType;
import net.osmand.plus.settings.datastorage.item.MemoryItem;
import java.io.File;
import static net.osmand.plus.settings.datastorage.DataStorageFragment.UI_REFRESH_TIME_MS;
import static net.osmand.util.Algorithms.objectEquals;
public class RefreshUsedMemoryTask extends AsyncTask<MemoryItem, Void, Void> {
private final UpdateMemoryInfoUIAdapter uiAdapter;
private final File root;
private final MemoryItem otherMemoryItem;
private final String[] directoriesToSkip;
private final String[] filePrefixesToSkip;
private final String tag;
private long lastRefreshTime;
public RefreshUsedMemoryTask(UpdateMemoryInfoUIAdapter uiAdapter,
MemoryItem otherMemoryItem,
File root,
String[] directoriesToSkip,
String[] filePrefixesToSkip,
String tag) {
this.uiAdapter = uiAdapter;
this.otherMemoryItem = otherMemoryItem;
this.root = root;
this.directoriesToSkip = directoriesToSkip;
this.filePrefixesToSkip = filePrefixesToSkip;
this.tag = tag;
}
@Override
protected Void doInBackground(MemoryItem... items) {
lastRefreshTime = System.currentTimeMillis();
if (root.canRead()) {
calculateMultiTypes(root, items);
}
return null;
}
private void calculateMultiTypes(File rootDir,
MemoryItem... items) {
File[] subFiles = rootDir.listFiles();
if (subFiles != null) {
for (File file : subFiles) {
if (isCancelled()) break;
if (file.isDirectory()) {
if (!shouldSkipDirectory(file)) {
processDirectory(file, items);
}
} else if (file.isFile()) {
if (!shouldSkipFile(file)) {
processFile(rootDir, file, items);
}
}
refreshUI();
}
}
}
private boolean shouldSkipDirectory(@NonNull File dir) {
if (directoriesToSkip != null) {
for (String dirToSkipPath : directoriesToSkip) {
String dirPath = dir.getAbsolutePath();
if (objectEquals(dirPath, dirToSkipPath)) {
return true;
}
}
}
return false;
}
private boolean shouldSkipFile(@NonNull File file) {
if (filePrefixesToSkip != null) {
String fileName = file.getName().toLowerCase();
for (String prefixToAvoid : filePrefixesToSkip) {
String prefix = prefixToAvoid.toLowerCase();
if (fileName.startsWith(prefix)) {
return true;
}
}
}
return false;
}
private void processDirectory(@NonNull File directory,
@NonNull MemoryItem... items) {
String directoryPath = directory.getAbsolutePath();
for (MemoryItem memoryItem : items) {
DirectoryItem[] targetDirectories = memoryItem.getDirectories();
if (targetDirectories != null) {
for (DirectoryItem dir : targetDirectories) {
String allowedDirPath = dir.getAbsolutePath();
boolean isPerfectlyMatch = objectEquals(directoryPath, allowedDirPath);
boolean isParentDirectory = !isPerfectlyMatch && (directoryPath.startsWith(allowedDirPath));
boolean isMatchDirectory = isPerfectlyMatch || isParentDirectory;
if (isPerfectlyMatch) {
calculateMultiTypes(directory, items);
return;
} else if (isParentDirectory && dir.shouldProcessInternalDirectories()) {
calculateMultiTypes(directory, items);
return;
} else if (isMatchDirectory && !dir.shouldAddUnmatchedToOtherMemory()) {
return;
}
}
}
}
// Current directory did not match to any type
otherMemoryItem.addBytes(calculateFolderSize(directory));
}
private void processFile(@NonNull File rootDir,
@NonNull File file,
@NonNull MemoryItem... items) {
for (MemoryItem item : items) {
DirectoryItem[] targetDirectories = item.getDirectories();
if (targetDirectories == null) continue;
String rootDirPath = rootDir.getAbsolutePath();
for (DirectoryItem targetDirectory : targetDirectories) {
String allowedDirPath = targetDirectory.getAbsolutePath();
boolean processInternal = targetDirectory.shouldProcessInternalDirectories();
if (objectEquals(rootDirPath, allowedDirPath)
|| (rootDirPath.startsWith(allowedDirPath) && processInternal)) {
CheckingType checkingType = targetDirectory.getCheckingType();
switch (checkingType) {
case EXTENSIONS: {
if (isSuitableExtension(file, item)) {
item.addBytes(file.length());
return;
}
break;
}
case PREFIX: {
if (isSuitablePrefix(file, item)) {
item.addBytes(file.length());
return;
}
break;
}
}
if (!targetDirectory.shouldAddUnmatchedToOtherMemory()) {
return;
}
}
}
}
// Current file did not match any type
otherMemoryItem.addBytes(file.length());
}
private boolean isSuitableExtension(@NonNull File file,
@NonNull MemoryItem item) {
String[] extensions = item.getExtensions();
if (extensions != null) {
for (String extension : extensions) {
if (file.getAbsolutePath().endsWith(extension)) {
return true;
}
}
}
return extensions == null;
}
private boolean isSuitablePrefix(@NonNull File file,
@NonNull MemoryItem item) {
String[] prefixes = item.getPrefixes();
if (prefixes != null) {
for (String prefix : prefixes) {
if (file.getName().toLowerCase().startsWith(prefix.toLowerCase())) {
return true;
}
}
}
return prefixes == null;
}
private long calculateFolderSize(@NonNull File dir) {
long bytes = 0;
if (dir.isDirectory()) {
File[] files = dir.listFiles();
if (files == null) return 0;
for (File file : files) {
if (isCancelled()) {
break;
}
if (file.isDirectory()) {
bytes += calculateFolderSize(file);
} else if (file.isFile()) {
bytes += file.length();
}
}
}
return bytes;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
if (uiAdapter != null) {
uiAdapter.onMemoryInfoUpdate();
}
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (uiAdapter != null) {
uiAdapter.onFinishUpdating(tag);
}
}
private void refreshUI() {
long currentTime = System.currentTimeMillis();
if ((currentTime - lastRefreshTime) > UI_REFRESH_TIME_MS) {
lastRefreshTime = currentTime;
publishProgress();
}
}
}

View file

@ -0,0 +1,50 @@
package net.osmand.plus.settings.datastorage.task;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.ProgressImplementation;
import net.osmand.plus.R;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
public class ReloadDataTask extends AsyncTask<Void, Void, Boolean> {
private WeakReference<Context> ctx;
protected ProgressImplementation progress;
private OsmandApplication app;
public ReloadDataTask(Context ctx, OsmandApplication app) {
this.ctx = new WeakReference<>(ctx);
this.app = app;
}
@Override
protected void onPreExecute() {
Context c = ctx.get();
if (c == null) {
return;
}
progress = ProgressImplementation.createProgressDialog(c, c.getString(R.string.loading_data),
c.getString(R.string.loading_data), ProgressDialog.STYLE_HORIZONTAL);
}
@Override
protected void onPostExecute(Boolean result) {
try {
if (progress.getDialog().isShowing()) {
progress.getDialog().dismiss();
}
} catch (Exception e) {
//ignored
}
}
@Override
protected Boolean doInBackground(Void... params) {
app.getResourceManager().reloadIndexes(progress, new ArrayList<String>());
return true;
}
}

View file

@ -61,6 +61,7 @@ import net.osmand.plus.activities.OsmandInAppPurchaseActivity;
import net.osmand.plus.audionotes.MultimediaNotesFragment; import net.osmand.plus.audionotes.MultimediaNotesFragment;
import net.osmand.plus.development.DevelopmentSettingsFragment; import net.osmand.plus.development.DevelopmentSettingsFragment;
import net.osmand.plus.monitoring.MonitoringSettingsFragment; import net.osmand.plus.monitoring.MonitoringSettingsFragment;
import net.osmand.plus.openplacereviews.OprSettingsFragment;
import net.osmand.plus.osmedit.OsmEditingFragment; import net.osmand.plus.osmedit.OsmEditingFragment;
import net.osmand.plus.profiles.SelectAppModesBottomSheetDialogFragment; import net.osmand.plus.profiles.SelectAppModesBottomSheetDialogFragment;
import net.osmand.plus.profiles.SelectAppModesBottomSheetDialogFragment.AppModeChangedListener; import net.osmand.plus.profiles.SelectAppModesBottomSheetDialogFragment.AppModeChangedListener;
@ -73,6 +74,7 @@ import net.osmand.plus.settings.bottomsheets.ChangeGeneralProfilesPrefBottomShee
import net.osmand.plus.settings.bottomsheets.EditTextPreferenceBottomSheet; import net.osmand.plus.settings.bottomsheets.EditTextPreferenceBottomSheet;
import net.osmand.plus.settings.bottomsheets.MultiSelectPreferencesBottomSheet; import net.osmand.plus.settings.bottomsheets.MultiSelectPreferencesBottomSheet;
import net.osmand.plus.settings.bottomsheets.SingleSelectPreferenceBottomSheet; import net.osmand.plus.settings.bottomsheets.SingleSelectPreferenceBottomSheet;
import net.osmand.plus.settings.datastorage.DataStorageFragment;
import net.osmand.plus.settings.preferences.ListPreferenceEx; import net.osmand.plus.settings.preferences.ListPreferenceEx;
import net.osmand.plus.settings.preferences.MultiSelectBooleanPreference; import net.osmand.plus.settings.preferences.MultiSelectBooleanPreference;
import net.osmand.plus.settings.preferences.SwitchPreferenceEx; import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
@ -132,6 +134,7 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
MONITORING_SETTINGS(MonitoringSettingsFragment.class.getName(), true, ApplyQueryType.SNACK_BAR, R.xml.monitoring_settings, R.layout.profile_preference_toolbar), MONITORING_SETTINGS(MonitoringSettingsFragment.class.getName(), true, ApplyQueryType.SNACK_BAR, R.xml.monitoring_settings, R.layout.profile_preference_toolbar),
LIVE_MONITORING(LiveMonitoringFragment.class.getName(), false, ApplyQueryType.SNACK_BAR, R.xml.live_monitoring, R.layout.global_preferences_toolbar_with_switch), LIVE_MONITORING(LiveMonitoringFragment.class.getName(), false, ApplyQueryType.SNACK_BAR, R.xml.live_monitoring, R.layout.global_preferences_toolbar_with_switch),
ACCESSIBILITY_SETTINGS(AccessibilitySettingsFragment.class.getName(), true, ApplyQueryType.SNACK_BAR, R.xml.accessibility_settings, R.layout.profile_preference_toolbar), ACCESSIBILITY_SETTINGS(AccessibilitySettingsFragment.class.getName(), true, ApplyQueryType.SNACK_BAR, R.xml.accessibility_settings, R.layout.profile_preference_toolbar),
OPEN_PLACE_REVIEWS(OprSettingsFragment.class.getName(), false, null, R.xml.open_place_reviews, R.layout.global_preference_toolbar),
DEVELOPMENT_SETTINGS(DevelopmentSettingsFragment.class.getName(), false, null, R.xml.development_settings, R.layout.global_preference_toolbar); DEVELOPMENT_SETTINGS(DevelopmentSettingsFragment.class.getName(), false, null, R.xml.development_settings, R.layout.global_preference_toolbar);
public final String fragmentName; public final String fragmentName;

View file

@ -1,485 +0,0 @@
package net.osmand.plus.settings.fragments;
import android.os.AsyncTask;
import android.os.Build;
import net.osmand.IndexConstants;
import net.osmand.ValueHolder;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import static net.osmand.plus.settings.fragments.DataStorageFragment.UI_REFRESH_TIME_MS;
import static net.osmand.plus.settings.fragments.DataStorageMemoryItem.Directory;
import static net.osmand.plus.settings.fragments.DataStorageMemoryItem.EXTENSIONS;
import static net.osmand.plus.settings.fragments.DataStorageMemoryItem.PREFIX;
public class DataStorageHelper {
public final static String INTERNAL_STORAGE = "internal_storage";
public final static String EXTERNAL_STORAGE = "external_storage";
public final static String SHARED_STORAGE = "shared_storage";
public final static String MULTIUSER_STORAGE = "multiuser_storage";
public final static String MANUALLY_SPECIFIED = "manually_specified";
public final static String MAPS_MEMORY = "maps_memory_used";
public final static String SRTM_AND_HILLSHADE_MEMORY = "contour_lines_and_hillshade_memory";
public final static String TRACKS_MEMORY = "tracks_memory_used";
public final static String NOTES_MEMORY = "notes_memory_used";
public final static String TILES_MEMORY = "tiles_memory_used";
public final static String OTHER_MEMORY = "other_memory_used";
private ArrayList<DataStorageMenuItem> menuItems = new ArrayList<>();
private DataStorageMenuItem currentDataStorage;
private DataStorageMenuItem manuallySpecified;
private ArrayList<DataStorageMemoryItem> memoryItems = new ArrayList<>();
private DataStorageMemoryItem mapsMemory;
private DataStorageMemoryItem srtmAndHillshadeMemory;
private DataStorageMemoryItem tracksMemory;
private DataStorageMemoryItem notesMemory;
private DataStorageMemoryItem tilesMemory;
private DataStorageMemoryItem otherMemory;
private int currentStorageType;
private String currentStoragePath;
public DataStorageHelper(OsmandApplication app) {
prepareData(app);
}
private void prepareData(OsmandApplication app) {
if (app == null) {
return;
}
OsmandSettings settings = app.getSettings();
if (settings.getExternalStorageDirectoryTypeV19() >= 0) {
currentStorageType = settings.getExternalStorageDirectoryTypeV19();
} else {
ValueHolder<Integer> vh = new ValueHolder<Integer>();
if (vh.value != null && vh.value >= 0) {
currentStorageType = vh.value;
} else {
currentStorageType = 0;
}
}
currentStoragePath = settings.getExternalStorageDirectory().getAbsolutePath();
String path;
File dir;
int iconId;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//internal storage
path = settings.getInternalAppPath().getAbsolutePath();
dir = new File(path);
iconId = R.drawable.ic_action_phone;
DataStorageMenuItem internalStorageItem = DataStorageMenuItem.builder()
.setKey(INTERNAL_STORAGE)
.setTitle(app.getString(R.string.storage_directory_internal_app))
.setDirectory(path)
.setDescription(app.getString(R.string.internal_app_storage_description))
.setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_INTERNAL_FILE)
.setIconResId(iconId)
.createItem();
addItem(internalStorageItem);
//shared_storage
dir = settings.getDefaultInternalStorage();
path = dir.getAbsolutePath();
iconId = R.drawable.ic_action_phone;
DataStorageMenuItem sharedStorageItem = DataStorageMenuItem.builder()
.setKey(SHARED_STORAGE)
.setTitle(app.getString(R.string.storage_directory_shared))
.setDirectory(path)
.setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_DEFAULT)
.setIconResId(iconId)
.createItem();
addItem(sharedStorageItem);
//external storage
File[] externals = app.getExternalFilesDirs(null);
if (externals != null) {
int i = 0;
for (File external : externals) {
if (external != null) {
++i;
dir = external;
path = dir.getAbsolutePath();
iconId = getIconForStorageType(dir);
DataStorageMenuItem externalStorageItem = DataStorageMenuItem.builder()
.setKey(EXTERNAL_STORAGE + i)
.setTitle(app.getString(R.string.storage_directory_external) + " " + i)
.setDirectory(path)
.setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_EXTERNAL_FILE)
.setIconResId(iconId)
.createItem();
addItem(externalStorageItem);
}
}
}
//multi user storage
File[] obbDirs = app.getObbDirs();
if (obbDirs != null) {
int i = 0;
for (File obb : obbDirs) {
if (obb != null) {
++i;
dir = obb;
path = dir.getAbsolutePath();
iconId = getIconForStorageType(dir);
DataStorageMenuItem multiuserStorageItem = DataStorageMenuItem.builder()
.setKey(MULTIUSER_STORAGE + i)
.setTitle(app.getString(R.string.storage_directory_multiuser) + " " + i)
.setDirectory(path)
.setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_OBB)
.setIconResId(iconId)
.createItem();
addItem(multiuserStorageItem);
}
}
}
}
//manually specified storage
manuallySpecified = DataStorageMenuItem.builder()
.setKey(MANUALLY_SPECIFIED)
.setTitle(app.getString(R.string.storage_directory_manual))
.setDirectory(currentStoragePath)
.setType(OsmandSettings.EXTERNAL_STORAGE_TYPE_SPECIFIED)
.setIconResId(R.drawable.ic_action_folder)
.createItem();
menuItems.add(manuallySpecified);
if (currentDataStorage == null) {
currentDataStorage = manuallySpecified;
}
initMemoryUsed(app);
}
private void initMemoryUsed(OsmandApplication app) {
mapsMemory = DataStorageMemoryItem.builder()
.setKey(MAPS_MEMORY)
.setExtensions(IndexConstants.BINARY_MAP_INDEX_EXT)
.setDirectories(
new Directory(app.getAppPath(IndexConstants.MAPS_PATH).getAbsolutePath(), false, EXTENSIONS, false),
new Directory(app.getAppPath(IndexConstants.ROADS_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false),
new Directory(app.getAppPath(IndexConstants.WIKI_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false),
new Directory(app.getAppPath(IndexConstants.WIKIVOYAGE_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false),
new Directory(app.getAppPath(IndexConstants.BACKUP_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false))
.createItem();
memoryItems.add(mapsMemory);
srtmAndHillshadeMemory = DataStorageMemoryItem.builder()
.setKey(SRTM_AND_HILLSHADE_MEMORY)
.setExtensions(IndexConstants.BINARY_SRTM_MAP_INDEX_EXT)
.setDirectories(
new Directory(app.getAppPath(IndexConstants.SRTM_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false),
new Directory(app.getAppPath(IndexConstants.TILES_INDEX_DIR).getAbsolutePath(), false, PREFIX, true))
.setPrefixes("Hillshade")
.createItem();
memoryItems.add(srtmAndHillshadeMemory);
tracksMemory = DataStorageMemoryItem.builder()
.setKey(TRACKS_MEMORY)
// .setExtensions(IndexConstants.GPX_FILE_EXT, ".gpx.bz2")
.setDirectories(
new Directory(app.getAppPath(IndexConstants.GPX_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false))
.createItem();
memoryItems.add(tracksMemory);
notesMemory = DataStorageMemoryItem.builder()
.setKey(NOTES_MEMORY)
// .setExtensions("")
.setDirectories(
new Directory(app.getAppPath(IndexConstants.AV_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false))
.createItem();
memoryItems.add(notesMemory);
tilesMemory = DataStorageMemoryItem.builder()
.setKey(TILES_MEMORY)
// .setExtensions("")
.setDirectories(
new Directory(app.getAppPath(IndexConstants.TILES_INDEX_DIR).getAbsolutePath(), true, EXTENSIONS, false))
.createItem();
memoryItems.add(tilesMemory);
otherMemory = DataStorageMemoryItem.builder()
.setKey(OTHER_MEMORY)
.createItem();
memoryItems.add(otherMemory);
}
public ArrayList<DataStorageMenuItem> getStorageItems() {
return menuItems;
}
private int getIconForStorageType(File dir) {
return R.drawable.ic_action_folder;
}
public DataStorageMenuItem getCurrentStorage() {
return currentDataStorage;
}
private void addItem(DataStorageMenuItem item) {
if (currentStorageType == item.getType() && currentStoragePath.equals(item.getDirectory())) {
currentDataStorage = item;
}
menuItems.add(item);
}
public DataStorageMenuItem getManuallySpecified() {
return manuallySpecified;
}
public DataStorageMenuItem getStorage(String key) {
if (menuItems != null && key != null) {
for (DataStorageMenuItem menuItem : menuItems) {
if (key.equals(menuItem.getKey())) {
return menuItem;
}
}
}
return null;
}
public int getCurrentType() {
return currentStorageType;
}
public String getCurrentPath() {
return currentStoragePath;
}
public ArrayList<DataStorageMemoryItem> getMemoryInfoItems() {
return memoryItems;
}
public RefreshMemoryUsedInfo calculateMemoryUsedInfo(UpdateMemoryInfoUIAdapter listener) {
File rootDir = new File(currentStoragePath);
RefreshMemoryUsedInfo task = new RefreshMemoryUsedInfo(listener, otherMemory, rootDir, null, null, OTHER_MEMORY);
task.execute(mapsMemory, srtmAndHillshadeMemory, tracksMemory, notesMemory);
return task;
}
public RefreshMemoryUsedInfo calculateTilesMemoryUsed(UpdateMemoryInfoUIAdapter listener) {
File rootDir = new File(tilesMemory.getDirectories()[0].getAbsolutePath());
RefreshMemoryUsedInfo task = new RefreshMemoryUsedInfo(listener, otherMemory, rootDir, null, srtmAndHillshadeMemory.getPrefixes(), TILES_MEMORY);
task.execute(tilesMemory);
return task;
}
public static class RefreshMemoryUsedInfo extends AsyncTask<DataStorageMemoryItem, Void, Void> {
private UpdateMemoryInfoUIAdapter listener;
private File rootDir;
private DataStorageMemoryItem otherMemory;
private String[] directoriesToAvoid;
private String[] prefixesToAvoid;
private String taskKey;
private long lastRefreshTime;
public RefreshMemoryUsedInfo(UpdateMemoryInfoUIAdapter listener, DataStorageMemoryItem otherMemory, File rootDir, String[] directoriesToAvoid, String[] prefixesToAvoid, String taskKey) {
this.listener = listener;
this.otherMemory = otherMemory;
this.rootDir = rootDir;
this.directoriesToAvoid = directoriesToAvoid;
this.prefixesToAvoid = prefixesToAvoid;
this.taskKey = taskKey;
}
@Override
protected Void doInBackground(DataStorageMemoryItem... items) {
lastRefreshTime = System.currentTimeMillis();
if (rootDir.canRead()) {
calculateMultiTypes(rootDir, items);
}
return null;
}
private void calculateMultiTypes(File rootDir, DataStorageMemoryItem... items) {
File[] subFiles = rootDir.listFiles();
for (File file : subFiles) {
if (isCancelled()) {
break;
}
nextFile : {
if (file.isDirectory()) {
//check current directory should be avoid
if (directoriesToAvoid != null) {
for (String directoryToAvoid : directoriesToAvoid) {
if (file.getAbsolutePath().equals(directoryToAvoid)) {
break nextFile;
}
}
}
//check current directory matched items type
for (DataStorageMemoryItem item : items) {
Directory[] directories = item.getDirectories();
if (directories == null) {
continue;
}
for (Directory dir : directories) {
if (file.getAbsolutePath().equals(dir.getAbsolutePath())
|| (file.getAbsolutePath().startsWith(dir.getAbsolutePath()))) {
if (dir.isGoDeeper()) {
calculateMultiTypes(file, items);
break nextFile;
} else if (dir.isSkipOther()) {
break nextFile;
}
}
}
}
//current directory did not match to any type
otherMemory.addBytes(getDirectorySize(file));
} else if (file.isFile()) {
//check current file should be avoid
if (prefixesToAvoid != null) {
for (String prefixToAvoid : prefixesToAvoid) {
if (file.getName().toLowerCase().startsWith(prefixToAvoid.toLowerCase())) {
break nextFile;
}
}
}
//check current file matched items type
for (DataStorageMemoryItem item : items) {
Directory[] directories = item.getDirectories();
if (directories == null) {
continue;
}
for (Directory dir : directories) {
if (rootDir.getAbsolutePath().equals(dir.getAbsolutePath())
|| (rootDir.getAbsolutePath().startsWith(dir.getAbsolutePath()) && dir.isGoDeeper())) {
int checkingType = dir.getCheckingType();
switch (checkingType) {
case EXTENSIONS : {
String[] extensions = item.getExtensions();
if (extensions != null) {
for (String extension : extensions) {
if (file.getAbsolutePath().endsWith(extension)) {
item.addBytes(file.length());
break nextFile;
}
}
} else {
item.addBytes(file.length());
break nextFile;
}
break ;
}
case PREFIX : {
String[] prefixes = item.getPrefixes();
if (prefixes != null) {
for (String prefix : prefixes) {
if (file.getName().toLowerCase().startsWith(prefix.toLowerCase())) {
item.addBytes(file.length());
break nextFile;
}
}
} else {
item.addBytes(file.length());
break nextFile;
}
break ;
}
}
if (dir.isSkipOther()) {
break nextFile;
}
}
}
}
//current file did not match any type
otherMemory.addBytes(file.length());
}
}
refreshUI();
}
}
private long getDirectorySize(File dir) {
long bytes = 0;
if (dir.isDirectory()) {
File[] files = dir.listFiles();
for (File file : files) {
if (isCancelled()) {
break;
}
if (file.isDirectory()) {
bytes += getDirectorySize(file);
} else if (file.isFile()) {
bytes += file.length();
}
}
}
return bytes;
}
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
if (listener != null) {
listener.onMemoryInfoUpdate();
}
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (listener != null) {
listener.onFinishUpdating(taskKey);
}
}
private void refreshUI() {
long currentTime = System.currentTimeMillis();
if ((currentTime - lastRefreshTime) > UI_REFRESH_TIME_MS) {
lastRefreshTime = currentTime;
publishProgress();
}
}
}
public long getTotalUsedBytes() {
long total = 0;
if (memoryItems != null && memoryItems.size() > 0) {
for (DataStorageMemoryItem mi : memoryItems) {
total += mi.getUsedMemoryBytes();
}
return total;
}
return -1;
}
public static String getFormattedMemoryInfo(long bytes, String[] formatStrings) {
int type = 0;
double memory = (double) bytes / 1024;
while (memory > 1024 && type < formatStrings.length) {
++type;
memory = memory / 1024;
}
String formattedUsed = new DecimalFormat("#.##").format(memory);
return String.format(formatStrings[type], formattedUsed);
}
public interface UpdateMemoryInfoUIAdapter {
void onMemoryInfoUpdate();
void onFinishUpdating(String taskKey);
}
}

View file

@ -34,6 +34,7 @@ import net.osmand.plus.settings.backend.ApplicationMode.ApplicationModeBean;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.lang3.StringUtils;
import java.io.File; import java.io.File;
import java.util.List; import java.util.List;
@ -91,7 +92,11 @@ public class DuplicatesSettingsAdapter extends RecyclerView.Adapter<RecyclerView
String profileName = modeBean.userProfileName; String profileName = modeBean.userProfileName;
if (Algorithms.isEmpty(profileName)) { if (Algorithms.isEmpty(profileName)) {
ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null); ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null);
profileName = app.getString(appMode.getNameKeyResource()); if (appMode != null) {
profileName = appMode.toHumanString();
} else {
profileName = StringUtils.capitalize(modeBean.stringKey);
}
} }
itemHolder.title.setText(profileName); itemHolder.title.setText(profileName);
String routingProfile = ""; String routingProfile = "";

View file

@ -62,6 +62,7 @@ import net.osmand.util.Algorithms;
import net.osmand.view.ThreeStateCheckbox; import net.osmand.view.ThreeStateCheckbox;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.lang3.StringUtils;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -279,7 +280,11 @@ public class ExportItemsBottomSheet extends MenuBottomSheetDialogFragment {
String profileName = modeBean.userProfileName; String profileName = modeBean.userProfileName;
if (Algorithms.isEmpty(profileName)) { if (Algorithms.isEmpty(profileName)) {
ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null); ApplicationMode appMode = ApplicationMode.valueOfStringKey(modeBean.stringKey, null);
profileName = appMode.toHumanString(); if (appMode != null) {
profileName = appMode.toHumanString();
} else {
profileName = StringUtils.capitalize(modeBean.stringKey);
}
} }
builder.setTitle(profileName); builder.setTitle(profileName);

View file

@ -22,6 +22,8 @@ import net.osmand.plus.profiles.SelectProfileBottomSheet.DialogMode;
import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback; import net.osmand.plus.profiles.SelectProfileBottomSheet.OnSelectProfileCallback;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.datastorage.DataStorageHelper;
import net.osmand.plus.settings.datastorage.item.StorageItem;
import net.osmand.plus.settings.preferences.ListPreferenceEx; import net.osmand.plus.settings.preferences.ListPreferenceEx;
import net.osmand.plus.settings.preferences.SwitchPreferenceEx; import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
@ -181,7 +183,7 @@ public class GlobalSettingsFragment extends BaseSettingsFragment
externalStorageDir.setIcon(getActiveIcon(R.drawable.ic_action_folder)); externalStorageDir.setIcon(getActiveIcon(R.drawable.ic_action_folder));
DataStorageHelper holder = new DataStorageHelper(app); DataStorageHelper holder = new DataStorageHelper(app);
DataStorageMenuItem currentStorage = holder.getCurrentStorage(); StorageItem currentStorage = holder.getCurrentStorage();
long totalUsed = app.getSettings().OSMAND_USAGE_SPACE.get(); long totalUsed = app.getSettings().OSMAND_USAGE_SPACE.get();
if (totalUsed > 0) { if (totalUsed > 0) {
String[] usedMemoryFormats = new String[] { String[] usedMemoryFormats = new String[] {

View file

@ -890,8 +890,6 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
private void updateMenuState() { private void updateMenuState() {
if (menuType == TrackMenuType.OPTIONS) { if (menuType == TrackMenuType.OPTIONS) {
openMenuFullScreen(); openMenuFullScreen();
} else if (menuType == TrackMenuType.OVERVIEW) {
openMenuHeaderOnly();
} else { } else {
openMenuHalfScreen(); openMenuHalfScreen();
} }
@ -1130,7 +1128,9 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
if (mapActivity != null) { if (mapActivity != null) {
OsmandApplication app = mapActivity.getMyApplication(); OsmandApplication app = mapActivity.getMyApplication();
SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().selectGpxFile(result, true, false); SelectedGpxFile selectedGpxFile = app.getSelectedGpxHelper().selectGpxFile(result, true, false);
showInstance(mapActivity, selectedGpxFile, null); if (selectedGpxFile != null) {
showInstance(mapActivity, selectedGpxFile, null);
}
} }
if (progress != null && AndroidUtils.isActivityNotDestroyed(mapActivity)) { if (progress != null && AndroidUtils.isActivityNotDestroyed(mapActivity)) {
progress.dismiss(); progress.dismiss();
@ -1142,7 +1142,7 @@ public class TrackMenuFragment extends ContextMenuScrollFragment implements Card
} }
} }
public static boolean showInstance(@NonNull MapActivity mapActivity, SelectedGpxFile selectedGpxFile, @Nullable LatLon latLon) { public static boolean showInstance(@NonNull MapActivity mapActivity, @NonNull SelectedGpxFile selectedGpxFile, @Nullable LatLon latLon) {
try { try {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putInt(ContextMenuFragment.MENU_STATE_KEY, MenuState.HEADER_ONLY); args.putInt(ContextMenuFragment.MENU_STATE_KEY, MenuState.HEADER_ONLY);

View file

@ -1,10 +1,12 @@
package net.osmand.plus.wikipedia; package net.osmand.plus.wikipedia;
import android.app.Activity;
import android.content.Intent; import android.content.Intent;
import android.view.View; import android.view.View;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
@ -24,6 +26,8 @@ import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadActivityType; import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.DownloadIndexesThread; import net.osmand.plus.download.DownloadIndexesThread;
import net.osmand.plus.download.DownloadResources; import net.osmand.plus.download.DownloadResources;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard;
import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener;
import net.osmand.plus.poi.PoiFiltersHelper; import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.search.QuickSearchDialogFragment; import net.osmand.plus.search.QuickSearchDialogFragment;
@ -32,8 +36,9 @@ import net.osmand.plus.search.listitems.QuickSearchBannerListItem;
import net.osmand.plus.search.listitems.QuickSearchFreeBannerListItem; import net.osmand.plus.search.listitems.QuickSearchFreeBannerListItem;
import net.osmand.plus.settings.backend.ApplicationMode; import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings; import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.views.layers.DownloadedRegionsLayer;
import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.layers.DownloadedRegionsLayer;
import net.osmand.plus.wikimedia.WikiImageHelper;
import net.osmand.search.core.ObjectType; import net.osmand.search.core.ObjectType;
import net.osmand.search.core.SearchPhrase; import net.osmand.search.core.SearchPhrase;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -42,6 +47,7 @@ import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.WIKIPEDIA_ID; import static net.osmand.aidlapi.OsmAndCustomizationConstants.WIKIPEDIA_ID;
@ -91,11 +97,24 @@ public class WikipediaPlugin extends OsmandPlugin {
this.mapActivity = activity; this.mapActivity = activity;
} }
@Override
public void mapActivityResumeOnTop(MapActivity activity) {
this.mapActivity = activity;
}
@Override @Override
public void mapActivityPause(MapActivity activity) { public void mapActivityPause(MapActivity activity) {
this.mapActivity = null; this.mapActivity = null;
} }
@Override
public boolean init(@NonNull OsmandApplication app, Activity activity) {
if (activity instanceof MapActivity) {
mapActivity = (MapActivity) activity;
}
return true;
}
@Override @Override
protected void registerLayerContextMenuActions(OsmandMapTileView mapView, protected void registerLayerContextMenuActions(OsmandMapTileView mapView,
ContextMenuAdapter adapter, ContextMenuAdapter adapter,
@ -435,4 +454,25 @@ public class WikipediaPlugin extends OsmandPlugin {
} }
return false; return false;
} }
@Override
protected List<ImageCard> getContextMenuImageCards(@NonNull Map<String, String> params, @Nullable Map<String, String> additionalParams, @Nullable GetImageCardsListener listener) {
List<ImageCard> imageCards = new ArrayList<>();
if (mapActivity != null) {
if (additionalParams != null) {
String wikidataId = additionalParams.get(Amenity.WIKIDATA);
if (wikidataId != null) {
additionalParams.remove(Amenity.WIKIDATA);
WikiImageHelper.addWikidataImageCards(mapActivity, wikidataId, imageCards);
}
String wikimediaContent = additionalParams.get(Amenity.WIKIMEDIA_COMMONS);
if (wikimediaContent != null) {
additionalParams.remove(Amenity.WIKIMEDIA_COMMONS);
WikiImageHelper.addWikimediaImageCards(mapActivity, wikimediaContent, imageCards);
}
params.putAll(additionalParams);
}
}
return imageCards;
}
} }

View file

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Osmand-Nautical</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Osmand-ParkingPlugin</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Osmand-SRTMPlugin</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

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