Android 对讲辅助功能 - 自定义声音

标签 android accessibility talkback

我创建了自己的一组字母发音(替换常规的 a、b、c、..z)。我想自定义对讲功能,以便在使用我自己的应用程序时使用我自己的声音而不是内置声音。这意味着当视障用户尝试阅读我的应用程序中的标签内容时,他会听到我自己的声音。这可能吗?如果是这样,实现这一目标的正确方法是什么?

最佳答案

假设您自己的声音具有“语音拼写”,这将非常简单。假设您有字母 A,并且您希望它发音为“A”,而不是发音“uh”。您只需将“A”替换为“ay”,TalkBack 就会正确发音。假设是这种情况,那么你想做的事情就很容易了。如果你创造的是实际的声音,并且不能像我假设的那样简单地使用拼音,正如 alanv 所说,这是不可能的。或者至少,涉及的不仅仅是对应用程序的更改!

您想要做的是拦截来自应用程序的所有辅助功能事件,然后当您拦截事件时,将内容描述替换为您的拼音内容描述。棘手的部分是模拟 TalkBack 逻辑以从辅助功能事件中抓取文本,以便抓取正确的文本!否则你最终会修改错误的字符串,或者什么也不修改。

如果您将此辅助功能委托(delegate)附加到 View 层次结构中的 View ,您可以覆盖辅助功能节点信息的内容描述,并将其替换为您的语音发音。我附上了解决方案的所有相关部分。可能有一种方法可以通过仅修改 Root View 的可访问性委托(delegate)而不是整个 View 层次结构来实现此目的。我稍后可能会进行更多调查,但这非常有效,并且是加载的线性操作(以及动态内容的 View 添加),这一点也不差。

将此代码添加到您的 onCreate 方法中,并修改“convertText”函数以满足您的需要,您应该已准备就绪!

final View.AccessibilityDelegate accessiblityDelegate =  new View.AccessibilityDelegate() {

    String convertText(String argString) {
        //Do your phonetic conversion in here!
        //A little Regex.  A little String replacement and you're golden!
        return argString;
    }
    @Override
    public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo nodeInfo) {
        super.onInitializeAccessibilityNodeInfo(host, nodeInfo);

        String text = null;

        if (nodeInfo.getContentDescription() != null) {
            text = convertText(nodeInfo.getContentDescription().toString());
        } else if (nodeInfo.getText() != null) {
            text = convertText(nodeInfo.getText().toString());
        } else if (host instanceof TextView) {
            TextView textView = (TextView)host;
            text = convertText(textView.getText().toString());
        }

        if (text != null) nodeInfo.setContentDescription(text);
    }

};

rootView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        addAccessibilityDelegateToViews(v);
    }

    private void addAccessibilityDelegateToViews(View v) {
        v.setAccessibilityDelegate(accessiblityDelegate);

        if (v instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup)v;

            for (int i = 0; i < viewGroup.getChildCount(); ++i) {
                View view = viewGroup.getChildAt(i);

                addAccessibilityDelegateToViews(view);
            }
        }
    }
});

关于Android 对讲辅助功能 - 自定义声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32629035/

相关文章:

android - 如何告诉 TalkBack 自定义 View 被用作按钮

Android NestedScrollView TalkBack - 仅导航到屏幕上可见的项目,跳过滚动下方的元素并转到底部选项卡

java - 为什么 context.startActivity(intent) 没有启动 Activity 以及如何在 android 中处理异常?

ios - 如何使 MasterDetailPage 图标 VoiceOver 易于访问?

带语音识别器的 Android 自定义键盘

html - 仅使用 SVG 开发整个网站

javascript - 如何确保函数 "window.location.reload()"只触发一次而不是无限循环?

android - 我可以为仅由 TalkBack 宣布的 TextView 提供额外的标签,而不是在视觉上显示吗?

java - 标准 zip 实用程序无法解压缩由 java.util.zip 压缩的文件

java - 查找 EditText 的行尾