我创建了自己的一组字母声音(取代了常规的a,b,c,.. z)。我想自定义对讲功能,因此在使用我自己的应用时,它会使用我自己的声音而不是内置声音。这意味着当视障用户试图阅读我的应用中的标签内容时,他会听到我自己的声音。这可能吗?如果是这样,那么实现这一目标的正确方法是什么?
答案 0 :(得分:1)
假设你自己的声音有“拼音”,这将非常容易。假设你有字母A,你希望它发音为“A”而不是声音“呃”。您可以简单地将“A”替换为“ay”,并且TalkBack会正确地发音。假设是这种情况,你想要做的事情很容易。如果你创造的是真实的声音,并且不能简单地使用我所假设的语音拼写,正如阿兰夫所说,这是不可能的。或者至少,不仅仅涉及对您的应用的更改!
您要做的是拦截来自您的应用程序的所有辅助功能事件,然后当您截取事件时,将内容描述替换为您的语音拼写内容说明。棘手的部分是模拟TalkBack逻辑以从Accessibility事件中获取文本,以便您获取正确的文本!否则你最终会修改错误的字符串,或者什么也不做。
如果将此辅助功能委托附加到视图heirarchy中的视图,则可以覆盖辅助功能节点信息的内容说明,并将其替换为您的语音发音。我附上了我的解决方案的所有相关部分。可能有一种方法可以通过仅查看根视图的可访问性委托而不是整个视图层次结构来实现此工作。我可能会稍后进行调查,但这只是花花公子,并且是对负载的线性操作(以及动态内容的视图添加),这一点都不错。
将此代码添加到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);
}
}
}
});