How to know if Android TalkBack is active?

23,053

Solution 1

For an example, look at isScreenReaderActive() in HomeLauncher.java file in the Eyes-Free shell application (via groups thread).

To sum up: you detect all screen readers with Intents, then query the status provider of each to see if it is active.

If you really want to limit it to TalkBack only, you could try checking the ResolveInfo.serviceInfo.packageName for each result returned from queryIntentServices() to see if it matches the TalkBack package.

Solution 2

The recommended way of doing this is to query the AccessibilityManager for the enabled state of accessibility services.

AccessibilityManager am = (AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE);
boolean isAccessibilityEnabled = am.isEnabled();
boolean isExploreByTouchEnabled = am.isTouchExplorationEnabled();

Solution 3

Novoda have released a library called accessibilitools which does this check. It queries the accessibility manager to check if there are any accessibility services enabled that support the "spoken feedback" flag.

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);
}

Solution 4

You can create an inline function in kotlin like:

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}

And then you can just call it whenever you need it like:

if(context.isScreenReaderOn()){
...
}

Tested and works fine for now.

Solution 5

    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;
Share:
23,053
David Carvalho
Author by

David Carvalho

Updated on July 09, 2022

Comments

  • David Carvalho
    David Carvalho almost 2 years

    I'm developing an application that uses TalkBack to guide people through it. However, in those situations I want to have some subtile differences in the layout of the application so navigation is easier and also have extra voice outputs (with TextToSpeech) to help guide the user.

    My problem is that I only want those changes and extra outputs if the user has TalkBack active.

    Is there any way to know if it is? I didn't find anything specific to access TalkBack settings directly, but I was hoping there was some form of accessing general phone settings that could let me know what I need.

    Regards and thanks in advance.

  • David Carvalho
    David Carvalho over 13 years
    I ended up going through all the services and see if the TalkBack one was active, but your solution is much better, thanks. I did had a problem with a cracked ROM, though. No services were being returned.
  • pandre
    pandre almost 12 years
    Mike, I have tried this in Jelly Bean and it doesn't seem to work... the cursor seems to be empty. DO you have any idea on how to do this in Jelly Bean? I created a new question: stackoverflow.com/questions/11831666/…
  • ataulm
    ataulm over 9 years
    If the TalkBack service is suspended (using the gesture shortcuts), the AccessibilityManager will not change its enabled state to disabled. Very very small edge case, I suppose, and technically it is still enabled, but this tripped me up today.
  • ataulm
    ataulm almost 9 years
    If you use the TalkBack service on the Nexus Player, does isTouchExplorationEnabled() still return true?
  • ataulm
    ataulm over 8 years
    To answer my own question, touch exploration is available on Nexus Player (on Lollipop at least) and it will return true if this is checked.
  • Nar Gar
    Nar Gar about 8 years
    Exploring the git hub one can see lots of good lines of Android API. Particularly detecting if a voice over service is enabled using 2 lines of code was my pick. Neat and nice.
  • ataulm
    ataulm over 7 years
    They could change the name of the settings activity in future updates.
  • Jonik
    Jonik over 6 years
    More details: if you are strictly interested in whether TalkBack is enabled, use am.isTouchExplorationEnabled(). (If Select to Speak is enabled and TalkBack disabled, am.isEnabled() will still return true.)
  • adiga
    adiga over 6 years
    I think OP is asking about programmatically checking if TalkBack is active.
  • Nick
    Nick over 6 years
    Perfect! Thank you for your time!
  • latsson
    latsson over 3 years
    Even more kotlin to have a val instead of a function val Context.isScreenReaderOn: Boolean get() { val am = getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager if (am.isEnabled) { val serviceInfoList = am.getEnabledAccessibilityServiceList(AccessibilityServiceIn‌​fo.FEEDBACK_SPOKEN) if (serviceInfoList.isNotEmpty()) return true } return false }
  • Jaco
    Jaco over 3 years
    But you can check the Android Accessibility Suite package name with accessibilityServiceInfo.getResolveInfo().serviceInfo.proces‌​sName instead of its name
  • Alvin Dizon
    Alvin Dizon over 3 years
    This will still return the previous value if you return to your app after disabling/enabling talkback or screen reader from Settings app...
  • rekire
    rekire over 2 years
    Interesting, but that repo was archived 5 days ago.
  • ataulm
    ataulm over 2 years
    Added code from the repo. It was archived because no one's around to maintain it anymore I suppose.