增加语音相关业务

This commit is contained in:
qiji4215
2023-05-04 11:02:33 +08:00
parent 62ce5b1566
commit 9379e7a7bb
14 changed files with 313 additions and 190 deletions

View File

@@ -1,13 +1,18 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import androidx.databinding.DataBindingUtil
import androidx.navigation.NavOptions
import androidx.navigation.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.navinfo.omqs.Constant
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.FragmentEvaluationResultBinding
import com.navinfo.omqs.ui.fragment.BaseFragment
@@ -66,18 +71,40 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
else -> true
}
}
binding.evaluationVoice.setOnTouchListener(object : View.OnTouchListener {
@RequiresApi(Build.VERSION_CODES.Q)
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
Log.e("qj",event?.action.toString())
when (event?.action) {
MotionEvent.ACTION_DOWN ->{
voiceOnTouchStart()//Do Something
Log.e("qj","voiceOnTouchStart")
}
MotionEvent.ACTION_UP ->{
voiceOnTouchStop()//Do Something
Log.e("qj","voiceOnTouchStop")
}
}
return v?.onTouchEvent(event) ?: true
}
})
/**
* 读取元数据
*/
if (arguments != null) {
val id = requireArguments().getString("QsId")
//语音路径
val filePath = requireArguments().getString("filePath")
if (id != null) {
viewModel.initData(id)
} else {
viewModel.initNewData()
viewModel.initNewData(filePath!!)
}
} else {
viewModel.initNewData()
viewModel.initNewData("")
}
// //监听大分类数据变化
@@ -240,4 +267,16 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
}
}
}
fun voiceOnTouchStart(){
viewModel!!.startSoundMetter(requireActivity(),binding.evaluationVoice)
}
@RequiresApi(Build.VERSION_CODES.Q)
fun voiceOnTouchStop(){
if(Constant.IS_VIDEO_SPEED){
viewModel!!.stopSoundMeter()
}
}
}

View File

@@ -1,26 +1,47 @@
package com.navinfo.omqs.ui.fragment.evaluationresult
import android.app.Activity
import android.content.Context
import android.graphics.drawable.AnimationDrawable
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.PopupWindow
import androidx.annotation.RequiresApi
import androidx.core.util.rangeTo
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.navigation.findNavController
import com.blankj.utilcode.util.ToastUtils
import com.navinfo.collect.library.data.entity.AttachmentBean
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.collect.library.data.entity.RenderEntity.Companion.LinkTable
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.utils.GeometryTools
import com.navinfo.omqs.Constant
import com.navinfo.omqs.bean.Attachment
import com.navinfo.omqs.R
import com.navinfo.omqs.bean.ChatMsgEntity
import com.navinfo.omqs.db.RealmOperateHelper
import com.navinfo.omqs.db.RoomAppDatabase
import com.navinfo.omqs.util.DateTimeUtil
import com.navinfo.omqs.util.SoundMeter
import com.navinfo.omqs.util.SpeakMode
import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.Realm
import io.realm.RealmList
import io.realm.kotlin.where
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.oscim.core.GeoPoint
import java.io.File
import java.util.*
import javax.inject.Inject
@@ -57,10 +78,18 @@ class EvaluationResultViewModel @Inject constructor(
var listDataChatMsgEntityList = MutableLiveData<MutableList<ChatMsgEntity>>()
var listDataAttachmentList = MutableLiveData<MutableList<Attachment>>()
var oldBean: QsRecordBean? = null
//语音窗体
private var pop: PopupWindow? = null
private var mSpeakMode: SpeakMode? = null
//录音图标
var volume: ImageView? = null
var mSoundMeter: SoundMeter? = null
init {
liveDataQsRecordBean.value = QsRecordBean(id = UUID.randomUUID().toString())
Log.e("jingo", "EvaluationResultViewModel 创建了 ${hashCode()}")
@@ -88,7 +117,7 @@ class EvaluationResultViewModel @Inject constructor(
/**
* 查询数据库,获取问题分类
*/
fun initNewData() {
fun initNewData(filePath: String) {
viewModelScope.launch(Dispatchers.IO) {
getClassTypeList()
getProblemLinkList()
@@ -101,6 +130,8 @@ class EvaluationResultViewModel @Inject constructor(
captureLink(geoPoint.longitude, geoPoint.latitude)
}
}
addChatMsgEntity(filePath)
}
/**
@@ -317,15 +348,119 @@ class EvaluationResultViewModel @Inject constructor(
@RequiresApi(Build.VERSION_CODES.N)
fun getChatMsgEntityList() {
val chatMsgEntityList: MutableList<ChatMsgEntity> = ArrayList()
liveDataQsRecordBean.value!!.attachments.forEach{
liveDataQsRecordBean.value?.attachmentBeanList?.forEach {
//1 录音
if(it.type==1){
if (it.type == 1) {
val chatMsgEntity = ChatMsgEntity()
chatMsgEntity.name = it.filename
chatMsgEntity.name = it.name
chatMsgEntity.voiceUri = Constant.USER_DATA_ATTACHEMNT_PATH
chatMsgEntityList.add(chatMsgEntity)
}
}
listDataChatMsgEntityList.postValue(chatMsgEntityList)
}
fun addChatMsgEntity(filePath: String) {
if(filePath!=null){
var chatMsgEntityList: MutableList<ChatMsgEntity> = ArrayList()
if(listDataChatMsgEntityList.value?.isEmpty() == false){
chatMsgEntityList = listDataChatMsgEntityList.value!!
}
val chatMsgEntity = ChatMsgEntity()
chatMsgEntity.name = filePath.replace(Constant.USER_DATA_ATTACHEMNT_PATH,"").toString()
chatMsgEntity.voiceUri = Constant.USER_DATA_ATTACHEMNT_PATH
chatMsgEntityList.add(chatMsgEntity)
var attachmentList: RealmList<AttachmentBean> = RealmList()
//赋值处理
if(liveDataQsRecordBean.value?.attachmentBeanList?.isEmpty() == false){
attachmentList = liveDataQsRecordBean.value?.attachmentBeanList!!
}
val attachmentBean = AttachmentBean()
attachmentBean.name = chatMsgEntity.name!!
attachmentBean.type = 1
attachmentList.add(attachmentBean)
liveDataQsRecordBean.value?.attachmentBeanList = attachmentList
listDataChatMsgEntityList.postValue(chatMsgEntityList)
}
}
fun startSoundMetter(activity: Activity, v: View) {
if(mSpeakMode==null){
mSpeakMode = SpeakMode(activity)
}
//语音识别动画
if (pop == null) {
pop = PopupWindow()
pop!!.width = ViewGroup.LayoutParams.MATCH_PARENT
pop!!.height = ViewGroup.LayoutParams.WRAP_CONTENT
pop!!.setBackgroundDrawable(BitmapDrawable())
val view = View.inflate(activity as Context, R.layout.cv_card_voice_rcd_hint_window, null)
pop!!.contentView = view
volume = view.findViewById(R.id.volume)
}
pop!!.update()
Constant.IS_VIDEO_SPEED = true
//录音动画
//录音动画
if (pop != null) {
pop!!.showAtLocation(v, Gravity.CENTER, 0, 0)
}
volume!!.setBackgroundResource(R.drawable.pop_voice_img)
val animation = volume!!.background as AnimationDrawable
animation.start()
val name: String = DateTimeUtil.getTimeSSS().toString() + ".m4a"
if (mSoundMeter == null) {
mSoundMeter = SoundMeter()
}
mSoundMeter!!.setmListener(object : SoundMeter.OnSoundMeterListener {
@RequiresApi(Build.VERSION_CODES.Q)
override fun onSuccess(filePath: String?) {
if (!TextUtils.isEmpty(filePath) && File(filePath).exists()) {
if (File(filePath) == null || File(filePath).length() < 1600) {
ToastUtils.showLong("语音时间太短,无效!")
mSpeakMode!!.speakText("语音时间太短,无效")
stopSoundMeter()
return
}
}
mSpeakMode!!.speakText("结束录音")
addChatMsgEntity(filePath!!)
}
@RequiresApi(api = Build.VERSION_CODES.Q)
override fun onfaild(message: String?) {
ToastUtils.showLong("录制失败!")
mSpeakMode!!.speakText("录制失败")
stopSoundMeter()
}
})
mSoundMeter!!.start(Constant.USER_DATA_ATTACHEMNT_PATH + name)
ToastUtils.showLong("开始录音")
mSpeakMode!!.speakText("开始录音")
}
//停止语音录制
@RequiresApi(api = Build.VERSION_CODES.Q)
fun stopSoundMeter() {
//先重置标识,防止按钮抬起时触发语音结束
Constant.IS_VIDEO_SPEED = false
if (mSoundMeter != null && mSoundMeter!!.isStartSound()) {
mSoundMeter!!.stop()
}
if (pop != null && pop!!.isShowing) pop!!.dismiss()
}
}

View File

@@ -64,17 +64,17 @@ class SoundtListAdapter(
val entity = data[position]
//tag 方便onclick里拿到数据
holder.tag = entity.name.toString()
holder.viewBinding.tvTime.isSelected = entity.isDelete
holder.viewBinding.tvTime.isSelected = entity.isDelete
holder.viewBinding.rlSoundContent.isSelected = entity.isDelete
holder.viewBinding.ivSoundAnim.setBackgroundResource(R.drawable.icon_sound_03)
if (itemClick != null) {
/* if (itemClick != null) {
holder.viewBinding.rlSoundContent.setOnClickListener {
itemClick!!.onItemClick(it.findViewById<View>(R.id.rl_sound_content), position)
}
}
}*/
//mixWidth
if (!TextUtils.isEmpty(entity.name)) {
if (entity.name.indexOf(".pcm") > 0) {
/* if (entity.name.indexOf(".pcm") > 0) {
val file: File = File(entity.voiceUri + entity.name)
if (file != null) {
val time = (file.length() / 16000).toInt()
@@ -89,15 +89,15 @@ class SoundtListAdapter(
} else {
try {
md = MediaPlayer()
md.reset()
md.setDataSource(entity.getVoiceUri() + entity.getName())
md.prepare()
md!!.reset()
md!!.setDataSource(entity.voiceUri+entity.name)
md!!.prepare()
} catch (e: Exception) {
// TODO Auto-generated catch block
e.printStackTrace()
}
var time =
if (entity.getVoiceTimeLong() == null) md!!.duration.toString() + "" else entity.getVoiceTimeLong()
if (entity.voiceTimeLong == null) md!!.duration.toString() + "" else entity.voiceTimeLong
.toString() + ""
if (!TextUtils.isEmpty(time)) {
val i = md!!.duration / 1000
@@ -107,16 +107,12 @@ class SoundtListAdapter(
layoutParams.width = 115 + i * 10
layoutParams.width =
if (layoutParams.width > layoutParams.width) maxWidth else layoutParams.width
holder.viewBinding.rlSoundContent.setLayoutParams(layoutParams)
holder.viewBinding.rlSoundContent.layoutParams = layoutParams
}
holder.viewBinding.tvTime.text = time
md!!.release()
}
}
override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_sound_list
}*/
}
}
/**
@@ -143,18 +139,18 @@ class SoundtListAdapter(
* @param name 录音名称
* @Description
*/
private fun playMusic(name: String, imageV: ImageView) {
fun playMusic(name: String, imageV: ImageView) {
imageV.setBackgroundResource(R.drawable.sound_anim)
animaV = imageV.background as AnimationDrawable
animaV!!.start()
if (name.indexOf(".pcm") > 0) {
/* if (name.index(".pcm") > 0) {
audioTrackPlay(name, imageV)
} else {
mediaPlayer(name, imageV)
}
}*/
}
private fun mediaPlayer(name: String, imageV: ImageView) {
fun mediaPlayer(name: String, imageV: ImageView) {
try {
if (mMediaPlayer.isPlaying) {
mMediaPlayer.stop()
@@ -173,7 +169,7 @@ class SoundtListAdapter(
}
}
private fun audioTrackPlay(name: String, imageV: ImageView) {
fun audioTrackPlay(name: String, imageV: ImageView) {
var dis: DataInputStream? = null
try {
//从音频文件中读取声音
@@ -236,6 +232,10 @@ class SoundtListAdapter(
interface OnItemClickListner {
fun onItemClick(view: View?, postion: Int)
}
override fun getItemViewRes(position: Int): Int {
return R.layout.adapter_sound_list
}
}