# Voice Overlay **Repository Path**: archermind-ti/voice-overlay-ohos ## Basic Information - **Project Name**: Voice Overlay - **Description**: 🗣 An overlay that gets your user’s voice permission and input as text in a customizable UI - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2021-05-27 - **Last Updated**: 2023-12-07 ## Categories & Tags **Categories**: harmonyos-multimedia, tts **Tags**: None ## README # Voice-Overlay-ohos #### 项目简介 - Voice overlay 帮助您将用户的语音转化为文本,在为您处理必要权限的同时提供了一个成熟的用户体验。 #### 功能演示 - 权限申请 ![gif](https://gitee.com/archermind-ti/voice-overlay-ohos/raw/master/docs/voice-permission.gif) - 语音转换文字 ![gif](https://gitee.com/archermind-ti/voice-overlay-ohos/raw/master/docs/using-voice.gif) #### 集成说明 方式一 下载voice-overlay_ohos源码,启动 DevEco Studio并打开本工程可直接编译运行entry示例工程。 方式二 在project的build.gradle中添加mavenCentral()的引用 ``` repositories { ... mavenCentral() ... } ``` 在entry的build.gradle中添加依赖 ``` dependencies { ... implementation 'com.gitee.archermind-ti:voice:1.0.0-beta' ... } ``` #### 使用说明 - 基础使用 进入应用,通过如下方式判断是否具有权限: ```java if (!Voice.isRecordAudioPermissionGranted(getApplicationContext())) { ((FractionAbility)getAbility()).getFractionManager() .startFractionScheduler() .replace(ResourceTable.Id_main_fraction, new VoicePermissionDialogFraction(this)) .submit(); } else { ((FractionAbility)getAbility()).getFractionManager() .startFractionScheduler() .replace(ResourceTable.Id_main_fraction, new VoicePermissionDialogFraction(this)) .submit(); } ``` _参见 [实现代码](entry/src/main/java/com/algolia/instantsearch/voice/demo/slice/MainAbilitySlice.java#L46-L53)._ 如果没有 `MICROPHONE` 权限则会弹出权限对话框,当确认权限后进入语音识别页面。 通过 `VoiceSpeechRecognizer.ResultsListener` 得到使用者语音转换的文字信息: ```java @Override public void onResults(List possibleTexts) { // Do something with the results, for example: StringBuilder sb = new StringBuilder(); for (String text : possibleTexts) { sb.append(text); sb.append('\n'); } resultsText.setText(sb.toString()); } ``` _参见 [实现代码](entry/src/main/java/com/algolia/instantsearch/voice/demo/slice/MainAbilitySlice.java#L66-L74)._ - 当权限申请未确认 如果用户不允许权限申请, 应该向用户解释使用权限的理由; 如果用户拒绝权限后还想使用语音转换功能,应该引导用户去恢复权限使用; Voice overlay都能处理以上情况: ```java @Override public void onRequestPermissionsFromUserResult(int requestCode, String[] permissions, int[] grantResults) { if (Voice.isRecordPermissionWithResults(requestCode, grantResults)) { if (Voice.isPermissionGranted(grantResults)) { if (currentSlice.get() != null) { currentSlice.get().showVoiceDialog(); } } else { Voice.showPermissionRationale(this, null, null); } } } ``` _参见 [实现代码](entry/src/main/java/com/algolia/instantsearch/voice/demo/MainAbility.java#L29-L44)._ 以上实现将展示权限说明和恢复权限的操作流程。 - 定制方式 你可以在Behavior和Suggestions中定制说明信息,例如以下的示例: ```java String[] suggestions = { "64GB Smartphone", "Red running shoes", "Cheap TV screen"}; voiceInput.setSuggestions(suggestions); ``` - 语音启动设置 你可以通过如下方式关闭自动启用语音: ```java // Requires the user to click the mic to start listening. voiceInput.setAutoStart(false); // [...] // you can also start listening programmatically with VoiceInputDialogFraction.start() ``` - 文字替换 你可以在 `strings.json`替换相关的说明文字: ```json { "string": [ { "name": "app_name", "value": "voice" }, { "name": "input_title_listening", "value": "Listening…" }, { "name": "input_subtitle_listening", "value": "Say something" }, { "name": "input_subtitle_suggestions", "value": "Say something like:" }, { "name": "input_title_error", "value": "Sorry, we didn't quite get that." }, { "name": "input_subtitle_error", "value": "Try repeating your request." }, { "name": "input_hint_error", "value": "Try again" }, { "name": "permission_title", "value": "You can use voice search to find products." }, { "name": "permission_subtitle", "value": "May we access your device’s microphone to enable voice search?" }, { "name": "permission_button_allow", "value": "Allow microphone access" }, { "name": "permission_button_reject", "value": "No" }, { "name": "permission_rationale", "value": "Voice search requires this permission." }, { "name": "permission_button_again", "value": "Request again?" }, { "name": "permission_enable_rationale", "value": "Permission denied, allow it to use voice search." }, { "name": "permission_button_enable", "value": "Allow recording" }, { "name": "permission_enable_instructions", "value": "On the next screen, tap Permissions then Microphone." } ] } ``` - 布局 你可以替换应用的布局,但要遵守如下的布局结构: - 在权限页面中使用 `voice_permission.xml` 布局文件,包括: + 一个id为 `$+id:close` 的关闭页面按钮 + 一个id为 `$+id:title` 的标题文字 + 一个id为 `$+id:subtitle` 的副标题文字 - 在语音转换页面使用 `voice_input.xml` 布局文件,包括: + 一个id为 `$+id:microphone` 的`VoiceMicrophone` 来处理语音操作 + 一个id为 `$+id:suggestions` 的操作说明文字 + 一个id为 `$+id:close` 的关闭页面按钮 + 一个id为 `$+id:title` 的标题文字 + 一个id为 `$+id:subtitle` 的副标题文字 + 一个id为 `$+id:hint` 的提示文字 + 一个id为 `$+id:ripple` 的 `RippleView` 的动画对象 #### 版本迭代 - v1.0.0-beta #### 版权和许可信息 - MIT license