diff --git a/OsmAnd/assets/voice/zh-tts/ttsconfig.p b/OsmAnd/assets/voice/zh-tts/ttsconfig.p
index 04afb348a9..2003c27e0d 100644
--- a/OsmAnd/assets/voice/zh-tts/ttsconfig.p
+++ b/OsmAnd/assets/voice/zh-tts/ttsconfig.p
@@ -1,84 +1,84 @@
-:- op('==', xfy, 500).
-version(101).
-language(zh).
-
-% before each announcement (beep)
-preamble - [].
-
-
-%% TURNS
-turn('left', ['左轉 ']).
-turn('left_sh', ['向左急轉 ']).
-turn('left_sl', ['稍向左轉 ']).
-turn('right', ['右轉 ']).
-turn('right_sh', ['向右急轉 ']).
-turn('right_sl', ['稍向右轉 ']).
-
-prepare_turn(Turn, Dist) == ['請準備 ', D, ' 後 ', M] :- distance(Dist) == D, turn(Turn, M).
-turn(Turn, Dist) == [D, ' 後 ',M] :- distance(Dist) == D, turn(Turn, M).
-turn(Turn) == M :- turn(Turn, M).
-
-prepare_make_ut(Dist) == ['請準備', D, ' 後迴轉 '] :- distance(Dist) == D.
-make_ut(Dist) == [D, ' 後請迴轉'] :- distance(Dist) == D.
-make_ut == ['請迴轉 '].
-make_ut_wp == ['可能的話, 請迴轉 '].
-
-prepare_roundabout(Dist) == ['請準備', D,' 後進入圓環 '] :- distance(Dist) == D.
-roundabout(Dist, _Angle, Exit) == [D, ' 後進入圓環, 然後在 ', E, ' 出口離開'] :- distance(Dist) == D, nth(Exit, E).
-roundabout(_Angle, Exit) == ['在 ', E, ' 出口離開'] :- nth(Exit, E).
-
-go_ahead == ['直直往前開 '].
-go_ahead(Dist) == ['沿著馬路往前 ', D]:- distance(Dist) == D.
-
-and_arrive_destination == ['然後可達終點 '].
-
-then == ['然後 '].
-reached_destination == ['抵達終點 '].
-bear_right == ['靠右 '].
-bear_left == ['靠左 '].
-
-route_new_calc(Dist) == ['路程有 ', D, ' 遠'] :- distance(Dist) == D.
-route_recalc(Dist) == ['重新計算路程, 距離有 ', D] :- distance(Dist) == D.
-
-location_lost == ['接收不到 g p s 信號 '].
-
-
-%%
-nth(1, '第一個 ').
-nth(2, '第二個 ').
-nth(3, '第三個 ').
-nth(4, '第四個 ').
-nth(5, '第五個 ').
-nth(6, '第六個 ').
-nth(7, '第七個 ').
-nth(8, '第八個 ').
-nth(9, '第九個 ').
-nth(10, '第十個 ').
-nth(11, '第十一個 ').
-nth(12, '第十二個 ').
-nth(13, '第十三個 ').
-nth(14, '第十四個 ').
-nth(15, '第十五個 ').
-nth(16, '第十六個 ').
-nth(17, '第十七個 ').
-
-
-%%% distance measure
-distance(Dist) == [ X, ' 公尺'] :- Dist < 100, D is round(Dist/10)*10, num_atom(D, X).
-distance(Dist) == [ X, ' 公尺'] :- Dist < 1000, D is round(2*Dist/100)*50, num_atom(D, X).
-distance(Dist) == ['約 1 公里 '] :- Dist < 1500.
-distance(Dist) == ['約 ', X, ' 公里 '] :- Dist < 10000, D is round(Dist/1000), num_atom(D, X).
-distance(Dist) == [ X, ' 公里 '] :- D is round(Dist/1000), num_atom(D, X).
-
-
-%% resolve command main method
-%% if you are familar with Prolog you can input specific to the whole mechanism,
-%% by adding exception cases.
-flatten(X, Y) :- flatten(X, [], Y), !.
-flatten([], Acc, Acc).
-flatten([X|Y], Acc, Res):- flatten(Y, Acc, R), flatten(X, R, Res).
-flatten(X, Acc, [X|Acc]).
-
-resolve(X, Y) :- resolve_impl(X,Z), flatten(Z, Y).
-resolve_impl([],[]).
+:- op('==', xfy, 500).
+version(101).
+language(zh).
+
+% before each announcement (beep)
+preamble - [].
+
+
+%% TURNS
+turn('left', ['左轉 ']).
+turn('left_sh', ['向左急轉 ']).
+turn('left_sl', ['稍向左轉 ']).
+turn('right', ['右轉 ']).
+turn('right_sh', ['向右急轉 ']).
+turn('right_sl', ['稍向右轉 ']).
+
+prepare_turn(Turn, Dist) == ['請準備 ', D, ' 後 ', M] :- distance(Dist) == D, turn(Turn, M).
+turn(Turn, Dist) == [D, ' 後 ',M] :- distance(Dist) == D, turn(Turn, M).
+turn(Turn) == M :- turn(Turn, M).
+
+prepare_make_ut(Dist) == ['請準備', D, ' 後迴轉 '] :- distance(Dist) == D.
+make_ut(Dist) == [D, ' 後請迴轉'] :- distance(Dist) == D.
+make_ut == ['請迴轉 '].
+make_ut_wp == ['可能的話, 請迴轉 '].
+
+prepare_roundabout(Dist) == ['請準備', D,' 後進入圓環 '] :- distance(Dist) == D.
+roundabout(Dist, _Angle, Exit) == [D, ' 後進入圓環, 然後在 ', E, ' 出口離開'] :- distance(Dist) == D, nth(Exit, E).
+roundabout(_Angle, Exit) == ['在 ', E, ' 出口離開'] :- nth(Exit, E).
+
+go_ahead == ['直直往前開 '].
+go_ahead(Dist) == ['沿著馬路往前 ', D]:- distance(Dist) == D.
+
+and_arrive_destination == ['然後可達終點 '].
+
+then == ['然後 '].
+reached_destination == ['抵達終點 '].
+bear_right == ['靠右 '].
+bear_left == ['靠左 '].
+
+route_new_calc(Dist) == ['路程有 ', D, ' 遠'] :- distance(Dist) == D.
+route_recalc(Dist) == ['重新計算路程, 距離有 ', D] :- distance(Dist) == D.
+
+location_lost == ['接收不到 g p s 信號 '].
+
+
+%%
+nth(1, '第一個 ').
+nth(2, '第二個 ').
+nth(3, '第三個 ').
+nth(4, '第四個 ').
+nth(5, '第五個 ').
+nth(6, '第六個 ').
+nth(7, '第七個 ').
+nth(8, '第八個 ').
+nth(9, '第九個 ').
+nth(10, '第十個 ').
+nth(11, '第十一個 ').
+nth(12, '第十二個 ').
+nth(13, '第十三個 ').
+nth(14, '第十四個 ').
+nth(15, '第十五個 ').
+nth(16, '第十六個 ').
+nth(17, '第十七個 ').
+
+
+%%% distance measure
+distance(Dist) == [ X, ' 公尺'] :- Dist < 100, D is round(Dist/10)*10, num_atom(D, X).
+distance(Dist) == [ X, ' 公尺'] :- Dist < 1000, D is round(2*Dist/100)*50, num_atom(D, X).
+distance(Dist) == ['約 1 公里 '] :- Dist < 1500.
+distance(Dist) == ['約 ', X, ' 公里 '] :- Dist < 10000, D is round(Dist/1000), num_atom(D, X).
+distance(Dist) == [ X, ' 公里 '] :- D is round(Dist/1000), num_atom(D, X).
+
+
+%% resolve command main method
+%% if you are familar with Prolog you can input specific to the whole mechanism,
+%% by adding exception cases.
+flatten(X, Y) :- flatten(X, [], Y), !.
+flatten([], Acc, Acc).
+flatten([X|Y], Acc, Res):- flatten(Y, Acc, R), flatten(X, R, Res).
+flatten(X, Acc, [X|Acc]).
+
+resolve(X, Y) :- resolve_impl(X,Z), flatten(Z, Y).
+resolve_impl([],[]).
resolve_impl([X|Rest], List) :- resolve_impl(Rest, Tail), ((X == L) -> append(L, Tail, List); List = Tail).
diff --git a/OsmAnd/res/layout-land/menu.xml b/OsmAnd/res/layout-land/menu.xml
index 43bd3dda7b..eda7c41d68 100644
--- a/OsmAnd/res/layout-land/menu.xml
+++ b/OsmAnd/res/layout-land/menu.xml
@@ -1,6 +1,7 @@
-
@@ -86,4 +87,4 @@ android:layout_width="fill_parent" android:layout_height="fill_parent" android:b
-
+
diff --git a/OsmAnd/res/layout-large-land/menu.xml b/OsmAnd/res/layout-large-land/menu.xml
index b7817c2167..1b1108c59f 100644
--- a/OsmAnd/res/layout-large-land/menu.xml
+++ b/OsmAnd/res/layout-large-land/menu.xml
@@ -1,6 +1,7 @@
-
@@ -89,4 +90,4 @@ android:layout_width="fill_parent" android:layout_height="fill_parent" android:b
-
+
diff --git a/OsmAnd/res/layout-large/menu.xml b/OsmAnd/res/layout-large/menu.xml
index 78189d2abb..febb9105ea 100644
--- a/OsmAnd/res/layout-large/menu.xml
+++ b/OsmAnd/res/layout-large/menu.xml
@@ -1,6 +1,7 @@
-
@@ -77,4 +78,4 @@ android:layout_width="fill_parent" android:layout_height="fill_parent" android:b
-
+
diff --git a/OsmAnd/res/layout/menu.xml b/OsmAnd/res/layout/menu.xml
index 25870cfaf7..040d179997 100644
--- a/OsmAnd/res/layout/menu.xml
+++ b/OsmAnd/res/layout/menu.xml
@@ -1,6 +1,7 @@
-
@@ -77,4 +78,4 @@ android:layout_width="fill_parent" android:layout_height="fill_parent" android:b
-
+
diff --git a/OsmAnd/res/layout/tips_and_tricks.xml b/OsmAnd/res/layout/tips_and_tricks.xml
index 24bc1a1501..1a2824148d 100644
--- a/OsmAnd/res/layout/tips_and_tricks.xml
+++ b/OsmAnd/res/layout/tips_and_tricks.xml
@@ -2,7 +2,7 @@
-
diff --git a/OsmAnd/res/values-ru/strings.xml b/OsmAnd/res/values-ru/strings.xml
index 5e1103f203..114794d0dd 100644
--- a/OsmAnd/res/values-ru/strings.xml
+++ b/OsmAnd/res/values-ru/strings.xml
@@ -478,7 +478,7 @@
Источник позиционирования
Включить фоновый сервис для обновления через долгий период времени
Сервис навигации
- Сервис маршрутизации OsmAnd включен, отключив позиционирование, он перестает вести по маршруту.
+ Сервис маршрутизации OsmAnd включен, если отключить позиционирование, он перестанет вести по маршруту.
Изменить настройки навигации
- Навигация
Скрыть фильтр
diff --git a/OsmAnd/res/xml/settings_pref.xml b/OsmAnd/res/xml/settings_pref.xml
index 2441fa5e16..8f9f720d7c 100644
--- a/OsmAnd/res/xml/settings_pref.xml
+++ b/OsmAnd/res/xml/settings_pref.xml
@@ -131,10 +131,14 @@
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/OsmAnd/src/net/osmand/access/AccessibilityDelegate.java b/OsmAnd/src/net/osmand/access/AccessibilityDelegate.java
index 90c6f0a3bf..4f4c446715 100644
--- a/OsmAnd/src/net/osmand/access/AccessibilityDelegate.java
+++ b/OsmAnd/src/net/osmand/access/AccessibilityDelegate.java
@@ -1,5 +1,7 @@
package net.osmand.access;
+import net.osmand.access.AccessibleLayout;
+
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
diff --git a/OsmAnd/src/net/osmand/access/AccessibilityMode.java b/OsmAnd/src/net/osmand/access/AccessibilityMode.java
new file mode 100644
index 0000000000..a6d472b54e
--- /dev/null
+++ b/OsmAnd/src/net/osmand/access/AccessibilityMode.java
@@ -0,0 +1,22 @@
+package net.osmand.access;
+
+import net.osmand.plus.R;
+import android.content.Context;
+
+public enum AccessibilityMode {
+
+ ON(R.string.accessibility_on),
+ OFF(R.string.accessibility_off),
+ DEFAULT(R.string.accessibility_default);
+
+ private final int key;
+
+ AccessibilityMode(int key) {
+ this.key = key;
+ }
+
+ public String toHumanString(Context ctx) {
+ return ctx.getResources().getString(key);
+ }
+
+}
diff --git a/OsmAnd/src/net/osmand/access/AccessibleActivity.java b/OsmAnd/src/net/osmand/access/AccessibleActivity.java
index e7a6c7ed59..a39509f8da 100644
--- a/OsmAnd/src/net/osmand/access/AccessibleActivity.java
+++ b/OsmAnd/src/net/osmand/access/AccessibleActivity.java
@@ -1,8 +1,9 @@
package net.osmand.access;
+import net.osmand.access.AccessibleContent;
+
import android.app.Activity;
import android.view.MotionEvent;
-import android.view.View;
// Provide some additional accessibility means for activity view elements.
//
@@ -16,22 +17,6 @@ public class AccessibleActivity extends Activity implements AccessibleContent.Ca
// to add element to it.
public final AccessibleContent accessibleContent = new AccessibleContent();
- // Below are two helper methods to improve AlertDialog accessibility.
- //
- // Since usual message in an AlertDialog that is set by
- // AlertDialog.Builder.setMessage() is spoken only once at the best case
- // and there is no way to repeat it, use following two methods
- // to wrap it into a View and set it by AlertDialog.Builder.setView().
- // Such message will be focusable and so it can be repeated by selecting.
-
- public View accessibleMessage(CharSequence msg) {
- return TextMessage.makeView(this, msg);
- }
-
- public View accessibleMessage(int msgid) {
- return TextMessage.makeView(this, msgid);
- }
-
@Override
public boolean dispatchNativeTouchEvent(MotionEvent event) {
return super.dispatchTouchEvent(event);
diff --git a/OsmAnd/src/net/osmand/access/AccessibleAlertBuilder.java b/OsmAnd/src/net/osmand/access/AccessibleAlertBuilder.java
new file mode 100644
index 0000000000..3c1c7e6d05
--- /dev/null
+++ b/OsmAnd/src/net/osmand/access/AccessibleAlertBuilder.java
@@ -0,0 +1,51 @@
+package net.osmand.access;
+
+import net.osmand.access.TextMessage;
+import net.osmand.plus.OsmandApplication;
+import net.osmand.plus.R;
+
+import android.app.AlertDialog.Builder;
+import android.content.Context;
+
+// Since usual message in an AlertDialog that is set by
+// AlertDialog.Builder.setMessage() is spoken only once
+// at the best case and there is no way to explore or even repeat it,
+// this class provides more accessible alternative
+// that wraps the message into a dedicated view.
+// Such message will be focusable and so it can be repeated
+// by selecting.
+//
+// Note: when accessibility extensions option is not checked
+// or system accessibility service is turned off this class
+// acts just identical to it's direct parent.
+//
+public class AccessibleAlertBuilder extends Builder {
+
+ // The method getContext() is only available
+ // starting from API level 11, so store it here.
+ private final Context context;
+
+ // Conventional constructor.
+ public AccessibleAlertBuilder(Context context) {
+ super(context);
+ this.context = context;
+ }
+
+
+ // Provided setMessage() alternatives.
+
+ @Override
+ public Builder setMessage(CharSequence msg) {
+ if (OsmandApplication.getSettings().ACCESSIBILITY_EXTENSIONS.get())
+ return setView(TextMessage.makeView(context, msg, R.layout.alert));
+ return super.setMessage(msg);
+ }
+
+ @Override
+ public Builder setMessage(int msgid) {
+ if (OsmandApplication.getSettings().ACCESSIBILITY_EXTENSIONS.get())
+ return setView(TextMessage.makeView(context, msgid, R.layout.alert));
+ return super.setMessage(msgid);
+ }
+
+}
diff --git a/OsmAnd/src/net/osmand/access/AccessibleContent.java b/OsmAnd/src/net/osmand/access/AccessibleContent.java
index 1cc91089a8..ac665d3dea 100644
--- a/OsmAnd/src/net/osmand/access/AccessibleContent.java
+++ b/OsmAnd/src/net/osmand/access/AccessibleContent.java
@@ -2,6 +2,8 @@ package net.osmand.access;
import java.util.ArrayList;
+import net.osmand.plus.OsmandApplication;
+
import android.graphics.Rect;
import android.os.SystemClock;
import android.view.MotionEvent;
@@ -19,7 +21,7 @@ import android.view.accessibility.AccessibilityEvent;
//
public class AccessibleContent extends ArrayList {
- public interface Callback {
+ protected interface Callback {
public boolean dispatchNativeTouchEvent(MotionEvent event);
}
@@ -36,39 +38,41 @@ public class AccessibleContent extends ArrayList {
}
public boolean dispatchTouchEvent(MotionEvent event, Callback callback) {
- int action = event.getAction();
- View newTouch;
- switch (action) {
- case MotionEvent.ACTION_MOVE:
- newTouch = findTouch(event);
- if ((newTouch != null) && (newTouch != nowTouched)) {
- float x = event.getX();
- float y = event.getY();
- float pressure = event.getPressure();
- float size = event.getSize();
- int metaState = event.getMetaState();
- float xPrecision = event.getXPrecision();
- float yPrecision = event.getYPrecision();
- int deviceId = event.getDeviceId();
- int edgeFlags = event.getEdgeFlags();
- event.setAction(MotionEvent.ACTION_CANCEL);
- callback.dispatchNativeTouchEvent(event);
- newTouch.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
- long now = SystemClock.uptimeMillis();
- event.recycle();
- event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x, y, pressure, size,
- metaState, xPrecision, yPrecision, deviceId, edgeFlags);
+ if (OsmandApplication.getSettings().ACCESSIBILITY_EXTENSIONS.get()) {
+ int action = event.getAction();
+ View newTouch;
+ switch (action) {
+ case MotionEvent.ACTION_MOVE:
+ newTouch = findTouch(event);
+ if ((newTouch != null) && (newTouch != nowTouched)) {
+ float x = event.getX();
+ float y = event.getY();
+ float pressure = event.getPressure();
+ float size = event.getSize();
+ int metaState = event.getMetaState();
+ float xPrecision = event.getXPrecision();
+ float yPrecision = event.getYPrecision();
+ int deviceId = event.getDeviceId();
+ int edgeFlags = event.getEdgeFlags();
+ event.setAction(MotionEvent.ACTION_CANCEL);
+ callback.dispatchNativeTouchEvent(event);
+ newTouch.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ long now = SystemClock.uptimeMillis();
+ event.recycle();
+ event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x, y, pressure, size,
+ metaState, xPrecision, yPrecision, deviceId, edgeFlags);
+ }
+ nowTouched = newTouch;
+ break;
+ case MotionEvent.ACTION_DOWN:
+ nowTouched = findTouch(event);
+ if (nowTouched != null)
+ nowTouched.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ break;
+ default:
+ nowTouched = null;
+ break;
}
- nowTouched = newTouch;
- break;
- case MotionEvent.ACTION_DOWN:
- nowTouched = findTouch(event);
- if (nowTouched != null)
- nowTouched.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
- break;
- default:
- nowTouched = null;
- break;
}
return callback.dispatchNativeTouchEvent(event);
}
diff --git a/OsmAnd/src/net/osmand/access/AccessibleLayout.java b/OsmAnd/src/net/osmand/access/AccessibleLayout.java
index e0a06bfc31..16545bb9be 100644
--- a/OsmAnd/src/net/osmand/access/AccessibleLayout.java
+++ b/OsmAnd/src/net/osmand/access/AccessibleLayout.java
@@ -1,5 +1,7 @@
package net.osmand.access;
+import net.osmand.plus.OsmandApplication;
+
import android.content.Context;
import android.graphics.Rect;
import android.os.SystemClock;
@@ -72,44 +74,46 @@ public class AccessibleLayout extends FrameLayout {
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
- int action = event.getAction();
- View newTouch;
- switch (action) {
- case MotionEvent.ACTION_MOVE:
- newTouch = findTouch(event);
- if ((newTouch != null) && (newTouch != nowTouched)) {
- if (newTouch.isClickable()) {
- float x = event.getX();
- float y = event.getY();
- float pressure = event.getPressure();
- float size = event.getSize();
- int metaState = event.getMetaState();
- float xPrecision = event.getXPrecision();
- float yPrecision = event.getYPrecision();
- int deviceId = event.getDeviceId();
- int edgeFlags = event.getEdgeFlags();
- event.setAction(MotionEvent.ACTION_CANCEL);
- super.dispatchTouchEvent(event);
- long now = SystemClock.uptimeMillis();
- event.recycle();
- event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x, y, pressure, size,
- metaState, xPrecision, yPrecision, deviceId, edgeFlags);
+ final boolean swallow = OsmandApplication.getSettings().ACCESSIBILITY_EXTENSIONS.get();
+ if (swallow) {
+ int action = event.getAction();
+ View newTouch;
+ switch (action) {
+ case MotionEvent.ACTION_MOVE:
+ newTouch = findTouch(event);
+ if ((newTouch != null) && (newTouch != nowTouched)) {
+ if (newTouch.isClickable()) {
+ float x = event.getX();
+ float y = event.getY();
+ float pressure = event.getPressure();
+ float size = event.getSize();
+ int metaState = event.getMetaState();
+ float xPrecision = event.getXPrecision();
+ float yPrecision = event.getYPrecision();
+ int deviceId = event.getDeviceId();
+ int edgeFlags = event.getEdgeFlags();
+ event.setAction(MotionEvent.ACTION_CANCEL);
+ super.dispatchTouchEvent(event);
+ long now = SystemClock.uptimeMillis();
+ event.recycle();
+ event = MotionEvent.obtain(now, now, MotionEvent.ACTION_DOWN, x, y, pressure, size,
+ metaState, xPrecision, yPrecision, deviceId, edgeFlags);
+ }
+ newTouch.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
}
- newTouch.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ nowTouched = newTouch;
+ break;
+ case MotionEvent.ACTION_DOWN:
+ nowTouched = findTouch(event);
+ if (nowTouched != null)
+ nowTouched.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ break;
+ default:
+ nowTouched = null;
+ break;
}
- nowTouched = newTouch;
- break;
- case MotionEvent.ACTION_DOWN:
- nowTouched = findTouch(event);
- if (nowTouched != null)
- nowTouched.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
- break;
- default:
- nowTouched = null;
- break;
}
- super.dispatchTouchEvent(event);
- return true;
+ return super.dispatchTouchEvent(event) || swallow;
}
}
diff --git a/OsmAnd/src/net/osmand/access/AccessibleToast.java b/OsmAnd/src/net/osmand/access/AccessibleToast.java
index ebb845c7b6..89331dadef 100644
--- a/OsmAnd/src/net/osmand/access/AccessibleToast.java
+++ b/OsmAnd/src/net/osmand/access/AccessibleToast.java
@@ -1,6 +1,9 @@
package net.osmand.access;
+import net.osmand.access.TextMessage;
+import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
+
import android.content.Context;
import android.view.accessibility.AccessibilityEvent;
import android.widget.Toast;
@@ -15,25 +18,23 @@ public class AccessibleToast extends Toast {
}
public static Toast makeText(Context context, int msg, int duration) {
- if(true){
- // currently disabled (waiting for settings)
- return Toast.makeText(context, msg, duration);
- }
- final Toast toast = new AccessibleToast(context);
- toast.setView(TextMessage.makeView(context, msg, R.layout.notification));
- toast.setDuration(duration);
- return toast;
+ if (OsmandApplication.getSettings().ACCESSIBILITY_EXTENSIONS.get()) {
+ final Toast toast = new AccessibleToast(context);
+ toast.setView(TextMessage.makeView(context, msg, R.layout.notification));
+ toast.setDuration(duration);
+ return toast;
+ }
+ return Toast.makeText(context, msg, duration);
}
public static Toast makeText(Context context, CharSequence msg, int duration) {
- if(true){
- // currently disabled (waiting for settings)
- return Toast.makeText(context, msg, duration);
- }
- final Toast toast = new AccessibleToast(context);
- toast.setView(TextMessage.makeView(context, msg, R.layout.notification));
- toast.setDuration(duration);
- return toast;
+ if (OsmandApplication.getSettings().ACCESSIBILITY_EXTENSIONS.get()) {
+ final Toast toast = new AccessibleToast(context);
+ toast.setView(TextMessage.makeView(context, msg, R.layout.notification));
+ toast.setDuration(duration);
+ return toast;
+ }
+ return Toast.makeText(context, msg, duration);
}
@Override
diff --git a/OsmAnd/src/net/osmand/access/AccessibleTrackedActivity.java b/OsmAnd/src/net/osmand/access/AccessibleTrackedActivity.java
deleted file mode 100644
index 4e671ebcb8..0000000000
--- a/OsmAnd/src/net/osmand/access/AccessibleTrackedActivity.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package net.osmand.access;
-
-import android.app.Activity;
-import android.view.MotionEvent;
-import android.view.View;
-
-// Provide some additional accessibility means for activity view elements.
-//
-// To make use of these capabilities simply derive your activity from this class
-// and then add view elements you wish to be accessible
-// to the accessibleContent list.
-//
-public class AccessibleTrackedActivity extends Activity implements AccessibleContent.Callback {
-
- // List of accessible views. Use accessibleContent.add(element)
- // to add element to it.
- public final AccessibleContent accessibleContent = new AccessibleContent();
-
- // Below are two helper methods to improve AlertDialog accessibility.
- //
- // Since usual message in an AlertDialog that is set by
- // AlertDialog.Builder.setMessage() is spoken only once at the best case
- // and there is no way to repeat it, use following two methods
- // to wrap it into a View and set it by AlertDialog.Builder.setView().
- // Such message will be focusable and so it can be repeated by selecting.
-
- public View accessibleMessage(CharSequence msg) {
- return TextMessage.makeView(this, msg);
- }
-
- public View accessibleMessage(int msgid) {
- return TextMessage.makeView(this, msgid);
- }
-
- @Override
- public boolean dispatchNativeTouchEvent(MotionEvent event) {
- return super.dispatchTouchEvent(event);
- }
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent event) {
- return accessibleContent.dispatchTouchEvent(event, this);
- }
-
-}
diff --git a/OsmAnd/src/net/osmand/access/ExplorableTextView.java b/OsmAnd/src/net/osmand/access/ExplorableTextView.java
index 644a3c168b..a705107d4a 100644
--- a/OsmAnd/src/net/osmand/access/ExplorableTextView.java
+++ b/OsmAnd/src/net/osmand/access/ExplorableTextView.java
@@ -1,5 +1,7 @@
package net.osmand.access;
+import net.osmand.plus.OsmandApplication;
+
import android.content.Context;
import android.text.Layout;
import android.text.method.ArrowKeyMovementMethod;
@@ -38,6 +40,8 @@ public class ExplorableTextView extends TextView {
@Override
public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ if (!OsmandApplication.getSettings().ACCESSIBILITY_EXTENSIONS.get())
+ return super.dispatchPopulateAccessibilityEvent(event);
cursorTrackingEnabled = false;
boolean result = super.dispatchPopulateAccessibilityEvent(event);
if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) {
@@ -57,13 +61,15 @@ public class ExplorableTextView extends TextView {
@Override
protected MovementMethod getDefaultMovementMethod() {
- return ArrowKeyMovementMethod.getInstance();
+ if (OsmandApplication.getSettings().ACCESSIBILITY_EXTENSIONS.get())
+ return ArrowKeyMovementMethod.getInstance();
+ return super.getDefaultMovementMethod();
}
@Override
protected void onTextChanged(CharSequence text, int start, int before, int after) {
super.onTextChanged(text, start, before, after);
- if (!isFocused()) {
+ if (OsmandApplication.getSettings().ACCESSIBILITY_EXTENSIONS.get() && !isFocused()) {
selectionLength = Math.min(text.length(), AccessibilityEvent.MAX_TEXT_LENGTH);
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED);
}
@@ -72,7 +78,7 @@ public class ExplorableTextView extends TextView {
@Override
protected void onSelectionChanged(int start, int end) {
super.onSelectionChanged(start, end);
- if (cursorTrackingEnabled && isFocused()) {
+ if (OsmandApplication.getSettings().ACCESSIBILITY_EXTENSIONS.get() && cursorTrackingEnabled && isFocused()) {
if (end >= getText().length()) {
cursor = getText().length();
} else if (cursor != end) {
diff --git a/OsmAnd/src/net/osmand/access/MapExplorer.java b/OsmAnd/src/net/osmand/access/MapExplorer.java
index 88ba9e60ff..8989ab8383 100644
--- a/OsmAnd/src/net/osmand/access/MapExplorer.java
+++ b/OsmAnd/src/net/osmand/access/MapExplorer.java
@@ -75,16 +75,15 @@ public class MapExplorer implements OnGestureListener, IContextMenuProvider {
contextProvider = this;
}
if (different(newSelections, selectedObjects)) {
- // FIXME Map explorer
-// ContextMenuLayer contextMenuLayer = mapView.getContextMenuLayer();
-// if (contextMenuLayer != null) {
-// contextMenuLayer.setSelections(newSelections, contextProvider);
-// if (!newSelections.isEmpty())
-// mapView.showMessage(mapView.getSettings().USE_SHORT_OBJECT_NAMES.get() ?
-// contextMenuLayer.getSelectedObjectName() :
-// contextMenuLayer.getSelectedObjectDescription());
-// }
-// selectedObjects = newSelections;
+ ContextMenuLayer contextMenuLayer = mapView.getLayerByClass(ContextMenuLayer.class);
+ if (contextMenuLayer != null) {
+ contextMenuLayer.setSelections(newSelections, contextProvider);
+ if (!newSelections.isEmpty())
+ mapView.showMessage(mapView.getSettings().USE_SHORT_OBJECT_NAMES.get() ?
+ contextMenuLayer.getSelectedObjectName() :
+ contextMenuLayer.getSelectedObjectDescription());
+ }
+ selectedObjects = newSelections;
}
}
@@ -96,9 +95,8 @@ public class MapExplorer implements OnGestureListener, IContextMenuProvider {
if (mapView.getSettings().SCROLL_MAP_BY_GESTURES.get())
return fallback.onDown(e);
ContextMenuLayer contextMenuLayer = mapView.getLayerByClass(ContextMenuLayer.class);
- // FIXME
-// if (contextMenuLayer != null)
-// contextMenuLayer.setSelections(null, null);
+ if (contextMenuLayer != null)
+ contextMenuLayer.setSelections(null, null);
selectedObjects = null;
describePointedObjects(e);
return false;
diff --git a/OsmAnd/src/net/osmand/access/NavigationInfo.java b/OsmAnd/src/net/osmand/access/NavigationInfo.java
index 088eccb3a9..1e76cf7917 100644
--- a/OsmAnd/src/net/osmand/access/NavigationInfo.java
+++ b/OsmAnd/src/net/osmand/access/NavigationInfo.java
@@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.List;
import net.osmand.OsmAndFormatter;
+import net.osmand.access.AccessibleToast;
+import net.osmand.access.RelativeDirectionStyle;
import net.osmand.osm.LatLon;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
@@ -100,7 +102,7 @@ public class NavigationInfo {
private int directionTo(final Location point, float heading) {
final float bearing = currentLocation.bearingTo(point) - heading;
final int nSectors = (style == RelativeDirectionStyle.CLOCKWISE) ? 12 : direction.length;
- int sector = (int)Math.round(Math.abs(bearing) * (float)nSectors / FULL_CIRCLE) % nSectors;
+ int sector = Math.round(Math.abs(bearing) * (float)nSectors / FULL_CIRCLE) % nSectors;
if ((bearing < 0) && (sector != 0))
sector = nSectors - sector;
return sector;
@@ -139,7 +141,7 @@ public class NavigationInfo {
public NavigationInfo(final Context context) {
this.context = context;
- settings = ((OsmandApplication)(context.getApplicationContext())).getSettings();
+ settings = OsmandApplication.getSettings();
currentLocation = null;
lastDirection = new RelativeDirection();
lastNotificationTime = SystemClock.uptimeMillis();
@@ -158,7 +160,7 @@ public class NavigationInfo {
// The argument must be not null as well as the currentLocation
private String absoluteDirectionString(float bearing) {
- int direction = (int)Math.round(Math.abs(bearing) * (float)cardinal.length / FULL_CIRCLE) % cardinal.length;
+ int direction = Math.round(Math.abs(bearing) * (float)cardinal.length / FULL_CIRCLE) % cardinal.length;
if ((bearing < 0) && (direction != 0))
direction = cardinal.length - direction;
return getString(cardinal[direction]);
@@ -234,7 +236,7 @@ public class NavigationInfo {
public synchronized void setLocation(Location location) {
currentLocation = location;
- if (autoAnnounce) {
+ if (autoAnnounce && ((OsmandApplication)(context.getApplicationContext())).accessibilityEnabled()) {
final LatLon point = settings.getPointToNavigate();
if (point != null) {
if ((currentLocation != null) && currentLocation.hasBearing()) {
diff --git a/OsmAnd/src/net/osmand/access/RelativeDirectionStyle.java b/OsmAnd/src/net/osmand/access/RelativeDirectionStyle.java
index aa4fea52ff..2451e6b924 100644
--- a/OsmAnd/src/net/osmand/access/RelativeDirectionStyle.java
+++ b/OsmAnd/src/net/osmand/access/RelativeDirectionStyle.java
@@ -14,8 +14,8 @@ public enum RelativeDirectionStyle {
this.key = key;
}
- public static String toHumanString(RelativeDirectionStyle style, Context ctx) {
- return ctx.getResources().getString(style.key);
+ public String toHumanString(Context ctx) {
+ return ctx.getResources().getString(key);
}
}
diff --git a/OsmAnd/src/net/osmand/access/TextMessage.java b/OsmAnd/src/net/osmand/access/TextMessage.java
index f67777e975..30ddfa7163 100644
--- a/OsmAnd/src/net/osmand/access/TextMessage.java
+++ b/OsmAnd/src/net/osmand/access/TextMessage.java
@@ -1,6 +1,8 @@
package net.osmand.access;
+import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
+
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
@@ -9,14 +11,6 @@ import android.widget.TextView;
// This class contains only static methods intended to improve
// accessibility for AlertDialog and Toast messages.
//
-// Since usual message in an AlertDialog that is set by
-// AlertDialog.Builder.setMessage() is spoken only once
-// at the best case and there is no way to explore or even repeat it,
-// use public methods of this class to wrap it into a View
-// and set it by AlertDialog.Builder.setView().
-// Such message will be focusable and so it can be repeated
-// by selecting.
-//
public class TextMessage {
protected static View makeView(Context ctx, CharSequence msg, int resid) {
@@ -31,12 +25,4 @@ public class TextMessage {
return layout;
}
- public static View makeView(Context ctx, CharSequence msg) {
- return makeView(ctx, msg, R.layout.alert);
- }
-
- public static View makeView(Context ctx, int msgid) {
- return makeView(ctx, msgid, R.layout.alert);
- }
-
}
diff --git a/OsmAnd/src/net/osmand/plus/OsmandApplication.java b/OsmAnd/src/net/osmand/plus/OsmandApplication.java
index 83212425cf..c11afe9eb5 100644
--- a/OsmAnd/src/net/osmand/plus/OsmandApplication.java
+++ b/OsmAnd/src/net/osmand/plus/OsmandApplication.java
@@ -21,6 +21,7 @@ import net.osmand.plus.OsmandSettings;
import net.osmand.plus.PoiFiltersHelper;
import net.osmand.plus.ProgressDialogImplementation;
import net.osmand.LogUtil;
+import net.osmand.access.AccessibilityMode;
import net.osmand.access.AccessibleToast;
import net.osmand.plus.activities.DayNightHelper;
import net.osmand.plus.activities.SavingTrackHelper;
@@ -43,6 +44,7 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.os.Handler;
import android.text.format.DateFormat;
+import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
import com.bidforfix.andorid.BidForFixHelper;
@@ -488,4 +490,14 @@ public class OsmandApplication extends Application {
}
}
+
+ public boolean accessibilityEnabled() {
+ final AccessibilityMode mode = getSettings().ACCESSIBILITY_MODE.get();
+ if (mode == AccessibilityMode.ON)
+ return true;
+ else if (mode == AccessibilityMode.OFF)
+ return false;
+ return ((AccessibilityManager)getSystemService(ACCESSIBILITY_SERVICE)).isEnabled();
+ }
+
}
diff --git a/OsmAnd/src/net/osmand/plus/OsmandSettings.java b/OsmAnd/src/net/osmand/plus/OsmandSettings.java
index de9882df38..98814af24e 100644
--- a/OsmAnd/src/net/osmand/plus/OsmandSettings.java
+++ b/OsmAnd/src/net/osmand/plus/OsmandSettings.java
@@ -8,8 +8,8 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import net.osmand.LogUtil;
import net.osmand.Version;
+import net.osmand.access.AccessibilityMode;
import net.osmand.access.AccessibleToast;
import net.osmand.access.RelativeDirectionStyle;
import net.osmand.map.ITileSource;
@@ -300,6 +300,32 @@ public class OsmandSettings {
return prefs.edit().putBoolean(getId(), val).commit();
}
}
+
+ private class BooleanAccessibilityPreference extends BooleanPreference {
+
+ private BooleanAccessibilityPreference(String id, boolean defaultValue, boolean global) {
+ super(id, defaultValue, global);
+ }
+
+ private BooleanAccessibilityPreference(String id, boolean defaultValue, boolean global, boolean cache) {
+ super(id, defaultValue, global, cache);
+ }
+
+ @Override
+ protected Boolean getValue(SharedPreferences prefs, Boolean defaultValue) {
+ return ctx.accessibilityEnabled() ?
+ super.getValue(prefs, defaultValue) :
+ defaultValue;
+ }
+
+ @Override
+ protected boolean setValue(SharedPreferences prefs, Boolean val) {
+ return ctx.accessibilityEnabled() ?
+ super.setValue(prefs, val) :
+ false;
+ }
+ }
+
private class IntPreference extends CommonPreference {
@@ -384,14 +410,13 @@ public class OsmandSettings {
protected E getValue(SharedPreferences prefs, E defaultValue) {
try {
int i = prefs.getInt(getId(), -1);
- if(i < 0 || i >= values.length){
- return defaultValue;
+ if(i >= 0 && i < values.length){
+ return values[i];
}
- return values[i];
- } catch (Exception e) {
- android.util.Log.e(LogUtil.TAG, "Error getting value for: " + this.getId(), e);
- return defaultValue;
+ } catch (ClassCastException ex) {
+ setValue(prefs, defaultValue);
}
+ return defaultValue;
}
@Override
@@ -414,32 +439,36 @@ public class OsmandSettings {
// cache of metrics constants as they are used very often
public final OsmandPreference METRIC_SYSTEM = new EnumIntPreference(
"default_metric_system", MetricsConstants.KILOMETERS_AND_METERS, true, true, MetricsConstants.values());
-
- public String getId() {
- return "direction_style";
- };
-
// this value string is synchronized with settings_pref.xml preference name
// cache of metrics constants as they are used very often
public final OsmandPreference DIRECTION_STYLE = new EnumIntPreference(
"direction_style", RelativeDirectionStyle.SIDEWISE, true, true, RelativeDirectionStyle.values());
+ // this value string is synchronized with settings_pref.xml preference name
+ // cache of metrics constants as they are used very often
+ public final OsmandPreference ACCESSIBILITY_MODE = new EnumIntPreference(
+ "accessibility_mode", AccessibilityMode.DEFAULT, true, true, AccessibilityMode.values());
+
// this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference USE_TRACKBALL_FOR_MOVEMENTS =
new BooleanPreference("use_trackball_for_movements", true, true);
// this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference ZOOM_BY_TRACKBALL =
- new BooleanPreference("zoom_by_trackball", true, true);
+ new BooleanAccessibilityPreference("zoom_by_trackball", true, true);
// this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference SCROLL_MAP_BY_GESTURES =
- new BooleanPreference("scroll_map_by_gestures", true, true);
+ new BooleanAccessibilityPreference("scroll_map_by_gestures", true, true);
// this value string is synchronized with settings_pref.xml preference name
public final OsmandPreference USE_SHORT_OBJECT_NAMES =
- new BooleanPreference("use_short_object_names", false, true);
+ new BooleanAccessibilityPreference("use_short_object_names", false, true);
+
+ // this value string is synchronized with settings_pref.xml preference name
+ public final OsmandPreference ACCESSIBILITY_EXTENSIONS =
+ new BooleanAccessibilityPreference("accessibility_extensions", false, true);
// this value string is synchronized with settings_pref.xml preference name
diff --git a/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java b/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java
index 999f95ae7c..a0dd9c4a63 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MainMenuActivity.java
@@ -5,6 +5,7 @@ import java.text.MessageFormat;
import java.util.Random;
import net.osmand.Version;
+import net.osmand.access.AccessibleAlertBuilder;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.ResourceManager;
@@ -58,7 +59,7 @@ public class MainMenuActivity extends Activity {
if (file.exists() && file.length() > 0) {
if (size != file.length() && !firstTime) {
String msg = MessageFormat.format(getString(R.string.previous_run_crashed), OsmandApplication.EXCEPTION_PATH);
- Builder builder = new AlertDialog.Builder(MainMenuActivity.this);
+ Builder builder = new AccessibleAlertBuilder(MainMenuActivity.this);
builder.setMessage(msg).setNeutralButton(getString(R.string.close), null);
builder.setPositiveButton(R.string.send_report, new DialogInterface.OnClickListener() {
@Override
@@ -287,12 +288,12 @@ public class MainMenuActivity extends Activity {
}
if(netOsmandWasInstalled){
- Builder builder = new AlertDialog.Builder(this);
+ Builder builder = new AccessibleAlertBuilder(this);
builder.setMessage(R.string.osmand_net_previously_installed);
builder.setPositiveButton(R.string.default_buttons_ok, null);
builder.show();
} else {
- Builder builder = new AlertDialog.Builder(this);
+ Builder builder = new AccessibleAlertBuilder(this);
builder.setMessage(R.string.first_time_msg);
builder.setPositiveButton(R.string.first_time_download, new DialogInterface.OnClickListener() {
@@ -313,7 +314,7 @@ public class MainMenuActivity extends Activity {
boolean check = pref.getBoolean(VECTOR_INDEXES_CHECK, true);
// do not show each time
if (check && new Random().nextInt() % 5 == 1) {
- Builder builder = new AlertDialog.Builder(this);
+ Builder builder = new AccessibleAlertBuilder(this);
if(maps.isEmpty()){
builder.setMessage(R.string.vector_data_missing);
} else if(!maps.basemapExists()){
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
index 946e447352..77b71b5750 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java
@@ -10,7 +10,10 @@ import net.osmand.GPXUtilities.GPXFile;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.LogUtil;
import net.osmand.Version;
+import net.osmand.access.AccessibleActivity;
+import net.osmand.access.AccessibleAlertBuilder;
import net.osmand.access.AccessibleToast;
+import net.osmand.access.NavigationInfo;
import net.osmand.data.MapTileDownloader.DownloadRequest;
import net.osmand.data.MapTileDownloader.IMapDownloaderCallback;
import net.osmand.map.IMapLocationListener;
@@ -77,7 +80,7 @@ import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.Toast;
-public class MapActivity extends Activity implements IMapLocationListener, SensorEventListener {
+public class MapActivity extends AccessibleActivity implements IMapLocationListener, SensorEventListener {
private static final String GPS_STATUS_ACTIVITY = "com.eclipsim.gpsstatus2.GPSStatus"; //$NON-NLS-1$
private static final String GPS_STATUS_COMPONENT = "com.eclipsim.gpsstatus2"; //$NON-NLS-1$
@@ -96,8 +99,8 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
private static final int LOST_LOCATION_MSG_ID = 10;
private static final long LOST_LOCATION_CHECK_DELAY = 20000;
-// private static final int LONG_KEYPRESS_MSG_ID = 28;
-// private static final int LONG_KEYPRESS_DELAY = 500;
+ private static final int LONG_KEYPRESS_MSG_ID = 28;
+ private static final int LONG_KEYPRESS_DELAY = 500;
private long lastTimeAutoZooming = 0;
@@ -108,6 +111,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
final private MapActivityActions mapActions = new MapActivityActions(this);
private EditingPOIActivity poiActions;
final private MapActivityLayers mapLayers = new MapActivityLayers(this);
+ private NavigationInfo navigationInfo;
private SavingTrackHelper savingTrackHelper;
private LiveMonitoringHelper liveMonitoringHelper;
@@ -150,6 +154,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settings = getMyApplication().getSettings();
+ navigationInfo = new NavigationInfo(this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Full screen is not used here
//getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
@@ -327,7 +332,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
if (pointToNavigate == null && gpxPath == null) {
notRestoreRoutingMode();
} else {
- Builder builder = new AlertDialog.Builder(MapActivity.this);
+ Builder builder = new AccessibleAlertBuilder(MapActivity.this);
builder.setMessage(R.string.continue_follow_previous_route);
builder.setPositiveButton(R.string.default_buttons_yes, new DialogInterface.OnClickListener() {
@Override
@@ -410,6 +415,8 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
public void changeZoom(int newZoom){
boolean changeLocation = settings.AUTO_ZOOM_MAP.get();
mapView.getAnimatedDraggingThread().startZooming(newZoom, changeLocation);
+ if (getMyApplication().accessibilityEnabled())
+ AccessibleToast.makeText(this, getString(R.string.zoomIs) + " " + String.valueOf(newZoom), Toast.LENGTH_SHORT).show(); //$NON-NLS-1$
showAndHideMapPosition();
}
@@ -515,6 +522,18 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
//that they could do some key combinations with it...
// Victor : doing in that way doesn't close dialog properly!
//return true;
+ } else if (getMyApplication().accessibilityEnabled() && (keyCode == KeyEvent.KEYCODE_DPAD_CENTER)) {
+ if (!uiHandler.hasMessages(LONG_KEYPRESS_MSG_ID)) {
+ Message msg = Message.obtain(uiHandler, new Runnable() {
+ @Override
+ public void run() {
+ emitNavigationHint();
+ }
+ });
+ msg.what = LONG_KEYPRESS_MSG_ID;
+ uiHandler.sendMessageDelayed(msg, LONG_KEYPRESS_DELAY);
+ }
+ return true;
} else if (keyCode == KeyEvent.KEYCODE_SEARCH && event.getRepeatCount() == 0) {
Intent newIntent = new Intent(MapActivity.this, SearchActivity.class);
// causes wrong position caching: newIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
@@ -540,6 +559,51 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
return super.onKeyDown(keyCode, event);
}
+ public String getNavigationHint(LatLon point) {
+ String hint = navigationInfo.getDirectionString(point, mapLayers.getLocationLayer().getHeading());
+ if (hint == null)
+ hint = getString(R.string.no_info);
+ return hint;
+ }
+
+ private void emitNavigationHint() {
+ final LatLon point = settings.getPointToNavigate();
+ if (point != null) {
+ if (routingHelper.isRouteCalculated()) {
+ routingHelper.getVoiceRouter().announceCurrentDirection();
+ } else {
+ AccessibleToast.makeText(this, getNavigationHint(point), Toast.LENGTH_LONG).show();
+ }
+ } else {
+ AccessibleToast.makeText(this, R.string.mark_final_location_first, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private void whereAmIDialog() {
+ final List items = new ArrayList();
+ items.add(getString(R.string.show_location));
+ items.add(getString(R.string.show_details));
+ AlertDialog.Builder menu = new AlertDialog.Builder(this);
+ menu.setItems(items.toArray(new String[items.size()]),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int item) {
+ dialog.dismiss();
+ switch (item) {
+ case 0:
+ backToLocationImpl();
+ break;
+ case 1:
+ navigationInfo.show(settings.getPointToNavigate(), mapLayers.getLocationLayer().getHeading());
+ break;
+ default:
+ break;
+ }
+ }
+ });
+ menu.show();
+ }
+
public void setMapLocation(double lat, double lon){
mapView.setLatLon(lat, lon);
locationChanged(lat, lon, this);
@@ -695,6 +759,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
registerUnregisterSensor(location);
updateSpeedBearing(location);
mapLayers.getLocationLayer().setLastKnownLocation(location);
+ navigationInfo.setLocation(location);
if(routingHelper.isFollowingMode()){
if(location == null || !location.hasAccuracy() || location.getAccuracy() < ACCURACY_FOR_GPX_AND_ROUTING) {
// Update routing position
@@ -958,16 +1023,22 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
//onBackPressed();
//return true;
} else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
- contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
+ if (!getMyApplication().accessibilityEnabled()) {
+ contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
+ } else if (uiHandler.hasMessages(LONG_KEYPRESS_MSG_ID)) {
+ uiHandler.removeMessages(LONG_KEYPRESS_MSG_ID);
+ contextMenuPoint(mapView.getLatitude(), mapView.getLongitude());
+ }
return true;
- } else
+ } else if (settings.ZOOM_BY_TRACKBALL.get()) {
// Parrot device has only dpad left and right
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
changeZoom(mapView.getZoom() - 1);
return true;
- } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
- changeZoom(mapView.getZoom() + 1);
- return true;
+ } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
+ changeZoom(mapView.getZoom() + 1);
+ return true;
+ }
}
return super.onKeyUp(keyCode,event);
}
@@ -1103,7 +1174,11 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
startActivity(intentSettings);
return true;
} else if (itemId == R.id.map_where_am_i) {
- backToLocationImpl();
+ if (getMyApplication().accessibilityEnabled()) {
+ whereAmIDialog();
+ } else {
+ backToLocationImpl();
+ }
return true;
} else if (itemId == R.id.map_show_gps_status) {
startGpsStatusIntent();
@@ -1181,7 +1256,7 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
if (resolved != null) {
startActivity(intent);
} else {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ AlertDialog.Builder builder = new AccessibleAlertBuilder(this);
builder.setMessage(getString(R.string.gps_status_app_not_found));
builder.setPositiveButton(
getString(R.string.default_buttons_yes),
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
index 484dbcb890..40f29db06d 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java
@@ -13,6 +13,7 @@ import net.osmand.FavouritePoint;
import net.osmand.GPXUtilities;
import net.osmand.GPXUtilities.GPXFile;
import net.osmand.LogUtil;
+import net.osmand.access.AccessibleAlertBuilder;
import net.osmand.access.AccessibleToast;
import net.osmand.data.Amenity;
import net.osmand.map.ITileSource;
@@ -233,7 +234,7 @@ public class MapActivityActions implements DialogProvider {
private Dialog createReloadTitleDialog(final Bundle args) {
- Builder builder = new AlertDialog.Builder(mapActivity);
+ Builder builder = new AccessibleAlertBuilder(mapActivity);
builder.setMessage(R.string.context_menu_item_update_map_confirm);
builder.setNegativeButton(R.string.default_buttons_cancel, null);
final OsmandMapTileView mapView = mapActivity.getMapView();
@@ -414,7 +415,7 @@ public class MapActivityActions implements DialogProvider {
saveDirections();
}
};
- Builder builder = new AlertDialog.Builder(mapActivity);
+ Builder builder = new AccessibleAlertBuilder(mapActivity);
builder.setTitle(R.string.show_route);
builder.setMessage(mapActivity.getRoutingHelper().getGeneralRouteInformation());
builder.setPositiveButton(R.string.default_buttons_save, saveDirections);
diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java
index 47d7bf3b21..a763bb242b 100644
--- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java
+++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java
@@ -155,7 +155,7 @@ public class MapActivityLayers {
mapInfoLayer = new MapInfoLayer(activity, routeLayer);
mapView.addLayer(mapInfoLayer, 9);
// 10. route info layer
- routeInfoLayer = new RouteInfoLayer(routingHelper, (LinearLayout) activity.findViewById(R.id.RouteLayout), contextMenuLayer);
+ routeInfoLayer = new RouteInfoLayer(routingHelper, activity, contextMenuLayer);
mapView.addLayer(routeInfoLayer, 10);
// 11. route info layer
mapControlsLayer = new MapControlsLayer(activity);
diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java
index 7e2a88eed9..02ec7a29de 100644
--- a/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java
+++ b/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java
@@ -12,6 +12,7 @@ import java.util.Set;
import net.osmand.ResultMatcher;
import net.osmand.Version;
+import net.osmand.access.AccessibilityMode;
import net.osmand.access.AccessibleToast;
import net.osmand.access.RelativeDirectionStyle;
import net.osmand.map.TileSourceManager;
@@ -84,6 +85,9 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
private ListPreference dayNightModePreference;
private ListPreference routerServicePreference;
+ private ListPreference accessibilityModePreference;
+ private ListPreference directionStylePreference;
+
private CheckBoxPreference routeServiceEnabled;
private BroadcastReceiver broadcastReceiver;
@@ -184,6 +188,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
registerBooleanPreference(osmandSettings.ZOOM_BY_TRACKBALL,screen);
registerBooleanPreference(osmandSettings.SCROLL_MAP_BY_GESTURES,screen);
registerBooleanPreference(osmandSettings.USE_SHORT_OBJECT_NAMES,screen);
+ registerBooleanPreference(osmandSettings.ACCESSIBILITY_EXTENSIONS,screen);
registerBooleanPreference(osmandSettings.USE_HIGH_RES_MAPS,screen);
registerBooleanPreference(osmandSettings.USE_ENGLISH_NAMES,screen);
registerBooleanPreference(osmandSettings.AUTO_ZOOM_MAP,screen);
@@ -283,9 +288,15 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference
}
registerListPreference(osmandSettings.MAP_TEXT_SIZE, screen, entries, floatValues);
+ entries = new String[AccessibilityMode.values().length];
+ for(int i=0; i items = new ArrayList();
+ items.add(getString(R.string.show_poi_on_map));
+ items.add(getString(R.string.navigate_to));
+ if (((OsmandApplication)getApplication()).accessibilityEnabled())
+ items.add(getString(R.string.show_details));
+
AlertDialog.Builder builder = new AlertDialog.Builder(SearchPOIActivity.this);
builder.setTitle(format);
- builder.setItems(new String[]{getString(R.string.show_poi_on_map), getString(R.string.navigate_to)}, new DialogInterface.OnClickListener(){
+ builder.setItems(items.toArray(new String[items.size()]), new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
+ if(which == 2){
+ showPOIDetails(amenity, settings.usingEnglishNames());
+ return;
+ }
if(which == 0){
int z = settings.getLastKnownMapZoom();
String poiSimpleFormat = OsmAndFormatter.getPoiSimpleFormat(amenity, SearchPOIActivity.this, settings.usingEnglishNames());
@@ -762,7 +777,34 @@ public class SearchPOIActivity extends OsmandListActivity implements SensorEvent
}
}
-
+ private void showPOIDetails(final Amenity amenity, boolean en) {
+ AlertDialog.Builder b = new AlertDialog.Builder(SearchPOIActivity.this);
+ b.setTitle(OsmAndFormatter.getPoiSimpleFormat(amenity, SearchPOIActivity.this, en));
+ b.setPositiveButton(R.string.default_buttons_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ });
+ List attributes = new ArrayList();
+ String direction = navigationInfo.getDirectionString(amenity.getLocation(), heading);
+ if (direction != null)
+ attributes.add(direction);
+ if (amenity.getPhone() != null)
+ attributes.add(getString(R.string.phone) + " " + amenity.getPhone());
+ if (amenity.getOpeningHours() != null)
+ attributes.add(getString(R.string.opening_hours) + " " + amenity.getOpeningHours());
+ attributes.add(getString(R.string.navigate_point_latitude) + " " + Double.toString(amenity.getLocation().getLatitude()));
+ attributes.add(getString(R.string.navigate_point_longitude) + " " + Double.toString(amenity.getLocation().getLongitude()));
+ b.setItems(attributes.toArray(new String[attributes.size()]),
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ }
+ });
+ b.show();
+ }
+
// Working with location listeners
private LocationListener networkListener = new LocationListener(){
@Override
diff --git a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java
index f543a7d6d6..8da1ee433d 100644
--- a/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java
+++ b/OsmAnd/src/net/osmand/plus/views/ContextMenuLayer.java
@@ -150,8 +150,26 @@ public class ContextMenuLayer extends OsmandMapLayer {
}
+ public void setSelections(List