从入门小白到精通,玩转React Native鸿蒙跨平台开发:AccessibilityInfo监听设备是否正在运行读屏应用
React Native 的 AccessibilityInfo 模块提供了与设备辅助功能交互的能力,主要包括监听辅助功能状态变化(如屏幕阅读器、减少动画等设置)和主动发送语音公告两大核心功能。开发者可通过该模块检测系统辅助功能变化,动态调整应用行为,并使用 announceForAccessibility 方法向屏幕阅读器发送自定义语音提示。此外还提供异步查询当前系统辅助功能状态的方法,帮助开发
AccessibilityInfo
有时候我们希望知道用户的设备是否正在运行读屏应用。AccessibilityInfo正是用于此目的。你可以用它来查询读屏应用的当前状态,并且可以监听其状态变化。
好的,以下是关于 React Native 中 AccessibilityInfo 模块的详细说明。
AccessibilityInfo 是 React Native 提供的一个核心模块,用于与设备的辅助功能(Accessibility)服务进行交互。它允许开发者检测系统辅助功能设置的变化,并主动向屏幕阅读器等工具发送自定义的可访问性公告,从而显著提升应用对视障用户或其他有特殊需求用户的友好度。
核心功能概览
AccessibilityInfo 主要提供两大类功能:事件监听和主动通知。
- 事件监听 (addEventListener)
你可以使用 addEventListener 方法监听系统辅助功能状态的变化。这对于根据用户的偏好动态调整应用行为非常有用。
支持的事件类型包括:
accessibilityServiceChanged(Android):当设备上启用或禁用了某些辅助功能服务(如 TalkBack)时触发。事件处理程序会收到一个布尔值,true表示服务已启用。announcementFinished(鸿蒙OpenHarmony):当屏幕阅读器完成一次公告时触发。事件处理程序会收到一个包含announcement(被朗读的字符串)和success(公告是否成功)字段的对象。boldTextChanged(鸿蒙OpenHarmony):当系统“加粗文本”功能的切换状态改变时触发。返回true表示已启用。grayscaleChanged(鸿蒙OpenHarmony):当系统“灰度”模式的切换状态改变时触发。返回true表示已启用。invertColorsChanged(鸿蒙OpenHarmony):当系统“反转颜色”功能的切换状态改变时触发。返回true表示已启用。reduceMotionChanged:当“减少动画”功能的切换状态改变时触发。返回true表示已启用(动画被关闭或减速)。reduceTransparencyChanged(鸿蒙OpenHarmony):当“减少透明度”功能的切换状态改变时触发。返回true表示已启用。screenReaderChanged:当系统屏幕阅读器(如 VoiceOver)的启用状态改变时触发。返回true表示屏幕阅读器已启用。
示例:监听屏幕阅读器状态变化
import { AccessibilityInfo } from 'react-native';
// 添加事件监听
const subscription = AccessibilityInfo.addEventListener(
'screenReaderChanged',
(isScreenReaderEnabled) => {
console.log('屏幕阅读器是否启用:', isScreenReaderEnabled);
// 根据状态调整UI或行为
}
);
// 之后,记得清理订阅以避免内存泄漏
// subscription.remove();
- 主动通知 (announceForAccessibility)
这是 AccessibilityInfo 最强大的功能之一,它允许你主动向系统屏幕阅读器发送文本进行朗读。
announceForAccessibility(announcement: string):将指定的字符串发送给屏幕阅读器进行朗读。默认情况下,这会中断任何正在进行的语音。announceForAccessibilityWithOptions(announcement: string, options: { queue?: boolean }):与上一个方法类似,但提供了更多选项。通过在options对象中设置{ queue: true },可以使公告在现有语音之后排队播放,而不是打断。
示例:向屏幕阅读器发送公告
import { AccessibilityInfo } from 'react-native';
// 立即朗读
AccessibilityInfo.announceForAccessibility('操作成功完成!');
// 在现有语音后排队朗读
AccessibilityInfo.announceForAccessibilityWithOptions('请检查您的订单详情', { queue: true });
- 查询系统状态 (异步方法)
这些方法用于查询当前系统的辅助功能设置状态,它们都返回一个 Promise。
isBoldTextEnabled()(鸿蒙OpenHarmony):查询“加粗文本”是否启用。isGrayscaleEnabled()(鸿蒙OpenHarmony):查询“灰度”模式是否启用。isInvertColorsEnabled()(鸿蒙OpenHarmony):查询“反转颜色”是否启用。isReduceTransparencyEnabled()(鸿蒙OpenHarmony):查询“减少透明度”是否启用。getRecommendedTimeoutMillis(originalTimeout: number)(Android):获取系统推荐的超时时间(毫秒),用于辅助功能操作。如果系统未设置,则返回originalTimeout。
实际案例演示:
import React, {useState, useEffect} from 'react';
import {AccessibilityInfo, View, Text, StyleSheet, TouchableOpacity, Alert} from 'react-native';
const App = () => {
const [reduceMotionEnabled, setReduceMotionEnabled] = useState(false);
const [screenReaderEnabled, setScreenReaderEnabled] = useState(false);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
const reduceMotionChangedSubscription = AccessibilityInfo.addEventListener(
'reduceMotionChanged',
isReduceMotionEnabled => {
setReduceMotionEnabled(isReduceMotionEnabled);
},
);
const screenReaderChangedSubscription = AccessibilityInfo.addEventListener(
'screenReaderChanged',
isScreenReaderEnabled => {
setScreenReaderEnabled(isScreenReaderEnabled);
},
);
AccessibilityInfo.isReduceMotionEnabled().then(isReduceMotionEnabled => {
setReduceMotionEnabled(isReduceMotionEnabled);
});
AccessibilityInfo.isScreenReaderEnabled().then(isScreenReaderEnabled => {
setScreenReaderEnabled(isScreenReaderEnabled);
});
return () => {
reduceMotionChangedSubscription.remove();
screenReaderChangedSubscription.remove();
};
}, []);
const toggleReduceMotion = async () => {
setIsLoading(true);
try {
await AccessibilityInfo.setReduceMotionEnabled(!reduceMotionEnabled);
Alert.alert('Success', `Reduce motion is now ${!reduceMotionEnabled ? 'enabled' : 'disabled'}`);
} catch (error) {
Alert.alert('Error', 'Failed to toggle reduce motion');
} finally {
setIsLoading(false);
}
};
const toggleScreenReader = async () => {
setIsLoading(true);
try {
await AccessibilityInfo.setScreenReaderEnabled(!screenReaderEnabled);
Alert.alert('Success', `Screen reader is now ${!screenReaderEnabled ? 'enabled' : 'disabled'}`);
} catch (error) {
Alert.alert('Error', 'Failed to toggle screen reader');
} finally {
setIsLoading(false);
}
};
return (
<View style={styles.container}>
<Text style={[styles.status, { color: reduceMotionEnabled ? 'green' : 'red' }]}>
The reduce motion is {reduceMotionEnabled ? 'enabled' : 'disabled'}.
</Text>
<TouchableOpacity
style={styles.button}
onPress={toggleReduceMotion}
disabled={isLoading}
>
<Text style={styles.buttonText}>
{isLoading ? 'Loading...' : 'Toggle Reduce Motion'}
</Text>
</TouchableOpacity>
<Text style={[styles.status, { color: screenReaderEnabled ? 'green' : 'red' }]}>
The screen reader is {screenReaderEnabled ? 'enabled' : 'disabled'}.
</Text>
<TouchableOpacity
style={styles.button}
onPress={toggleScreenReader}
disabled={isLoading}
>
<Text style={styles.buttonText}>
{isLoading ? 'Loading...' : 'Toggle Screen Reader'}
</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
status: {
margin: 20,
fontSize: 16,
},
button: {
backgroundColor: '#007AFF',
padding: 15,
borderRadius: 10,
margin: 10,
width: 200,
alignItems: 'center',
},
buttonText: {
color: 'white',
fontSize: 16,
},
});
export default App;
这段React Native代码实现了一个完整的无障碍功能管理应用,其核心原理基于React Native的无障碍API和React的响应式状态管理机制。应用通过AccessibilityInfo模块来监听和控制系统级别的无障碍设置,包括减少动画效果和屏幕阅读器功能。
在初始化阶段,应用使用useEffect钩子来建立与设备无障碍系统的连接。它通过AccessibilityInfo.isReduceMotionEnabled()和AccessibilityInfo.isScreenReaderEnabled()这两个异步方法获取当前的系统设置状态,并将结果存储在组件的状态中。同时,应用注册了两个事件监听器来实时响应系统无障碍设置的变更,当用户在系统设置中修改这些选项时,应用界面会自动更新以反映最新的状态。

状态管理方面,应用维护了三个关键状态变量:reduceMotionEnabled用于跟踪减少动画功能的启用状态,screenReaderEnabled用于跟踪屏幕阅读器的启用状态,isLoading用于管理异步操作期间的加载状态。这种状态设计确保了用户界面的实时响应性和操作反馈的完整性。
用户交互层面,应用提供了两个主要功能按钮,分别用于切换减少动画和屏幕阅读器设置。当用户点击这些按钮时,会触发相应的异步操作函数。这些函数首先设置加载状态为true,然后通过AccessibilityInfo.setReduceMotionEnabled()和AccessibilityInfo.setScreenReaderEnabled()方法尝试修改系统设置。这些操作被包装在try-catch块中,以确保在操作成功或失败时都能给用户适当的反馈。
界面渲染逻辑采用条件样式设计,根据当前的无障碍设置状态动态改变文本颜色。启用状态显示为绿色,禁用状态显示为红色,这种视觉反馈帮助用户快速理解当前系统状态。按钮在异步操作期间会显示加载状态并禁用交互,防止用户重复操作。
打包
接下来通过打包命令npn run harmony将reactNative的代码打包成为bundle,这样可以进行在开源鸿蒙OpenHarmony中进行使用。

最后运行效果图如下显示:

欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。
更多推荐



所有评论(0)