有没有办法让Talkback朗读?

3

我正在使我的应用程序变得更易访问,但出现了一个问题 - 没有办法让它“说话”!!

通过引用谷歌的库,我做出了

public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event)

在我的自定义视图上,我收到了正确的事件消息 - 我使用Log.d进行了检查。
然而,没有办法让Talkback发声...
我的应用程序运行于API8,因此也不能使用...。

onPopulateAccessibilityEvent()

我想的有问题吗?请有人帮帮我...


您是否在设备设置>辅助功能部分打开了TalkBack? - ataulm
5个回答

7

对于想要在Java中实现@Carter Hudson代码的人(请不要因为我在2019年仍未使用Kotlin而评判我):

AccessibilityManager accessibilityManager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
AccessibilityEvent accessibilityEvent = AccessibilityEvent.obtain();
accessibilityEvent.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT);

accessibilityEvent.getText().add("Text to be spoken by TalkBack");
if (accessibilityManager != null) {
    accessibilityManager.sendAccessibilityEvent(accessibilityEvent);
}

1
我仍然没有使用 Kotlin。 - Ahmad
1
它在2022年运行正常。 - dotrinh PM

4

当使用新数据集重新加载RecyclerView项目时,我需要宣布按钮何时变得可见。RecyclerView是一个框架视图,支持 Talkback / Accessibility。加载新数据后,Talkback会自动宣布“显示项目x到y共z项”。利用TTS API解决我提出的用例引入了以下缺点:

  • TTS实例初始化和管理对以下原因来说很麻烦且存疑:
    • 使用onInit侦听器管理TTS实例生命周期
    • 管理语言环境设置
    • 通过shutdown()管理资源将你绑定到文档中Activity的生命周期
    • 无法保证Activity的onDestroy被调用,这似乎是调用shutdown()以释放TTS资源的不良机制。

一种更简单、更易于维护的解决方案是与TalkBack友好合作,并像下面这样利用Accessibility API:

class AccessibilityHelper {
    companion object {
        @JvmStatic
        fun announceForAccessibility(context: Context, announcement: String) {
            context
                .getSystemService(ACCESSIBILITY_SERVICE)
                .let { it as AccessibilityManager }
                .let { manager ->
                    AccessibilityEvent
                        .obtain()
                        .apply {
                            eventType = TYPE_ANNOUNCEMENT
                            className = context.javaClass.name
                            packageName = context.packageName
                            text.add(announcement)
                        }
                        .let {
                            manager.sendAccessibilityEvent(it)
                        }
                }
        }
    }
}

您可以从任何需要的地方调用上述方法(我在我的基础活动中添加了一个方法以转发到助手)。这将把公告插入到TalkBack的消息队列中,以大声宣布,并且不需要处理TTS实例。最终,我添加了延迟参数和机制到我的实现中,以将这些事件与正在进行的UI触发事件分开,因为它们有时会覆盖手动公告。


0

这是一个非常实用的工具,可以随时随地使用,并且带有保护功能。

public static void speak_loud(String str_speak) {
    if (isGoogleTalkbackActive()) {
        AccessibilityManager accessibilityManager = (AccessibilityManager) getDefaultContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
        AccessibilityEvent accessibilityEvent = AccessibilityEvent.obtain();
        accessibilityEvent.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT);

        accessibilityEvent.getText().add(str_speak);
        if (accessibilityManager != null) {
            accessibilityManager.sendAccessibilityEvent(accessibilityEvent);
        }
    }
}


 public static boolean isGoogleTalkbackActive() {
        AccessibilityManager am = (AccessibilityManager) getDefaultContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
        if (am != null && am.isEnabled()) {
            List<AccessibilityServiceInfo> serviceInfoList = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN);
            if (!serviceInfoList.isEmpty())
                return true;
        }
        return false;
    }

0

announceForAccessibility 方法定义在 View 类中,可能在这里起到作用。它是在 API 级别 16 中引入的。更多细节请参见 此处


0
如果你想让它说话,可以使用TextToSpeech API。它接受一个字符串并朗读出来。

谢谢!这是解决问题的非常简单的方法! - Initiator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接