[Modify]声音签名功能完善
This commit is contained in:
BIN
app/src/main/assets/svga/user_sound_play.svga
Normal file
BIN
app/src/main/assets/svga/user_sound_play.svga
Normal file
Binary file not shown.
@@ -23,6 +23,7 @@ import com.yizhuan.erban.ui.webview.CommonWebViewActivity;
|
||||
import com.yizhuan.xchat_android_core.UriProvider;
|
||||
import com.yizhuan.xchat_android_core.statistic.StatisticManager;
|
||||
import com.yizhuan.xchat_android_core.statistic.protocol.StatisticsProtocol;
|
||||
import com.yizhuan.xchat_android_core.user.bean.UserInfo;
|
||||
import com.yizhuan.xchat_android_library.utils.ResUtil;
|
||||
|
||||
|
||||
@@ -136,9 +137,10 @@ public class UIHelper {
|
||||
mActivity.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
public static void showSoundAct(Activity mActivity, int requestCode, String label) {
|
||||
public static void showSoundAct(Activity mActivity, int requestCode, String label, UserInfo.SoundBean audioCard) {
|
||||
StatisticManager.Instance().onEvent(StatisticsProtocol.EVENT_MY_SOUND, ResUtil.getString(R.string.yizhuan_erban_uihelper_03) + label);
|
||||
Intent intent = new Intent(mActivity, SoundSignatureActivity.class);
|
||||
intent.putExtra(SoundSignatureActivity.AUDIO_BEAN, audioCard);
|
||||
mActivity.startActivityForResult(intent, requestCode);
|
||||
}
|
||||
|
||||
|
@@ -19,7 +19,6 @@ import com.opensource.svgaplayer.SVGAParser
|
||||
import com.opensource.svgaplayer.SVGAVideoEntity
|
||||
import com.yizhuan.erban.R
|
||||
import com.yizhuan.erban.audio.helper.AudioPlayerHelper
|
||||
import com.yizhuan.erban.audio.presenter.RecordingVoicePresenter
|
||||
import com.yizhuan.erban.audio.viewmodel.SoundViewModel
|
||||
import com.yizhuan.erban.base.BaseViewBindingActivity
|
||||
import com.yizhuan.erban.common.widget.dialog.DialogManager.OkCancelDialogListener
|
||||
@@ -29,6 +28,7 @@ import com.yizhuan.xchat_android_core.file.FileModel
|
||||
import com.yizhuan.xchat_android_core.room.model.AvRoomModel
|
||||
import com.yizhuan.xchat_android_core.statistic.StatisticManager
|
||||
import com.yizhuan.xchat_android_core.statistic.protocol.StatisticsProtocol
|
||||
import com.yizhuan.xchat_android_core.user.bean.UserInfo.SoundBean
|
||||
import com.yizhuan.xchat_android_library.utils.ResUtil
|
||||
import com.yizhuan.xchat_android_library.utils.SingleToastUtil
|
||||
import io.reactivex.SingleObserver
|
||||
@@ -43,6 +43,7 @@ class SoundSignatureActivity : BaseViewBindingActivity<ActivitySoundSignatureBin
|
||||
View.OnClickListener {
|
||||
|
||||
companion object {
|
||||
const val AUDIO_BEAN = "audio_bean"
|
||||
const val AUDIO_FILE = "AUDIO_FILE"
|
||||
const val AUDIO_DURA = "AUDIO_DURA"
|
||||
const val MIN_RECORD_VOICE_DURATION = 1 // 最少1秒
|
||||
@@ -67,7 +68,39 @@ class SoundSignatureActivity : BaseViewBindingActivity<ActivitySoundSignatureBin
|
||||
playDrawable = ContextCompat.getDrawable(context, R.drawable.ic_pause_record)
|
||||
pauseDrawable = ContextCompat.getDrawable(context, R.drawable.ic_resume_record)
|
||||
|
||||
refreshButtonView(RecordingVoicePresenter.STATE_RECORD_NORMAL)
|
||||
val audioCard = intent.getSerializableExtra(AUDIO_BEAN) as SoundBean
|
||||
when (audioCard.status ?: 0) {
|
||||
0 -> {
|
||||
refreshButtonView(SoundViewModel.STATE_RECORD_NORMAL)
|
||||
}
|
||||
1 -> {
|
||||
val showStr = String.format(
|
||||
Locale.getDefault(),
|
||||
"%ds / %ds",
|
||||
0,
|
||||
MAX_RECORD_VOICE_DURATION
|
||||
)
|
||||
binding.tvSoundTime.text = showStr
|
||||
soundViewModel.audioState = SoundViewModel.STATE_RECORD_SUCCESS
|
||||
soundViewModel.audioUrl = audioCard.audioUrl ?: ""
|
||||
refreshButtonView(SoundViewModel.STATE_RECORD_SAVE_SUCCESS)
|
||||
}
|
||||
2 -> {
|
||||
val showStr = String.format(
|
||||
Locale.getDefault(),
|
||||
"%ds / %ds",
|
||||
0,
|
||||
MAX_RECORD_VOICE_DURATION
|
||||
)
|
||||
binding.tvSoundTime.text = showStr
|
||||
soundViewModel.audioState = SoundViewModel.STATE_RECORD_SUCCESS
|
||||
soundViewModel.audioUrl = audioCard.audioUrl ?: ""
|
||||
refreshButtonView(SoundViewModel.STATE_RECORD_AUDIT_SUCCESS)
|
||||
}
|
||||
else -> {
|
||||
refreshButtonView(SoundViewModel.STATE_RECORD_NORMAL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setListener() {
|
||||
@@ -136,7 +169,7 @@ class SoundSignatureActivity : BaseViewBindingActivity<ActivitySoundSignatureBin
|
||||
}
|
||||
|
||||
soundViewModel.deleteRecordLiveData.observe(this) {
|
||||
refreshButtonView(SoundViewModel.STATE_RECORD_NORMAL)
|
||||
soundViewModel.showNormalState()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -172,9 +205,10 @@ class SoundSignatureActivity : BaseViewBindingActivity<ActivitySoundSignatureBin
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}else {
|
||||
soundViewModel.clickCenterIcon()
|
||||
}
|
||||
}
|
||||
R.id.ivSaveRecord -> {//保存按钮
|
||||
finishRecord()
|
||||
}
|
||||
@@ -271,6 +305,15 @@ class SoundSignatureActivity : BaseViewBindingActivity<ActivitySoundSignatureBin
|
||||
binding.tvUnderReview.visibility = View.VISIBLE
|
||||
binding.svgRecorder.stopAnimation()
|
||||
}
|
||||
SoundViewModel.STATE_RECORD_AUDIT_SUCCESS -> {
|
||||
binding.ivSoundStatus.post { binding.ivSoundStatus.setImageResource(R.drawable.ic_pause_record) }
|
||||
binding.tvRecordTip.text = getString(R.string.click_to_listen)
|
||||
binding.groupRsRecord.visibility = View.VISIBLE
|
||||
binding.groupSaveSound.visibility = View.INVISIBLE
|
||||
binding.groupDeleteSound.visibility = View.VISIBLE
|
||||
binding.tvUnderReview.visibility = View.GONE
|
||||
binding.svgRecorder.stopAnimation()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -34,9 +34,10 @@ class SoundViewModel : BaseViewModel() {
|
||||
const val STATE_RECORD_RECORDING = 1//录音中
|
||||
const val STATE_RECORD_SUCCESS = 2//录音完成
|
||||
const val STATE_RECORD_SAVE_SUCCESS = 3//保存成功
|
||||
const val STATE_RECORD_AUDIT_SUCCESS = 4//审核成功
|
||||
}
|
||||
|
||||
private var audioState = STATE_RECORD_NORMAL
|
||||
var audioState = STATE_RECORD_NORMAL
|
||||
|
||||
private var audioManager: AudioPlayAndRecordManager? = null
|
||||
private var audioRecorder: AudioRecorder? = null
|
||||
@@ -170,6 +171,9 @@ class SoundViewModel : BaseViewModel() {
|
||||
*/
|
||||
fun showNormalState() {
|
||||
audioState = STATE_RECORD_NORMAL
|
||||
audioUrl = null
|
||||
audioDur = 0
|
||||
audioFile = null
|
||||
_refreshLiveData.value = audioState
|
||||
if (null != audioRecorder) {
|
||||
audioRecorder?.destroyAudioRecorder()
|
||||
@@ -276,6 +280,30 @@ class SoundViewModel : BaseViewModel() {
|
||||
}
|
||||
})
|
||||
_refreshPlayStatusLiveData.value = true// 点击试听按钮此时并没有正在播放声音,则播放声音并显示正在播放状态(暂停按钮)
|
||||
}else if(null != audioUrl && audioUrl?.contains("http") == true){
|
||||
MLog.debug(TAG, "play audioUrl: $audioUrl")
|
||||
AudioPlayerHelper.get().playInThread(audioUrl, object : OnPlayListener {
|
||||
override fun onError(error: String) {
|
||||
_refreshPlayStatusLiveData.value = false // 出错:停止状态(播放按钮)
|
||||
}
|
||||
|
||||
override fun onPrepared() {
|
||||
_refreshPlayStatusLiveData.value = true// 准备完毕要开始播放:播放状态(暂停按钮)
|
||||
}
|
||||
|
||||
override fun onPlaying(currDuration: Long) {
|
||||
MLog.debug(
|
||||
TAG,
|
||||
"duration = $currDuration"
|
||||
)
|
||||
_showCountDownLiveData.value = (currDuration / 1000).toInt()
|
||||
}
|
||||
|
||||
override fun onCompletion() {
|
||||
_refreshPlayStatusLiveData.value = false// 播放完成:停止状态(播放按钮)
|
||||
}
|
||||
})
|
||||
_refreshPlayStatusLiveData.value = true// 点击试听按钮此时并没有正在播放声音,则播放声音并显示正在播放状态(暂停按钮)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,15 +1,15 @@
|
||||
package com.yizhuan.erban.ui.user;
|
||||
|
||||
import static com.yizhuan.erban.ui.user.UserInfoActivity.IdentityState.OWN;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.Chronometer;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
@@ -31,6 +31,7 @@ import com.opensource.svgaplayer.SVGAParser;
|
||||
import com.opensource.svgaplayer.SVGAVideoEntity;
|
||||
import com.yizhuan.erban.R;
|
||||
import com.yizhuan.erban.UIHelper;
|
||||
import com.yizhuan.erban.audio.SoundSignatureActivity;
|
||||
import com.yizhuan.erban.audio.helper.AudioPlayerHelper;
|
||||
import com.yizhuan.erban.audio.helper.OnPlayListener;
|
||||
import com.yizhuan.erban.avroom.ButtonItemFactory;
|
||||
@@ -75,13 +76,11 @@ import com.yizhuan.xchat_android_core.user.UserInfoUiMgr;
|
||||
import com.yizhuan.xchat_android_core.user.UserModel;
|
||||
import com.yizhuan.xchat_android_core.user.bean.UserDetailInfo;
|
||||
import com.yizhuan.xchat_android_core.user.bean.UserInfo;
|
||||
import com.yizhuan.xchat_android_core.user.bean.UserInfoSkillEntity;
|
||||
import com.yizhuan.xchat_android_core.user.bean.UserPhoto;
|
||||
import com.yizhuan.xchat_android_core.user.event.LoginUserInfoUpdateEvent;
|
||||
import com.yizhuan.xchat_android_core.utils.LogUtils;
|
||||
import com.yizhuan.xchat_android_core.utils.Logger;
|
||||
import com.yizhuan.xchat_android_core.utils.StarUtils;
|
||||
import com.yizhuan.xchat_android_core.utils.net.BeanObserver;
|
||||
import com.yizhuan.xchat_android_library.annatation.ActLayoutRes;
|
||||
import com.yizhuan.xchat_android_library.utils.ListUtils;
|
||||
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
|
||||
@@ -94,8 +93,9 @@ import org.greenrobot.eventbus.ThreadMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import lombok.val;
|
||||
import static com.yizhuan.erban.ui.user.UserInfoActivity.IdentityState.OWN;
|
||||
|
||||
/**
|
||||
* create by lvzebiao on 2018/8/31
|
||||
@@ -340,6 +340,8 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
|
||||
|
||||
VipHelper.loadVipIcon(mBinding.ivVipIcon, userInfo.getUserVipInfoVO());
|
||||
|
||||
initVoiceShow(userInfo.getAudioCard());
|
||||
|
||||
mBinding.tvErbanId.setOnLongClickListener(view -> {
|
||||
try {
|
||||
ClipboardManager cm = (ClipboardManager) UserInfoActivity.this.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
@@ -607,7 +609,22 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode == RESULT_OK) {
|
||||
|
||||
// 获取数据并刷新显示
|
||||
String audioFileUrl = data.getStringExtra(SoundSignatureActivity.AUDIO_FILE);
|
||||
int audioDuration = data.getIntExtra(SoundSignatureActivity.AUDIO_DURA, 0);
|
||||
if (!TextUtils.isEmpty(audioFileUrl) && audioDuration != 0) {
|
||||
mBinding.llAudio.setVisibility(View.VISIBLE);
|
||||
String url = "";
|
||||
if (audioFileUrl.contains("http")) {
|
||||
url = audioFileUrl;
|
||||
}
|
||||
if (TextUtils.isEmpty(url)) return;
|
||||
if (!audioPlaying) {
|
||||
playAudio(url, audioDuration);
|
||||
} else {
|
||||
stopAudio();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,36 +641,35 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
|
||||
}
|
||||
}
|
||||
|
||||
public void initVoiceShow(UserInfoSkillEntity skillEntity) {
|
||||
if (skillEntity != null) {
|
||||
public void initVoiceShow(UserInfo.SoundBean audioCard) {
|
||||
if (audioCard != null && !TextUtils.isEmpty(audioCard.getAudioUrl())) {
|
||||
mBinding.llAudio.setVisibility(View.VISIBLE);
|
||||
mBinding.livUser.stop();
|
||||
mBinding.llAudio.setOnClickListener(v -> toggleAudio(skillEntity.getPropVals()));
|
||||
mBinding.tvAudio.setText(String.valueOf(audioCard.getSecond()));
|
||||
mBinding.livUser.stopAnimation();
|
||||
mBinding.llAudio.setOnClickListener(v -> toggleAudio(audioCard));
|
||||
} else {
|
||||
mBinding.llAudio.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void toggleAudio(List<String> list) {
|
||||
if (ListUtils.isListEmpty(list)) return;
|
||||
private void toggleAudio(UserInfo.SoundBean audioCard) {
|
||||
String url = "";
|
||||
for (String s : list) {
|
||||
if (s.contains("http")) {
|
||||
url = s;
|
||||
}
|
||||
if (audioCard.getAudioUrl().contains("http")) {
|
||||
url = audioCard.getAudioUrl();
|
||||
}
|
||||
if (TextUtils.isEmpty(url)) return;
|
||||
if (!audioPlaying) {
|
||||
playAudio(url);
|
||||
playAudio(url, audioCard.getSecond());
|
||||
} else {
|
||||
stopAudio();
|
||||
}
|
||||
}
|
||||
|
||||
private void playAudio(String url) {
|
||||
private void playAudio(String url, int second) {
|
||||
if (audioPlaying) return;
|
||||
audioPlaying = true;
|
||||
mBinding.livUser.start();
|
||||
playSvgaBg(mBinding.livUser, "svga/user_sound_play.svga");
|
||||
startChronometer(second);
|
||||
mBinding.ivAudioControl.setImageResource(R.drawable.ic_skill_play);
|
||||
AudioPlayerHelper.get().playInThread(url, new OnPlayListener() {
|
||||
|
||||
@@ -681,10 +697,34 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
|
||||
});
|
||||
}
|
||||
|
||||
private void startChronometer(int time) {
|
||||
mBinding.tvAudio.setOnChronometerTickListener(chronometer -> {
|
||||
long elapsedMillis =
|
||||
SystemClock.elapsedRealtime() - chronometer.getBase();
|
||||
int second = (int) (elapsedMillis / 1000);
|
||||
String showStr = String.format(
|
||||
Locale.getDefault(),
|
||||
"%d",
|
||||
second
|
||||
);
|
||||
if (second >= time) {
|
||||
stopChronometer();// 录制时长超过上限时,停止录制
|
||||
}
|
||||
chronometer.setText(showStr);
|
||||
});
|
||||
mBinding.tvAudio.setBase(SystemClock.elapsedRealtime());
|
||||
mBinding.tvAudio.start();
|
||||
}
|
||||
|
||||
private void stopChronometer(){
|
||||
mBinding.tvAudio.stop();
|
||||
}
|
||||
|
||||
private void stopAudio() {
|
||||
stopChronometer();
|
||||
if (!audioPlaying) return;
|
||||
audioPlaying = false;
|
||||
mBinding.livUser.stop();
|
||||
mBinding.livUser.stopAnimation();
|
||||
mBinding.ivAudioControl.setImageResource(R.drawable.ic_skill_pause);
|
||||
AudioPlayerHelper.get().endPlay();
|
||||
}
|
||||
@@ -701,7 +741,6 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
|
||||
StatusBarUtil.StatusBarLightMode(this);
|
||||
}
|
||||
|
||||
|
||||
public interface IdentityState {
|
||||
int NON = 0; // 无法识别
|
||||
int OWN = 1; // 自己
|
||||
|
@@ -264,7 +264,8 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
|
||||
UIHelper.showSoundAct(
|
||||
this@UserInfoModifyActivity,
|
||||
Method.AUDIO,
|
||||
ResUtil.getString(R.string.ui_user_userinfomodifyactivity_07)
|
||||
ResUtil.getString(R.string.ui_user_userinfomodifyactivity_07),
|
||||
mUserInfo?.audioCard
|
||||
)
|
||||
isAvatar = false
|
||||
}, R.string.ask_again,
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_pause.webp
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_skill_pause.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 966 B |
Binary file not shown.
Before Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/drawable-xhdpi/ic_skill_play.webp
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_skill_play.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 822 B |
@@ -329,10 +329,10 @@
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_audio"
|
||||
android:layout_width="63dp"
|
||||
android:layout_height="@dimen/dp_25"
|
||||
android:layout_gravity="end|center_vertical"
|
||||
android:background="@drawable/bg_userinfo_skill_audio"
|
||||
android:layout_width="98dp"
|
||||
android:layout_height="@dimen/dp_28"
|
||||
android:layout_marginEnd="@dimen/dp_15"
|
||||
android:background="@drawable/bg_common_confirm_normal"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
@@ -340,21 +340,35 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv_audio_control"
|
||||
android:layout_width="@dimen/dp_15"
|
||||
android:layout_height="@dimen/dp_15"
|
||||
android:layout_marginStart="@dimen/dp_8"
|
||||
android:layout_width="@dimen/dp_18"
|
||||
android:layout_height="18dp"
|
||||
android:layout_marginStart="@dimen/dp_4"
|
||||
android:src="@drawable/ic_skill_pause" />
|
||||
|
||||
<com.yizhuan.erban.ui.widget.LivingIconView
|
||||
<com.opensource.svgaplayer.SVGAImageView
|
||||
android:id="@+id/liv_user"
|
||||
android:layout_width="60dp"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@mipmap/user_sound_play"
|
||||
android:layout_marginStart="@dimen/dp_4"
|
||||
app:autoPlay="true"/>
|
||||
|
||||
<Chronometer
|
||||
android:id="@+id/tvAudio"
|
||||
android:layout_marginStart="@dimen/dp_6"
|
||||
android:background="@color/transparent"
|
||||
android:scaleType="fitXY"
|
||||
app:cus_dp_height="20dp"
|
||||
app:cus_dp_width="60dp"
|
||||
app:cus_drawable="@drawable/skill_audio_animation" />
|
||||
android:format="60"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_14"
|
||||
tools:text="60" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:text="''"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="@dimen/sp_14"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
BIN
app/src/main/res/mipmap-xhdpi/user_sound_play.webp
Normal file
BIN
app/src/main/res/mipmap-xhdpi/user_sound_play.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 304 B |
@@ -821,7 +821,7 @@ public class UserInfo implements Serializable {
|
||||
* 声音签名
|
||||
*/
|
||||
@Data
|
||||
public static class SoundBean {
|
||||
public static class SoundBean implements Serializable{
|
||||
private long uid;
|
||||
private String audioUrl;//音频七牛云url
|
||||
private Integer second;//时间
|
||||
|
Reference in New Issue
Block a user