• Kotlin高仿微信-第11篇-单聊-语音


     Kotlin高仿微信-项目实践58篇详细讲解了各个功能点,包括:注册、登录、主页、单聊(文本、表情、语音、图片、小视频、视频通话、语音通话、红包、转账)、群聊、个人信息、朋友圈、支付服务、扫一扫、搜索好友、添加好友、开通VIP等众多功能。

    Kotlin高仿微信-项目实践58篇,点击查看详情

    效果图:

    详细的聊天功能请查看Kotlin高仿微信-第8篇-单聊,这里是提示文本功能的部分实现。

    实现代码:

    我的语言布局:

    
    
        
        
    
    

    好友的语音布局:

    
    
        
    
        
    
    

    /**
     * Author : wangning
     * Email : maoning20080809@163.com
     * Date : 2022/5/4 17:36
     * Description : 聊天语言按钮
     */
    class ChatRecordButton : AppCompatButton {
    
        constructor(context: Context) : super(context)
        constructor(context: Context, attributeSet: AttributeSet) :super(context, attributeSet)
        constructor(context: Context, attributeSet: AttributeSet, defStyle : Int) : super(context, attributeSet, defStyle)
        private var mFile : String = ""
        private var mFileMp3 : String = ""
        private var finishedListener: OnFinishedRecordListener? = null
    
        /**
         * 最短录音时间
         */
        private val MIN_INTERVAL_TIME = 1000
    
        /**
         * 最长录音时间
         */
        private val MAX_INTERVAL_TIME = 1000 * 60
    
    
        private var view: View? = null
    
        private var mStateTV: TextView? = null
    
        private var mStateIV: ImageView? = null
    
        companion object var mRecorder: MediaRecorder? = null
        private val mThread: ObtainDecibelThread? = null
        private var volumeHandler: Handler? = null
    
        private var y1 : Float = 0f
        private var anim: AnimationDrawable? = null
    
    
        fun setOnFinishedRecordListener(listener: OnFinishedRecordListener?) {
            finishedListener = listener
        }
    
        private var startTime: Long = 0
        private var recordDialog: Dialog? = null
        private val res = intArrayOf(
            R.drawable.wc_chat_volume_0,
            R.drawable.wc_chat_volume_1,
            R.drawable.wc_chat_volume_2,
            R.drawable.wc_chat_volume_3,
            R.drawable.wc_chat_volume_4,
            R.drawable.wc_chat_volume_5,
            R.drawable.wc_chat_volume_6,
            R.drawable.wc_chat_volume_7,
            R.drawable.wc_chat_volume_8
        )
    
        //private var audioRecordTool: AudioRecordTool? = null
    
        init {
            volumeHandler = object : Handler() {
                override fun handleMessage(msg: Message) {
                    if (msg.what == -100) {
                        stopRecording()
                        recordDialog!!.dismiss()
                    } else if (msg.what != -1) {
                        mStateIV!!.setImageResource(res.get(msg.what))
                    }
                }
            }
        }
    
        override fun onTouchEvent(event: MotionEvent?): Boolean {
            val action = event!!.action
            y1 = event.y
            if (mStateTV != null && mStateIV != null && y1 < 0) {
                mStateTV?.text = "松开手指,取消发送"
                mStateIV?.setImageDrawable(resources.getDrawable(R.drawable.wc_chat_volume_cancel))
            } else if (mStateTV != null) {
                mStateTV?.text = "手指上滑,取消发送"
            }
            when (action) {
                MotionEvent.ACTION_DOWN -> {
                    text = "松开发送"
                    initDialogAndStartRecord()
                }
                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                    this.text = "按住录音"
                    if (y1 >= 0 && System.currentTimeMillis() - startTime <= MAX_INTERVAL_TIME) {
                        TagUtils.d("结束录音:")
                        finishRecord()
                    } else if (y1 < 0) {  //当手指向上滑,会cancel
                        cancelRecord()
                    }
                }
            }
    
            return true
        }
    
    
        /**
         * 初始化录音对话框 并 开始录音
         */
        private fun initDialogAndStartRecord() {
            startTime = System.currentTimeMillis()
            recordDialog = Dialog(context, R.style.like_toast_dialog_style)
            // view = new ImageView(getContext());
            view = inflate(context, R.layout.wc_chat_dialog_record, null)
            mStateIV = view?.findViewById(R.id.rc_audio_state_image)
            mStateTV = view?.findViewById(R.id.rc_audio_state_text)
            mStateIV?.setImageDrawable(resources.getDrawable(R.drawable.anim_mic))
            anim = mStateIV?.getDrawable() as AnimationDrawable
            anim?.start()
            mStateIV?.setVisibility(VISIBLE)
            //mStateIV.setImageResource(R.drawable.ic_volume_1);
            mStateTV?.setVisibility(VISIBLE)
            mStateTV?.setText("手指上滑,取消发送")
            recordDialog?.setContentView(view!!, LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT)
            )
            recordDialog?.setOnDismissListener(onDismiss)
            val lp = recordDialog?.getWindow()!!.attributes
            lp.gravity = Gravity.CENTER
            startRecording()
            recordDialog?.show()
        }
    
        /**
         * 放开手指,结束录音处理
         */
        private fun finishRecord() {
            val intervalTime: Long = System.currentTimeMillis() - startTime
            if (intervalTime < MIN_INTERVAL_TIME) {
                TagUtils.d("录音时间太短")
                volumeHandler!!.sendEmptyMessageDelayed(-100, 500)
                //view.setBackgroundResource(R.drawable.ic_voice_cancel);
                mStateIV!!.setImageDrawable(resources.getDrawable(R.drawable.wc_chat_volume_wraning))
                mStateTV!!.text = "录音时间太短"
                anim!!.stop()
                val file = File(mFile!!)
                file.delete()
                return
            } else {
                stopRecording()
                recordDialog!!.dismiss()
            }
            TagUtils.d("录音完成的路径:$mFile")
            val mediaPlayer = MediaPlayer()
            try {
                mediaPlayer.setDataSource(mFile)
                mediaPlayer.prepare()
                mediaPlayer.duration
                TagUtils.d("获取到的时长:" + mediaPlayer.duration / 1000)
            } catch (e: Exception) {
            }
            //if (finishedListener != null) finishedListener!!.onFinishedRecord( mFile, mediaPlayer.duration / 1000)
            //删除原文件
            TagUtils.d("amr录音保存路径:${mFile}")
            File(mFile).delete()
            /*TagUtils.d("pcm录音保存路径:${audioRecordTool?.pcmFileName}")
            audioRecordTool?.deletePcmFile()
            //最终使用的是wav录音文件,音质非常的好
            mFile = audioRecordTool?.wavFileName!!
            TagUtils.d("wav录音保存路径:${audioRecordTool?.wavFileName!!}")*/
            TagUtils.d("mp3录音保存路径:${mFileMp3}")
            if (finishedListener != null) finishedListener!!.onFinishedRecord( mFileMp3, mediaPlayer.duration / 1000)
        }
    
        /**
         * 取消录音对话框和停止录音
         */
        fun cancelRecord() {
            stopRecording()
            recordDialog!!.dismiss()
            val file = File(mFile)
            file.delete()
    
            LameMp3Manager.instance.cancelRecorder()
            var mp3File = File(mFileMp3)
            mp3File.delete()
    
        }
    
    
        /**
         * 执行录音操作
         */
        private fun startRecording() {
    
            if(ContextCompat.checkSelfPermission(WcApp.getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED){
                mFile = FileUtils.getBaseFile("voice_" + System.currentTimeMillis() + ".amr").absolutePath
                mFileMp3 = FileUtils.getBaseFile("voice_" + System.currentTimeMillis() + ".mp3").absolutePath
            } else {
                ToastUtils.makeText(R.string.wc_permission_tip_record)
                return
            }
            //使用MP3文件代替wav,因为mp3语音清晰,占用空间小
            LameMp3Manager.instance.startRecorder(mFileMp3)
            /*audioRecordTool = AudioRecordTool()
            //初始化
            audioRecordTool?.createAudioRecord()
            audioRecordTool?.start()*/
    
            if (mRecorder != null) {
                mRecorder?.reset()
            } else {
                mRecorder = MediaRecorder()
            }
            mRecorder?.setAudioSource(MediaRecorder.AudioSource.MIC)
            mRecorder?.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB)
            mRecorder?.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
            mRecorder?.setOutputFile(mFile)
            try {
                mRecorder?.prepare()
                mRecorder?.start()
            } catch (e: Exception) {
                TagUtils.d("preparestart异常,重新开始录音:$e")
                e.printStackTrace()
                mRecorder?.release()
                mRecorder = null
                startRecording()
            }
        }
    
    
        private fun stopRecording() {
            //audioRecordTool?.stop()
            LameMp3Manager.instance.stopRecorder()
    
            if (mThread != null) {
                mThread.exit()
                //mThread = null
            }
            if (mRecorder != null) {
                try {
                    mRecorder?.stop() //停止时没有prepare,就会报stop failed
                    mRecorder?.reset()
                    mRecorder?.release()
                    mRecorder = null
                } catch (pE: RuntimeException) {
                    pE.printStackTrace()
                } finally {
                    if (recordDialog!!.isShowing) {
                        recordDialog!!.dismiss()
                    }
                }
            }
        }
    
        private class ObtainDecibelThread(val obj: ChatRecordButton) : Thread() {
            @Volatile
            private var running = true
    
    
            fun exit() {
                running = false
            }
    
            override fun run() {
                TagUtils.d("检测到的分贝001:")
                while (running) {
    
                    if (obj.mRecorder == null || !running) {
                        break
                    }
                    // int x = recorder.getMaxAmplitude(); //振幅
                    val db: Int = obj.mRecorder!!.getMaxAmplitude() / 600
                    TagUtils.d("检测到的分贝002:$")
                    if (db != 0 && obj.y1 >= 0) {
                        val f = (db / 5)
                        if (f == 0) obj.volumeHandler?.sendEmptyMessage(0) else if (f == 1) obj.volumeHandler?.sendEmptyMessage(
                            1
                        ) else if (f == 2) obj.volumeHandler?.sendEmptyMessage(2) else if (f == 3) obj.volumeHandler?.sendEmptyMessage(
                            3
                        ) else if (f == 4) obj.volumeHandler?.sendEmptyMessage(4) else if (f == 5) obj.volumeHandler?.sendEmptyMessage(
                            5
                        ) else if (f == 6) obj.volumeHandler?.sendEmptyMessage(6) else obj.volumeHandler?.sendEmptyMessage(
                            7
                        )
                    }
                    obj.volumeHandler?.sendEmptyMessage(-1)
                    if (System.currentTimeMillis() - obj.startTime > 20000) {
                        obj.finishRecord()
                    }
                    try {
                        sleep(200)
                    } catch (e: InterruptedException) {
                        e.printStackTrace()
                    }
                }
            }
        }
    
        private val onDismiss = DialogInterface.OnDismissListener { stopRecording() }
    
        interface OnFinishedRecordListener{
            fun onFinishedRecord(audioPath : String, time : Int)
        }
    
    }

    //录音完成回调
    chat_record_btn.setOnFinishedRecordListener(object : ChatRecordButton.OnFinishedRecordListener{
        override fun onFinishedRecord(audioPath: String, time: Int) {
            chat_content.isFocusable = false
            SoftInputUtils.hideSoftInput(chat_record_btn)
            AddFileListener.sendFile(ChatBean.CONTENT_TYPE_VOICE, audioPath, toUserId, time)
        }
    })

    /**
     * 发送图片、小视频、语音
     * @param fileType Int
     * @param picPath String
     * @param toUserID String
     */
    fun sendFile(fileType: Int, filePath : String, toUserId : String, time: Int) {
        CoroutineScope(Dispatchers.IO).launch {
            //语音、小视频多少秒
            val toId: String = BaseUtils.getChatId(toUserId) + "/Smack"
            var resultFilePath = ""
    
            if(TextUtils.isEmpty(filePath)){
                return@launch
            }
    
            if(!File(filePath).exists()){
                return@launch
            }
    
            var second = time
    
            if(fileType == ChatBean.CONTENT_TYPE_VOICE){
                second = time
            } else if(fileType == ChatBean.CONTENT_TYPE_VIDEO){
                second = CommonUtils.Media.getMediaTime(filePath, fileType)
            }
    
            //先刷新页面,再慢慢上传文件
            var chatBean = processSendChatBean(toUserId, fileType, filePath, second)
    
            if(fileType == ChatBean.CONTENT_TYPE_IMG){
                //图片
                //压缩图片后路径
                var resultPicPath = UploadFileUtils.getCompressFile(filePath)
                resultFilePath = resultPicPath
    
            } else if(fileType == ChatBean.CONTENT_TYPE_VOICE){
                //语音
                resultFilePath = filePath
    
                TagUtils.d("语音时间:${second}")
            } else if(fileType == ChatBean.CONTENT_TYPE_VIDEO){
                //小视频
                var videoFilePath = UploadFileUtils.getVideoCompressFile()
                //TagUtils.d("开始发送小视频压缩前文件2:${videoFilePath}")
                var compressResult = VideoController.getInstance().convertVideo(filePath, videoFilePath, VideoController.COMPRESS_QUALITY_LOW, object : VideoController.CompressProgressListener {
                    override fun onProgress(percent: Float) {
                        //TagUtils.d("压缩小视频进度:${percent}")
                    }
                })
    
                TagUtils.d("小视频时间:${second}")
                resultFilePath = videoFilePath
            }
    
            TagUtils.d("上传文件:${resultFilePath}")
            val filetosend = File(resultFilePath)
            if (!filetosend.exists()) {
                return@launch
            }
    
    
            try {
                var account : String = DataStoreUtils.getAccount()
    
                if(fileType == ChatBean.CONTENT_TYPE_IMG){
                    //图片
                    TagUtils.d("图片发送成功。")
                    var chatBeanServer = UploadFileUtils.uploadChatImages(account, toUserId, resultFilePath,0)
                    if(chatBeanServer != null){
                        chatBeanServer.imgPath = chatBeanServer.imgPath
                        chatBean = chatBeanServer
                    }
                } else if(fileType == ChatBean.CONTENT_TYPE_VOICE){
                    //录音完成,要转码,等待0.2秒再发送
                    delay(100)
                    //语音
                    var chatBeanServer = UploadFileUtils.uploadChatVoice(account, toUserId, resultFilePath, second)
                    if(chatBeanServer != null){
                        chatBeanServer.voiceLocal = resultFilePath
                        chatBean = chatBeanServer
                    }
                } else if(fileType == ChatBean.CONTENT_TYPE_VIDEO){
                    //小视频
                    var chatBeanServer = UploadFileUtils.uploadChatVideo(account, toUserId, resultFilePath, second)
                    if(chatBeanServer != null){
                        chatBeanServer.videoLocal = resultFilePath
                        chatBean = chatBeanServer
                    }
                }
                chatBean?.let {
                    ChatRepository.updateChat(it)
                }
    
                var baseSystemBoolean = BaseSystemRepository.getBaseSystemSync(WcApp.getContext().packageName)
                if(baseSystemBoolean != null && baseSystemBoolean.sync == CommonUtils.Sync.SERVER_SYNC){
                    //同步不需要使用transfer上传文件,因为transfer上传太慢了, 直接上传到服务器,然后发送普通的消息
                    if(fileType == ChatBean.CONTENT_TYPE_VOICE){
                        var content = CommonUtils.Chat.VOICE_MARK + chatBean.voice
                        ChatManagerUtils.getInstance().sendMessage(toUserId, content)
                    } else if(fileType == ChatBean.CONTENT_TYPE_VIDEO){
                        var content = CommonUtils.Chat.VIDEO_MARK + chatBean.video
                        ChatManagerUtils.getInstance().sendMessage(toUserId, content)
                    } else if(fileType == ChatBean.CONTENT_TYPE_IMG){
                        var content = CommonUtils.Chat.IMAGE_MARK + chatBean.imgPath
                        ChatManagerUtils.getInstance().sendMessage(toUserId, content)
                    }
                    return@launch
                }
    
                val fileTransferManager = getFileTransferManager()
                val transfer = fileTransferManager.createOutgoingFileTransfer(toId) // 创建一个输出文件传输对象
    
                //对方用户在线才需要上传文件
                if(XmppConnectionManager.getInstance().isOnLine(toUserId)){
                    TagUtils.d("${toUserId} 在线 开始上传。")
                    transfer.sendFile(filetosend,"recv img")
                    while (!transfer.isDone) {
                        if (transfer.status == FileTransfer.Status.error) {
                            TagUtils.d("聊天文件上传错误 , ERROR!!! " + transfer.error)
                        } else {
                            TagUtils.d("聊天文件上传 " + transfer.status +" , " + transfer.progress)
                        }
    
                        Thread.sleep(20)
    
                    }
                } else {
                    TagUtils.d("toUserId 不在线")
                }
                if (transfer.isDone) {
                    //上传完成
                }
            } catch (e1: XMPPException) {
                e1.printStackTrace()
            }
        }
    }

    //接收图片、语音、小视频文件监听
    fun addFileListerer() {
        val manager = getFileTransferManager()
    
        manager.addFileTransferListener { request ->
            CoroutineScope(Dispatchers.IO).launch {
                //文件接收
                val transfer = request.accept()
    
                OutgoingFileTransfer.getResponseTimeout()
    
                //获取文件名字
                val fileName = transfer.fileName
                TagUtils.d("接收图片、语音:${fileName}")
                //本地创建文件
                val sdCardDir  = File(FileUtils.CHAT_ALBUM_PATH)
                if (!sdCardDir.exists()) { //判断文件夹目录是否存在
                    sdCardDir.mkdir() //如果不存在则创建
                }
                //val savePath: String = FileUtils.CHAT_ALBUM_PATH + fileName
                val savePath: String = FileUtils.getBaseFile(fileName).path
                val file = File(savePath)
                //接收文件
                try {
                    transfer.recieveFile(file)
                    while (!transfer.isDone) {
                        if (transfer.status == FileTransfer.Status.error) {
                            TagUtils.d("接收、语音文件 ERROR!!! " + transfer.error)
                        } else {
                            TagUtils.d("接收、语音文件" + transfer.status + " , " + transfer.progress)
                        }
    
                        //接收小视频,要停顿一下,否则小视频不完整打不开。
                        Thread.sleep(20)
    
                    }
                    if (transfer.isDone) {
    
                        var account = DataStoreUtils.getAccount()
                        var chatBean : ChatBean? = null
                        var userType = ChatBean.USER_TYPE_OTHER
                        var peer = transfer.peer
                        TagUtils.d("接收文件完成peer:${peer}")
                        var toUserId = BaseUtils.getChatAccountFrom(peer)
                        TagUtils.d("接收文件完成toUserId:${toUserId}, account = ${account}")
                        if(fileName.endsWith(".mp3", true)){
                            //接收语音
                            var second = CommonUtils.Media.getMediaTime(savePath, ChatBean.CONTENT_TYPE_VOICE)
                            chatBean = CommonUtils.Chat.getChatBeanVoice(toUserId, account, userType, ChatBean.CONTENT_TYPE_VOICE, savePath, second)
                        } else if(fileName.endsWith(".mp4", true)){
                            //接收小视频
                            var second = CommonUtils.Media.getMediaTime(file.path, ChatBean.CONTENT_TYPE_VIDEO)
                            TagUtils.d("接收的小视频文件:${savePath}, ${second}秒")
                            chatBean = CommonUtils.Chat.getChatBeanVideo(toUserId, account, userType,  ChatBean.CONTENT_TYPE_VIDEO, savePath, second)
                        } else {
                            //接收图片
                            chatBean = CommonUtils.Chat.getChatBean(toUserId, account, userType, "", ChatBean.CONTENT_TYPE_IMG, savePath,0.0, 0.0)
                        }
    
                        chatBean?.let {
                            ChatRepository.insertChat(chatBean)
                            EventBus.getDefault().post(chatBean)
                        }
                    }
                } catch (e: XMPPException) {
                    e.printStackTrace()
                }
            }
    
        }
    }

     

    //web服务器方式下载
    override fun chatCreated(chat: Chat, createdLocally: Boolean) {
        TagUtils.d("消息监听回调:chat = ${chat} , createdLocally = ${createdLocally}")
        if(!createdLocally){
            chat.addMessageListener { chat, message ->
                TagUtils.d("获取好友发来的信息 ${message.from} , ${message.to}, ${message.body}")
                var content = message.getBody()
                if(!TextUtils.isEmpty(content) && content.length > 0){
                    var fromUser = BaseUtils.getChatAccountFrom(message.from)
                    var toUser = BaseUtils.getChatAccount(message.to)
                    var userType = ChatBean.USER_TYPE_OTHER
    
                    if(content.startsWith(CommonUtils.Chat.LOCATION_MARK)){
                        //发送定位
                        //去掉location###标志
                        var remarkContent = CommonUtils.Chat.getLocation(content)
                        //使用逗号分隔符,分别读取经纬度
                        var contents = remarkContent.split(",")
                        var latitude = contents[0].toDouble()
                        var longitude = contents[1].toDouble()
                        var chatBean = CommonUtils.Chat.getChatBean(fromUser, toUser, userType, content, ChatBean.CONTENT_TYPE_LOCATION, "", latitude, longitude)
                        ChatRepository.insertChat(chatBean)
                        chatBean.isReceive = true
                        EventBus.getDefault().post(chatBean)
                    } else if(content.startsWith(CommonUtils.Chat.REDPACKET_MARK)){
                        //发送红包, 去掉redpacket###写入数据库
                        content = CommonUtils.Chat.getRedpacket(content).toString()
                        var chatBean = CommonUtils.Chat.getChatBean(fromUser, toUser, userType, content, ChatBean.CONTENT_TYPE_REDPACKET, "",0.0, 0.0)
                        ChatRepository.insertChat(chatBean)
                        chatBean.isReceive = true
                        EventBus.getDefault().post(chatBean)
                    } else if(content.startsWith(CommonUtils.Chat.VOICE_MARK)){
                        //发送语音, 去掉voice###写入数据库
                        content = CommonUtils.Chat.getMedia(content, CommonUtils.Chat.VOICE_MARK)
                        var chatBean = CommonUtils.Chat.getChatBeanVoiceServer(fromUser, toUser, userType,ChatBean.CONTENT_TYPE_VOICE, content,0)
                        chatBean.isReceive = true
                        processDownload(chatBean)
                    } else if(content.startsWith(CommonUtils.Chat.VIDEO_MARK)){
                        //发送小视频, 去掉video###写入数据库
                        content = CommonUtils.Chat.getMedia(content, CommonUtils.Chat.VIDEO_MARK)
                        var chatBean = CommonUtils.Chat.getChatBeanVideoServer(fromUser, toUser, userType,ChatBean.CONTENT_TYPE_VIDEO, content,0)
                        chatBean.isReceive = true
                        processDownload(chatBean)
                    } else if(content.startsWith(CommonUtils.Chat.IMAGE_MARK)){
                        //发送图片, 去掉image###写入数据库
                        content = CommonUtils.Chat.getMedia(content, CommonUtils.Chat.IMAGE_MARK)
                        var chatBean = CommonUtils.Chat.getChatBeanImageServer(fromUser, toUser, userType,ChatBean.CONTENT_TYPE_IMG, content,0)
                        chatBean.isReceive = true
                        processDownload(chatBean)
                    } else if(content.startsWith(CommonUtils.Chat.TRANSFER_MARK)){
                        //发送转账, 去掉transfer###写入数据库
                        content = CommonUtils.Chat.getTransfer(content).toString()
                        var chatBean = CommonUtils.Chat.getChatBean(fromUser, toUser, userType, content, ChatBean.CONTENT_TYPE_TRANSFER, "",0.0, 0.0)
                        ChatRepository.insertChat(chatBean)
                        chatBean.isReceive = true
                        EventBus.getDefault().post(chatBean)
                    } else if(content.startsWith(CommonUtils.QRCommon.QR_RECEIVE_CODE)){
                        //向个人发送收款
                        var balance = content.substring(CommonUtils.QRCommon.QR_RECEIVE_CODE.length, content.length)
                        TagUtils.d("MyChatManagerListener 向个人发送收款金额: ${fromUser} , ${toUser},  ${balance}")
                        updateBalanceServer(fromUser, toUser, CommonUtils.User.OPERATOR_PLUS, balance.toFloat())
                    } else if(content.startsWith(CommonUtils.QRCommon.QR_PAYMENT_CODE)){
                        //向商家付款
                        var balance = content.substring(CommonUtils.QRCommon.QR_RECEIVE_CODE.length, content.length)
                        TagUtils.d("MyChatManagerListener 向商家付款金额: ${fromUser} , ${toUser}, ${balance}")
                        updateBalanceServer(fromUser, toUser, CommonUtils.User.OPERATOR_MINUS, balance.toFloat())
                    } else {
                        var chatBean = CommonUtils.Chat.getChatBean(fromUser, toUser, userType, content, ChatBean.CONTENT_TYPE_TEXT, "",0.0, 0.0)
                        ChatRepository.insertChat(chatBean)
                        chatBean.isReceive = true
                        EventBus.getDefault().post(chatBean)
                    }
                    ChatNotificationUtils.sendNotification(fromUser)
                }
            }
        }
    }
    
    /**
     * 下载图片、语音、小视频
     */
    private fun processDownload(chatBean : ChatBean){
        var fileName = ""
        if(chatBean.contentType == ChatBean.CONTENT_TYPE_VOICE){
            fileName = chatBean.voice
        } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_VIDEO){
            fileName = chatBean.video
        } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_IMG){
            fileName = chatBean.imgPath
        } else {
            return
        }
    
        var videoUrl = CommonUtils.Moments.getReallyImageUrl(fileName)
        var videoFile = FileUtils.getBaseFile(fileName)
    
        TagUtils.d("下载多媒体Url :${videoUrl} ")
        TagUtils.d("下载多媒体File :${videoFile} ")
    
        VideoDownloadManager.downloadFast(videoUrl, videoFile, object : VideoDownloadInter {
            override fun onDone(filePath: String) {
                TagUtils.d("小视频多媒体完成:${filePath}")
    
                if(chatBean.contentType == ChatBean.CONTENT_TYPE_VOICE){
                    var second = CommonUtils.Media.getMediaTime(filePath, chatBean.contentType)
                    chatBean.second = second
                    chatBean.voiceLocal = filePath
                } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_VIDEO){
                    chatBean.videoLocal = filePath
                    var second = CommonUtils.Media.getMediaTime(filePath, chatBean.contentType)
                    chatBean.second = second
                } else if(chatBean.contentType == ChatBean.CONTENT_TYPE_IMG){
                    chatBean.imgPathLocal = filePath
                }
    
                ChatRepository.insertChat(chatBean)
                EventBus.getDefault().post(chatBean)
            }
    
            override fun onError() {
            }
    
            override fun onProgress(process: Int) {
            }
        })
    }
  • 相关阅读:
    JavaSPI详解
    springboot物流配送推荐系统毕业设计源码072257
    接口自动化框架(四):组装请求数据并通过requests库发送请求
    Codeforces Round #804 (Div. 2)
    leetcode 43.字符串相乘
    java入门,从CK导一部分数据到mysql
    汽车智能座舱/智能驾驶SOC -2
    vivo 自研Jenkins资源调度系统设计与实践
    我的大二web课程设计 使用HTML做一个简单漂亮的页面(纯html代码)
    全国第一届学生(青年)运动会女子拳击比赛60公斤冠军载誉归来
  • 原文地址:https://blog.csdn.net/maoning20080808/article/details/128109017