I.목표
앱상에서 주소검색등의 화면에 음성인식 기능을 추가하여 편리성을 향상시키려고 한다.
II. 연구및 개발내용
1. 설치
npm i @react-native-voice/voice –save |
2. 사용방법
import Voice from “@react-native-voice/voice”;
class AddrSearch extends PureComponent { constructor(props) { super(props);
this.state = { title : “”, voiceStat : “” }; Voice.onSpeechStart = this.onSpeechStart; Voice.onSpeechEnd = this.onSpeechEnd; Voice.onSpeechError = this.onSpeechError; Voice.onSpeechRecognized = this.onSpeechRecognized; Voice.onSpeechResults = this.onSpeechResults; this.mClsVoiceTimer = null; } /** * componentDidMount 이벤트 */ componentDidMount() { // 음석인식 종료 타이머 this.mClsVoiceTimer = new mosaic.timer.TimerMgr(); this.mClsVoiceTimer.setInterval(5000); // 5초후에 음성인식 종료 this.mClsVoiceTimer.addTickHandler(()=> { console.log(“타이머 루틴”); this.doStopVoice(); // 음석인식 종료 this.doAddrSearch(); // 주소 검색 }); } /** * componentWillUnmount 이벤트 */ componentWillUnmount() { Voice.destroy().then(Voice.removeAllListeners); if(this.mClsVoiceTimer != null) { this.mClsVoiceTimer.stop(); this.mClsVoiceTimer = null; } } doAddrSearch = () => {
} doStartVoice = async() => { this.setState({ voiceStat: “원하시는 주소를 말씀해주세요.” }); this.mClsVoiceTimer.stop(); // 타이머 종료 this.mClsVoiceTimer.start(); try { await Voice.start(“ko-KR”); } catch (e) { console.error(e); } } doStopVoice = async() => { this.mClsVoiceTimer.stop(); // 타이머 종료 try { await Voice.stop(); } catch (e) { console.error(e); } } onSpeechStart = (e) => { //console.log(“onSpeechStart: “, e); this.setState({ voiceStat: “음성인식을 시작하였습니다.” }); };
onSpeechEnd = (e) => { console.log(“onSpeechEnd: “, e); this.setState({voiceStat : “” }); }; onSpeechError = (e) => { console.log(“onSpeechError: “, e); if(e.error.code != 5) { // {“error”: {“code”: “5”, “message”: “5/Client side error”}} 가 아닌 경우만 출력 this.setState({ voiceStat : “음성인식에 실패하였습니다. 다시 시도하여 주세요.”}); } }; onSpeechRecognized = (e) => { //console.log(“onSpeechRecognized: “, e); this.setState({ voiceStat: “음성인식이 되었습니다.” }); }; onSpeechResults = async(e) => { console.log(” 음성인식결과: “, e); let arrData = e.value; if(arrData.length > 0) { this.setState({voiceStat: “”, searchValue : arrData[0]}, ()=>{ this.doAddrSearch(); }); } }; /** * 화면 렌더 */ render() { const {title, voiceStat} = this.state return ( <BottomSheetView style={baseStyle.bottomSheetBox}> <View style={baseStyle.bottomSheetBoxBody}> <View style={baseStyle.bottomSheetBoxBodyTitH3}> <Text style={baseStyle.bottomSheetTitH3}><Text style={baseStyle.bottomSheetTitBoldH3}>주소</Text>검색</Text> </View> <View style={{position:”relative”, width:”100%”, alignItems:”center”, paddingHorizontal:15, paddingTop:10, paddingBottom:5 }}> <View style={{ width: “100%”, backgroundColor:”#f3f3f3″, borderRadius:10, justifyContent:”center”}}> <TextInput style={{paddingVertical:13, paddingHorizontal:15, fontSize:fonts.getFontSize(15, this.props.appData), fontWeight:”400″, color: colors.PLACEHOLDER, fontFamily:fonts.GMARKET_MEDIUM }} numberOfLines={1} autoCorrect={false} underlineColorAndroid={“transparent”} placeholder={“주소나 건물 이름을 입력하세요”} placeholderTextColor={colors.PLACEHOLDER} returnKeyType={“search”} onChangeText={(strText) => this.setState({ searchValue: strText })} value={this.state.searchValue} onSubmitEditing={this.doAddrSearch}/> <TouchableOpacity style={{position:”absolute”, right: 35, paddingVertical:10, paddingHorizontal:10 }} activeOpacity={0.6} onPress={this.doAddrSearch}> <IconFa6 name=”magnifying-glass” solid style={{fontSize: fonts.getFontSize(22, this.props.appData), fontWeight:”700″, opacity:0.7, color: colors.PLACEHOLDER}} /> </TouchableOpacity> <TouchableOpacity style={{position:”absolute”, right: 0, paddingVertical:10, paddingHorizontal:10 }} activeOpacity={0.6} onPress={this.doStartVoice}> <IconFa6 name=”microphone” solid style={{fontSize: fonts.getFontSize(22, this.props.appData), fontWeight:”700″, opacity:0.7, color: colors.DARK}} /> </TouchableOpacity> </View> </View> <View style={{position:”relative”, width:”100%”, alignItems:”center”, paddingHorizontal:10, paddingTop:5, paddingBottom:5, }}> <Text style={{color: colors.PRIMARY, padding:0, fontSize: fonts.getFontSize(13, this.props.appData), fontWeight:”bold”, fontFamily: fonts.NANUNM_REGULAR}}>{voiceStat}</Text> </View> <View style={{width: (width – 40), flex:1 }}> <FlatList data={this.state.addrLocation} keyExtractor={item => item.addrSeq.toString()} renderItem={this.renderItem} contentContainerStyle={{backgroundColor: colors.WHITE}} ListEmptyComponent={this.renderNoDataItem} /> </View> </View> </BottomSheetView> ); } } |
III. 결론
가끔씩 onSpeechError로 오류가 리턴되어, 아래와 같이 code가 5번인 경우는 제외하고 보여주도록 하였다.
{“error”: {“code”: “5”, “message”: “5/Client side error”}}