我正在开发一个使用 TalkBack 来引导人们完成它的应用程序。但是,在这些情况下,我希望在应用程序的布局中有一些细微的差异,以便导航更容易,并且还有额外的语音输出(使用 TextToSpeech)来帮助引导用户。
我的问题是,如果用户激活了 TalkBack,我只想要这些更改和额外的输出。
有没有办法知道是不是?我没有找到任何特定于直接访问 TalkBack 设置的内容,但我希望有某种形式的访问通用电话设置可以让我知道我需要什么。
提前致以问候和感谢。
我正在开发一个使用 TalkBack 来引导人们完成它的应用程序。但是,在这些情况下,我希望在应用程序的布局中有一些细微的差异,以便导航更容易,并且还有额外的语音输出(使用 TextToSpeech)来帮助引导用户。
我的问题是,如果用户激活了 TalkBack,我只想要这些更改和额外的输出。
有没有办法知道是不是?我没有找到任何特定于直接访问 TalkBack 设置的内容,但我希望有某种形式的访问通用电话设置可以让我知道我需要什么。
提前致以问候和感谢。
推荐的方法是查询AccessibilityManager
无障碍服务的启用状态。
AccessibilityManager am = (AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE);
boolean isAccessibilityEnabled = am.isEnabled();
boolean isExploreByTouchEnabled = am.isTouchExplorationEnabled();
Novoda 发布了一个名为accessibilitools的库来进行这项检查。它查询可访问性管理器以检查是否启用了任何支持“口头反馈”标志的可访问性服务。
AccessibilityServices services = AccessibilityServices.newInstance(context);
services.isSpokenFeedbackEnabled();
public boolean isSpokenFeedbackEnabled() {
List<AccessibilityServiceInfo> enabledServices = getEnabledServicesFor(AccessibilityServiceInfo.FEEDBACK_SPOKEN);
return !enabledServices.isEmpty();
}
private List<AccessibilityServiceInfo> getEnabledServicesFor(int feedbackTypeFlags) {
return accessibilityManager.getEnabledAccessibilityServiceList(feedbackTypeFlags);
}
例如,查看Eyes-Free shell 应用程序isScreenReaderActive()
中的HomeLauncher.java 文件(通过组线程)。
总结一下:您检测所有带有 Intent 的屏幕阅读器,然后查询每个屏幕阅读器的状态提供程序以查看它是否处于活动状态。
如果您真的想将其限制为仅 TalkBack,您可以尝试检查ResolveInfo.serviceInfo.packageName
返回的每个结果queryIntentServices()
以查看它是否与 TalkBack 包匹配。
您可以在 kotlin 中创建一个内联函数,例如:
fun Context.isScreenReaderOn():Boolean{
val am = getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager
if (am != null && am.isEnabled) {
val serviceInfoList =
am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN)
if (!serviceInfoList.isEmpty())
return true
}
return false}
然后您可以在需要时调用它,例如:
if(context.isScreenReaderOn()){
...
}
经测试,目前工作正常。
AccessibilityManager am = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
if (am != null && am.isEnabled()) {
List<AccessibilityServiceInfo> serviceInfoList = am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN);
if (!serviceInfoList.isEmpty())
return true;
}
return false;
对我来说,我以这种方式解决了这个问题,它在我的项目中运行良好:
详细代码如下:</p>
private static final String TALKBACK_SETTING_ACTIVITY_NAME = "com.android.talkback.TalkBackPreferencesActivity";
public static boolean accessibilityEnable(Context context) {
boolean enable = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
try {
AccessibilityManager manager = (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
List<AccessibilityServiceInfo> serviceList = manager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN);
for (AccessibilityServiceInfo serviceInfo : serviceList) {
String name = serviceInfo.getSettingsActivityName();
if (!TextUtils.isEmpty(name) && name.equals(TALKBACK_SETTING_ACTIVITY_NAME)) {
enable = true;
}
}
} catch (Exception e) {
if (Logging.isDebugLogging()) {
e.printStackTrace();
}
}
}
return enable;
}
感谢@david-z 的回答(https://stackoverflow.com/a/41357058/2713403),我采用这种方法来了解 Google 的 Android Accessibility Suite 是否已启用
/**
* This method checks if Google Talkback is enabled by using the [accessibilityManager]
*/
private fun isGoogleTalkbackActive(accessibilityManager : AccessibilityManager) : Boolean
{
val accessibilityServiceInfoList = accessibilityManager.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_SPOKEN)
for (accessibilityServiceInfo in accessibilityServiceInfoList)
{
if ("com.google.android.marvin.talkback".equals(accessibilityServiceInfo.resolveInfo.serviceInfo.processName))
{
return true
}
}
return false
}
请记住将 google URI 注册为常量 :) 并按照 @caseyburkhardt 的说明获取 Accessibility Manager 实例 ( https://stackoverflow.com/a/12362545/2713403 )。与@david-z 答案的不同之处在于我得到了 Android Accessibility Suite 包名称而不是其应用名称,因为它更安全。如果您想在此检查后查看是否启用了其他辅助功能套件(如三星屏幕阅读器),您可以检查
if (accessibilityManager.isTouchExplorationEnabled)
干杯!
打开系统设置并转到辅助功能并点击关闭对讲选项