From 3abecf2ee9fc724af571f8c7da4302f7bee9eadb Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Sat, 27 Jul 2013 00:11:20 +0200 Subject: Accessibility for Android This enables both modes for TalkBack, explore-by-touch and the normal swiping mode. It is partially inspired by the BarGraphView example of the Google/Android Eyes-Free project. Note that for any accessibility to work you'll need a device with api level 16 at least. Using reflection we should be able to dynamically pick up the classes if we have the high enough api level. Change-Id: I11b93bead451483782a1711434d45c8f9a35996f Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../src/org/qtproject/qt5/android/QtSurface.java | 46 +++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) (limited to 'src/android/jar') diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java index 6cc2f1e333..cd0bddf2c8 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java @@ -55,17 +55,23 @@ import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + public class QtSurface extends SurfaceView implements SurfaceHolder.Callback { private Bitmap m_bitmap = null; private boolean m_started = false; private boolean m_usesGL = false; private GestureDetector m_gestureDetector; + private Object m_accessibilityDelegate = null; public QtSurface(Context context, int id) { super(context); - setFocusable(true); + setFocusable(false); + setFocusableInTouchMode(false); + getHolder().addCallback(this); getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU); setId(id); @@ -107,6 +113,44 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback if (m_usesGL) holder.setFormat(PixelFormat.RGBA_8888); + + + // Initialize Accessibility + // The accessibility code depends on android API level 16, so dynamically resolve it + try { + final String a11yDelegateClassName = "org.qtproject.qt5.android.accessibility.QtAccessibilityDelegate"; + Class qtDelegateClass = Class.forName(a11yDelegateClassName); + Constructor constructor = qtDelegateClass.getConstructor(Class.forName("android.view.View")); + m_accessibilityDelegate = constructor.newInstance(this); + + Class a11yDelegateClass = Class.forName("android.view.View$AccessibilityDelegate"); + Method setDelegateMethod = this.getClass().getMethod("setAccessibilityDelegate", a11yDelegateClass); + setDelegateMethod.invoke(this, m_accessibilityDelegate); + } catch (ClassNotFoundException e) { + // Class not found is fine since we are compatible with Android API < 16, but the function will + // only be available with that API level. + } catch (Exception e) { + // Unknown exception means something went wrong. + Log.w("Qt A11y", "Unknown exception: " + e.toString()); + } + } + + public boolean dispatchHoverEvent(MotionEvent event) { + // Always attempt to dispatch hover events to accessibility first. + if (m_accessibilityDelegate != null) { + try { + Method dispHoverA11y = m_accessibilityDelegate.getClass().getMethod("dispatchHoverEvent", MotionEvent.class); + boolean ret = (Boolean) dispHoverA11y.invoke(m_accessibilityDelegate, event); + if (ret) + return true; + SurfaceView view = (SurfaceView) this; + Method dispHoverView = view.getClass().getMethod("dispatchHoverEvent", MotionEvent.class); + return (Boolean) dispHoverView.invoke(view, event); + } catch (Exception e) { + Log.w("Qt A11y", "EXCEPTION in dispatchHoverEvent for Accessibility: " + e); + } + } + return false; } @Override -- cgit v1.2.3