diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/ZhiView.kt b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/ZhiView.kt index 177a36e5b8..e71ddfe6f7 100644 --- a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/ZhiView.kt +++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/ZhiView.kt @@ -3,6 +3,7 @@ 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.kotlin.onClick 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 @@ -22,21 +23,64 @@ class ZhiView @JvmOverloads constructor( const val TAG = "ZhiView" } - private var createProgressDialogAnim: FrameAnimatorContainer?=null + private var normalAnim: FrameAnimatorContainer?=null + private var listeningAnim: FrameAnimatorContainer?=null + private var understandingAnim: FrameAnimatorContainer?=null + private var speakingAnim: FrameAnimatorContainer?=null + + @Volatile + private var currentAni:FrameAnimatorContainer?=null init { - createProgressDialogAnim = FrameAnimatorContainer(R.array.xiaozhi_normal, 20,this) - createProgressDialogAnim?.setOnAnimStopListener(object : FrameAnimatorContainer.OnAnimationStoppedListener{ + normalAnim = FrameAnimatorContainer(R.array.xiaozhi_normal, 20,this) + normalAnim?.setOnAnimStopListener(object : FrameAnimatorContainer.OnAnimationStoppedListener{ override fun AnimationStopped() { - CallerLogger.d(SceneConstant.M_TAXI_P + TAG, "动画暂停") + CallerLogger.d(SceneConstant.M_OCHCOMMON + TAG, "常态动画暂停") + currentAni?.reStart() } }) + + listeningAnim = FrameAnimatorContainer(R.array.xiaozhi_normal, 20,this) + listeningAnim?.setOnAnimStopListener(object : FrameAnimatorContainer.OnAnimationStoppedListener{ + override fun AnimationStopped() { + CallerLogger.d(SceneConstant.M_OCHCOMMON + TAG, "侦听动画暂停") + currentAni?.reStart() + } + }) + + understandingAnim = FrameAnimatorContainer(R.array.xiaozhi_normal, 20,this) + understandingAnim?.setOnAnimStopListener(object : FrameAnimatorContainer.OnAnimationStoppedListener{ + override fun AnimationStopped() { + CallerLogger.d(SceneConstant.M_OCHCOMMON + TAG, "理解中动画暂停") + currentAni?.reStart() + } + }) + + speakingAnim = FrameAnimatorContainer(R.array.xiaozhi_normal, 20,this) + speakingAnim?.setOnAnimStopListener(object : FrameAnimatorContainer.OnAnimationStoppedListener{ + override fun AnimationStopped() { + CallerLogger.d(SceneConstant.M_OCHCOMMON + TAG, "说话动画暂停") + currentAni?.reStart() + } + }) + + currentAni = normalAnim + + onClick { + AvatarManager.wakeupXiaoZhi() + } + } + + override fun onWindowFocusChanged(hasWindowFocus: Boolean) { + super.onWindowFocusChanged(hasWindowFocus) + CallerLogger.d(SceneConstant.M_OCHCOMMON + TAG, "焦点与否:${hasWindowFocus}") + AvatarManager.enableXiaoZhi(!hasWindowFocus) } override fun onAttachedToWindow() { super.onAttachedToWindow() AvatarManager.addDistanceListener(TAG,this) - createProgressDialogAnim?.start() + normalAnim?.reStart() } override fun onDetachedFromWindow() { @@ -50,25 +94,67 @@ class ZhiView @JvmOverloads constructor( override fun onStatusChange(status: ZhiRecordWinUi.RecordStatus?) { CallerLogger.d(TAG,"-----onStatusChange $status") + + + when (status) { + ZhiRecordWinUi.RecordStatus.STATUS_SILENCE -> {} + ZhiRecordWinUi.RecordStatus.STATUS_LISTENING -> { + // 正在听取 + currentAni?.stop() + currentAni = listeningAnim + } + ZhiRecordWinUi.RecordStatus.STATUS_UNDERSTANDING -> { + // 正在理解 + currentAni?.stop() + currentAni = understandingAnim + } + ZhiRecordWinUi.RecordStatus.STATUS_UNDERSTAND_END -> { + + } + ZhiRecordWinUi.RecordStatus.STATUS_SPEAKING -> { + // 正在说话 + currentAni?.stop() + currentAni = speakingAnim + } + else -> { + + } + } + + + + } override fun close(trigger: Boolean) { CallerLogger.d(TAG,"-----close $trigger") + currentAni?.stop() + currentAni = normalAnim } + override fun onVolumeChange(volume: Int) { CallerLogger.d(TAG,"-----onVolumeChange $volume") } + /** + * 用户输入的 + */ override fun showInputText(asrTextBean: AsrTextBean?) { CallerLogger.d(TAG,"-----showInputText $asrTextBean") } + /** + * 特定View + */ override fun showOutPutWidget(callbackWidget: CallbackWidget?) { // todo 咱不支持定制显示 包括天气 CallerLogger.d(TAG,"-----showOutPutWidget $callbackWidget") } + /** + * 小智说的 + */ override fun showOutputText(outPutText: String?) { CallerLogger.d(TAG,"-----showOutputText $outPutText") } diff --git a/tts/tts-base/src/main/java/com/mogo/tts/base/zhi/AvatarManager.kt b/tts/tts-base/src/main/java/com/mogo/tts/base/zhi/AvatarManager.kt index df5241d1c6..21723674b5 100644 --- a/tts/tts-base/src/main/java/com/mogo/tts/base/zhi/AvatarManager.kt +++ b/tts/tts-base/src/main/java/com/mogo/tts/base/zhi/AvatarManager.kt @@ -7,6 +7,8 @@ object AvatarManager { private var isShowing = false private val mControllerStatusCallbackMap = ConcurrentHashMap() + private var actionCallback:IActionCallback?=null + fun addDistanceListener(tag: String, listener: ZhiRecordWinUi) { if (mControllerStatusCallbackMap.containsKey(tag)) { return @@ -22,6 +24,19 @@ object AvatarManager { mControllerStatusCallbackMap.remove(tag) } + fun setActionCallback(actionCallback:IActionCallback){ + this.actionCallback = actionCallback + } + + fun wakeupXiaoZhi(){ + this.actionCallback?.wakeupXiaoZhi() + } + + fun enableXiaoZhi(enable:Boolean){ + this.actionCallback?.enableXiaoZhi(enable) + } + + fun isShowing():Boolean{ return isShowing } diff --git a/tts/tts-base/src/main/java/com/mogo/tts/base/zhi/IActionCallback.java b/tts/tts-base/src/main/java/com/mogo/tts/base/zhi/IActionCallback.java new file mode 100644 index 0000000000..5bcc749004 --- /dev/null +++ b/tts/tts-base/src/main/java/com/mogo/tts/base/zhi/IActionCallback.java @@ -0,0 +1,15 @@ +package com.mogo.tts.base.zhi; + +public +/** + * @author congtaowang + * @since 2020/10/12 + * + * 描述 + */ +interface IActionCallback { + // 手动唤醒小智 + void wakeupXiaoZhi(); + // 临时暂停启用小智 + void enableXiaoZhi(boolean enable); +} diff --git a/tts/tts-zhi/build.gradle b/tts/tts-zhi/build.gradle index 78c3ba5cb5..659c632ae9 100644 --- a/tts/tts-zhi/build.gradle +++ b/tts/tts-zhi/build.gradle @@ -47,7 +47,6 @@ dependencies { kapt rootProject.ext.dependencies.aroutercompiler api rootProject.ext.dependencies.aiassist - implementation rootProject.ext.dependencies.aiassistReplace implementation rootProject.ext.dependencies.androidxrecyclerview if (Boolean.valueOf(USE_MAVEN_PACKAGE)) { @@ -59,8 +58,15 @@ dependencies { } // implementation project(":xiaozhisdk") - implementation 'com.zhidao.speech.adapter:speechadapter:1.0.0-SNAPSHOT' - implementation 'com.mogo.xiaozhi.sdk:xiaozhisdk:1.0.0-SNAPSHOT' +// implementation project(':speechadapter') +// implementation project(':mogoVoiceSdk') +// implementation project(':mogospeechsdk') + + implementation 'com.zhidao.mogoVoicesdk:voicesdk:1.0.1-SNAPSHOT' + implementation 'com.zhidao.speech.adapter:speechadapter:1.0.1-SNAPSHOT' + implementation 'com.zhidao.mogo.speech.sdk:mogospeech:1.0.1-SNAPSHOT' + implementation 'com.mogo.xiaozhi.sdk:xiaozhisdk:1.0.1-SNAPSHOT' + } diff --git a/tts/tts-zhi/src/main/AndroidManifest.xml b/tts/tts-zhi/src/main/AndroidManifest.xml index c9bed99b00..38acf1b022 100644 --- a/tts/tts-zhi/src/main/AndroidManifest.xml +++ b/tts/tts-zhi/src/main/AndroidManifest.xml @@ -70,14 +70,16 @@ - + - + + diff --git a/tts/tts-zhi/src/main/java/com/mogo/tts/pad/ZhiAvatarWindow.java b/tts/tts-zhi/src/main/java/com/mogo/tts/pad/ZhiAvatarWindow.java index 6953894453..a59d950da2 100644 --- a/tts/tts-zhi/src/main/java/com/mogo/tts/pad/ZhiAvatarWindow.java +++ b/tts/tts-zhi/src/main/java/com/mogo/tts/pad/ZhiAvatarWindow.java @@ -33,13 +33,6 @@ 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() { } @@ -127,7 +120,6 @@ public class ZhiAvatarWindow implements RecordWinUi { 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; @@ -148,90 +140,6 @@ public class ZhiAvatarWindow implements RecordWinUi { 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()); diff --git a/tts/tts-zhi/src/main/java/com/mogo/tts/pad/ZhiTTS.java b/tts/tts-zhi/src/main/java/com/mogo/tts/pad/ZhiTTS.java index 3cd1fd5eb0..beba84816d 100644 --- a/tts/tts-zhi/src/main/java/com/mogo/tts/pad/ZhiTTS.java +++ b/tts/tts-zhi/src/main/java/com/mogo/tts/pad/ZhiTTS.java @@ -3,24 +3,27 @@ package com.mogo.tts.pad; import android.content.Context; import android.os.Build; import android.provider.Settings; -import android.util.Pair; import androidx.annotation.MainThread; import com.elegant.utils.storage.SharedPrefsMgr; import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger; +import com.mogo.eagle.core.utilcode.util.ToastUtils; import com.mogo.tts.base.IMogoTTS; import com.mogo.tts.base.IMogoTTSCallback; import com.mogo.tts.base.MultiLangTtsEntity; import com.mogo.tts.base.PreemptType; +import com.mogo.tts.base.zhi.AvatarManager; +import com.mogo.tts.base.zhi.IActionCallback; import com.mogo.xiaozhi.sdk.engine.DMStatusListener; import com.mogo.xiaozhi.sdk.engine.RecorderDMManager; +import com.mogo.xiaozhi.sdk.engine.tts.AILocalTTS; import com.mogo.xiaozhi.sdk.module.show.ZDCloudDMManager; -import com.zhidao.auto.platform.voice.VoiceClient; +import com.zhidao.mogo.speech.sdk.ActionExecutor; import com.zhidao.speech.adapter.AdapterApp; import com.zhidao.voicesdk.callback.OnTtsListener; -import java.util.LinkedList; +import java.util.concurrent.atomic.AtomicBoolean; /** * @author congtaowang @@ -34,6 +37,8 @@ public class ZhiTTS implements IMogoTTS, OnTtsListener { private Context mContext; + private AtomicBoolean initStatus = new AtomicBoolean(false); + public void release() { CallerLogger.d(TAG, "release"); } @@ -42,14 +47,32 @@ public class ZhiTTS implements IMogoTTS, OnTtsListener { @Override public void initTts(String sn) { CallerLogger.d(TAG, "initTts"); + // TODO: 2023/11/3 后续小智放入到子进程中 小智目前已支持 AdapterApp.getInstance().init(mContext); + AvatarManager.INSTANCE.setActionCallback(new IActionCallback() { + @Override + public void wakeupXiaoZhi() { + if(initStatus.get()){ + ActionExecutor.getInstance().action("mos.action.config.trigger", null); + }else { + ToastUtils.showShort("请稍后在试试吧"); + } + } + @Override + public void enableXiaoZhi(boolean enable) { + if(enable){ + ActionExecutor.getInstance().action("mos.action.config.cancel", null); + } + AILocalTTS.getInstance().setIsForbidASR(enable); + } + }); ZDCloudDMManager.getInstance().setUIView(ZhiAvatarWindow.class); - RecorderDMManager.getInstance().registerListener(new DMStatusListener() { @Override public void onInitSuccess() { CallerLogger.d(TAG, "RecorderDMManager---onInitSuccess"); + initStatus.set(true); } @Override @@ -75,7 +98,7 @@ public class ZhiTTS implements IMogoTTS, OnTtsListener { @Override public boolean hasFlush() { CallerLogger.d(TAG, "hasFlush"); - return true; + return initStatus.get(); } /**