语音转文字
This commit is contained in:
parent
6b7fd4d53e
commit
7fabc4f1b6
@ -12,11 +12,12 @@ import androidx.annotation.NonNull;
|
|||||||
import com.bumptech.glide.Glide;
|
import com.bumptech.glide.Glide;
|
||||||
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
|
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
|
import com.iflytek.cloud.SpeechConstant;
|
||||||
|
import com.iflytek.cloud.SpeechUtility;
|
||||||
import com.yunbao.common.CommonAppConfig;
|
import com.yunbao.common.CommonAppConfig;
|
||||||
import com.yunbao.common.bean.IMLoginModel;
|
import com.yunbao.common.bean.IMLoginModel;
|
||||||
import com.yunbao.common.event.RongIMConnectionStatusEvent;
|
import com.yunbao.common.event.RongIMConnectionStatusEvent;
|
||||||
import com.yunbao.common.manager.IMLoginManager;
|
import com.yunbao.common.manager.IMLoginManager;
|
||||||
import com.yunbao.common.views.weight.Recognizer;
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
|
|
||||||
@ -61,7 +62,8 @@ public class RongcloudIMManager {
|
|||||||
Log.e(CLASSNAME, "initRongIM:");
|
Log.e(CLASSNAME, "initRongIM:");
|
||||||
initPhotoGlide();
|
initPhotoGlide();
|
||||||
//初始化科大讯飞语音转文字
|
//初始化科大讯飞语音转文字
|
||||||
Recognizer.setAppId("671d2ae3");
|
String params = SpeechConstant.APPID + "=" + "671d2ae3";
|
||||||
|
SpeechUtility.createUtility(application.getApplicationContext(), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RongIMClient.OnReceiveMessageWrapperListener mListener;
|
private static RongIMClient.OnReceiveMessageWrapperListener mListener;
|
||||||
|
@ -1,362 +0,0 @@
|
|||||||
package com.yunbao.common.views.weight;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.drawable.AnimationDrawable;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.iflytek.cloud.ErrorCode;
|
|
||||||
import com.iflytek.cloud.InitListener;
|
|
||||||
import com.iflytek.cloud.RecognizerListener;
|
|
||||||
import com.iflytek.cloud.RecognizerResult;
|
|
||||||
import com.iflytek.cloud.SpeechConstant;
|
|
||||||
import com.iflytek.cloud.SpeechError;
|
|
||||||
import com.iflytek.cloud.SpeechRecognizer;
|
|
||||||
import com.iflytek.cloud.SpeechUtility;
|
|
||||||
import com.yunbao.common.R;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.json.JSONTokener;
|
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
|
|
||||||
public class Recognizer extends RelativeLayout {
|
|
||||||
private static final String TAG = "Recognizer";
|
|
||||||
|
|
||||||
private ImageView imgMic;
|
|
||||||
|
|
||||||
private Random random;
|
|
||||||
private IRecognizedResult mResultCallBack;
|
|
||||||
private SpeechRecognizer mIat = null;
|
|
||||||
private AnimationDrawable animStart;
|
|
||||||
private AnimationDrawable animEnd;
|
|
||||||
private static String mAppId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 开发者可以通过此接口设置自己从科大讯飞官网申请的 appId。 此方法可以在 SDK init 之后调用。
|
|
||||||
*
|
|
||||||
* <p>注意: appid 必须和下载的SDK保持一致,否则会出现10407错误
|
|
||||||
*
|
|
||||||
* @param appId 自定义的 appId
|
|
||||||
*/
|
|
||||||
public static void setAppId(String appId) {
|
|
||||||
mAppId = appId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Recognizer(Context context) {
|
|
||||||
super(context);
|
|
||||||
initViews();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Recognizer(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
|
||||||
initViews();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initViews() {
|
|
||||||
// setClickable(true);
|
|
||||||
// setBackgroundColor(getResources().getColor(R.color.white));
|
|
||||||
// RelativeLayout recognizerContainer =
|
|
||||||
// (RelativeLayout)
|
|
||||||
// LayoutInflater.from(getContext())
|
|
||||||
// .inflate(R.layout.rc_view_recognizer, null);
|
|
||||||
// View rlMic = recognizerContainer.findViewById(R.id.rl_mic);
|
|
||||||
// rlMic.setOnClickListener(
|
|
||||||
// new OnClickListener() {
|
|
||||||
// @Override
|
|
||||||
// public void onClick(View view) {
|
|
||||||
// if (mIat == null || !mIat.isListening()) {
|
|
||||||
// startRecognize();
|
|
||||||
// } else {
|
|
||||||
// reset();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// imgMic = (ImageView) recognizerContainer.findViewById(R.id.img_mic);
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// addView(recognizerContainer);
|
|
||||||
// random = new Random();
|
|
||||||
// String params = SpeechConstant.APPID + "=" + mAppId;
|
|
||||||
// SpeechUtility.createUtility(getContext().getApplicationContext(), params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 初始化监听器。
|
|
||||||
*/
|
|
||||||
private static InitListener mInitListener =
|
|
||||||
new InitListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onInit(int code) {
|
|
||||||
Log.e(TAG, "onInit " + code);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public void startRecognize() {
|
|
||||||
// if (null == mIat) {
|
|
||||||
// mIat = SpeechRecognizer.createRecognizer(getContext(), mInitListener);
|
|
||||||
// }
|
|
||||||
// if (mIat.isListening()) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// setParam();
|
|
||||||
// int ret = mIat.startListening(this);
|
|
||||||
// if (ret != ErrorCode.SUCCESS) {
|
|
||||||
// Log.e(TAG, "startRecognize ret error " + ret);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 参数设置,设置听写参数,详见《科大讯飞MSC API手册(Android)》SpeechConstant类
|
|
||||||
*
|
|
||||||
* @param
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private void setParam() {
|
|
||||||
// 清空参数
|
|
||||||
mIat.setParameter(SpeechConstant.PARAMS, null);
|
|
||||||
|
|
||||||
// 设置听写引擎
|
|
||||||
mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
|
|
||||||
// 设置返回结果格式
|
|
||||||
mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
|
|
||||||
|
|
||||||
mIat.setParameter(SpeechConstant.DOMAIN, "iat");
|
|
||||||
if ("zh".equals(Locale.getDefault().getLanguage().toLowerCase())) {
|
|
||||||
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
|
|
||||||
mIat.setParameter(SpeechConstant.ACCENT, "mandarin ");
|
|
||||||
} else {
|
|
||||||
mIat.setParameter(SpeechConstant.LANGUAGE, "en_us");
|
|
||||||
}
|
|
||||||
// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
|
|
||||||
mIat.setParameter(SpeechConstant.VAD_BOS, "4000");
|
|
||||||
// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
|
|
||||||
mIat.setParameter(SpeechConstant.VAD_EOS, "1000");
|
|
||||||
// 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
|
|
||||||
mIat.setParameter(SpeechConstant.ASR_PTT, "1");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setRandomImageResource() {
|
|
||||||
// int num = random.nextInt(3) + 1;
|
|
||||||
// switch (num) {
|
|
||||||
// case 1:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_01);
|
|
||||||
// break;
|
|
||||||
// case 2:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_02);
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_03);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
private void changeVolume(int volume) {
|
|
||||||
// if (null != imgMic) {
|
|
||||||
// switch (volume / 2) {
|
|
||||||
// case 0:
|
|
||||||
// setRandomImageResource();
|
|
||||||
// break;
|
|
||||||
// case 1:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_02);
|
|
||||||
// break;
|
|
||||||
// case 2:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_03);
|
|
||||||
// break;
|
|
||||||
// case 3:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_04);
|
|
||||||
// break;
|
|
||||||
// case 4:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_05);
|
|
||||||
// break;
|
|
||||||
// case 5:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_06);
|
|
||||||
// break;
|
|
||||||
// case 6:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_07);
|
|
||||||
// break;
|
|
||||||
// case 7:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_08);
|
|
||||||
// break;
|
|
||||||
// case 8:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_09);
|
|
||||||
// break;
|
|
||||||
// case 9:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_10);
|
|
||||||
// break;
|
|
||||||
// case 10:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_11);
|
|
||||||
// break;
|
|
||||||
// case 11:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_12);
|
|
||||||
// break;
|
|
||||||
// case 12:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_13);
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_volume_14);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
private void endOfSpeech() {
|
|
||||||
// if (null == imgMic) return;
|
|
||||||
// imgMic.setImageResource(R.drawable.rc_anim_speech_end);
|
|
||||||
// animEnd = (AnimationDrawable) imgMic.getDrawable();
|
|
||||||
// imgMic.clearAnimation();
|
|
||||||
// animEnd.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void beginOfSpeech() {
|
|
||||||
// if (null == imgMic) return;
|
|
||||||
// imgMic.setImageResource(R.drawable.rc_anim_speech_start);
|
|
||||||
// animStart = (AnimationDrawable) imgMic.getDrawable();
|
|
||||||
// imgMic.clearAnimation();
|
|
||||||
// animStart.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDetachedFromWindow() {
|
|
||||||
super.onDetachedFromWindow();
|
|
||||||
if (null != mIat) {
|
|
||||||
mIat.cancel();
|
|
||||||
mIat.destroy();
|
|
||||||
mIat = null;
|
|
||||||
}
|
|
||||||
if (null != mResultCallBack) {
|
|
||||||
mResultCallBack = null;
|
|
||||||
}
|
|
||||||
if (animEnd != null) {
|
|
||||||
animEnd.stop();
|
|
||||||
animEnd = null;
|
|
||||||
}
|
|
||||||
if (animStart != null) {
|
|
||||||
animStart.stop();
|
|
||||||
animEnd = null;
|
|
||||||
}
|
|
||||||
mInitListener = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void printResult(RecognizerResult result) {
|
|
||||||
String json = result.getResultString();
|
|
||||||
String text = parseRecognizeResult(result);
|
|
||||||
Log.e(TAG, "printResult " + text);
|
|
||||||
try {
|
|
||||||
JSONObject obj = new JSONObject(json);
|
|
||||||
boolean isLast = obj.getBoolean("ls");
|
|
||||||
if (isLast) {
|
|
||||||
endOfSpeech();
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mResultCallBack != null) {
|
|
||||||
mResultCallBack.onResult(text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onResult(RecognizerResult recognizerResult, boolean b) {
|
|
||||||
// printResult(recognizerResult);
|
|
||||||
// if (imgMic != null) {
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_disable);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onError(SpeechError speechError) {
|
|
||||||
// if (speechError.getErrorCode() == ErrorCode.ERROR_NO_NETWORK) {
|
|
||||||
// Toast.makeText(
|
|
||||||
// getContext(),
|
|
||||||
// getContext().getString(R.string.load_failure),
|
|
||||||
// Toast.LENGTH_SHORT)
|
|
||||||
// .show();
|
|
||||||
// }
|
|
||||||
// if (imgMic != null) {
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_disable);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onEvent(int eventType, int i1, int i2, Bundle bundle) {
|
|
||||||
// Log.e(TAG, "RecognizerView onEvent eventType: " + eventType);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onVolumeChanged(int volume, byte[] bytes) {
|
|
||||||
// changeVolume(volume);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onBeginOfSpeech() {
|
|
||||||
// Log.e(TAG, "RecognizerView onBeginOfSpeech");
|
|
||||||
// beginOfSpeech();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public void onEndOfSpeech() {
|
|
||||||
// Log.e(TAG, "RecognizerView onEndOfSpeech");
|
|
||||||
// endOfSpeech();
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void setCallBack(IRecognizedResult resultCallBack) {
|
|
||||||
mResultCallBack = resultCallBack;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void reset() {
|
|
||||||
if (null != mIat) {
|
|
||||||
mIat.cancel();
|
|
||||||
mIat.destroy();
|
|
||||||
mIat = null;
|
|
||||||
}
|
|
||||||
if (null != animEnd) {
|
|
||||||
animEnd.stop();
|
|
||||||
animEnd = null;
|
|
||||||
}
|
|
||||||
if (animStart != null) {
|
|
||||||
animStart.stop();
|
|
||||||
animStart = null;
|
|
||||||
}
|
|
||||||
if (imgMic != null) {
|
|
||||||
// imgMic.setImageResource(R.mipmap.rc_recognize_disable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String parseRecognizeResult(RecognizerResult results) {
|
|
||||||
StringBuilder ret = new StringBuilder();
|
|
||||||
try {
|
|
||||||
JSONTokener jsonTokener = new JSONTokener(results.getResultString());
|
|
||||||
JSONObject jsonObject = new JSONObject(jsonTokener);
|
|
||||||
|
|
||||||
JSONArray words = jsonObject.getJSONArray("ws");
|
|
||||||
for (int i = 0; i < words.length(); i++) {
|
|
||||||
// 转写结果词,默认使用第一个结果
|
|
||||||
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
|
|
||||||
JSONObject obj = items.getJSONObject(0);
|
|
||||||
ret.append(obj.getString("w"));
|
|
||||||
// 如果需要多候选结果,解析数组其他字段
|
|
||||||
// for(int j = 0; j < items.length(); j++)
|
|
||||||
// {
|
|
||||||
// JSONObject obj = items.getJSONObject(j);
|
|
||||||
// ret.append(obj.getString("w"));
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return ret.toString();
|
|
||||||
}
|
|
||||||
}
|
|
BIN
common/src/main/res/mipmap-xxhdpi/icon_withdraw.png
Normal file
BIN
common/src/main/res/mipmap-xxhdpi/icon_withdraw.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
BIN
common/src/main/res/mipmap-xxhdpi/voice_fluctuations.gif
Normal file
BIN
common/src/main/res/mipmap-xxhdpi/voice_fluctuations.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 KiB |
@ -139,6 +139,7 @@ public class LiveAudienceActivity extends LiveActivity {
|
|||||||
private int liveBg = 0;
|
private int liveBg = 0;
|
||||||
//直播间进入房间队列
|
//直播间进入房间队列
|
||||||
private Handler liveHandler = new Handler();
|
private Handler liveHandler = new Handler();
|
||||||
|
private ImageView voicePress;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends View> T findViewById(@IdRes int id) {
|
public <T extends View> T findViewById(@IdRes int id) {
|
||||||
@ -178,7 +179,7 @@ public class LiveAudienceActivity extends LiveActivity {
|
|||||||
private void initView() {
|
private void initView() {
|
||||||
// 竖直滑动 ViewPager
|
// 竖直滑动 ViewPager
|
||||||
verticalViewPager = findViewById(R.id.view_pager);
|
verticalViewPager = findViewById(R.id.view_pager);
|
||||||
|
voicePress = findViewById(R.id.voice_press);
|
||||||
verticalViewPager.setEnableScroll(IMLoginManager.get(mContext).isSlide());
|
verticalViewPager.setEnableScroll(IMLoginManager.get(mContext).isSlide());
|
||||||
//判断是否有直播悬浮窗,有直接关闭
|
//判断是否有直播悬浮窗,有直接关闭
|
||||||
if (EasyFloat.isShow("LiveFloatView")) {
|
if (EasyFloat.isShow("LiveFloatView")) {
|
||||||
@ -623,7 +624,7 @@ public class LiveAudienceActivity extends LiveActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setEnableScroll(boolean enableScroll) {
|
public void setEnableScroll(boolean enableScroll) {
|
||||||
verticalViewPager.setEnableScroll(enableScroll);
|
verticalViewPager.setEnableScroll(IMLoginManager.get(mContext).isSlide());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
@ -645,7 +646,7 @@ public class LiveAudienceActivity extends LiveActivity {
|
|||||||
manager.onAdd(liveBean, mLiveType, mLiveTypeVal, mLiveSDK);
|
manager.onAdd(liveBean, mLiveType, mLiveTypeVal, mLiveSDK);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
verticalViewPager.setEnableScroll(true);
|
verticalViewPager.setEnableScroll(IMLoginManager.get(mContext).isSlide());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,6 +909,18 @@ public class LiveAudienceActivity extends LiveActivity {
|
|||||||
case MESSAGE_BOTTOM:
|
case MESSAGE_BOTTOM:
|
||||||
manager.messageBottom();
|
manager.messageBottom();
|
||||||
break;
|
break;
|
||||||
|
case VOICE_PRESS:
|
||||||
|
voicePress.setVisibility(event.isVoicePress() ? View.VISIBLE : View.GONE);
|
||||||
|
if (IMLoginManager.get(mContext).isSlide()) {
|
||||||
|
if (event.isVoicePress()) {
|
||||||
|
verticalViewPager.setEnableScroll(false);
|
||||||
|
} else {
|
||||||
|
verticalViewPager.setEnableScroll(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.yunbao.live.dialog;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
|
import com.yunbao.common.dialog.AbsDialogFragment;
|
||||||
|
import com.yunbao.common.utils.DpUtil;
|
||||||
|
import com.yunbao.live.R;
|
||||||
|
|
||||||
|
public class TextHintDialog extends AbsDialogFragment {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getLayoutId() {
|
||||||
|
return R.layout.view_text_hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getDialogStyle() {
|
||||||
|
return R.style.dialog4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canCancel() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setWindowAttributes(Window window) {
|
||||||
|
window.setWindowAnimations(com.yunbao.common.R.style.bottomToTopAnim);
|
||||||
|
WindowManager.LayoutParams params = window.getAttributes();
|
||||||
|
params.width = DpUtil.dp2px(309);
|
||||||
|
params.height = DpUtil.dp2px(44);
|
||||||
|
params.gravity = Gravity.CENTER;
|
||||||
|
window.setAttributes(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
new Handler().postDelayed(() -> dismiss(), 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
292
live/src/main/java/com/yunbao/live/dialog/VoiceDialog.java
Normal file
292
live/src/main/java/com/yunbao/live/dialog/VoiceDialog.java
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
package com.yunbao.live.dialog;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.SpannableStringBuilder;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.iflytek.cloud.ErrorCode;
|
||||||
|
import com.iflytek.cloud.InitListener;
|
||||||
|
import com.iflytek.cloud.RecognizerListener;
|
||||||
|
import com.iflytek.cloud.RecognizerResult;
|
||||||
|
import com.iflytek.cloud.SpeechConstant;
|
||||||
|
import com.iflytek.cloud.SpeechError;
|
||||||
|
import com.iflytek.cloud.SpeechRecognizer;
|
||||||
|
import com.yunbao.common.dialog.AbsDialogFragment;
|
||||||
|
import com.yunbao.common.glide.ImgLoader;
|
||||||
|
import com.yunbao.common.utils.DpUtil;
|
||||||
|
import com.yunbao.live.R;
|
||||||
|
import com.yunbao.live.activity.LiveAudienceActivity;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.json.JSONTokener;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import pl.droidsonroids.gif.GifImageView;
|
||||||
|
|
||||||
|
public class VoiceDialog extends AbsDialogFragment {
|
||||||
|
// 语音识别对象
|
||||||
|
private SpeechRecognizer mIat = null;
|
||||||
|
private String TAG = "VoiceDialog";
|
||||||
|
private ImageView voiceFluctuations, iconWithdraw;
|
||||||
|
private TextView voiceChat, fingersSlide;
|
||||||
|
private GifImageView gifView;
|
||||||
|
private SpannableStringBuilder builder = new SpannableStringBuilder();
|
||||||
|
private boolean isSend = true;
|
||||||
|
|
||||||
|
public boolean isSend() {
|
||||||
|
return isSend;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
if (mIat != null) {
|
||||||
|
mIat.cancel();
|
||||||
|
mIat.destroy();
|
||||||
|
mIat = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String sendMessage() {
|
||||||
|
|
||||||
|
return voiceChat.getText().toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getLayoutId() {
|
||||||
|
return R.layout.view_voice_dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getDialogStyle() {
|
||||||
|
return R.style.dialog4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canCancel() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setWindowAttributes(Window window) {
|
||||||
|
window.setWindowAnimations(com.yunbao.common.R.style.bottomToTopAnim);
|
||||||
|
WindowManager.LayoutParams params = window.getAttributes();
|
||||||
|
params.width = DpUtil.dp2px(350);
|
||||||
|
params.height = DpUtil.dp2px(200);
|
||||||
|
params.gravity = Gravity.CENTER;
|
||||||
|
window.setAttributes(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
voiceFluctuations = (ImageView) findViewById(R.id.voice_fluctuations);
|
||||||
|
iconWithdraw = (ImageView) findViewById(R.id.icon_withdraw);
|
||||||
|
voiceChat = (TextView) findViewById(R.id.voice_chat);
|
||||||
|
fingersSlide = (TextView) findViewById(R.id.fingers_slide);
|
||||||
|
gifView = (GifImageView) findViewById(R.id.gif_view);
|
||||||
|
startRecognize();
|
||||||
|
iconWithdraw.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上划取消
|
||||||
|
*/
|
||||||
|
public void withdraw() {
|
||||||
|
voiceFluctuations.setVisibility(View.GONE);
|
||||||
|
gifView.setVisibility(View.GONE);
|
||||||
|
iconWithdraw.setVisibility(View.VISIBLE);
|
||||||
|
fingersSlide.setText(getString(R.string.release_cancel_send));
|
||||||
|
isSend = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上划取消
|
||||||
|
*/
|
||||||
|
public void notWithdraw() {
|
||||||
|
voiceFluctuations.setVisibility(View.VISIBLE);
|
||||||
|
iconWithdraw.setVisibility(View.GONE);
|
||||||
|
fingersSlide.setText(getString(R.string.fingers_slide));
|
||||||
|
gifView.setVisibility(View.VISIBLE);
|
||||||
|
isSend = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 科大讯飞内置录音机
|
||||||
|
*/
|
||||||
|
RecognizerListener recognizerListener = new RecognizerListener() {
|
||||||
|
@Override
|
||||||
|
public void onVolumeChanged(int volume, byte[] bytes) {
|
||||||
|
if (volume > 20) {
|
||||||
|
gifView.setVisibility(View.VISIBLE);
|
||||||
|
voiceFluctuations.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBeginOfSpeech() {
|
||||||
|
Log.e(TAG, "onBeginOfSpeech 开始讲话");
|
||||||
|
voiceFluctuations.setVisibility(View.GONE);
|
||||||
|
gifView.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEndOfSpeech() {
|
||||||
|
Log.e(TAG, "onBeginOfSpeech 结束讲话");
|
||||||
|
ImgLoader.displayGif(mContext, R.mipmap.img_p, voiceFluctuations);
|
||||||
|
if (TextUtils.isEmpty(voiceChat.getText())) {
|
||||||
|
dismiss();
|
||||||
|
TextHintDialog textHintDialog = new TextHintDialog();
|
||||||
|
textHintDialog.show(((LiveAudienceActivity) mContext).getSupportFragmentManager(), "TextHintDialog");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResult(RecognizerResult recognizerResult, boolean b) {
|
||||||
|
printResult(recognizerResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(SpeechError speechError) {
|
||||||
|
if (speechError.getErrorCode() == ErrorCode.ERROR_NO_NETWORK) {
|
||||||
|
Toast.makeText(
|
||||||
|
getContext(),
|
||||||
|
getContext().getString(com.yunbao.common.R.string.load_failure),
|
||||||
|
Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEvent(int i, int i1, int i2, Bundle bundle) {
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束录音
|
||||||
|
*/
|
||||||
|
private void endOfSpeech() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化监听器。
|
||||||
|
*/
|
||||||
|
private InitListener mInitListener =
|
||||||
|
code -> Log.e(TAG, "onInit " + code);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始识别
|
||||||
|
*/
|
||||||
|
public void startRecognize() {
|
||||||
|
if (null == mIat) {
|
||||||
|
mIat = SpeechRecognizer.createRecognizer(getContext(), mInitListener);
|
||||||
|
}
|
||||||
|
if (mIat.isListening()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setParam();
|
||||||
|
int ret = mIat.startListening(recognizerListener);
|
||||||
|
if (ret != ErrorCode.SUCCESS) {
|
||||||
|
Log.e(TAG, "startRecognize ret error " + ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数设置,设置听写参数,详见《科大讯飞MSC API手册(Android)》SpeechConstant类
|
||||||
|
*
|
||||||
|
* @param
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private void setParam() {
|
||||||
|
// 清空参数
|
||||||
|
mIat.setParameter(SpeechConstant.PARAMS, null);
|
||||||
|
|
||||||
|
// 设置听写引擎
|
||||||
|
mIat.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
|
||||||
|
// 设置返回结果格式
|
||||||
|
mIat.setParameter(SpeechConstant.RESULT_TYPE, "json");
|
||||||
|
|
||||||
|
mIat.setParameter(SpeechConstant.DOMAIN, "iat");
|
||||||
|
if ("zh".equals(Locale.getDefault().getLanguage().toLowerCase())) {
|
||||||
|
mIat.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
|
||||||
|
mIat.setParameter(SpeechConstant.ACCENT, "mandarin ");
|
||||||
|
} else {
|
||||||
|
mIat.setParameter(SpeechConstant.LANGUAGE, "en_us");
|
||||||
|
}
|
||||||
|
// 设置语音前端点:静音超时时间,即用户多长时间不说话则当做超时处理
|
||||||
|
mIat.setParameter(SpeechConstant.VAD_BOS, "10000");
|
||||||
|
// 设置语音后端点:后端点静音检测时间,即用户停止说话多长时间内即认为不再输入, 自动停止录音
|
||||||
|
mIat.setParameter(SpeechConstant.VAD_EOS, "30000");
|
||||||
|
// 设置标点符号,设置为"0"返回结果无标点,设置为"1"返回结果有标点
|
||||||
|
mIat.setParameter(SpeechConstant.ASR_PTT, "1");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打印数据结果
|
||||||
|
*
|
||||||
|
* @param result
|
||||||
|
*/
|
||||||
|
private void printResult(RecognizerResult result) {
|
||||||
|
String json = result.getResultString();
|
||||||
|
String text = parseRecognizeResult(result);
|
||||||
|
Log.e(TAG, "printResult " + text);
|
||||||
|
try {
|
||||||
|
JSONObject obj = new JSONObject(json);
|
||||||
|
boolean isLast = obj.getBoolean("ls");
|
||||||
|
if (isLast) {
|
||||||
|
endOfSpeech();
|
||||||
|
}
|
||||||
|
builder.append(text);
|
||||||
|
voiceChat.setText(builder);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转译语音返回
|
||||||
|
*
|
||||||
|
* @param results
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String parseRecognizeResult(RecognizerResult results) {
|
||||||
|
StringBuilder ret = new StringBuilder();
|
||||||
|
try {
|
||||||
|
JSONTokener jsonTokener = new JSONTokener(results.getResultString());
|
||||||
|
JSONObject jsonObject = new JSONObject(jsonTokener);
|
||||||
|
|
||||||
|
JSONArray words = jsonObject.getJSONArray("ws");
|
||||||
|
for (int i = 0; i < words.length(); i++) {
|
||||||
|
// 转写结果词,默认使用第一个结果
|
||||||
|
JSONArray items = words.getJSONObject(i).getJSONArray("cw");
|
||||||
|
JSONObject obj = items.getJSONObject(0);
|
||||||
|
ret.append(obj.getString("w"));
|
||||||
|
// 如果需要多候选结果,解析数组其他字段
|
||||||
|
// for(int j = 0; j < items.length(); j++)
|
||||||
|
// {
|
||||||
|
// JSONObject obj = items.getJSONObject(j);
|
||||||
|
// ret.append(obj.getString("w"));
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return ret.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,16 @@ public class LiveAudienceEvent extends BaseModel {
|
|||||||
private int liveTypeVal;
|
private int liveTypeVal;
|
||||||
private MsgModel msgModel;//全服消息
|
private MsgModel msgModel;//全服消息
|
||||||
private AiAutomaticSpeechModel aiAutomaticSpeechModel;//机器人消息
|
private AiAutomaticSpeechModel aiAutomaticSpeechModel;//机器人消息
|
||||||
|
private boolean voicePress = false;
|
||||||
|
|
||||||
|
public boolean isVoicePress() {
|
||||||
|
return voicePress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveAudienceEvent setVoicePress(boolean voicePress) {
|
||||||
|
this.voicePress = voicePress;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public AiAutomaticSpeechModel getAiAutomaticSpeechModel() {
|
public AiAutomaticSpeechModel getAiAutomaticSpeechModel() {
|
||||||
return aiAutomaticSpeechModel;
|
return aiAutomaticSpeechModel;
|
||||||
@ -149,7 +159,8 @@ public class LiveAudienceEvent extends BaseModel {
|
|||||||
AI_AUTOMATIC_SPEECH(26, "机器人助手"),
|
AI_AUTOMATIC_SPEECH(26, "机器人助手"),
|
||||||
STAR_CHALLENGE_UPGRADE_NOTIFY(27, "星级挑战成功"),
|
STAR_CHALLENGE_UPGRADE_NOTIFY(27, "星级挑战成功"),
|
||||||
MESSAGE_BOTTOM(28, "聊天消息滚动到底部"),
|
MESSAGE_BOTTOM(28, "聊天消息滚动到底部"),
|
||||||
FLOAT_SETTING(29, "悬浮窗设置");
|
FLOAT_SETTING(29, "悬浮窗设置"),
|
||||||
|
VOICE_PRESS(30, "长按展示图片");
|
||||||
|
|
||||||
private int type;
|
private int type;
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -12,29 +12,28 @@ import android.text.TextUtils;
|
|||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.ViewFlipper;
|
import android.widget.ViewFlipper;
|
||||||
|
|
||||||
import com.opensource.svgaplayer.SVGACallback;
|
|
||||||
import com.opensource.svgaplayer.SVGADrawable;
|
import com.opensource.svgaplayer.SVGADrawable;
|
||||||
import com.opensource.svgaplayer.SVGAImageView;
|
import com.opensource.svgaplayer.SVGAImageView;
|
||||||
import com.opensource.svgaplayer.SVGAParser;
|
import com.opensource.svgaplayer.SVGAParser;
|
||||||
import com.opensource.svgaplayer.SVGAVideoEntity;
|
import com.opensource.svgaplayer.SVGAVideoEntity;
|
||||||
import com.yunbao.common.CommonAppConfig;
|
import com.yunbao.common.CommonAppConfig;
|
||||||
import com.yunbao.common.Constants;
|
import com.yunbao.common.Constants;
|
||||||
import com.yunbao.common.bean.MsgModel;
|
|
||||||
import com.yunbao.common.bean.NewPeopleInfo;
|
import com.yunbao.common.bean.NewPeopleInfo;
|
||||||
import com.yunbao.common.event.MessageIMEvent;
|
import com.yunbao.common.event.MessageIMEvent;
|
||||||
import com.yunbao.common.glide.ImgLoader;
|
import com.yunbao.common.glide.ImgLoader;
|
||||||
import com.yunbao.common.http.API;
|
import com.yunbao.common.http.API;
|
||||||
import com.yunbao.common.http.HttpCallback;
|
import com.yunbao.common.http.HttpCallback;
|
||||||
import com.yunbao.common.http.HttpClient;
|
import com.yunbao.common.http.HttpClient;
|
||||||
import com.yunbao.common.manager.imrongcloud.MessageIMManager;
|
|
||||||
import com.yunbao.common.utils.Bus;
|
import com.yunbao.common.utils.Bus;
|
||||||
import com.yunbao.common.utils.DpUtil;
|
import com.yunbao.common.utils.DpUtil;
|
||||||
import com.yunbao.common.utils.SVGAViewUtils;
|
import com.yunbao.common.utils.SVGAViewUtils;
|
||||||
@ -48,6 +47,7 @@ import com.yunbao.live.bean.LiveChatBean;
|
|||||||
import com.yunbao.live.dialog.LiveHDDialogFragment;
|
import com.yunbao.live.dialog.LiveHDDialogFragment;
|
||||||
import com.yunbao.live.dialog.LiveMicUserDialogFragment;
|
import com.yunbao.live.dialog.LiveMicUserDialogFragment;
|
||||||
import com.yunbao.live.dialog.LivePromotionDialogFragment;
|
import com.yunbao.live.dialog.LivePromotionDialogFragment;
|
||||||
|
import com.yunbao.live.dialog.VoiceDialog;
|
||||||
import com.yunbao.live.event.LiveAudienceEvent;
|
import com.yunbao.live.event.LiveAudienceEvent;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
@ -79,6 +79,7 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder {
|
|||||||
private ImageView giftImage, liveNewPeople;
|
private ImageView giftImage, liveNewPeople;
|
||||||
private String newPeopleUrl = null;
|
private String newPeopleUrl = null;
|
||||||
private View mNewPeopleRedDot;
|
private View mNewPeopleRedDot;
|
||||||
|
private LinearLayout voiceButton;
|
||||||
|
|
||||||
public LiveAudienceViewHolder(Context context, ViewGroup parentView) {
|
public LiveAudienceViewHolder(Context context, ViewGroup parentView) {
|
||||||
super(context, parentView);
|
super(context, parentView);
|
||||||
@ -179,6 +180,7 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder {
|
|||||||
return R.layout.view_live_audience;
|
return R.layout.view_live_audience;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
super.init();
|
super.init();
|
||||||
@ -188,6 +190,7 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder {
|
|||||||
findViewById(R.id.btn_red_pack).setOnClickListener(this);
|
findViewById(R.id.btn_red_pack).setOnClickListener(this);
|
||||||
findViewById(R.id.btn_gift).setOnClickListener(this);
|
findViewById(R.id.btn_gift).setOnClickListener(this);
|
||||||
findViewById(R.id.btn_zg).setOnClickListener(this);
|
findViewById(R.id.btn_zg).setOnClickListener(this);
|
||||||
|
voiceButton = (LinearLayout) findViewById(R.id.voice_button);
|
||||||
giftImage = (ImageView) findViewById(R.id.gift_image);
|
giftImage = (ImageView) findViewById(R.id.gift_image);
|
||||||
liveNewPeople = (ImageView) findViewById(R.id.live_new_people);
|
liveNewPeople = (ImageView) findViewById(R.id.live_new_people);
|
||||||
svga_new_user_gif = (SVGAImageView) findViewById(R.id.svga_new_user_gif);
|
svga_new_user_gif = (SVGAImageView) findViewById(R.id.svga_new_user_gif);
|
||||||
@ -262,8 +265,57 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder {
|
|||||||
String language = locale.getLanguage();
|
String language = locale.getLanguage();
|
||||||
|
|
||||||
ImgLoader.display(mContext, TextUtils.equals(language, "zh") ? R.mipmap.live_icon_new_people_cn : R.mipmap.live_icon_newpeople_en, liveNewPeople);
|
ImgLoader.display(mContext, TextUtils.equals(language, "zh") ? R.mipmap.live_icon_new_people_cn : R.mipmap.live_icon_newpeople_en, liveNewPeople);
|
||||||
|
|
||||||
|
voiceButton.setOnTouchListener((v, event) -> {
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
|
downY = event.getY();
|
||||||
|
//按下
|
||||||
|
handler.postDelayed(mLongPressed, 500);
|
||||||
|
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||||
|
float moveY = event.getY();
|
||||||
|
if (downY - moveY > 120) {
|
||||||
|
voiceDialog.withdraw();
|
||||||
|
}
|
||||||
|
if ((downY - moveY < 100) && (downY - moveY > 30)) {
|
||||||
|
voiceDialog.notWithdraw();
|
||||||
|
}
|
||||||
|
} else if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||||
|
//松开
|
||||||
|
handler.removeCallbacks(mLongPressed);
|
||||||
|
Bus.get().post(new LiveAudienceEvent()
|
||||||
|
.setVoicePress(false)
|
||||||
|
.setType(LiveAudienceEvent.LiveAudienceType.VOICE_PRESS));
|
||||||
|
|
||||||
|
if (voiceDialog != null) {
|
||||||
|
if (voiceDialog.isSend() && !TextUtils.isEmpty(voiceDialog.sendMessage())) {
|
||||||
|
((LiveActivity) mContext).sendChatMessage(voiceDialog.sendMessage(), null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
voiceDialog.dismiss();
|
||||||
|
voiceDialog = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private float downY = 0;
|
||||||
|
|
||||||
|
private VoiceDialog voiceDialog = null;
|
||||||
|
private Runnable mLongPressed = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (voiceDialog == null) {
|
||||||
|
voiceDialog = new VoiceDialog();
|
||||||
|
}
|
||||||
|
voiceDialog.show(((LiveAudienceActivity) mContext).getSupportFragmentManager(), "VoiceDialog");
|
||||||
|
Bus.get().post(new LiveAudienceEvent()
|
||||||
|
.setVoicePress(true)
|
||||||
|
.setType(LiveAudienceEvent.LiveAudienceType.VOICE_PRESS));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public static Handler handler = new Handler();
|
public static Handler handler = new Handler();
|
||||||
public static Runnable runnable;
|
public static Runnable runnable;
|
||||||
|
|
||||||
@ -360,13 +412,13 @@ public class LiveAudienceViewHolder extends AbsLiveViewHolder {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
String url = newPeopleUrl+ (newPeopleUrl.contains("?")?"&":"?") + "g=Appapi&m=Turntable&a=tricky";
|
String url = newPeopleUrl + (newPeopleUrl.contains("?") ? "&" : "?") + "g=Appapi&m=Turntable&a=tricky";
|
||||||
url += "&uid=" + CommonAppConfig.getInstance().getUid() + "&token="
|
url += "&uid=" + CommonAppConfig.getInstance().getUid() + "&token="
|
||||||
+ CommonAppConfig.getInstance().getToken() + "&anchorUid=" + mLiveUid;
|
+ CommonAppConfig.getInstance().getToken() + "&anchorUid=" + mLiveUid;
|
||||||
bundle.putString("url", url);
|
bundle.putString("url", url);
|
||||||
bundle.putInt("show_type", 0);
|
bundle.putInt("show_type", 0);
|
||||||
bundle.putInt("height",DpUtil.dp2px(1));
|
bundle.putInt("height", DpUtil.dp2px(1));
|
||||||
// bundle.putBoolean("banScrollY",true);
|
// bundle.putBoolean("banScrollY",true);
|
||||||
LiveHDDialogFragment liveHDDialogFragment = new LiveHDDialogFragment();
|
LiveHDDialogFragment liveHDDialogFragment = new LiveHDDialogFragment();
|
||||||
liveHDDialogFragment.setArguments(bundle);
|
liveHDDialogFragment.setArguments(bundle);
|
||||||
liveHDDialogFragment.show(((LiveAudienceActivity) mContext).getSupportFragmentManager(), "LiveHDDialogFragment");
|
liveHDDialogFragment.show(((LiveAudienceActivity) mContext).getSupportFragmentManager(), "LiveHDDialogFragment");
|
||||||
|
5
live/src/main/res/drawable/bg_voice_chat.xml
Normal file
5
live/src/main/res/drawable/bg_voice_chat.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<corners android:radius="9dp"/>
|
||||||
|
<solid android:color="#000000"/>
|
||||||
|
</shape>
|
@ -9,6 +9,13 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:overScrollMode="never" />
|
android:overScrollMode="never" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/voice_press"
|
||||||
|
android:layout_width="54dp"
|
||||||
|
android:layout_height="54dp"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:src="@mipmap/icon_voice_press"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_marginStart="54dp" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -245,7 +245,7 @@
|
|||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_marginStart="10dp"
|
android:layout_marginStart="10dp"
|
||||||
android:layout_marginTop="5dp"
|
android:layout_marginTop="5dp"
|
||||||
|
android:clickable="false"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@ -264,17 +264,24 @@
|
|||||||
android:textSize="12sp" />
|
android:textSize="12sp" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/voice_button"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="4"
|
android:layout_weight="4"
|
||||||
android:gravity="center"
|
android:background="@drawable/bc_sound_recording_right"
|
||||||
android:background="@drawable/bc_sound_recording_right">
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:focusableInTouchMode="true"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
|
||||||
android:layout_width="14dp"
|
android:layout_width="14dp"
|
||||||
android:layout_height="14dp"
|
android:layout_height="14dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
|
android:clickable="false"
|
||||||
|
android:focusable="false"
|
||||||
|
android:focusableInTouchMode="false"
|
||||||
android:src="@mipmap/icon_voice"
|
android:src="@mipmap/icon_voice"
|
||||||
android:visibility="visible" />
|
android:visibility="visible" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
15
live/src/main/res/layout/view_text_hint.xml
Normal file
15
live/src/main/res/layout/view_text_hint.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="309dp"
|
||||||
|
android:layout_height="44dp"
|
||||||
|
android:background="@drawable/bg_voice_chat">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:text="@string/more_than"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</RelativeLayout>
|
55
live/src/main/res/layout/view_voice_dialog.xml
Normal file
55
live/src/main/res/layout/view_voice_dialog.xml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="270dp"
|
||||||
|
android:layout_height="170dp"
|
||||||
|
android:background="@drawable/bg_voice_chat">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon_withdraw"
|
||||||
|
android:layout_width="38dp"
|
||||||
|
android:layout_height="31dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:src="@mipmap/icon_withdraw" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/voice_fluctuations"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="30dp"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@mipmap/img_p" />
|
||||||
|
|
||||||
|
<pl.droidsonroids.gif.GifImageView
|
||||||
|
android:id="@+id/gif_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="30dp"
|
||||||
|
android:background="@mipmap/voice_fluctuations"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/fingers_slide"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:text="@string/fingers_slide"
|
||||||
|
android:textColor="#9A9A9A" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/voice_chat"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="55dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:maxLines="4"
|
||||||
|
android:textColor="#FFFFFF"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</RelativeLayout>
|
BIN
live/src/main/res/mipmap-xxxhdpi/icon_voice_press.png
Normal file
BIN
live/src/main/res/mipmap-xxxhdpi/icon_voice_press.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
BIN
live/src/main/res/mipmap-xxxhdpi/img_p.png
Normal file
BIN
live/src/main/res/mipmap-xxxhdpi/img_p.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
@ -21,4 +21,7 @@
|
|||||||
<string name="live_gift_buy_gold" translatable="false">開通貴族</string>
|
<string name="live_gift_buy_gold" translatable="false">開通貴族</string>
|
||||||
<string name="live_gift_buy_gold_desc" translatable="false">享受專屬特權!</string>
|
<string name="live_gift_buy_gold_desc" translatable="false">享受專屬特權!</string>
|
||||||
<string name="live_gift_buy_gold_desc_to" translatable="false">前往貴族中心</string>
|
<string name="live_gift_buy_gold_desc_to" translatable="false">前往貴族中心</string>
|
||||||
|
<string name="fingers_slide" translatable="false">手指上滑,取消發送</string>
|
||||||
|
<string name="release_cancel_send" translatable="false">松開取消發送</string>
|
||||||
|
<string name="more_than" translatable="false">已超过10秒未识别到录音</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1264,12 +1264,11 @@ public class MainActivity extends AbsActivity implements MainAppBarLayoutListene
|
|||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
public void onLiveFloatEvent(LiveFloatEvent event) {
|
public void onLiveFloatEvent(LiveFloatEvent event) {
|
||||||
|
if (event != null && event.getmLiveBean() != null && !TextUtils.isEmpty(event.getmLiveBean().getPull())){
|
||||||
new Handler().post(() -> LiveFloatView.getInstance()
|
new Handler().post(() -> LiveFloatView.getInstance()
|
||||||
.cacheLiveData(event.getmLiveBean(), event.getmLiveType(), event.getmLiveSDK(), event.getmLiveTypeVal())
|
.cacheLiveData(event.getmLiveBean(), event.getmLiveType(), event.getmLiveSDK(), event.getmLiveTypeVal())
|
||||||
.builderFloat(mContext, event.getmLiveBean().getPull(), LiveAudienceActivity.class));
|
.builderFloat(mContext, event.getmLiveBean().getPull(), LiveAudienceActivity.class));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,30 +6,18 @@ import android.widget.TextView;
|
|||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
import com.yunbao.common.views.weight.IRecognizedResult;
|
|
||||||
import com.yunbao.common.views.weight.Recognizer;
|
|
||||||
import com.yunbao.main.R;
|
import com.yunbao.main.R;
|
||||||
|
|
||||||
|
|
||||||
public class TestActivity extends AppCompatActivity {
|
public class TestActivity extends AppCompatActivity {
|
||||||
private TextView contextLayout;
|
private TextView contextLayout;
|
||||||
private Recognizer recognizer;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_test);
|
setContentView(R.layout.activity_test);
|
||||||
contextLayout = findViewById(R.id.context_layout);
|
contextLayout = findViewById(R.id.context_layout);
|
||||||
recognizer = findViewById(R.id.recognizer);
|
|
||||||
SpannableStringBuilder builder = new SpannableStringBuilder();
|
SpannableStringBuilder builder = new SpannableStringBuilder();
|
||||||
recognizer.setCallBack(new IRecognizedResult() {
|
|
||||||
@Override
|
|
||||||
public void onResult(String data) {
|
|
||||||
builder.append(data);
|
|
||||||
contextLayout.setText(builder);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,11 +12,5 @@
|
|||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1" />
|
android:layout_weight="1" />
|
||||||
|
|
||||||
<com.yunbao.common.views.weight.Recognizer
|
|
||||||
android:id="@+id/recognizer"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="100dp"
|
|
||||||
android:gravity="center" />
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
Loading…
Reference in New Issue
Block a user