-
Notifications
You must be signed in to change notification settings - Fork 24.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Talkback double announcement when using accessibilityRole={'header'} #28800
Comments
Just as additional info I tested the above snack with the following devices: iPhone X [iOS v13.4] - Works as expected |
*** Note : |
Another test result: |
This has been fixed in v0.63.1: |
Just updated from RN 62.2 to 63.4 and accessibilityRole='header' doesn't work anymore. Does anyone experience the same issue? |
Yes! I have the same issue for Samsung s10e. It works as expected on any IOS device. |
@blavalla has not been able to reproduce this issue on the current RN version. Was this issue resolved by updates since the issue was created? |
I'm using a fork of react-native based on 61.4. I applied the change which @babylone-star said was added in 63.1. This bug was reported after my app was tested for accessibility on a Pixel 4XL, but I could not reproduce it on the only testing phone I have, a Samsung Galaxy S8. Someone else tested this for me on a Razor Phone 2 and was able to reproduce the error. So it seems like the header role was announced once on Samsung phones and twice on other phones. After applying this change, I don't hear the role announced at all on my Samsung device. I suspect the role will now be announced once on the Pixel 4XL and Razor Phone 2. |
@arsimr16, this one may actually be caused by a difference in Talkback or Android versions between devices as well, or could possibly be caused by Samsung's own fork of Talkback that they use. For what it's worth, I wasn't able to reproduce this on a Samsung Galaxy S20 or a Pixel 5. Both were running Android 11 however, and the latest versions of Talkback (Samsung's is technically a fork, but it's a new fork that should be up to date with Google's implementation). This was the link used to test: https://snack.expo.io/7tjnjlJbO On a technical note, the "header" role in RN right now is mapping to the older-style of heading that was only allowed within collection structures in Android (lists, grids, etc.). This works on both older and newer OS and Talkback versions (assuming your element is in a list), but starting in Android 9, Google added a more general-purpose API for headings. Since you are already working with a fork of RN, one thing to try would be to update this to the newer-style of API to see if it works to resolve the issue. It will limit support down to only API 28 and above (Android 9) or API 19 and above (Android 4.4.) if using the AndroidX compat library. To do that, you'll want to change these lines: react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java Lines 398 to 400 in dfa8eb0
To this:
@kacieb, what is the lowest version of Android that React Native currently supports? If it's above 19, we may want to just switch to use the newer API here. |
Thanks for the explanation. I switched to the newer API (I'm using AndroidX) and I still don't hear the header role being announced on my Samsung Galaxy S8 running Android 9. |
@arsimr16, just to confirm here. Are you using Google's Talkback (installed from the Play Store), or Samsung's Voice Assistant (comes pre-installed). Voice Assistant was quite an old fork of talkback, and may not have support for the header role. If you're using Talkback, which version? |
Thanks, I didn't know that. I was using the Samsung Voice Assistant. Let me try downloading Talkback. |
Works with Talkback! Thanks so much :) |
That's a good idea. The minimum SDK version supported is 21 so we can switch to the newer API. |
I had an issue with accessibilityRole="link", it's also announced twice like: " one link, link" |
@anup690 , was this double-link announcement on iOS or Android? If Android, was it using Samsung's "Voice Assistant" or Google's "Talkback"? If I had to guess, I'd say that this sounds like something that Samsung's Voice Assistant would do. Generally speaking, Voice Assistant tried to be a bit more like Apple's VoiceOver (which automatically announces "link" after links), and RN adding a roleDescription of "Link" may have doubled this up inadvertently. That's a random guess though, and since Samsung has deprecated Voice Assistant in favor of Talkback, I can't really verify it on any of my devices. If you do have a repro case, see if commenting out this line fixes it: react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java Line 375 in da899c0
|
@blavalla you guessed it bang on, it is Samsung's Voice Assistant indeed, got my tester do away with android talkback, yes I recently learned that Voice Assistant is a fork of talkback and outdated, though with talkback, it reads, |
From an Android perspective, Talkback is doing this for each TextView that contains a ClickableSpan or URLSpan in its text. From the RN side, whenever you set a link role on a component, we are under the hood creating a URLSpan and setting it as the full length of text on that component: react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.java Lines 377 to 387 in da899c0
This is definitely not a great experience currently, and I'm actually working right now to implement a better approach to link handling in general, where the links act more like they do on web surfaces and get focused on their own rather than being accessed via a dedicated menu. |
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
This issue was closed because it has been stalled for 7 days with no activity. |
Summary: This sync includes the changes from: - D56103750 - [TODO] A shim for SECRET_INTERNALS This sync includes the following changes: - **[b5e5ce8e0](facebook/react@b5e5ce8e0 )**: Update ReactNativeTypes for root options (part 2) ([#28857](facebook/react#28857)) //<Ricky>// - **[da6ba53b1](facebook/react@da6ba53b1 )**: [UMD] Remove umd builds ([#28735](facebook/react#28735)) //<Josh Story>// - **[0c245df1d](facebook/react@0c245df1d )**: Complete the typo fix ([#28856](facebook/react#28856)) //<Sebastian Silbermann>// - **[f82051d7a](facebook/react@f82051d7a )**: console test utils fix: match entire string, not just first letter ([#28855](facebook/react#28855)) //<Andrew Clark>// - **[4ca20fd36](facebook/react@4ca20fd36 )**: Test top level fragment inside lazy semantics ([#28852](facebook/react#28852)) //<Sebastian Markbåge>// - **[c0cf7c696](facebook/react@c0cf7c696 )**: Promote ASYNC_ITERATOR symbol to React Symbols ([#28851](facebook/react#28851)) //<Sebastian Markbåge>// - **[657428a9e](facebook/react@657428a9e )**: Add ReactNativeTypes for root options ([#28850](facebook/react#28850)) //<Ricky>// - **[7909d8eab](facebook/react@7909d8eab )**: [Flight] Encode ReadableStream and AsyncIterables ([#28847](facebook/react#28847)) //<Sebastian Markbåge>// - **[13eb61d05](facebook/react@13eb61d05 )**: Move enableUseDeferredValueInitialArg to canary ([#28818](facebook/react#28818)) //<Andrew Clark>// - **[8afa144bd](facebook/react@8afa144bd )**: Enable flag disableClientCache ([#28846](facebook/react#28846)) //<Jan Kassens>// - **[734956ace](facebook/react@734956ace )**: Devtools: Add support for useFormStatus ([#28413](facebook/react#28413)) //<Sebastian Silbermann>// - **[17e920c00](facebook/react@17e920c00 )**: [Flight Reply] Encode Typed Arrays and Blobs ([#28819](facebook/react#28819)) //<Sebastian Markbåge>// - **[0347fcd00](facebook/react@0347fcd00 )**: Add on(Caught|Uncaught|Recoverable) opts to RN ([#28836](facebook/react#28836)) //<Ricky>// - **[c113503ad](facebook/react@c113503ad )**: Flush direct streams in Bun ([#28837](facebook/react#28837)) //<Kenta Iwasaki>// - **[9defcd56b](facebook/react@9defcd56b )**: Remove redundant props assign ([#28829](facebook/react#28829)) //<Sebastian Silbermann>// - **[ed4023603](facebook/react@ed4023603 )**: Fix mistaken "react-server" condition ([#28835](facebook/react#28835)) //<Sebastian Markbåge>// - **[c8a035036](facebook/react@c8a035036 )**: [Fizz] hoistables should never flush before the preamble ([#28802](facebook/react#28802)) //<Josh Story>// - **[4f5c812a3](facebook/react@4f5c812a3 )**: DevTools: Rely on sourcemaps to compute hook name of built-in hooks in newer versions ([#28593](facebook/react#28593)) //<Sebastian Silbermann>// - **[435415962](facebook/react@435415962 )**: Backwards compatibility for string refs on WWW ([#28826](facebook/react#28826)) //<Jack Pope>// - **[608edcc90](facebook/react@608edcc90 )**: [tests] add `assertConsole<method>Dev` helpers ([#28732](facebook/react#28732)) //<Ricky>// - **[da69b6af9](facebook/react@da69b6af9 )**: ReactDOM.requestFormReset ([#28809](facebook/react#28809)) //<Andrew Clark>// - **[374b5d26c](facebook/react@374b5d26c )**: Scaffolding for requestFormReset API ([#28808](facebook/react#28808)) //<Andrew Clark>// - **[41950d14a](facebook/react@41950d14a )**: Automatically reset forms after action finishes ([#28804](facebook/react#28804)) //<Andrew Clark>// - **[dc6a7e01e](facebook/react@dc6a7e01e )**: [Float] Don't preload images inside `<noscript>` ([#28815](facebook/react#28815)) //<Josh Story>// - **[3f947b1b4](facebook/react@3f947b1b4 )**: [tests] Assert scheduler log empty in internalAct ([#28737](facebook/react#28737)) //<Ricky>// - **[bf09089f6](facebook/react@bf09089f6 )**: Remove Scheduler.log from ReactSuspenseFuzz-test ([#28812](facebook/react#28812)) //<Ricky>// - **[84cb3b4cb](facebook/react@84cb3b4cb )**: Hardcode disableIEWorkarounds for www ([#28811](facebook/react#28811)) //<Ricky>// - **[2243b40ab](facebook/react@2243b40ab )**: [tests] assertLog before act in useEffectEvent ([#28763](facebook/react#28763)) //<Ricky>// - **[dfc64c6e3](facebook/react@dfc64c6e3 )**: [tests] assertLog before act in ReactUse ([#28762](facebook/react#28762)) //<Ricky>// - **[42eff4bc7](facebook/react@42eff4bc7 )**: [tests] Fix assertions not flushed before act ([#28745](facebook/react#28745)) //<Ricky>// - **[ed3c65caf](facebook/react@ed3c65caf )**: Warn if outdated JSX transform is detected ([#28781](facebook/react#28781)) //<Andrew Clark>// - **[3f9e237a2](facebook/react@3f9e237a2 )**: Fix: Suspend while recovering from hydration error ([#28800](facebook/react#28800)) //<Andrew Clark>// - **[7f5d25e23](facebook/react@7f5d25e23 )**: Fix cloneElement using string ref w no owner ([#28797](facebook/react#28797)) //<Joseph Savona>// - **[bf40b0244](facebook/react@bf40b0244 )**: [Fizz] Stop publishing external-runtime to stable channel ([#28796](facebook/react#28796)) //<Josh Story>// - **[7f93cb41c](facebook/react@7f93cb41c )**: [DOM] Infer react-server entries bundles if not explicitly configured ([#28795](facebook/react#28795)) //<Josh Story>// - **[f61316535](facebook/react@f61316535 )**: Rename SECRET INTERNALS to `__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE` ([#28789](facebook/react#28789)) //<Sebastian Markbåge>// - **[9644d206e](facebook/react@9644d206e )**: Soften useFormState warning ([#28788](facebook/react#28788)) //<Ricky>// - **[c771016e1](facebook/react@c771016e1 )**: Rename The Secret Export of Server Internals ([#28786](facebook/react#28786)) //<Sebastian Markbåge>// - **[d50323eb8](facebook/react@d50323eb8 )**: Flatten ReactSharedInternals ([#28783](facebook/react#28783)) //<Sebastian Markbåge>// - **[f62cf8c62](facebook/react@f62cf8c62 )**: [Float] treat `props.async` in Float consistent with the rest of react-dom ([#26760](facebook/react#26760)) //<Josh Story>// - **[dfd3d5af8](facebook/react@dfd3d5af8 )**: Add support for transition{run,start,cancel} events ([#27345](facebook/react#27345)) //<Hugo Sales>// - **[1f8327f83](facebook/react@1f8327f83 )**: [Fiber] Use real event priority for hydration scheduling ([#28765](facebook/react#28765)) //<Josh Story>// - **[97c90ed88](facebook/react@97c90ed88 )**: [DOM] Shrink ReactDOMCurrentDispatcher method names ([#28770](facebook/react#28770)) //<Josh Story>// - **[9007fdc8f](facebook/react@9007fdc8f )**: [DOM] Shrink ReactDOMSharedInternals source representation ([#28771](facebook/react#28771)) //<Josh Story>// - **[14f50ad15](facebook/react@14f50ad15 )**: [Flight] Allow lazily resolving outlined models ([#28780](facebook/react#28780)) //<Sebastian Markbåge>// - **[4c12339ce](facebook/react@4c12339ce )**: [DOM] move `flushSync` out of the reconciler ([#28500](facebook/react#28500)) //<Josh Story>// - **[8e1462e8c](facebook/react@8e1462e8c )**: [Fiber] Move updatePriority tracking to renderers ([#28751](facebook/react#28751)) //<Josh Story>// - **[0b3b8a6a3](facebook/react@0b3b8a6a3 )**: jsx: Remove unnecessary hasOwnProperty check ([#28775](facebook/react#28775)) //<Andrew Clark>// - **[2acfb7b60](facebook/react@2acfb7b60 )**: [Flight] Support FormData from Server to Client ([#28754](facebook/react#28754)) //<Sebastian Markbåge>// - **[d1547defe](facebook/react@d1547defe )**: Fast JSX: Don't clone props object ([#28768](facebook/react#28768)) //<Andrew Clark>// - **[bfd8da807](facebook/react@bfd8da807 )**: Make class prop resolution faster ([#28766](facebook/react#28766)) //<Andrew Clark>// - **[cbb6f2b54](facebook/react@cbb6f2b54 )**: [Flight] Support Blobs from Server to Client ([#28755](facebook/react#28755)) //<Sebastian Markbåge>// - **[f33a6b69c](facebook/react@f33a6b69c )**: Track Owner for Server Components in DEV ([#28753](facebook/react#28753)) //<Sebastian Markbåge>// - **[e3ebcd54b](facebook/react@e3ebcd54b )**: Move string ref coercion to JSX runtime ([#28473](facebook/react#28473)) //<Andrew Clark>// - **[fd0da3eef](facebook/react@fd0da3eef )**: Remove _owner field from JSX elements in prod if string refs are disabled ([#28739](facebook/react#28739)) //<Sebastian Markbåge>// Changelog: [General][Changed] - React Native sync for revisions 48b4ecc...b5e5ce8 jest_e2e[run_all_tests] bypass-github-export-checks Reviewed By: kassens Differential Revision: D56251607 fbshipit-source-id: e16db2fa101fc7ed1e009158c76388206beabd5f
Please provide all the information requested. Issues that do not follow this format are likely to stall.
Description
For whatever reason when attaching
accessibilityRole={'header'}
to an element it is announcing 'heading' twice with TalkBack on. Testing the same component on iOS using VoiceOver achieves the expected result of it only announcing once.React Native version:
61.4
Steps To Reproduce
Provide a detailed list of steps that reproduce the issue.
Expected Results
Talkback should announce 'header' only once when using TalkBack like it does with VoiceOver.
Snack, code example, screenshot, or link to a repository:
https://snack.expo.io/@jcron/accessibility-role-double-announce
The text was updated successfully, but these errors were encountered: