Merge pull request #9204 from osmandapp/speed_cameras

Speed cameras
This commit is contained in:
vshcherb 2020-06-19 13:15:55 +02:00 committed by GitHub
commit 6270e202fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 433 additions and 100 deletions

View file

@ -694,10 +694,11 @@ public class BinaryMapPoiReaderAdapter {
StringBuilder retValue = new StringBuilder();
PoiCategory amenityType = null;
LinkedList<String> textTags = null;
boolean isForbidden = false;
while (true) {
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
if (amenityType == null && (tag > OsmandOdb.OsmAndPoiBoxDataAtom.CATEGORIES_FIELD_NUMBER || tag == 0)) {
if (amenityType == null && (tag > OsmandOdb.OsmAndPoiBoxDataAtom.CATEGORIES_FIELD_NUMBER || tag == 0) || isForbidden) {
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
return null;
}
@ -772,6 +773,7 @@ public class BinaryMapPoiReaderAdapter {
}
}
subtype = poiTypes.replaceDeprecatedSubtype(type, subtype);
isForbidden = poiTypes.isKeyNameForbidden(subtype);
if (req.poiTypeFilter == null || req.poiTypeFilter.accept(type, subtype)) {
if (amenityType == null) {
amenityType = type;

View file

@ -67,7 +67,6 @@ public abstract class AbstractPoiType {
return this instanceof PoiType && this.isAdditional();
}
public String getTranslation() {
if(translation == null) {
translation = registry.getTranslation(this);

View file

@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@ -34,6 +35,7 @@ public class MapPoiTypes {
private static final Log log = PlatformUtil.getLog(MapRenderingTypes.class);
private String resourceName;
private List<PoiCategory> categories = new ArrayList<PoiCategory>();
private Set<String> forbiddenKeyNames = new HashSet<>();
private PoiCategory otherCategory;
private PoiCategory otherMapCategory;
@ -945,4 +947,12 @@ public class MapPoiTypes {
return pat.isText();
}
}
public void setForbiddenKeyNames(Set<String> forbiddenKeyNames) {
this.forbiddenKeyNames = forbiddenKeyNames;
}
public boolean isKeyNameForbidden(String key) {
return forbiddenKeyNames.contains(key);
}
}

View file

@ -30,13 +30,14 @@ public class PoiFilter extends AbstractPoiType {
List<PoiType> npoiTypes = null;
Map<String, PoiType> nmap = null;
for (PoiType poiType : poiTypesToAdd.values()) {
if (!map.containsKey(poiType.getKeyName())) {
String keyName = poiType.getKeyName();
if (!map.containsKey(keyName) && !registry.isKeyNameForbidden(keyName)) {
if (npoiTypes == null) {
npoiTypes = new ArrayList<PoiType>(this.poiTypes);
nmap = new LinkedHashMap<>(map);
}
npoiTypes.add(poiType);
nmap.put(poiType.getKeyName(), poiType);
nmap.put(keyName, poiType);
}
}
if (npoiTypes != null) {
@ -46,6 +47,9 @@ public class PoiFilter extends AbstractPoiType {
}
public void addPoiType(PoiType type) {
if (registry.isKeyNameForbidden(type.keyName)) {
return;
}
if (!map.containsKey(type.getKeyName())) {
poiTypes.add(type);
map.put(type.getKeyName(), type);

View file

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="@dimen/content_padding">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:src="@drawable/img_speed_camera_warning" />
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/content_padding"
android:layout_marginBottom="@dimen/content_padding"
android:text="@string/speed_camera_pois"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/dialog_header_text_size"
osmand:typeface="@string/font_roboto_medium" />
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size"
tools:text="@string/speed_cameras_legal_descr" />
</LinearLayout>

View file

@ -11,6 +11,8 @@
Thx - Hardy
-->
<string name="shared_string_uninstall_and_restart">Uninstall and Restart</string>
<string name="speed_cameras_restart_descr">Restart is needed to completely delete speed camera data.</string>
<string name="item_deleted">%1$s deleted</string>
<string name="shared_string_bearing">Bearing</string>
<string name="quick_action_showhide_mapillary_descr">A toggle to show or hide the Mapillary layer on the map.</string>
@ -30,6 +32,16 @@
<string name="shared_string_tones">tones</string>
<string name="default_screen_timeout">Default screen timeout</string>
<string name="screen_timeout_descr">If \"%1$s\" is on, the activity time will depend on it.</string>
<string name="speed_cameras_alert">Speed cameras alerts in some countries is prohibited by the law.</string>
<string name="shared_string_uninstall">Uninstall</string>
<string name="keep_active">Keep active</string>
<string name="speed_cameras_legal_descr">In some countries or regions, the use of speed camera warning applications is prohibited by law.
\n\nYou need to make a choice depending on the law of your country.
\n\nSelect %1$s and you will receive alerts and warnings about speed cameras.
\n\nSelect %2$s. All data related to speed cameras: alerts, notifications, POIs will be deleted until OsmAnd is completely reinstalled.</string>
<string name="speed_camera_pois">Speed camera POIs</string>
<string name="shared_string_legal">Legal</string>
<string name="uninstall_speed_cameras">Uninstall speed cameras</string>
<string name="screen_timeout">Screen timeout</string>
<string name="delete_all_actions_message_q">Are you sure you want to irrevocably delete %d quick actions?</string>
<string name="shared_string_delete_all_q">Delete all?</string>

View file

@ -60,4 +60,16 @@
app:fragment="net.osmand.plus.settings.fragments.ProxySettingsFragment"
tools:icon="@drawable/ic_action_proxy" />
<PreferenceCategory
android:key="legal"
android:layout="@layout/preference_category_with_descr"
android:title="@string/shared_string_legal" />
<Preference
android:key="speed_cameras_uninstalled"
android:persistent="false"
android:layout="@layout/preference_with_descr"
android:title="@string/uninstall_speed_cameras"
tools:icon="@drawable/ic_speed_camera_disabled" />
</PreferenceScreen>

View file

@ -31,6 +31,14 @@
android:layout="@layout/preference_switch"
android:title="@string/show_cameras" />
<Preference
android:key="speed_cameras_uninstalled"
android:layout="@layout/preference_permission"
android:persistent="false"
android:summary="@string/read_more"
android:title="@string/speed_cameras_alert"
tools:icon="@drawable/ic_action_alert" />
<SwitchPreferenceCompat
android:key="show_tunnels"
android:layout="@layout/preference_switch"

View file

@ -49,6 +49,14 @@
android:layout="@layout/preference_switch"
android:title="@string/speak_cameras" />
<Preference
android:key="speed_cameras_uninstalled"
android:layout="@layout/preference_permission"
android:persistent="false"
android:summary="@string/read_more"
android:title="@string/speed_cameras_alert"
tools:icon="@drawable/ic_action_alert" />
<SwitchPreferenceCompat
android:key="speak_tunnels"
android:layout="@layout/preference_switch"

View file

@ -2,27 +2,20 @@ package net.osmand.access;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceViewHolder;
import net.osmand.AndroidUtils;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.access.AccessibilityMode;
import net.osmand.plus.access.RelativeDirectionStyle;
import net.osmand.plus.monitoring.OsmandMonitoringPlugin;
@ -215,23 +208,7 @@ public class AccessibilitySettingsFragment extends BaseSettingsFragment implemen
super.onBindPreferenceViewHolder(preference, holder);
String prefId = preference.getKey();
if (ACCESSIBILITY_OPTIONS.equals(prefId)) {
View selectableView = holder.itemView.findViewById(R.id.selectable_list_item);
if (selectableView != null) {
int color = AndroidUtils.getColorFromAttr(app, R.attr.activity_background_color);
int selectedColor = UiUtilities.getColorWithAlpha(getActiveProfileColor(), 0.3f);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
Drawable bgDrawable = getPaintedIcon(R.drawable.rectangle_rounded, color);
Drawable selectable = getPaintedIcon(R.drawable.ripple_rectangle_rounded, selectedColor);
Drawable[] layers = {bgDrawable, selectable};
AndroidUtils.setBackground(selectableView, new LayerDrawable(layers));
} else {
Drawable bgDrawable = getPaintedIcon(R.drawable.rectangle_rounded, color);
AndroidUtils.setBackground(selectableView, bgDrawable);
}
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) selectableView.getLayoutParams();
params.setMargins(params.leftMargin, AndroidUtils.dpToPx(app, 6), params.rightMargin, params.bottomMargin);
}
setupPrefRoundedBg(holder);
} else if (settings.ACCESSIBILITY_MODE.getId().equals(prefId)) {
ImageView imageView = (ImageView) holder.findViewById(android.R.id.icon);
if (imageView != null) {

View file

@ -302,6 +302,7 @@ public class AppInitializer implements IProgress {
}
private void initPoiTypes() {
app.poiTypes.setForbiddenKeyNames(app.osmandSettings.getForbiddenPoiKeyNames());
if (app.getAppPath(IndexConstants.SETTINGS_DIR + "poi_types.xml").exists()) {
app.poiTypes.init(app.getAppPath(IndexConstants.SETTINGS_DIR + "poi_types.xml").getAbsolutePath());
} else {

View file

@ -3,6 +3,7 @@ package net.osmand.plus;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
@ -52,12 +53,14 @@ import net.osmand.data.LatLon;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.views.DirectionDrawable;
import net.osmand.plus.widgets.TextViewEx;
import net.osmand.plus.widgets.style.CustomTypefaceSpan;
import org.apache.commons.logging.Log;
import java.util.ArrayList;
import java.util.List;
import gnu.trove.map.hash.TLongObjectHashMap;
import static net.osmand.plus.SimplePopUpMenuItemAdapter.SimplePopUpMenuItem;
@ -77,6 +80,7 @@ public class UiUtilities {
public enum DialogButtonType {
PRIMARY,
SECONDARY,
SECONDARY_HARMFUL,
STROKED
}
@ -623,6 +627,13 @@ public class UiUtilities {
AndroidUtils.setBackground(ctx, buttonView, nightMode, R.drawable.dlg_btn_secondary_light, R.drawable.dlg_btn_secondary_dark);
textAndIconColorResId = nightMode ? R.color.dlg_btn_secondary_text_dark : R.color.dlg_btn_secondary_text_light;
break;
case SECONDARY_HARMFUL:
if (v21) {
AndroidUtils.setBackground(ctx, buttonContainer, nightMode, R.drawable.ripple_solid_light, R.drawable.ripple_solid_dark);
}
AndroidUtils.setBackground(ctx, buttonView, nightMode, R.drawable.dlg_btn_secondary_light, R.drawable.dlg_btn_secondary_dark);
textAndIconColorResId = R.color.color_osm_edit_delete;
break;
case STROKED:
if (v21) {
AndroidUtils.setBackground(ctx, buttonContainer, nightMode, R.drawable.ripple_light, R.drawable.ripple_dark);
@ -672,22 +683,35 @@ public class UiUtilities {
}
}
public static SpannableString createSpannableString(@NonNull String text, @NonNull String textToStyle, @NonNull StyleSpan styleSpan) {
public static SpannableString createSpannableString(@NonNull String text, @NonNull StyleSpan styleSpan, @NonNull String... textToStyle) {
SpannableString spannable = new SpannableString(text);
for (String t : textToStyle) {
setSpan(spannable, styleSpan, text, t);
}
return spannable;
}
private static void setSpan(@NonNull SpannableString spannable, @NonNull Object styleSpan, @NonNull String text, @NonNull String t) {
try {
int startIndex = text.indexOf(textToStyle);
int startIndex = text.indexOf(t);
spannable.setSpan(
styleSpan,
startIndex,
startIndex + textToStyle.length(),
startIndex + t.length(),
Spanned.SPAN_INCLUSIVE_INCLUSIVE);
return spannable;
} catch (RuntimeException e) {
LOG.error("Error trying to find index of " + textToStyle + " " + e);
return spannable;
LOG.error("Error trying to find index of " + t + " " + e);
}
}
public static SpannableString createCustomFontSpannable(@NonNull Typeface typeface, @NonNull String text, @NonNull String... textToStyle) {
SpannableString spannable = new SpannableString(text);
for (String s : textToStyle) {
setSpan(spannable, new CustomTypefaceSpan(typeface), text, s);
}
return spannable;
}
public static ListPopupWindow createListPopupWindow(Context themedCtx,
View v, int minWidth,
List<SimplePopUpMenuItem> items,

View file

@ -37,6 +37,7 @@ import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect;
import net.osmand.data.RotatedTileBox;
import net.osmand.map.ITileSource;
import net.osmand.plus.dialogs.SpeedCamerasBottomSheet;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.ContextMenuAdapter;
import net.osmand.plus.ContextMenuAdapter.ItemClickListener;
@ -569,6 +570,9 @@ public class MapActivityActions implements DialogProvider {
if (targets.hasTooLongDistanceToNavigate()) {
app.showToastMessage(R.string.route_is_too_long_v2);
}
if (!settings.SPEED_CAMERAS_ALERT_SHOWED.get()) {
SpeedCamerasBottomSheet.showInstance(mapActivity.getSupportFragmentManager(), null);
}
}
public void recalculateRoute(boolean showDialog) {

View file

@ -6,7 +6,6 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
@ -14,7 +13,6 @@ import android.os.Build;
import android.os.Bundle;
import android.os.StatFs;
import android.text.SpannableString;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
@ -28,7 +26,6 @@ import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmAndAppCustomization;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.profiles.SelectCopyAppModeBottomSheet;
@ -466,21 +463,7 @@ public class MultimediaNotesFragment extends BaseSettingsFragment implements Cop
super.onBindPreferenceViewHolder(preference, holder);
String prefId = preference.getKey();
if (CAMERA_PERMISSION.equals(prefId)) {
View selectableView = holder.itemView.findViewById(R.id.selectable_list_item);
if (selectableView != null) {
int color = AndroidUtils.getColorFromAttr(app, R.attr.activity_background_color);
int selectedColor = UiUtilities.getColorWithAlpha(getActiveProfileColor(), 0.3f);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
Drawable bgDrawable = getPaintedIcon(R.drawable.rectangle_rounded, color);
Drawable selectable = getPaintedIcon(R.drawable.ripple_rectangle_rounded, selectedColor);
Drawable[] layers = {bgDrawable, selectable};
AndroidUtils.setBackground(selectableView, new LayerDrawable(layers));
} else {
Drawable bgDrawable = getPaintedIcon(R.drawable.rectangle_rounded, color);
AndroidUtils.setBackground(selectableView, bgDrawable);
}
}
setupPrefRoundedBg(holder);
} else if (OPEN_NOTES_DESCRIPTION.equals(prefId)) {
int minHeight = getResources().getDimensionPixelSize(R.dimen.bottom_sheet_list_item_height);
holder.itemView.setMinimumHeight(minHeight);

View file

@ -0,0 +1,92 @@
package net.osmand.plus.dialogs;
import android.os.Bundle;
import android.text.SpannableString;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
import net.osmand.plus.base.bottomsheetmenu.BaseBottomSheetItem;
import net.osmand.plus.helpers.FontCache;
import net.osmand.plus.settings.backend.OsmandSettings;
public class SpeedCamerasBottomSheet extends MenuBottomSheetDialogFragment {
public static final String TAG = SpeedCamerasBottomSheet.class.getName();
public static final String SPEED_CAMERA_KEY_NAME = "speed_camera";
private OsmandApplication app;
private OsmandSettings settings;
public static void showInstance(@NonNull FragmentManager fm, @Nullable Fragment targetFragment) {
if (!fm.isStateSaved()) {
SpeedCamerasBottomSheet bottomSheet = new SpeedCamerasBottomSheet();
bottomSheet.setTargetFragment(targetFragment, 0);
bottomSheet.show(fm, TAG);
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = requiredMyApplication();
settings = app.getSettings();
}
@Override
public void createMenuItems(Bundle savedInstanceState) {
View root = UiUtilities.getInflater(app, nightMode).inflate(R.layout.bottom_sheet_speed_cameras, null);
((ImageView) root.findViewById(R.id.icon)).setImageDrawable(app.getUIUtilities().getIcon(R.drawable.img_speed_camera_warning));
((TextView) root.findViewById(R.id.description)).setText(getDescriptionText());
items.add(new BaseBottomSheetItem.Builder().setCustomView(root).create());
}
@Override
protected void onRightBottomButtonClick() {
setDialogShowed();
dismiss();
}
@Override
protected void onDismissButtonClickAction() {
FragmentManager fm = getFragmentManager();
if (fm != null) {
SpeedCamerasUninstallRestartBottomSheet.showInstance(fm);
}
setDialogShowed();
}
@Override
protected int getDismissButtonTextId() {
return R.string.shared_string_uninstall;
}
@Override
protected int getRightBottomButtonTextId() {
return R.string.keep_active;
}
@Override
protected UiUtilities.DialogButtonType getRightBottomButtonType() {
return getDismissButtonType();
}
private SpannableString getDescriptionText() {
String keepActive = getString(R.string.keep_active);
String uninstall = getString(R.string.shared_string_uninstall);
String text = getString(R.string.speed_cameras_legal_descr, keepActive, uninstall);
return UiUtilities.createCustomFontSpannable(FontCache.getRobotoMedium(app), text, keepActive, uninstall);
}
private void setDialogShowed() {
app.getSettings().SPEED_CAMERAS_ALERT_SHOWED.set(true);
}
}

View file

@ -0,0 +1,64 @@
package net.osmand.plus.dialogs;
import android.app.Activity;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentManager;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities.DialogButtonType;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.base.MenuBottomSheetDialogFragment;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.LongDescriptionItem;
import net.osmand.plus.base.bottomsheetmenu.simpleitems.TitleItem;
import net.osmand.plus.settings.backend.OsmandSettings;
public class SpeedCamerasUninstallRestartBottomSheet extends MenuBottomSheetDialogFragment {
public static final String TAG = SpeedCamerasUninstallRestartBottomSheet.class.getSimpleName();
public static void showInstance(@NonNull FragmentManager fm) {
if (!fm.isStateSaved()) {
SpeedCamerasUninstallRestartBottomSheet bottomSheet = new SpeedCamerasUninstallRestartBottomSheet();
bottomSheet.show(fm, TAG);
}
}
@Override
public void createMenuItems(Bundle savedInstanceState) {
items.add(new TitleItem(getString(R.string.uninstall_speed_cameras)));
items.add(new LongDescriptionItem(getString(R.string.speed_cameras_restart_descr)));
}
@Override
protected int getDismissButtonTextId() {
return R.string.shared_string_cancel;
}
@Override
protected int getRightBottomButtonTextId() {
return R.string.shared_string_uninstall_and_restart;
}
@Override
protected DialogButtonType getRightBottomButtonType() {
return DialogButtonType.SECONDARY_HARMFUL;
}
@Override
protected void onRightBottomButtonClick() {
OsmandApplication app = requiredMyApplication();
OsmandSettings settings = app.getSettings();
settings.SPEED_CAMERAS_UNINSTALLED.set(true);
settings.SPEAK_SPEED_CAMERA.set(false);
settings.SHOW_CAMERAS.set(false);
Activity activity = getActivity();
if (activity instanceof MapActivity) {
MapActivity.doRestart(activity);
} else {
android.os.Process.killProcess(android.os.Process.myPid());
}
}
}

View file

@ -428,6 +428,9 @@ public class SearchHistoryHelper {
do {
String name = query.getString(0);
PointDescription p = PointDescription.deserializeFromString(name, new LatLon(query.getDouble(1), query.getDouble(2)));
if (context.getPoiTypes().isKeyNameForbidden(p.getName())){
query.moveToNext();
}
HistoryEntry e = new HistoryEntry(query.getDouble(1), query.getDouble(2),
p);
long time = query.getLong(3);

View file

@ -6,6 +6,7 @@ import android.content.DialogInterface;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.StyleSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
@ -90,7 +91,7 @@ public class InputZoomLevelsBottomSheet extends MenuBottomSheetDialogFragment {
String mapSource = getString(R.string.map_source);
String overlayUnderlay = getString(R.string.pref_overlay);
String dialogDesr = getString(dialogDescrRes, mapSource, overlayUnderlay);
dialogDescrTv.setText(createSpannableString(dialogDesr, mapSource, overlayUnderlay));
dialogDescrTv.setText(UiUtilities.createCustomFontSpannable(FontCache.getRobotoMedium(app), dialogDesr, mapSource, overlayUnderlay));
} else {
dialogDescrTv.setText(getString(dialogDescrRes));
}

View file

@ -890,7 +890,7 @@ public class QuickActionListFragment extends BaseOsmAndFragment
String message = String.format(ctx.getString(
R.string.quick_actions_delete_text), actionName);
SpannableString styledMessage = UiUtilities.createSpannableString(
message, actionName, new StyleSpan(Typeface.BOLD));
message, new StyleSpan(Typeface.BOLD), actionName);
ConfirmationBottomSheet.showInstance(ctx.getSupportFragmentManager(), target,
ctx.getString(R.string.quick_actions_delete), styledMessage,

View file

@ -1262,7 +1262,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
//show "Apply to all profiles" SnackBar
String modeName = appMode.toHumanString();
String text = app.getString(R.string.changes_applied_to_profile, modeName);
SpannableString message = UiUtilities.createSpannableString(text, modeName, new StyleSpan(Typeface.BOLD));
SpannableString message = UiUtilities.createSpannableString(text, new StyleSpan(Typeface.BOLD), modeName);
Snackbar snackbar = Snackbar.make(containerView, message, Snackbar.LENGTH_LONG)
.setAction(R.string.apply_to_all_profiles, new View.OnClickListener() {
@Override

View file

@ -29,6 +29,7 @@ import net.osmand.plus.poi.NominatimPoiFilter;
import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.resources.ResourceManager.ResourceListener;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
import net.osmand.search.SearchUICore;
@ -65,8 +66,9 @@ public class QuickSearchHelper implements ResourceListener {
public QuickSearchHelper(OsmandApplication app) {
this.app = app;
core = new SearchUICore(app.getPoiTypes(), app.getSettings().MAP_PREFERRED_LOCALE.get(),
app.getSettings().MAP_TRANSLITERATE_NAMES.get());
OsmandSettings settings = app.getSettings();
core = new SearchUICore(app.getPoiTypes(), settings.MAP_PREFERRED_LOCALE.get(),
settings.MAP_TRANSLITERATE_NAMES.get());
app.getResourceManager().addResourceListener(this);
}

View file

@ -35,6 +35,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

View file

@ -74,6 +74,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@ -87,6 +88,7 @@ import java.util.StringTokenizer;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.CONFIGURE_MAP_ITEM_ID_SCHEME;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_ITEM_ID_SCHEME;
import static net.osmand.aidlapi.OsmAndCustomizationConstants.MAP_CONTEXT_MENU_ACTIONS;
import static net.osmand.plus.dialogs.SpeedCamerasBottomSheet.SPEED_CAMERA_KEY_NAME;
public class OsmandSettings {
@ -2108,6 +2110,17 @@ public class OsmandSettings {
public final OsmandPreference<Boolean> SPEAK_SPEED_CAMERA = new BooleanPreference("speak_cameras", false).makeProfile().cache();
public final OsmandPreference<Boolean> SPEAK_TUNNELS = new BooleanPreference("speak_tunnels", false).makeProfile().cache();
public final OsmandPreference<Boolean> SPEED_CAMERAS_UNINSTALLED = new BooleanPreference("speed_cameras_uninstalled", false).makeGlobal();
public final OsmandPreference<Boolean> SPEED_CAMERAS_ALERT_SHOWED = new BooleanPreference("speed_cameras_alert_showed", false).makeGlobal();
public Set<String> getForbiddenPoiKeyNames() {
Set<String> keyNames = new HashSet<>();
if (SPEED_CAMERAS_UNINSTALLED.get()) {
keyNames.add(SPEED_CAMERA_KEY_NAME);
}
return keyNames;
}
public final OsmandPreference<Boolean> ANNOUNCE_WPT = new BooleanPreference("announce_wpt", true) {
@Override
protected boolean setValue(Object prefs, Boolean val) {

View file

@ -16,6 +16,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.ColorInt;
@ -923,14 +924,40 @@ public abstract class BaseSettingsFragment extends PreferenceFragmentCompat impl
}
}
protected void applyPreferenceWithSnackBar(final String prefId, final Serializable newValue) {
public void setupSpeedCamerasAlert() {
Preference speedCamerasAlert = findPreference(settings.SPEED_CAMERAS_UNINSTALLED.getId());
speedCamerasAlert.setIcon(getContentIcon(R.drawable.ic_action_alert));
speedCamerasAlert.setVisible(!settings.SPEED_CAMERAS_UNINSTALLED.get());
}
public void setupPrefRoundedBg(PreferenceViewHolder holder) {
View selectableView = holder.itemView.findViewById(R.id.selectable_list_item);
if (selectableView != null) {
int color = AndroidUtils.getColorFromAttr(app, R.attr.activity_background_color);
int selectedColor = UiUtilities.getColorWithAlpha(getActiveProfileColor(), 0.3f);
Drawable bgDrawable = getPaintedIcon(R.drawable.rectangle_rounded, color);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
Drawable selectable = getPaintedIcon(R.drawable.ripple_rectangle_rounded, selectedColor);
Drawable[] layers = {bgDrawable, selectable};
AndroidUtils.setBackground(selectableView, new LayerDrawable(layers));
} else {
AndroidUtils.setBackground(selectableView, bgDrawable);
}
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) selectableView.getLayoutParams();
params.setMargins(params.leftMargin, AndroidUtils.dpToPx(app, 6), params.rightMargin, params.bottomMargin);
}
}
protected void applyPreferenceWithSnackBar(final String prefId,
final Serializable newValue) {
onApplyPreferenceChange(prefId, false, newValue);
updateSetting(prefId);
View containerView = getView();
if (containerView != null) {
String modeName = appMode.toHumanString();
String text = app.getString(R.string.changes_applied_to_profile, modeName);
SpannableString message = UiUtilities.createSpannableString(text, modeName, new StyleSpan(Typeface.BOLD));
SpannableString message = UiUtilities.createSpannableString(text, new StyleSpan(Typeface.BOLD), modeName);
Snackbar snackbar = Snackbar.make(containerView, message, Snackbar.LENGTH_LONG)
.setAction(R.string.apply_to_all_profiles, new View.OnClickListener() {
@Override

View file

@ -7,6 +7,7 @@ import android.widget.ImageView;
import androidx.fragment.app.FragmentManager;
import androidx.preference.Preference;
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreferenceCompat;
@ -14,18 +15,22 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.SettingsGeneralActivity;
import net.osmand.plus.dialogs.SendAnalyticsBottomSheetDialogFragment;
import net.osmand.plus.dialogs.SendAnalyticsBottomSheetDialogFragment.OnSendAnalyticsPrefsUpdate;
import net.osmand.plus.dialogs.SpeedCamerasBottomSheet;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.settings.preferences.ListPreferenceEx;
import net.osmand.plus.settings.preferences.SwitchPreferenceEx;
public class GlobalSettingsFragment extends BaseSettingsFragment implements SendAnalyticsBottomSheetDialogFragment.OnSendAnalyticsPrefsUpdate, OnPreferenceChanged {
public class GlobalSettingsFragment extends BaseSettingsFragment
implements OnSendAnalyticsPrefsUpdate, OnPreferenceChanged {
public static final String TAG = GlobalSettingsFragment.class.getSimpleName();
private static final String SEND_ANONYMOUS_DATA_PREF_ID = "send_anonymous_data";
private static final String DIALOGS_AND_NOTIFICATIONS_PREF_ID = "dialogs_and_notifications";
private static final String LEGAL_CATEGORY_ID = "legal";
@Override
protected void setupPreferences() {
@ -36,6 +41,8 @@ public class GlobalSettingsFragment extends BaseSettingsFragment implements Send
setupSendAnonymousDataPref();
setupDialogsAndNotificationsPref();
setupEnableProxyPref();
setupLegalCategory();
setupUninstallSpeedCamerasPref();
}
@Override
@ -100,6 +107,9 @@ public class GlobalSettingsFragment extends BaseSettingsFragment implements Send
app.checkPreferredLocale();
app.restartApp(activity);
}
} else if (prefId.equals(settings.SPEED_CAMERAS_UNINSTALLED.getId())) {
setupLegalCategory();
setupUninstallSpeedCamerasPref();
}
}
@ -108,6 +118,18 @@ public class GlobalSettingsFragment extends BaseSettingsFragment implements Send
setupSendAnonymousDataPref();
}
@Override
public boolean onPreferenceClick(Preference preference) {
String prefId = preference.getKey();
if (settings.SPEED_CAMERAS_UNINSTALLED.getId().equals(prefId)) {
FragmentManager fm = getFragmentManager();
if (fm != null) {
SpeedCamerasBottomSheet.showInstance(fm, this);
}
}
return super.onPreferenceClick(preference);
}
private void setupDefaultAppModePref() {
OsmandApplication app = getMyApplication();
if (app == null) {
@ -191,4 +213,15 @@ public class GlobalSettingsFragment extends BaseSettingsFragment implements Send
SwitchPreferenceEx enableProxy = (SwitchPreferenceEx) findPreference(settings.ENABLE_PROXY.getId());
enableProxy.setIcon(getPersistentPrefIcon(R.drawable.ic_action_proxy));
}
private void setupLegalCategory() {
PreferenceCategory legalCategory = (PreferenceCategory) findPreference(LEGAL_CATEGORY_ID);
legalCategory.setVisible(!settings.SPEED_CAMERAS_UNINSTALLED.get());
}
private void setupUninstallSpeedCamerasPref() {
Preference uninstallSpeedCameras = (Preference) findPreference(settings.SPEED_CAMERAS_UNINSTALLED.getId());
uninstallSpeedCameras.setIcon(getActiveIcon(R.drawable.ic_speed_camera_disabled));
uninstallSpeedCameras.setVisible(!settings.SPEED_CAMERAS_UNINSTALLED.get());
}
}

View file

@ -77,8 +77,7 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
recyclerView = root.findViewById(R.id.list);
description.setText(UiUtilities.createSpannableString(
String.format(getString(R.string.import_complete_description), fileName),
fileName,
new StyleSpan(Typeface.BOLD)
new StyleSpan(Typeface.BOLD), fileName
));
btnClose.setOnClickListener(new View.OnClickListener() {
@Override

View file

@ -257,8 +257,7 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
toolbarLayout.setTitle(getString(R.string.shared_string_importing));
description.setText(UiUtilities.createSpannableString(
String.format(getString(R.string.importing_from), file.getName()),
file.getName(),
new StyleSpan(Typeface.BOLD)
new StyleSpan(Typeface.BOLD), file.getName()
));
progressBar.setVisibility(View.VISIBLE);
list.setVisibility(View.GONE);

View file

@ -234,8 +234,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
toolbarLayout.setTitle(getString(toolbarTitleRes));
description.setText(UiUtilities.createSpannableString(
String.format(getString(descriptionRes), fileName),
fileName,
new StyleSpan(Typeface.BOLD)
new StyleSpan(Typeface.BOLD), fileName
));
buttonsContainer.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);

View file

@ -15,13 +15,15 @@ import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreferenceCompat;
import net.osmand.AndroidUtils;
import net.osmand.plus.dialogs.SpeedCamerasBottomSheet;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.R;
import net.osmand.plus.UiUtilities;
import static net.osmand.plus.UiUtilities.CompoundButtonType.TOOLBAR;
public class ScreenAlertsFragment extends BaseSettingsFragment {
public class ScreenAlertsFragment extends BaseSettingsFragment implements OnPreferenceChanged {
public static final String TAG = ScreenAlertsFragment.class.getSimpleName();
@ -33,16 +35,16 @@ public class ScreenAlertsFragment extends BaseSettingsFragment {
Preference showRoutingAlarmsInfo = findPreference(SHOW_ROUTING_ALARMS_INFO);
SwitchPreferenceCompat showTrafficWarnings = (SwitchPreferenceCompat) findPreference(settings.SHOW_TRAFFIC_WARNINGS.getId());
SwitchPreferenceCompat showPedestrian = (SwitchPreferenceCompat) findPreference(settings.SHOW_PEDESTRIAN.getId());
SwitchPreferenceCompat showCameras = (SwitchPreferenceCompat) findPreference(settings.SHOW_CAMERAS.getId());
SwitchPreferenceCompat showTunnels = (SwitchPreferenceCompat) findPreference(settings.SHOW_TUNNELS.getId());
showRoutingAlarmsInfo.setIcon(getContentIcon(R.drawable.ic_action_info_dark));
showTrafficWarnings.setIcon(getIcon(R.drawable.list_warnings_traffic_calming));
showPedestrian.setIcon(getIcon(R.drawable.list_warnings_pedestrian));
showCameras.setIcon(getIcon(R.drawable.list_warnings_speed_camera));
showTunnels.setIcon(getIcon(R.drawable.list_warnings_tunnel));
setupScreenAlertsImage();
setupShowCamerasPref();
setupSpeedCamerasAlert();
enableDisablePreferences(settings.SHOW_ROUTING_ALARMS.getModeValue(getSelectedAppMode()));
}
@ -103,6 +105,8 @@ public class ScreenAlertsFragment extends BaseSettingsFragment {
deviceImage.setImageDrawable(getDeviceImage());
warningIcon.setImageDrawable(getWarningIcon());
} else if (settings.SPEED_CAMERAS_UNINSTALLED.getId().equals(key)) {
setupPrefRoundedBg(holder);
}
}
}
@ -113,10 +117,20 @@ public class ScreenAlertsFragment extends BaseSettingsFragment {
Preference routeParametersImage = findPreference(SCREEN_ALERTS_IMAGE);
updatePreference(routeParametersImage);
}
if (settings.SPEED_CAMERAS_UNINSTALLED.getId().equals(preference.getKey())) {
SpeedCamerasBottomSheet.showInstance(requireActivity().getSupportFragmentManager(), this);
}
return super.onPreferenceClick(preference);
}
@Override
public void onPreferenceChanged(String prefId) {
if (prefId.equals(settings.SPEED_CAMERAS_UNINSTALLED.getId())) {
setupShowCamerasPref();
setupSpeedCamerasAlert();
}
}
private void setupScreenAlertsImage() {
Preference routeParametersImage = findPreference(SCREEN_ALERTS_IMAGE);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
@ -144,4 +158,10 @@ public class ScreenAlertsFragment extends BaseSettingsFragment {
return null;
}
private void setupShowCamerasPref() {
SwitchPreferenceCompat showCameras = (SwitchPreferenceCompat) findPreference(settings.SHOW_CAMERAS.getId());
showCameras.setIcon(getIcon(R.drawable.list_warnings_speed_camera));
showCameras.setVisible(!settings.SPEED_CAMERAS_UNINSTALLED.get());
}
}

View file

@ -1,8 +1,6 @@
package net.osmand.plus.settings.fragments;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@ -12,7 +10,6 @@ import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.SwitchCompat;
import androidx.core.content.ContextCompat;
import androidx.preference.Preference;
@ -20,6 +17,7 @@ import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreferenceCompat;
import net.osmand.AndroidUtils;
import net.osmand.plus.dialogs.SpeedCamerasBottomSheet;
import net.osmand.plus.settings.backend.ApplicationMode;
import net.osmand.plus.settings.backend.OsmandSettings;
import net.osmand.plus.R;
@ -37,7 +35,7 @@ import static net.osmand.plus.settings.backend.OsmandSettings.VOICE_PROVIDER_NOT
import static net.osmand.plus.UiUtilities.CompoundButtonType.TOOLBAR;
import static net.osmand.plus.activities.SettingsNavigationActivity.MORE_VALUE;
public class VoiceAnnouncesFragment extends BaseSettingsFragment {
public class VoiceAnnouncesFragment extends BaseSettingsFragment implements OnPreferenceChanged {
public static final String TAG = VoiceAnnouncesFragment.class.getSimpleName();
@ -100,6 +98,8 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment {
setupInterruptMusicPref();
}
enableDisablePreferences(!settings.VOICE_MUTE.getModeValue(getSelectedAppMode()));
setupSpeakCamerasPref();
setupSpeedCamerasAlert();
}
private void setupSpeedLimitExceedPref() {
@ -209,29 +209,6 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment {
getPreferenceScreen().addPreference(interruptMusicPref);
}
public void confirmSpeedCamerasDlg() {
Context ctx = getContext();
if (ctx == null) {
return;
}
AlertDialog.Builder bld = new AlertDialog.Builder(UiUtilities.getThemedContext(ctx, isNightMode()));
bld.setMessage(R.string.confirm_usage_speed_cameras);
bld.setPositiveButton(R.string.shared_string_yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
onConfirmPreferenceChange(
settings.SPEAK_SPEED_CAMERA.getId(), true, ApplyQueryType.SNACK_BAR);
SwitchPreferenceCompat speakSpeedCamera = (SwitchPreferenceCompat) findPreference(settings.SPEAK_SPEED_CAMERA.getId());
if (speakSpeedCamera != null) {
speakSpeedCamera.setChecked(true);
}
}
});
bld.setNegativeButton(R.string.shared_string_cancel, null);
bld.show();
}
private void updateMenu() {
MapActivity mapActivity = getMapActivity();
if (mapActivity != null) {
@ -252,6 +229,8 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment {
Object currentValue = ((ListPreferenceEx) preference).getValue();
imageView.setEnabled(preference.isEnabled() && !OsmandSettings.VOICE_PROVIDER_NOT_USE.equals(currentValue));
}
} else if (settings.SPEED_CAMERAS_UNINSTALLED.getId().equals(preference.getKey())) {
setupPrefRoundedBg(holder);
}
}
@ -275,8 +254,8 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment {
}
if (prefId.equals(settings.SPEAK_SPEED_CAMERA.getId())) {
if (!settings.SPEAK_SPEED_CAMERA.getModeValue(selectedMode)) {
confirmSpeedCamerasDlg();
return false;
return onConfirmPreferenceChange(
settings.SPEAK_SPEED_CAMERA.getId(), true, ApplyQueryType.SNACK_BAR);
} else {
return onConfirmPreferenceChange(
settings.SPEAK_SPEED_CAMERA.getId(), false, ApplyQueryType.SNACK_BAR);
@ -313,4 +292,25 @@ public class VoiceAnnouncesFragment extends BaseSettingsFragment {
super.onApplyPreferenceChange(prefId, applyToAllProfiles, newValue);
}
}
@Override
public boolean onPreferenceClick(Preference preference) {
if (settings.SPEED_CAMERAS_UNINSTALLED.getId().equals(preference.getKey())) {
SpeedCamerasBottomSheet.showInstance(requireActivity().getSupportFragmentManager(), this);
}
return super.onPreferenceClick(preference);
}
@Override
public void onPreferenceChanged(String prefId) {
if (prefId.equals(settings.SPEED_CAMERAS_UNINSTALLED.getId())) {
setupSpeakCamerasPref();
setupSpeedCamerasAlert();
}
}
private void setupSpeakCamerasPref() {
SwitchPreferenceCompat showCameras = (SwitchPreferenceCompat) findPreference(settings.SPEAK_SPEED_CAMERA.getId());
showCameras.setVisible(!settings.SPEED_CAMERAS_UNINSTALLED.get());
}
}