[feature]

[xiaozhi]
[init]
This commit is contained in:
yangyakun
2023-11-01 17:51:43 +08:00
parent 4c62a64f85
commit e4632fc800
77 changed files with 915 additions and 345 deletions

View File

@@ -44,7 +44,7 @@ object DebugDataDispatch {
const val trajectoryStation = "trajectoryStation"
const val showDebugView = "showDebugView"
// aadb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "location" --es path "1111/11111"
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "location" --es path "1111/11111"
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "globalPath" --es path "sy73.json"
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "carDoor" --ei doorPostion 1 --ei doorStatus 1
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "trunAroud" --es code "IMAP_TRA_LOADED"
@@ -53,10 +53,14 @@ object DebugDataDispatch {
val ROOT_PATH =
Environment.getExternalStorageDirectory().absolutePath + File.separator + "MLog" + File.separator + "APPLog" + File.separator //程序外部存储跟目录
Environment.getExternalStorageDirectory().absolutePath + File.separator + "MLog" + File.separator + "APP_mock" + File.separator //程序外部存储跟目录
fun disPathc(type: String?, frequency: Int, sourceFilePath: String?, intent: Intent) {
val file = File(ROOT_PATH);
if(file.exists()){
}
when (type) {
globalPathMock -> {
sourceFilePath?.let {

View File

@@ -0,0 +1,77 @@
package com.mogo.och.common.module.wigets
import android.content.Context
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.och.common.module.R
import com.mogo.och.common.module.utils.FrameAnimatorContainer
import com.mogo.tts.base.zhi.AsrTextBean
import com.mogo.tts.base.zhi.CallbackWidget
import com.mogo.tts.base.zhi.AvatarManager
import com.mogo.tts.base.zhi.ZhiRecordWinUi
class ZhiView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr),
ZhiRecordWinUi {
companion object {
const val TAG = "ZhiView"
}
private var createProgressDialogAnim: FrameAnimatorContainer?=null
init {
createProgressDialogAnim = FrameAnimatorContainer(R.array.xiaozhi_normal, 20,this)
createProgressDialogAnim?.setOnAnimStopListener(object : FrameAnimatorContainer.OnAnimationStoppedListener{
override fun AnimationStopped() {
CallerLogger.d(SceneConstant.M_TAXI_P + TAG, "动画暂停")
}
})
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
AvatarManager.addDistanceListener(TAG,this)
createProgressDialogAnim?.start()
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
AvatarManager.removeListener(TAG)
}
override fun start(reason: String?) {
CallerLogger.d(TAG,"-----start $reason")
}
override fun onStatusChange(status: ZhiRecordWinUi.RecordStatus?) {
CallerLogger.d(TAG,"-----onStatusChange $status")
}
override fun close(trigger: Boolean) {
CallerLogger.d(TAG,"-----close $trigger")
}
override fun onVolumeChange(volume: Int) {
CallerLogger.d(TAG,"-----onVolumeChange $volume")
}
override fun showInputText(asrTextBean: AsrTextBean?) {
CallerLogger.d(TAG,"-----showInputText $asrTextBean")
}
override fun showOutPutWidget(callbackWidget: CallbackWidget?) {
// todo 咱不支持定制显示 包括天气
CallerLogger.d(TAG,"-----showOutPutWidget $callbackWidget")
}
override fun showOutputText(outPutText: String?) {
CallerLogger.d(TAG,"-----showOutputText $outPutText")
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="xiaozhi_normal">
<item>@drawable/xiaozhi_normal002</item>
<item>@drawable/xiaozhi_normal004</item>
<item>@drawable/xiaozhi_normal006</item>
<item>@drawable/xiaozhi_normal008</item>
<item>@drawable/xiaozhi_normal010</item>
<item>@drawable/xiaozhi_normal012</item>
<item>@drawable/xiaozhi_normal014</item>
<item>@drawable/xiaozhi_normal016</item>
<item>@drawable/xiaozhi_normal018</item>
<item>@drawable/xiaozhi_normal020</item>
<item>@drawable/xiaozhi_normal022</item>
<item>@drawable/xiaozhi_normal024</item>
<item>@drawable/xiaozhi_normal026</item>
<item>@drawable/xiaozhi_normal028</item>
<item>@drawable/xiaozhi_normal030</item>
<item>@drawable/xiaozhi_normal032</item>
<item>@drawable/xiaozhi_normal034</item>
<item>@drawable/xiaozhi_normal036</item>
<item>@drawable/xiaozhi_normal038</item>
<item>@drawable/xiaozhi_normal040</item>
<item>@drawable/xiaozhi_normal042</item>
<item>@drawable/xiaozhi_normal044</item>
<item>@drawable/xiaozhi_normal046</item>
<item>@drawable/xiaozhi_normal048</item>
<item>@drawable/xiaozhi_normal050</item>
<item>@drawable/xiaozhi_normal052</item>
<item>@drawable/xiaozhi_normal054</item>
<item>@drawable/xiaozhi_normal056</item>
<item>@drawable/xiaozhi_normal058</item>
<item>@drawable/xiaozhi_normal060</item>
<item>@drawable/xiaozhi_normal062</item>
<item>@drawable/xiaozhi_normal064</item>
<item>@drawable/xiaozhi_normal066</item>
<item>@drawable/xiaozhi_normal068</item>
<item>@drawable/xiaozhi_normal070</item>
<item>@drawable/xiaozhi_normal072</item>
<item>@drawable/xiaozhi_normal074</item>
<item>@drawable/xiaozhi_normal076</item>
<item>@drawable/xiaozhi_normal078</item>
<item>@drawable/xiaozhi_normal080</item>
<item>@drawable/xiaozhi_normal082</item>
<item>@drawable/xiaozhi_normal084</item>
<item>@drawable/xiaozhi_normal086</item>
<item>@drawable/xiaozhi_normal088</item>
<item>@drawable/xiaozhi_normal090</item>
<item>@drawable/xiaozhi_normal092</item>
<item>@drawable/xiaozhi_normal094</item>
<item>@drawable/xiaozhi_normal096</item>
<item>@drawable/xiaozhi_normal098</item>
<item>@drawable/xiaozhi_normal100</item>
<item>@drawable/xiaozhi_normal102</item>
<item>@drawable/xiaozhi_normal104</item>
<item>@drawable/xiaozhi_normal106</item>
<item>@drawable/xiaozhi_normal108</item>
<item>@drawable/xiaozhi_normal110</item>
<item>@drawable/xiaozhi_normal112</item>
<item>@drawable/xiaozhi_normal114</item>
<item>@drawable/xiaozhi_normal116</item>
<item>@drawable/xiaozhi_normal118</item>
</string-array>
</resources>

View File

@@ -72,12 +72,12 @@ class TaxiPassengerBaseFragment() :
overMapView.onCreateView(savedInstanceState)
overMapView.hideResetView()
createProgressDialogAnim = FrameAnimatorContainer(R.array.xiaozhi_normal, 20,aciv_xiaozhi_normal)
createProgressDialogAnim?.setOnAnimStopListener(object : FrameAnimatorContainer.OnAnimationStoppedListener{
override fun AnimationStopped() {
CallerLogger.d(M_TAXI_P + TAG, "动画暂停")
}
})
// createProgressDialogAnim = FrameAnimatorContainer(R.array.xiaozhi_normal, 20,aciv_xiaozhi_normal)
// createProgressDialogAnim?.setOnAnimStopListener(object : FrameAnimatorContainer.OnAnimationStoppedListener{
// override fun AnimationStopped() {
// CallerLogger.d(M_TAXI_P + TAG, "动画暂停")
// }
// })
}
private fun initListener() {

View File

@@ -148,7 +148,7 @@
android:layout_height="@dimen/dp_160"
app:layout_constraintBottom_toBottomOf="parent" />
<androidx.appcompat.widget.AppCompatImageView
<com.mogo.och.common.module.wigets.ZhiView
android:id="@+id/aciv_xiaozhi_normal"
android:layout_width="@dimen/dp_216"
android:layout_height="@dimen/dp_216"

View File

@@ -330,10 +330,16 @@ def variantName() {
if (taskName.contains("Yantai")) {
project.dependencies.add('implementation', project.project(':tts:tts-iflytek'))
}else if (taskName.contains("Mogo") || taskName.contains("Saas")) {
}else if (taskName.contains("Mogo")) {
project.dependencies.add('implementation', project.project(':tts:tts-pad'))
}else if (taskName.contains("Dali")) {
project.dependencies.add('implementation', project.project(':tts:tts-pad'))
}else if (taskName.contains("Saas")) {
if(taskName.contains("TaxiunmannedPassenger")) {
project.dependencies.add('implementation', project.project(':tts:tts-zhi'))
}else {
project.dependencies.add('implementation', project.project(':tts:tts-pad'))
}
}else {
// 不能再else 加任何逻辑 是android dlc的特效
println("-----------$taskName")

View File

@@ -63,6 +63,9 @@ public class AIAssist {
try {
clazz2 = Class.forName("com.mogo.tts.iflytek.IFlyTekTts");
} catch (Exception ignored) {}
try {
clazz2 = Class.forName("com.mogo.tts.pad.ZhiTTS");
} catch (Exception ignored) {}
if (clazz1 != null) {
mTTS = (IMogoTTS) clazz1.getConstructor().newInstance();

View File

@@ -50,6 +50,7 @@ include ':libraries:mapmodule'
include ':tts:tts-base'
include ':tts:tts-pad'
include ':tts:tts-iflytek'
include ':tts:tts-zhi'
// 测试DEBUG
include ':test:crashreport'

View File

@@ -0,0 +1,33 @@
package com.mogo.tts.base.zhi;
import androidx.annotation.NonNull;
/**
* 引擎识别内容
*/
public class AsrTextBean {
private String text;
private boolean isLast;
public AsrTextBean(boolean isLast, String text) {
this.isLast = isLast;
this.text = text;
}
public String getText() {
return text;
}
public boolean isLast() {
return isLast;
}
@Override
public String toString() {
return "AsrTextBean{" +
"text='" + text + '\'' +
", isLast=" + isLast +
'}';
}
}

View File

@@ -0,0 +1,74 @@
package com.mogo.tts.base.zhi
import java.util.concurrent.ConcurrentHashMap
object AvatarManager {
private const val TAG = "AvatarManager"
private var isShowing = false
private val mControllerStatusCallbackMap = ConcurrentHashMap<String, ZhiRecordWinUi>()
fun addDistanceListener(tag: String, listener: ZhiRecordWinUi) {
if (mControllerStatusCallbackMap.containsKey(tag)) {
return
}
mControllerStatusCallbackMap[tag] = listener
}
/**
* 删除监听
* @param tag 标记,用来注销监听使用
*/
fun removeListener(tag: String) {
mControllerStatusCallbackMap.remove(tag)
}
fun isShowing():Boolean{
return isShowing
}
fun dispatchStartEvent(reason:String){
isShowing = true
mControllerStatusCallbackMap.forEach {
it.value.start(reason)
}
}
fun dispatchStatusChangeEvent(reason: ZhiRecordWinUi.RecordStatus){
mControllerStatusCallbackMap.forEach {
it.value.onStatusChange(reason)
}
}
fun dispatchCloseEvent(trigger:Boolean){
isShowing = false
mControllerStatusCallbackMap.forEach {
it.value.close(trigger)
}
}
fun dispatchOnVolumeChangeEvent(volume:Int){
mControllerStatusCallbackMap.forEach {
it.value.onVolumeChange(volume)
}
}
fun dispatchShowInputTextEvent(reason: AsrTextBean){
mControllerStatusCallbackMap.forEach {
it.value.showInputText(reason)
}
}
@Suppress("UNUSED_PARAMETER")
fun dispatchShowOutPutWidgetEvent(callbackWidget: CallbackWidget){
mControllerStatusCallbackMap.forEach {
it.value.showOutPutWidget(null)
}
}
fun dispatchShowOutputTextEvent(reason: String){
if (!isShowing) {
return
}
mControllerStatusCallbackMap.forEach {
it.value.showOutputText(reason)
}
}
}

View File

@@ -0,0 +1,53 @@
package com.mogo.tts.base.zhi;
import android.text.TextUtils;
import org.json.JSONArray;
import org.json.JSONObject;
public class CallbackWidget {
public int type;
public String intentName;
public String skillId;
public String taskName;
public JSONArray recommendations;
public JSONObject extra;
public CallbackWidget() {
}
protected CallbackWidget(JSONObject var1, int var2, String var3, String var4, String var5) {
this.type = var2;
this.intentName = var5;
this.skillId = var3;
this.taskName = var4;
this.recommendations = var1.optJSONArray("recommendations");
this.extra = var1.optJSONObject("extra");
}
public String getIntentName() {
return this.intentName;
}
public String getSkillId() {
return this.skillId;
}
public String getTaskName() {
return this.taskName;
}
public JSONArray getRecommendations() {
return this.recommendations;
}
public JSONObject getExtra() {
return this.extra;
}
public int getType() {
return this.type;
}
}

View File

@@ -0,0 +1,60 @@
package com.mogo.tts.base.zhi;
public interface ZhiRecordWinUi {
/**
* 开始对话
*
* @param reason
*/
void start(String reason);
/**
* 语音卡状态变化
*
* @param status
*/
void onStatusChange(RecordStatus status);
/**
* 关闭对话
* @param trigger 是否手动
*/
void close(boolean trigger);
/**
* 语音输入音量变化
*
* @param volume
*/
void onVolumeChange(int volume);
/**
* 显示用户输入的内容
*
* @param asrTextBean
*/
void showInputText(AsrTextBean asrTextBean);
/**
* 显示控件 暂时没有需求
*
* @param callbackWidget
*/
void showOutPutWidget(CallbackWidget callbackWidget);
/**
* 显示系统输出内容
*
* @param outPutText
*/
void showOutputText(String outPutText);
enum RecordStatus {
STATUS_SILENCE,
STATUS_LISTENING,
STATUS_UNDERSTANDING,
STATUS_UNDERSTAND_END,
STATUS_SPEAKING
}
}

View File

@@ -47,7 +47,8 @@ dependencies {
kapt rootProject.ext.dependencies.aroutercompiler
api rootProject.ext.dependencies.aiassist
api rootProject.ext.dependencies.aiassistReplace
implementation rootProject.ext.dependencies.aiassistReplace
implementation rootProject.ext.dependencies.androidxrecyclerview
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
implementation rootProject.ext.dependencies.ttsbase
@@ -56,6 +57,11 @@ dependencies {
implementation project(":tts:tts-base")
implementation project(':core:mogo-core-utils')
}
// implementation project(":xiaozhisdk")
implementation 'com.zhidao.speech.adapter:speechadapter:1.0.0-SNAPSHOT'
implementation 'com.mogo.xiaozhi.sdk:xiaozhisdk:1.0.0-SNAPSHOT'
}
apply from: new File(rootProject.rootDir, "gradle/upload.gradle").toString()

View File

@@ -1,5 +1,94 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mogo.tts.pad">
/
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.RESTART_PACKAGES" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--用于申请调用A-GPS模块-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS/" />
<uses-permission android:name="com.tencent.wecarflow.PLAY_CONTROL"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="com.nwd.bt.PHONEBOOK_READ" />
<uses-permission android:name="com.nwd.bt.PHONEBOOK_WRITE" />
<uses-permission android:name="com.zhidao.guide.lock.permission.READ_LOCK_STATE"/>
<!--读取导航设置地图contentProvider的权限-->
<uses-permission android:name="com.zhidao.auto.personal.info.Read"/>
<uses-permission android:name="android.permission.INJECT_EVENTS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
<uses-permission android:name="android.permission.FORCE_STOP_PACKAGES" /> />
<application>
<activity android:name="com.mogo.xiaozhi.sdk.ui.dui.view.VoiceCenterActivity"
android:windowSoftInputMode="adjustPan"/>
<service android:name="com.mogo.xiaozhi.sdk.SpeechCoreService"
android:exported="true"
android:priority="1000"
android:permission="android.permission.BIND_SCREENING_SERVICE">
<intent-filter>
<action android:name="com.zhidao.speech.service.connect" />
</intent-filter>
</service>
<service android:name="com.zhidao.speech.adapter.service.AdapterService"
android:enabled="true"
android:exported="true"
android:priority="1000" >
<intent-filter>
<action android:name="com.zd.speech.power.switch"/>
</intent-filter>
</service>
<service android:name="com.zhidao.mogo.speech.sdk.ZDSpeechService"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="com.zhidao.speech.adapter.service"/>
</intent-filter>
</service>
<meta-data
android:name="XIAOZHI_API_KEY"
android:value="113cc31f6385113cc31f6385618c86f5" />
<meta-data
android:name="XIAOZHI_PRODUCT_ID"
android:value="@string/product_id" />
<meta-data
android:name="XIAOZHI_PRODUCT_KEY"
android:value="1fe5930844b488a8d32d9ef7717be7dc" />
<meta-data
android:name="XIAOZHI_PRODUCT_SECRET"
android:value="f601ecc407986b548ac8ab2a9144162e" />
</application>
</manifest>

View File

@@ -0,0 +1,243 @@
package com.mogo.tts.pad;
import android.animation.Animator;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ImageView;
import android.widget.TextView;
import com.aispeech.export.widget.callback.CallbackWidget;
import com.aispeech.export.widget.callback.CallbackWidgetType;
import com.aispeech.export.widget.callback.CustomCallbackWidget;
import com.aispeech.export.widget.callback.ListCallbackWidget;
import com.aispeech.upload.util.LogUtil;
import com.mogo.tts.base.zhi.AvatarManager;
import com.mogo.tts.base.zhi.ZhiRecordWinUi;
import com.mogo.xiaozhi.sdk.analytics.AnalyticsConst;
import com.mogo.xiaozhi.sdk.bean.AsrTextBean;
import com.mogo.xiaozhi.sdk.engine.cdm.AICloudDManager;
import com.mogo.xiaozhi.sdk.engine.tts.AILocalTTS;
import com.mogo.xiaozhi.sdk.ui.dui.RecordWinUi;
import com.mogo.xiaozhi.sdk.utils.AnalyticsUtil;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
/**
* Created by pangfan on 2020/12/14
*/
public class ZhiAvatarWindow implements RecordWinUi {
private static final String TAG = ZhiAvatarWindow.class.getSimpleName();
private ImageView leftImageView;
private TextView mNormalChatTextView;
private boolean flagWeather = false;
private boolean isLeftImageShowingWeather = false;
public ZhiAvatarWindow() {
}
@Override
protected void finalize() throws Throwable {
super.finalize();
Log.d(TAG, "finalize");
}
@Override
public boolean isSpeeching() {
return AvatarManager.INSTANCE.isShowing();
}
@Override
public void start(String reason) {
trackAwakeEvent();
if(AvatarManager.INSTANCE.isShowing()) {
AILocalTTS.getInstance().setIsForbidASR(false);
}
AvatarManager.INSTANCE.dispatchStartEvent(reason);
}
@Override
public void onStatusChange(RecordStatus status) {
Log.d(TAG, "onStatusChange status = " + status);
if (status== RecordStatus.STATUS_SILENCE) {
AvatarManager.INSTANCE.dispatchStatusChangeEvent(ZhiRecordWinUi.RecordStatus.STATUS_UNDERSTANDING);
}else if(status== RecordStatus.STATUS_LISTENING) {
AvatarManager.INSTANCE.dispatchStatusChangeEvent(ZhiRecordWinUi.RecordStatus.STATUS_LISTENING);
}else if(status== RecordStatus.STATUS_UNDERSTANDING) {
AvatarManager.INSTANCE.dispatchStatusChangeEvent(ZhiRecordWinUi.RecordStatus.STATUS_UNDERSTANDING);
}else if(status== RecordStatus.STATUS_UNDERSTAND_END) {
AvatarManager.INSTANCE.dispatchStatusChangeEvent(ZhiRecordWinUi.RecordStatus.STATUS_UNDERSTAND_END);
}else if(status== RecordStatus.STATUS_SPEAKING) {
AvatarManager.INSTANCE.dispatchStatusChangeEvent(ZhiRecordWinUi.RecordStatus.STATUS_SPEAKING);
}
// if (status == RecordStatus.STATUS_LISTENING) {// 听取中
// if (flagWeather) {
// flagWeather = false;
// mNormalChatTextView.setText("");
// return;
// }
// if (isLeftImageShowingWeather) {
// isLeftImageShowingWeather = false;
// }
// showIconAnimation(status);
// } else if (status == RecordStatus.STATUS_UNDERSTANDING) {
// if (isLeftImageShowingWeather) {
// isLeftImageShowingWeather = false;
// }
// showIconAnimation(status);
// } else if (status == RecordStatus.STATUS_SPEAKING) {
// if (flagWeather) {
// flagWeather = false;
// return;
// }
// if (isLeftImageShowingWeather) {
// isLeftImageShowingWeather = false;
// } else {
// showIconAnimation(status);
// }
// }
}
@Override
public void close(boolean trigger) {
Log.i(TAG, "close: trigger = $trigger");
if (trigger) {
AICloudDManager.getInstance().stop();
}
AILocalTTS.getInstance().setIsForbidASR(false);
AvatarManager.INSTANCE.dispatchCloseEvent(trigger);
}
@Override
public void onVolumeChange(int volume) {
AvatarManager.INSTANCE.dispatchOnVolumeChangeEvent(volume);
}
@Override
public void showOutPutWidget(CallbackWidget callbackWidget) {
if (callbackWidget == null) return;
if (CallbackWidgetType.CUSTOM.getType() == callbackWidget.getType()) {
CustomCallbackWidget customCallbackWidget = (CustomCallbackWidget) callbackWidget;
//showCustomWidget(customCallbackWidget);
Log.w(TAG, "天气支持");
} else if (CallbackWidgetType.LIST.getType() == callbackWidget.getType()) {
ListCallbackWidget listCallbackWidget = (ListCallbackWidget) callbackWidget;
Log.w(TAG, "暂不支持列表");
}
AvatarManager.INSTANCE.dispatchShowOutPutWidgetEvent(new com.mogo.tts.base.zhi.CallbackWidget());
}
@Override
public void showInputText(AsrTextBean asrTextBean) {
if (asrTextBean == null) return;
AvatarManager.INSTANCE.dispatchShowInputTextEvent(
new com.mogo.tts.base.zhi.AsrTextBean(asrTextBean.isLast(),asrTextBean.getText()));
}
@Override
public void showOutputText(String outPutText) {
AvatarManager.INSTANCE.dispatchShowOutputTextEvent(outPutText);
}
private void showIconAnimation(RecordStatus status) {
LogUtil.d(TAG, "status = " + status);
switch (status) {
case STATUS_LISTENING:
playAnimation(leftImageView, R.drawable.anim_voice_listening);
break;
case STATUS_UNDERSTANDING:
playAnimation(leftImageView, R.drawable.anim_voice_loading);
case STATUS_SPEAKING:
playAnimation(leftImageView, R.drawable.anim_voice_speaking);
break;
}
}
/**
* 播放动画
* 如果当前是天气图片,直接返回;
*
* @param chatIconView 需要播放动画的 ImageView
* @param resourceId 需要播放动画的ImageView 的 Animation Drawable.
*/
private void playAnimation(final ImageView chatIconView, final int resourceId) {
chatIconView.setImageResource(resourceId);
if (isLeftImageShowingWeather) {
LogUtil.d(TAG, "weather icon, not animation.");
return;
}
// stop current animation first.
Drawable animDrawable = chatIconView.getDrawable();
if (!(animDrawable instanceof AnimationDrawable)) {
LogUtil.e(TAG, "chatIconView should have a AnimationDrawable");
return;
}
AnimationDrawable anim = (AnimationDrawable) animDrawable;
anim.stop();
chatIconView.animate()
.scaleX(0f)
.scaleY(0f)
.setDuration(100)
.setInterpolator(new AccelerateDecelerateInterpolator())
.setListener(new AnimationEndListener() {
@Override
public void onAnimationEnd(Animator animation) {
chatIconView.setImageResource(resourceId);
chatIconView.setAlpha(0f);
chatIconView.setScaleX(0f);
chatIconView.setScaleY(0f);
chatIconView.animate()
.alpha(1f)
.scaleX(1f)
.scaleY(1f)
.setInterpolator(new AccelerateDecelerateInterpolator())
.setDuration(100)
.setListener(new AnimationEndListener() {
@Override
public void onAnimationEnd(Animator animation) {
AnimationDrawable anim = (AnimationDrawable) chatIconView.getDrawable();
anim.start();
}
})
.start();
}
})
.start();
}
/**
* only onAnimationEnd is required here. other call back is empty.
*/
abstract static class AnimationEndListener implements Animator.AnimatorListener {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
}
private void trackAwakeEvent() {
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
String time = dateformat.format(System.currentTimeMillis());
Map<String, Object> eventMap = new HashMap<>();
eventMap.put(AnalyticsConst.Key.KEY_SESSION_START_TIME, time);
AnalyticsUtil.trackNormalEvent(AnalyticsConst.Event.XIAOZHI_AWAKE, eventMap);
}
}

View File

@@ -1,95 +1,70 @@
package com.mogo.tts.pad;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.os.Build;
import android.provider.Settings;
import android.util.Pair;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.mogo.eagle.core.utilcode.util.AppUtils;
import androidx.annotation.MainThread;
import com.elegant.utils.storage.SharedPrefsMgr;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.tts.base.IMogoTTS;
import com.mogo.tts.base.IMogoTTSCallback;
import com.mogo.tts.base.MogoTTSConstants;
import com.mogo.tts.base.MultiLangTtsEntity;
import com.mogo.tts.base.PreemptType;
import com.mogo.xiaozhi.sdk.engine.DMStatusListener;
import com.mogo.xiaozhi.sdk.engine.RecorderDMManager;
import com.mogo.xiaozhi.sdk.module.show.ZDCloudDMManager;
import com.zhidao.auto.platform.voice.VoiceClient;
import com.zhidao.voicesdk.MogoVoiceManager;
import com.zhidao.voicesdk.MogoVoiceManagerImpl;
import com.zhidao.voicesdk.callback.OnConnStatusListener;
import com.zhidao.speech.adapter.AdapterApp;
import com.zhidao.voicesdk.callback.OnTtsListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.LinkedList;
public
/**
* @author congtaowang
* @since 2020/10/12
* <p>
* 描述
*/
@Route( path = MogoTTSConstants.API_PATH )
class ZhiTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsListener {
//@Route(path = MogoTTSConstants.API_PATH)
public class ZhiTTS implements IMogoTTS, OnTtsListener {
private static final String TAG = "ZhiTTS";
private String mLastQAndASpeakText;
private boolean mHasFlush = false;
private boolean mInitReady = false;
private Context mContext;
public synchronized void release() {
if ( mCmdMap != null && !mCmdMap.isEmpty() && mVoiceClient != null ) {
for ( String cmd : mCmdMap.keySet() ) {
try {
mVoiceClient.unRegisterCustomWakeupCmd( cmd );
} catch ( Exception e ) {
}
public void release() {
CallerLogger.d(TAG, "release");
}
@Override
public void initTts(String sn) {
CallerLogger.d(TAG, "initTts");
AdapterApp.getInstance().init(mContext);
ZDCloudDMManager.getInstance().setUIView(ZhiAvatarWindow.class);
RecorderDMManager.getInstance().registerListener(new DMStatusListener() {
@Override
public void onInitSuccess() {
CallerLogger.d(TAG, "RecorderDMManager---onInitSuccess");
}
}
mQAndAMap.clear();
mVoiceClient.release();
mSpeakVoiceMap.clear();
mCacheUnWakeupCommands.clear();
mContext = null;
@Override
public void onError(int code, String info) {
CallerLogger.d(TAG, "RecorderDMManager---onError---code"+code+"--info"+info);
}
});
}
private VoiceClient mVoiceClient;
private MogoVoiceManager mogoVoiceManager;
// 免唤醒指令
private Map< String, List< IMogoTTSCallback > > mCmdMap = new HashMap<>();
// 问答指令
private Map< String, IMogoTTSCallback > mQAndAMap = new HashMap<>();
// 单独的语音播放
private Map< String, IMogoTTSCallback > mSpeakVoiceMap = new HashMap<>();
private Map< String, String[] > mCacheUnWakeupCommands = new ConcurrentHashMap<>();
private void initFlushStatus() {
if ( !mHasFlush ) {
mHasFlush = isVoiceServiceReady( mContext );
}
}
/**
* 初始化
*/
private void initSpeech( Context context ) {
mogoVoiceManager = MogoVoiceManagerImpl.getInstance();
mogoVoiceManager.init( context, new OnConnStatusListener() {
@Override
public void onSuccess() {
mInitReady = true;
}
@Override
public void onFailed() {
}
} );
private void initSpeech(Context context) {
CallerLogger.d(TAG, "initSpeech");
}
/**
@@ -99,82 +74,8 @@ class ZhiTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsListener {
*/
@Override
public boolean hasFlush() {
return mHasFlush;
}
@Override
public void onCmdSelected( String cmd ) {
if ( !mCmdMap.containsKey( cmd ) ) {
return;
}
Iterator< IMogoTTSCallback > iterator = null;
try {
List< IMogoTTSCallback > cmdCallBacks = mCmdMap.get( cmd );
iterator = new ArrayList<>( cmdCallBacks ).iterator();
} catch ( Exception e ) {
}
while ( iterator != null && iterator.hasNext() ) {
IMogoTTSCallback callBack = iterator.next();
if ( callBack != null ) {
callBack.onCmdSelected( cmd );
}
}
}
@Override
public void onCmdAction( String speakText ) {
if ( !TextUtils.isEmpty( mLastQAndASpeakText ) ) {
IMogoTTSCallback cmdCallBack = mQAndAMap.remove( mLastQAndASpeakText );
if ( cmdCallBack != null ) {
cmdCallBack.onCmdAction( speakText );
}
}
}
@Override
public void onCmdCancel( String speakText ) {
if ( !TextUtils.isEmpty( mLastQAndASpeakText ) ) {
IMogoTTSCallback cmdCallBack = mQAndAMap.remove( mLastQAndASpeakText );
if ( cmdCallBack != null ) {
cmdCallBack.onCmdCancel( speakText );
}
}
}
@Override
public void onSpeakEnd( String speakText ) {
if ( mQAndAMap.containsKey( speakText ) ) {
mLastQAndASpeakText = speakText;
IMogoTTSCallback cmdCallBack = mQAndAMap.get( speakText );
if ( cmdCallBack != null ) {
cmdCallBack.onSpeakEnd( speakText );
return;
}
}
IMogoTTSCallback callBack = mSpeakVoiceMap.remove( speakText );
if ( callBack != null ) {
callBack.onSpeakEnd( speakText );
}
}
@Override
public void onSpeakSelectTimeOut( String speakText ) {
if ( mQAndAMap.containsKey( speakText ) ) {
if ( TextUtils.equals( speakText, mLastQAndASpeakText ) ) {
mLastQAndASpeakText = null;
}
IMogoTTSCallback cmdCallBack = mQAndAMap.remove( speakText );
if ( cmdCallBack != null ) {
cmdCallBack.onSpeakSelectTimeOut( speakText );
return;
}
}
IMogoTTSCallback callBack = mSpeakVoiceMap.remove( speakText );
if ( callBack != null ) {
callBack.onSpeakSelectTimeOut( speakText );
}
CallerLogger.d(TAG, "hasFlush");
return true;
}
/**
@@ -182,15 +83,16 @@ class ZhiTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsListener {
*
* @param text
*/
public void speakTTSVoice( String text, IMogoTTSCallback callBack ) {
try {
initFlushStatus();
if ( mHasFlush ) {
mSpeakVoiceMap.put( text, callBack );
mVoiceClient.speakDefault( text );
}
} catch ( Exception e ) {
}
public void speakTTSVoice(String text, IMogoTTSCallback callBack) {
CallerLogger.d(TAG, "speakTTSVoice");
}
public void stopSpeakTts(String text) {
CallerLogger.d(TAG, "text");
}
public void stopTts() {
CallerLogger.d(TAG, "stopTts");
}
/**
@@ -198,48 +100,35 @@ class ZhiTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsListener {
*
* @param text
*/
public void speakTTSVoice( String text ) {
try {
initFlushStatus();
if ( mHasFlush ) {
mVoiceClient.speakDefault( text );
}
} catch ( Exception e ) {
}
public void speakTTSVoice(String text) {
CallerLogger.d(TAG, "speakTTSVoice");
}
@MainThread
public void speakTTSVoiceWithLevel(String text, int ttsLevel) {
CallerLogger.d(TAG, "speakTTSVoiceWithLevel");
}
@MainThread
public void speakTTSVoiceWithLevel(String text, int ttsLevel, IMogoTTSCallback callBack) {
CallerLogger.d(TAG, "speakTTSVoiceWithLevel");
}
/**
* 语音播报
*
* @param text 播报内容
* @param type 播报策略
*/
public void speakTTSVoice( String text, PreemptType type, IMogoTTSCallback callBack ) {
try {
initFlushStatus();
if ( mHasFlush ) {
mSpeakVoiceMap.put( text, callBack );
VoiceClient.PreemptType preemptType = VoiceClient.PreemptType.PREEMPT_TYPE_NONE;
if ( type != null ) {
switch ( type ) {
case PREEMPT_TYPE_NEXT:
preemptType = VoiceClient.PreemptType.PREEMPT_TYPE_NEXT;
break;
case PREEMPT_TYPE_FLUSH:
preemptType = VoiceClient.PreemptType.PREEMPT_TYPE_FLUSH;
break;
case PREEMPT_TYPE_IMMEDIATELY:
preemptType = VoiceClient.PreemptType.PREEMPT_TYPE_IMMEADIATELY;
break;
case PREEMPT_TYPE_IMMEDIATELY_WITHOUT_CANCEL:
preemptType = VoiceClient.PreemptType.PREEMPT_TYPE_IMMEADIATELY_WITHOUT_CANCLE;
break;
}
}
mVoiceClient.speakTypeText( text, preemptType );
}
} catch ( Exception e ) {
}
public void speakTTSVoice(String text, PreemptType type, IMogoTTSCallback callBack) {
CallerLogger.d(TAG, "speakTTSVoice");
}
@Override
public void speakMultiLangTTSWithLevel(MultiLangTtsEntity ttsEntity, int level, IMogoTTSCallback callback) {
CallerLogger.d(TAG, "speakMultiLangTTSWithLevel");
}
/**
@@ -247,12 +136,8 @@ class ZhiTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsListener {
*
* @param tts 播报内容
*/
public void speakQAndACmd( String tts, IMogoTTSCallback callBack ) {
initFlushStatus();
if ( mHasFlush ) {
mQAndAMap.put( tts, callBack );
mVoiceClient.speakTtsAndRegistCmd( tts );
}
public void speakQAndACmd(String tts, IMogoTTSCallback callBack) {
CallerLogger.d(TAG, "speakQAndACmd");
}
/**
@@ -262,12 +147,8 @@ class ZhiTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsListener {
* @param okCmds 确认命令唤醒词
* @param cancelCmds 取消命令唤醒词
*/
public void speakQAndACmd( String tts, String[] okCmds, String[] cancelCmds, IMogoTTSCallback callBack ) {
initFlushStatus();
if ( mHasFlush ) {
mQAndAMap.put( tts, callBack );
mVoiceClient.speakTtsAndRegistCmd( tts, okCmds, cancelCmds );
}
public void speakQAndACmd(String tts, String[] okCmds, String[] cancelCmds, IMogoTTSCallback callBack) {
CallerLogger.d(TAG, "speakQAndACmd");
}
/**
@@ -277,33 +158,8 @@ class ZhiTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsListener {
* @param cmdWords
* @param callBack
*/
public void registerUnWakeupCommand( String cmd, String[] cmdWords, IMogoTTSCallback callBack ) {
if ( !mCmdMap.containsKey( cmd ) ) {
mCmdMap.put( cmd, new ArrayList<>() );
}
mCmdMap.get( cmd ).add( callBack );
initFlushStatus();
if ( mHasFlush ) {
mVoiceClient.registerCustomWakeupCmd( cmd, cmdWords );
mCacheUnWakeupCommands.remove( cmd );
}
mCacheUnWakeupCommands.put( cmd, cmdWords );
}
/**
* 注册免唤醒命令
*
* @param cmd
* @param cmdWords
*/
private void registerUnWakeupCommand( String cmd, String[] cmdWords ) {
initFlushStatus();
if ( mHasFlush ) {
mVoiceClient.registerCustomWakeupCmd( cmd, cmdWords );
mCacheUnWakeupCommands.remove( cmd );
}
mCacheUnWakeupCommands.put( cmd, cmdWords );
public void registerUnWakeupCommand(String cmd, String[] cmdWords, IMogoTTSCallback callBack) {
CallerLogger.d(TAG, "registerUnWakeupCommand");
}
/**
@@ -311,13 +167,8 @@ class ZhiTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsListener {
*
* @param cmd
*/
public synchronized void unregisterUnWakeupCommand( String cmd ) {
mCmdMap.remove( cmd );
try {
mVoiceClient.unRegisterCustomWakeupCmd( cmd );
} catch ( Exception e ) {
}
mCacheUnWakeupCommands.remove( cmd );
public synchronized void unregisterUnWakeupCommand(String cmd) {
CallerLogger.d(TAG, "unregisterUnWakeupCommand");
}
/**
@@ -325,83 +176,26 @@ class ZhiTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsListener {
*
* @param cmd
*/
public synchronized void unregisterUnWakeupCommand( String cmd, IMogoTTSCallback callBack ) {
if ( mCmdMap.containsKey( cmd ) ) {
List< IMogoTTSCallback > callBacks = mCmdMap.get( cmd );
if ( callBacks != null ) {
callBacks.remove( callBack );
}
if ( callBacks.isEmpty() ) {
mCmdMap.remove( cmd );
try {
mVoiceClient.unRegisterCustomWakeupCmd( cmd );
} catch ( Exception e ) {
}
mCacheUnWakeupCommands.remove( cmd );
}
}
public synchronized void unregisterUnWakeupCommand(String cmd, IMogoTTSCallback callBack) {
CallerLogger.d(TAG, "unregisterUnWakeupCommand");
}
public static void startAssistant( Context context ) {
startAssistant( context, 1 );
}
/**
* @param context
* @param status window_start_cancel 0 - 结束, 1 - 显示, 2 - 未激活调试进入
*/
public static void startAssistant( Context context, int status ) {
final Intent intent = new Intent();
intent.setFlags( Intent.FLAG_INCLUDE_STOPPED_PACKAGES );
intent.setAction( "pvetec.intent.action.txz.switch" );
intent.putExtra( "window_start_cancel", status );
intent.putExtra( "extra_switch_type", "window_start_cancel" );
context.sendBroadcast( intent );
}
public synchronized void flush() {
if ( mCacheUnWakeupCommands.isEmpty() ) {
return;
}
mHasFlush = true;
final Map< String, String[] > tmp = new HashMap<>( mCacheUnWakeupCommands );
for ( String cmd : tmp.keySet() ) {
registerUnWakeupCommand( cmd, tmp.get( cmd ) );
}
CallerLogger.d(TAG, "flush");
}
private boolean isVoiceServiceReady( Context context ) {
if ( AppUtils.isProcessRunning( context, AppUtils.getPackageUid( context, "com.zhidao.speech" ) )
&& AppUtils.isProcessRunning( context, AppUtils.getPackageUid( context, "com.zhidao.speech.adapter" ) ) ) {
return true;
} else if ( AppUtils.isProcessRunning( context, AppUtils.getPackageUid( context, "com.txznet.txz" ) )
&& AppUtils.isProcessRunning( context, AppUtils.getPackageUid( context, "com.txznet.adapter" ) ) ) {
return true;
}
return false;
public void speakTTSAndDuck(String text) {
CallerLogger.d(TAG, "speakTTSAndDuck");
}
public void speakTTSAndDuck( String text ) {
speakTTSAndDuck( text, null );
public void speakTTSAndDuck(String text, IMogoTTSCallback callBack) {
CallerLogger.d(TAG, "speakTTSAndDuck");
}
public void speakTTSAndDuck( String text, IMogoTTSCallback callBack ) {
try {
if ( mInitReady ) {
mSpeakVoiceMap.put( text, callBack );
mogoVoiceManager.toSpeak( text, -3, this );
}
} catch ( Exception e ) {
}
}
public void shutUp( String ttsId, String text ) {
try {
mSpeakVoiceMap.remove( text );
mogoVoiceManager.shutUp( ttsId );
} catch ( Exception e ) {
}
public void shutUp(String ttsId, String text) {
CallerLogger.d(TAG, "shutUp");
}
/**
@@ -409,64 +203,54 @@ class ZhiTTS implements IMogoTTS, VoiceClient.VoiceCmdCallBack, OnTtsListener {
* 语音SDK生效版本从1.0.8.4版本起
*/
public void breakOffSpeak() {
mVoiceClient.breakOffSpeak();
CallerLogger.d(TAG, "breakOffSpeak");
}
public void clearTTSCallback( String text ) {
try {
mSpeakVoiceMap.remove( text );
} catch ( Exception e ) {
e.printStackTrace();
}
public void clearTTSCallback(String text) {
CallerLogger.d(TAG, "clearTTSCallback");
}
@Override
public void onTtsStart( String ttsId, String text ) {
IMogoTTSCallback callBack = mSpeakVoiceMap.get( text );
if ( callBack != null ) {
callBack.onTTSStart( ttsId, text );
}
public void onTtsStart(String ttsId, String text) {
CallerLogger.d(TAG, "onTtsStart");
}
@Override
public void onTtsFinish( String ttsId, String text ) {
IMogoTTSCallback callBack = mSpeakVoiceMap.remove( text );
if ( callBack != null ) {
callBack.onTTSEnd( ttsId, text );
}
public void onTtsFinish(String ttsId, String text) {
CallerLogger.d(TAG, "onTtsFinish");
}
@Override
public void onTtsError( String ttsId, String text ) {
IMogoTTSCallback callBack = mSpeakVoiceMap.remove( text );
if ( callBack != null ) {
callBack.onTTSError( ttsId, text );
}
public void onTtsError(String ttsId, String text) {
CallerLogger.d(TAG, "onTtsError");
}
@Override
public void init( Context context ) {
if ( context != null ) {
public void init(Context context) {
CallerLogger.d(TAG, "onTtsError");
if (context != null) {
mContext = context.getApplicationContext();
mVoiceClient = new VoiceClient( mContext );
mVoiceClient.setCallBack( this );
initFlushStatus();
initSpeech( context );
initTts(SharedPrefsMgr.getInstance(mContext).getString("sn"));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 检查是否有悬浮窗权限
if (Settings.canDrawOverlays(context)) {
initSpeech(context);
}
} else {
initSpeech(context);
}
}
}
@Override
public void startAIAssist( Context context ) {
startAssistant( context, 1 );
public void startAIAssist(Context context) {
}
@Override
public void startAIAssist( Context context, int status ) {
final Intent intent = new Intent();
intent.setFlags( Intent.FLAG_INCLUDE_STOPPED_PACKAGES );
intent.setAction( "pvetec.intent.action.txz.switch" );
intent.putExtra( "window_start_cancel", status );
intent.putExtra( "extra_switch_type", "window_start_cancel" );
context.sendBroadcast( intent );
public void startAIAssist(Context context, int status) {
}
}

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/linearOutView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/normal_chat_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top"
android:background="@drawable/normal_bg_dark">
<ImageView
android:id="@+id/chatLeftImageView"
android:layout_width="@dimen/chat_left_image_size"
android:layout_height="@dimen/chat_left_image_size"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="@dimen/chat_left_margin"
android:layout_marginTop="@dimen/chat_left_image_top_margin"
android:layout_marginEnd="@dimen/chat_center_margin"
android:scaleType="fitXY"
android:src="@drawable/anim_voice_speaking" />
<TextView
android:id="@+id/normal_chat_text"
android:layout_width="@dimen/normal_chat_dialog_text_width"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/chat_main_top_margin"
android:layout_toEndOf="@id/chatLeftImageView"
android:ellipsize="end"
android:gravity="start|center_vertical"
android:maxLines="5"
android:textColor="@color/white"
android:textSize="@dimen/chat_main_text_size" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/rl_choice"
android:background="@drawable/main_bg_choice">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dialog_content_list_ll_height"
android:layout_marginStart="@dimen/txt_title_pic_margin_left"
android:orientation="horizontal">
<ImageView
android:id="@+id/txt_Title_Pic"
android:layout_width="@dimen/txt_title_pic_width"
android:layout_height="@dimen/txt_title_pic_height"
android:layout_margin="@dimen/dialog_content_list_image_margin"
android:src="@drawable/xiaozhi_icon" />
<TextView
android:id="@+id/txtList_Title"
style="@style/Style_Choice_Title_Text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:layout_marginStart="@dimen/title_left_margin"
android:textSize="@dimen/title_text_size" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="product_id">278586132</string>
</resources>