DustinB
DustinB

Reputation: 11284

How to get React-Native to announce specific accessibility message via AccessibiliyManager?

How would you approach announcing an accessibility message via TalkBack on Android (or iOS equivalent)? Is this possible with existing ReactNative version? I just can't find any information and it seems quite limited, esp for Android clients (ie, "button", "radio button checked/unchecked" are the only two states I can see for any views.

Wondering if this is possible ootb, or do I need to create a bridge that exposes this from native?

Upvotes: 1

Views: 2802

Answers (2)

Maxim Toyberman
Maxim Toyberman

Reputation: 2006

@DustinB You can use this library i wrote:

https://github.com/MaxToyberman/react-native-accessibility

follow this steps:

1)npm install react-native-accessibility --save

2)react-native link react-native-accessibility

3)import { announceForAccessibility } from 'react-native-accessibility'

4) announceForAccessibility('Some message to be announced')

Upvotes: 2

DustinB
DustinB

Reputation: 11284

I ended up creating an accessibility module (just for Android currently, will have to implement same functionality on iOS later). Here are the steps:

Created AccessibilityModule.java:

public class AccessibilityModule extends ReactContextBaseJavaModule {

    private final ReactApplicationContext mContext;

    public AccessibilityModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mContext = reactContext;
    }

    @Override
    public String getName() {
        return "A11yModule";
    }

    @ReactMethod
    void announce(String message) {
        final AccessibilityManager a11yManager = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
        if (a11yManager == null || !a11yManager.isEnabled()) {
            return;
        }

        final int eventType = AccessibilityEventCompat.TYPE_ANNOUNCEMENT;
        final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
        event.getText().add(message);
        event.setClassName(AccessibilityModule.class.getName());
        event.setPackageName(mContext.getPackageName());

        a11yManager.sendAccessibilityEvent(event);
    }
}

Then, in my ReactPackage class, I register the module:

@Override
public List<NativeModule> createNativeModules(
        ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();

    modules.add(new AccessibilityModule(reactContext));

    return modules;
}

Then, import NativeModules and use it in javascript:

import { NativeModules } from 'react-native'
const A11yModule = NativeModules.A11yModule; // this matches getName()
A11yModule.announce("Hello World");

Upvotes: 2

Related Questions