Merge branch 'master' of gitlab.navinfo.com:vivo/navinfovivo
Conflicts: app/build.gradle app/src/main/java/com/navinfo/volvo/database/entity/GreetingMessage.kt app/src/main/java/com/navinfo/volvo/ui/fragments/message/ObtainMessageViewModel.kt
This commit is contained in:
commit
0da95021ce
3
.idea/gradle.xml
generated
3
.idea/gradle.xml
generated
@ -7,8 +7,7 @@
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleHome" value="$USER_HOME$/.gradle/wrapper/dists/gradle-7.2-all/260hg96vuh6ex27h9vo47iv4d/gradle-7.2" />
|
||||
<option name="gradleJvm" value="JDK" />
|
||||
<option name="gradleJvm" value="11" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
||||
@ -149,8 +149,10 @@ dependencies {
|
||||
implementation("com.github.bumptech.glide:glide:4.11.0") {
|
||||
exclude group: "com.android.support"
|
||||
}
|
||||
|
||||
|
||||
// 多媒体播放库 https://github.com/JagarYousef/ChatVoicePlayer
|
||||
implementation 'com.github.JagarYousef:ChatVoicePlayer:1.1.0'
|
||||
// 图片查看器 https://github.com/XiaoGe-1996/ImageViewer
|
||||
implementation 'com.github.XiaoGe-1996:ImageViewer:v1.0.0'
|
||||
}
|
||||
|
||||
kapt {
|
||||
|
||||
@ -4,10 +4,12 @@
|
||||
<!-- 拍照 -->
|
||||
<uses-permission
|
||||
android:name="android.permission.CAMERA"
|
||||
android:required="false" /> <!-- 网络请求 -->
|
||||
android:required="false" />
|
||||
<!-- 网络请求 -->
|
||||
<uses-permission
|
||||
android:name="android.permission.INTERNET"
|
||||
android:required="false" /> <!-- 录音 -->
|
||||
android:required="false" />
|
||||
<!-- 录音 -->
|
||||
<uses-permission
|
||||
android:name="android.permission.RECORD_AUDIO"
|
||||
android:required="false" /> <!-- 读写文件 -->
|
||||
|
||||
@ -38,9 +38,9 @@ data class GreetingMessage @JvmOverloads constructor(
|
||||
var sendType: String? = "",
|
||||
var del: String? = "",
|
||||
var version: String? = "",
|
||||
/**
|
||||
* 附件列表
|
||||
*/
|
||||
var attachment: MutableList<Attachment> = mutableListOf(),
|
||||
// /**
|
||||
// * 附件列表
|
||||
// */
|
||||
// var attachment: MutableList<Attachment> = mutableListOf(),
|
||||
var read: Boolean = false,
|
||||
)
|
||||
|
||||
86
app/src/main/java/com/navinfo/volvo/http/DownloadManager.kt
Normal file
86
app/src/main/java/com/navinfo/volvo/http/DownloadManager.kt
Normal file
@ -0,0 +1,86 @@
|
||||
package com.navinfo.volvo.http
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.Retrofit
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
object DownloadManager {
|
||||
suspend fun download(url: String, file: File): Flow<DownloadState> {
|
||||
return flow {
|
||||
val retrofit = Retrofit.Builder()
|
||||
.baseUrl(UrlUtils.getBaseUrl(url))
|
||||
.build()
|
||||
val response = retrofit.create(NavinfoVolvoService::class.java).downloadFile(url).execute()
|
||||
if (response.isSuccessful) {
|
||||
saveToFile(response.body()!!, file) {
|
||||
emit(DownloadState.InProgress(it))
|
||||
}
|
||||
emit(DownloadState.Success(file))
|
||||
} else {
|
||||
emit(DownloadState.Error(IOException(response.toString())))
|
||||
}
|
||||
}.catch {
|
||||
emit(DownloadState.Error(it))
|
||||
}.flowOn(Dispatchers.IO)
|
||||
}
|
||||
|
||||
private inline fun saveToFile(responseBody: ResponseBody, file: File, progressListener: (Int) -> Unit) {
|
||||
val total = responseBody.contentLength()
|
||||
var bytesCopied = 0
|
||||
var emittedProgress = 0
|
||||
file.outputStream().use { output ->
|
||||
val input = responseBody.byteStream()
|
||||
val buffer = ByteArray(DEFAULT_BUFFER_SIZE)
|
||||
var bytes = input.read(buffer)
|
||||
while (bytes >= 0) {
|
||||
output.write(buffer, 0, bytes)
|
||||
bytesCopied += bytes
|
||||
bytes = input.read(buffer)
|
||||
val progress = (bytesCopied * 100 / total).toInt()
|
||||
if (progress - emittedProgress > 0) {
|
||||
progressListener(progress)
|
||||
emittedProgress = progress
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed class DownloadState {
|
||||
data class InProgress(val progress: Int) : DownloadState()
|
||||
data class Success(val file: File) : DownloadState()
|
||||
data class Error(val throwable: Throwable) : DownloadState()
|
||||
}
|
||||
|
||||
interface DownloadCallback {
|
||||
fun progress(progress: Int)
|
||||
fun error(throwable: Throwable)
|
||||
fun success(file: File)
|
||||
}
|
||||
|
||||
object UrlUtils {
|
||||
|
||||
/**
|
||||
* 从url分割出BaseUrl
|
||||
*/
|
||||
fun getBaseUrl(url: String): String {
|
||||
var mutableUrl = url
|
||||
var head = ""
|
||||
var index = mutableUrl.indexOf("://")
|
||||
if (index != -1) {
|
||||
head = mutableUrl.substring(0, index + 3)
|
||||
mutableUrl = mutableUrl.substring(index + 3)
|
||||
}
|
||||
index = mutableUrl.indexOf("/")
|
||||
if (index != -1) {
|
||||
mutableUrl = mutableUrl.substring(0, index + 1)
|
||||
}
|
||||
return head + mutableUrl
|
||||
}
|
||||
}
|
||||
@ -2,18 +2,16 @@ package com.navinfo.volvo.http
|
||||
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.RequestBody
|
||||
import okhttp3.ResponseBody
|
||||
import retrofit2.Call
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.Multipart
|
||||
import retrofit2.http.POST
|
||||
import retrofit2.http.Part
|
||||
import retrofit2.http.*
|
||||
import java.io.File
|
||||
|
||||
interface NavinfoVolvoService {
|
||||
@POST("/navi/cardDelivery/insertCardByApp")
|
||||
fun insertCardByApp(@Body insertData: MutableMap<String, String>)
|
||||
suspend fun insertCardByApp(@Body insertData: Map<String, String>):DefaultResponse<String>
|
||||
@POST("/navi/cardDelivery/updateCardByApp")
|
||||
fun updateCardByApp(@Body updateData: MutableMap<String, String>)
|
||||
suspend fun updateCardByApp(@Body updateData: Map<String, String>):DefaultResponse<String>
|
||||
@POST("/navi/cardDelivery/queryCardListByApp")
|
||||
fun queryCardListByApp(@Body queryData: MutableMap<String, String>)
|
||||
@POST("/navi/cardDelivery/deleteCardByApp")
|
||||
@ -22,5 +20,8 @@ interface NavinfoVolvoService {
|
||||
@Multipart
|
||||
suspend fun uploadAttachment(@Part attachmentFile: MultipartBody.Part):DefaultResponse<MutableMap<String, String>>
|
||||
@POST("/img/download")
|
||||
fun downLoadAttachment(@Body downloadData: MutableMap<String, String>):Call<DefaultResponse<MutableMap<String, String>>>
|
||||
suspend fun downLoadAttachment(@Body downloadData: Map<String, String>):DefaultResponse<String>
|
||||
@Streaming
|
||||
@GET
|
||||
fun downloadFile(@Url url: String): Call<ResponseBody>
|
||||
}
|
||||
@ -1,9 +1,12 @@
|
||||
package com.navinfo.volvo.ui.fragments.message
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.graphics.Paint
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.View.*
|
||||
import android.view.ViewGroup
|
||||
@ -13,11 +16,18 @@ import android.widget.ArrayAdapter
|
||||
import android.widget.Toast
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.Navigation
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.easytools.tools.DateUtils
|
||||
import com.easytools.tools.DeviceUtils
|
||||
import com.easytools.tools.DisplayUtils
|
||||
import com.easytools.tools.FileIOUtils
|
||||
import com.easytools.tools.FileUtils
|
||||
import com.easytools.tools.ResourceUtils
|
||||
import com.easytools.tools.ToastUtils
|
||||
import com.elvishew.xlog.XLog
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
@ -25,17 +35,25 @@ import com.gredicer.datetimepicker.DateTimePickerFragment
|
||||
import com.hjq.permissions.OnPermissionCallback
|
||||
import com.hjq.permissions.Permission
|
||||
import com.hjq.permissions.XXPermissions
|
||||
import com.navinfo.volvo.R
|
||||
import com.navinfo.volvo.RecorderLifecycleObserver
|
||||
import com.navinfo.volvo.databinding.FragmentObtainMessageBinding
|
||||
import com.navinfo.volvo.database.entity.Attachment
|
||||
import com.navinfo.volvo.database.entity.AttachmentType
|
||||
import com.navinfo.volvo.database.entity.GreetingMessage
|
||||
import com.navinfo.volvo.databinding.FragmentObtainMessageBinding
|
||||
import com.navinfo.volvo.http.DownloadCallback
|
||||
import com.navinfo.volvo.ui.markRequiredInRed
|
||||
import com.navinfo.volvo.util.PhotoLoader
|
||||
import com.navinfo.volvo.utils.EasyMediaFile
|
||||
import com.navinfo.volvo.utils.SystemConstant
|
||||
import com.nhaarman.supertooltips.ToolTip
|
||||
import indi.liyi.viewer.Utils
|
||||
import indi.liyi.viewer.ViewData
|
||||
import top.zibin.luban.Luban
|
||||
import top.zibin.luban.OnCompressListener
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.FileOutputStream
|
||||
import java.util.*
|
||||
|
||||
|
||||
@ -52,6 +70,9 @@ class ObtainMessageFragment: Fragment() {
|
||||
RecorderLifecycleObserver()
|
||||
}
|
||||
|
||||
private val dateSendFormat = "yyyy-MM-dd HH:mm:ss"
|
||||
private val dateShowFormat = "yyyy-MM-dd HH:mm"
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
@ -72,37 +93,63 @@ class ObtainMessageFragment: Fragment() {
|
||||
if(it.name?.isNotEmpty() == true)
|
||||
binding.tvMessageTitle?.setText(it.name)
|
||||
if (it.sendDate?.isNotEmpty() == true) {
|
||||
// 获取当前发送时间,如果早于当前时间,则显示现在
|
||||
val sendDate = DateUtils.str2Date(it.sendDate, dateSendFormat)
|
||||
if (sendDate<=Date()) {
|
||||
binding.btnSendTime.text = "现在"
|
||||
} else {
|
||||
binding.btnSendTime.text = it.sendDate
|
||||
}
|
||||
} else { // 如果发送时间此时为空,自动设置发送时间为当前时间
|
||||
it.sendDate = DateUtils.date2Str(Date(), dateSendFormat)
|
||||
}
|
||||
var hasPhoto = false
|
||||
var hasAudio = false
|
||||
if (it.attachment.isNotEmpty()) {
|
||||
// 展示照片文件或录音文件
|
||||
for (attachment in it.attachment) {
|
||||
if (attachment.attachmentType == AttachmentType.PIC) {
|
||||
Glide.with(context!!)
|
||||
.asBitmap().fitCenter()
|
||||
.load(attachment.pathUrl)
|
||||
.into(binding.imgMessageAttachment)
|
||||
// 显示名称
|
||||
binding.tvPhotoName.text = attachment.pathUrl.replace("\\", "/").substringAfterLast("/")
|
||||
if (it.imageUrl!=null&&it.imageUrl?.isNotEmpty() == true) {
|
||||
hasPhoto = true
|
||||
|
||||
// Glide.with(this@ObtainMessageFragment)
|
||||
// .asBitmap().fitCenter()
|
||||
// .load(it.imageUrl)
|
||||
// .diskCacheStrategy(DiskCacheStrategy.ALL)
|
||||
// .into(binding.imgMessageAttachment)
|
||||
// 如果当前attachment文件是本地文件,开始尝试网络上传
|
||||
if (!attachment.pathUrl.startsWith("http")) {
|
||||
obtainMessageViewModel.uploadAttachment(File(attachment.pathUrl))
|
||||
val str = it.imageUrl?.replace("\\", "/")
|
||||
binding.tvPhotoName.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG )
|
||||
if (!str!!.startsWith("http")) {
|
||||
obtainMessageViewModel.uploadAttachment(File(it.imageUrl), AttachmentType.PIC)
|
||||
binding.tvPhotoName.text = str.substringAfterLast("/", "picture.jpg")
|
||||
} else {
|
||||
if (str.contains("?")) {
|
||||
binding.tvPhotoName.text = str.substring(str.lastIndexOf("/")+1, str.indexOf("?"))
|
||||
} else {
|
||||
binding.tvPhotoName.text = str.substringAfterLast("/")
|
||||
}
|
||||
}
|
||||
if (attachment.attachmentType == AttachmentType.AUDIO) {
|
||||
binding.tvAudioName.text = attachment.pathUrl.replace("\\", "/").substringAfterLast("/")
|
||||
}
|
||||
|
||||
if (it.mediaUrl!=null&&it.mediaUrl?.isNotEmpty() == true) {
|
||||
hasAudio = true
|
||||
binding.tvAudioName.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG )
|
||||
// 如果当前attachment文件是本地文件,开始尝试网络上传
|
||||
val str = it.mediaUrl?.replace("\\", "/")
|
||||
if (!str!!.startsWith("http")) {
|
||||
obtainMessageViewModel.uploadAttachment(File(it.mediaUrl),AttachmentType.AUDIO)
|
||||
binding.tvAudioName.text = str.substringAfterLast("/", "audio.m4a")
|
||||
} else {
|
||||
if (str.contains("?")) {
|
||||
binding.tvAudioName.text = str.substring(str.lastIndexOf("/")+1, str.indexOf("?"))
|
||||
} else {
|
||||
binding.tvAudioName.text = str.substringAfterLast("/")
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.layerPhotoResult.visibility = if (hasPhoto) VISIBLE else GONE
|
||||
binding.layerGetPhoto.visibility = if (hasPhoto) GONE else VISIBLE
|
||||
// binding.imgMessageAttachment.visibility = if (hasPhoto) VISIBLE else GONE
|
||||
|
||||
binding.layerAudioResult.visibility = if (hasAudio) VISIBLE else GONE
|
||||
binding.layerGetAudio.visibility = if (hasAudio) GONE else VISIBLE
|
||||
// binding.llAudioPlay.visibility = if (hasAudio) VISIBLE else GONE
|
||||
}
|
||||
)
|
||||
lifecycle.addObserver(recorderLifecycleObserver)
|
||||
@ -113,16 +160,20 @@ class ObtainMessageFragment: Fragment() {
|
||||
fun initView() {
|
||||
// 设置问候信息提示的红色星号
|
||||
binding.tiLayoutTitle.markRequiredInRed()
|
||||
binding.tvMessageTitle.addTextChangedListener {
|
||||
obtainMessageViewModel.updateMessageTitle(it.toString())
|
||||
}
|
||||
binding.tvMessageTitle.addTextChangedListener(afterTextChanged = {
|
||||
obtainMessageViewModel.getMessageLiveData().value?.name = it.toString()
|
||||
})
|
||||
|
||||
binding.edtSendFrom.addTextChangedListener (afterTextChanged = {
|
||||
obtainMessageViewModel.getMessageLiveData().value?.who = it.toString()
|
||||
})
|
||||
|
||||
binding.imgPhotoDelete.setOnClickListener {
|
||||
obtainMessageViewModel.updateMessagePic(null)
|
||||
obtainMessageViewModel.updateMessagePic("")
|
||||
}
|
||||
|
||||
binding.imgAudioDelete.setOnClickListener {
|
||||
obtainMessageViewModel.updateMessageAudio(null)
|
||||
obtainMessageViewModel.updateMessageAudio("")
|
||||
}
|
||||
|
||||
val sendToArray = mutableListOf<String>("绑定车辆1(LYVXFEFEXNL754427)")
|
||||
@ -143,11 +194,11 @@ class ObtainMessageFragment: Fragment() {
|
||||
val dialog = DateTimePickerFragment.newInstance().mode(0)
|
||||
dialog.listener = object : DateTimePickerFragment.OnClickListener {
|
||||
override fun onClickListener(selectTime: String) {
|
||||
val sendDate = DateUtils.str2Date(selectTime, "yyyy-MM-dd HH:mm")
|
||||
val sendDate = DateUtils.str2Date(selectTime, dateShowFormat)
|
||||
if (sendDate <= Date()) {
|
||||
obtainMessageViewModel.updateMessageSendTime("现在")
|
||||
obtainMessageViewModel.updateMessageSendTime(DateUtils.date2Str(Date(), dateSendFormat))
|
||||
} else {
|
||||
obtainMessageViewModel.updateMessageSendTime(selectTime)
|
||||
obtainMessageViewModel.updateMessageSendTime(DateUtils.date2Str(sendDate, dateSendFormat))
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,12 +244,22 @@ class ObtainMessageFragment: Fragment() {
|
||||
// 用户选择录音文件
|
||||
binding.btnSelectSound.setOnClickListener {
|
||||
photoHelper.setCrop(false).selectAudio(activity!!)
|
||||
// SingleAudioPicker.showPicker(context!!) {
|
||||
// val audioFile = File(it.contentUri.path)
|
||||
// ToastUtils.showToast(audioFile.absolutePath)
|
||||
// if (!audioFile.parentFile.parentFile.absolutePath.equals(SystemConstant.SoundFolder)) {
|
||||
// val copyResult = FileIOUtils.writeFileFromIS(File(SystemConstant.SoundFolder, audioFile.name), FileInputStream(audioFile))
|
||||
// XLog.e("拷贝结果:"+copyResult)
|
||||
// obtainMessageViewModel.updateMessageAudio(File(SystemConstant.SoundFolder, audioFile.name).absolutePath)
|
||||
// } else {
|
||||
// obtainMessageViewModel.updateMessageAudio(audioFile.absolutePath)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// 开始录音
|
||||
binding.btnStartRecord.setOnClickListener {
|
||||
binding.btnStartRecord.setOnTouchListener { view, motionEvent ->
|
||||
// 申请权限
|
||||
XXPermissions.with(this)
|
||||
XXPermissions.with(this@ObtainMessageFragment)
|
||||
// 申请单个权限
|
||||
.permission(Permission.RECORD_AUDIO)
|
||||
.request(object : OnPermissionCallback {
|
||||
@ -207,17 +268,23 @@ class ObtainMessageFragment: Fragment() {
|
||||
Toast.makeText(activity, "获取部分权限成功,但部分权限未正常授予", Toast.LENGTH_SHORT).show()
|
||||
return
|
||||
}
|
||||
|
||||
if (it.isSelected) {
|
||||
it.isSelected = false
|
||||
when(motionEvent.action) {
|
||||
MotionEvent.ACTION_DOWN-> {
|
||||
// 申请权限
|
||||
recorderLifecycleObserver.initAndStartRecorder()
|
||||
ToastUtils.showToast("开始录音!")
|
||||
false
|
||||
}
|
||||
MotionEvent.ACTION_UP -> {
|
||||
val recorderAudioPath = recorderLifecycleObserver.stopAndReleaseRecorder()
|
||||
if (File(recorderAudioPath).exists()) {
|
||||
obtainMessageViewModel.updateMessageAudio(recorderAudioPath)
|
||||
}
|
||||
} else{
|
||||
it.isSelected = true
|
||||
|
||||
recorderLifecycleObserver.initAndStartRecorder()
|
||||
false
|
||||
}
|
||||
else -> {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,6 +299,7 @@ class ObtainMessageFragment: Fragment() {
|
||||
}
|
||||
}
|
||||
})
|
||||
false
|
||||
}
|
||||
|
||||
// 获取照片文件和音频文件
|
||||
@ -260,9 +328,17 @@ class ObtainMessageFragment: Fragment() {
|
||||
if (!it.absolutePath.equals(file?.absolutePath)) {
|
||||
it?.delete()
|
||||
}
|
||||
// 如果当前文件不在camera缓存文件夹下,则移动该文件
|
||||
if (!file!!.parentFile.absolutePath.equals(SystemConstant.CameraFolder)) {
|
||||
val copyResult = FileIOUtils.writeFileFromIS(File(SystemConstant.CameraFolder, fileName), FileInputStream(file))
|
||||
XLog.e("拷贝结果:"+copyResult)
|
||||
// 跳转回原Fragment,展示拍摄的照片
|
||||
ViewModelProvider(requireActivity()).get(ObtainMessageViewModel::class.java).updateMessagePic(File(SystemConstant.CameraFolder, fileName).absolutePath)
|
||||
} else {
|
||||
// 跳转回原Fragment,展示拍摄的照片
|
||||
ViewModelProvider(requireActivity()).get(ObtainMessageViewModel::class.java).updateMessagePic(file!!.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
XLog.d("压缩图片失败:${e.message}")
|
||||
@ -270,20 +346,52 @@ class ObtainMessageFragment: Fragment() {
|
||||
}).launch()
|
||||
} else if (fileName.endsWith(".mp3")||fileName.endsWith(".wav")||fileName.endsWith(".amr")||fileName.endsWith(".m4a")) {
|
||||
ToastUtils.showToast(it.absolutePath)
|
||||
if (!it.parentFile.parentFile.absolutePath.equals(SystemConstant.SoundFolder)) {
|
||||
val copyResult = FileIOUtils.writeFileFromIS(File(SystemConstant.SoundFolder, fileName), FileInputStream(it))
|
||||
XLog.e("拷贝结果:"+copyResult)
|
||||
obtainMessageViewModel.updateMessageAudio(File(SystemConstant.SoundFolder, fileName).absolutePath)
|
||||
} else {
|
||||
obtainMessageViewModel.updateMessageAudio(it.absolutePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
photoHelper.setError {
|
||||
ToastUtils.showToast(it.message)
|
||||
}
|
||||
|
||||
binding.tvAudioName.setOnClickListener {
|
||||
binding.llAudioPlay.visibility = if (binding.llAudioPlay.visibility == VISIBLE) GONE else VISIBLE
|
||||
// 判断当前播放的文件是否在缓存文件夹内,如果不在首先下载该文件
|
||||
val fileUrl = obtainMessageViewModel.getMessageLiveData().value!!.mediaUrl!!
|
||||
val localFile = obtainMessageViewModel.getLocalFileFromNetUrl(fileUrl, AttachmentType.AUDIO)
|
||||
if (!localFile.exists()) {
|
||||
obtainMessageViewModel.downLoadFile(fileUrl, localFile, object: DownloadCallback {
|
||||
override fun progress(progress: Int) {
|
||||
}
|
||||
|
||||
override fun error(throwable: Throwable) {
|
||||
}
|
||||
|
||||
override fun success(file: File) {
|
||||
binding.voicePlayerView.setAudio(localFile.absolutePath)
|
||||
}
|
||||
|
||||
})
|
||||
} else {
|
||||
binding.voicePlayerView.setAudio(localFile.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
binding.btnObtainMessageBack.setOnClickListener {
|
||||
Navigation.findNavController(it).popBackStack()
|
||||
}
|
||||
|
||||
binding.btnObtainMessageConfirm.setOnClickListener {
|
||||
var checkResult = true
|
||||
val toolTipBackColor = ResourceUtils.getColor(R.color.teal_200)
|
||||
val toolTipTextColor = ResourceUtils.getColor(R.color.black)
|
||||
// 检查当前输入数据
|
||||
val messageData = obtainMessageViewModel.getMessageLiveData().value
|
||||
if (messageData?.name?.isEmpty() == true) {
|
||||
@ -291,40 +399,49 @@ class ObtainMessageFragment: Fragment() {
|
||||
binding.ttTitle
|
||||
val toolTip = ToolTip()
|
||||
.withText("请输入问候信息")
|
||||
.withColor(com.navinfo.volvo.R.color.purple_200)
|
||||
.withShadow()
|
||||
.withColor(toolTipBackColor)
|
||||
.withTextColor(toolTipTextColor)
|
||||
.withoutShadow()
|
||||
.withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
|
||||
toolTipRelativeLayout.showToolTipForView(toolTip, binding.tiLayoutTitle)
|
||||
}
|
||||
var hasPic = false
|
||||
var hasAudio = false
|
||||
for (attachment in messageData?.attachment!!) {
|
||||
if (attachment.attachmentType == AttachmentType.PIC) {
|
||||
hasPic = true
|
||||
}
|
||||
if (attachment.attachmentType == AttachmentType.AUDIO) {
|
||||
hasAudio = true
|
||||
checkResult = false
|
||||
} else {
|
||||
if (messageData?.name!!.length>10) {
|
||||
val toolTipRelativeLayout =
|
||||
binding.ttTitle
|
||||
val toolTip = ToolTip()
|
||||
.withText("问候信息长度不能超过10")
|
||||
.withColor(toolTipBackColor)
|
||||
.withTextColor(toolTipTextColor)
|
||||
.withoutShadow()
|
||||
.withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
|
||||
toolTipRelativeLayout.showToolTipForView(toolTip, binding.tiLayoutTitle)
|
||||
checkResult = false
|
||||
}
|
||||
}
|
||||
if (!hasPic) {
|
||||
if (messageData?.imageUrl?.isEmpty() == true) {
|
||||
val toolTipRelativeLayout =
|
||||
binding.ttPic
|
||||
val toolTip = ToolTip()
|
||||
.withText("需要提供照片文件")
|
||||
.withColor(com.navinfo.volvo.R.color.purple_200)
|
||||
.withShadow()
|
||||
.withColor(toolTipBackColor)
|
||||
.withTextColor(toolTipTextColor)
|
||||
.withoutShadow()
|
||||
.withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
|
||||
toolTipRelativeLayout.showToolTipForView(toolTip, binding.tvUploadPic)
|
||||
checkResult = false
|
||||
}
|
||||
if (!hasAudio) {
|
||||
if (messageData?.mediaUrl?.isEmpty() == true) {
|
||||
val toolTipRelativeLayout =
|
||||
binding.ttAudio
|
||||
val toolTip = ToolTip()
|
||||
.withText("需要提供音频文件")
|
||||
.withColor(com.navinfo.volvo.R.color.purple_200)
|
||||
.withShadow()
|
||||
.withColor(toolTipBackColor)
|
||||
.withTextColor(toolTipTextColor)
|
||||
.withoutShadow()
|
||||
.withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
|
||||
toolTipRelativeLayout.showToolTipForView(toolTip, binding.tvUploadPic)
|
||||
checkResult = false
|
||||
}
|
||||
|
||||
if (messageData?.who?.isEmpty()==true) {
|
||||
@ -332,21 +449,86 @@ class ObtainMessageFragment: Fragment() {
|
||||
binding.ttSendFrom
|
||||
val toolTip = ToolTip()
|
||||
.withText("请输入您的名称")
|
||||
.withColor(com.navinfo.volvo.R.color.purple_200)
|
||||
.withShadow()
|
||||
.withColor(toolTipBackColor)
|
||||
.withTextColor(toolTipTextColor)
|
||||
.withoutShadow()
|
||||
.withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
|
||||
toolTipRelativeLayout.showToolTipForView(toolTip, binding.edtSendFrom)
|
||||
checkResult = false
|
||||
}
|
||||
if (messageData?.toWho?.isEmpty()==true) {
|
||||
val toolTipRelativeLayout =
|
||||
binding.ttSendTo
|
||||
val toolTip = ToolTip()
|
||||
.withText("请选择要发送的车辆")
|
||||
.withColor(com.navinfo.volvo.R.color.purple_200)
|
||||
.withShadow()
|
||||
.withColor(toolTipBackColor)
|
||||
.withTextColor(toolTipTextColor)
|
||||
.withoutShadow()
|
||||
.withAnimationType(ToolTip.AnimationType.FROM_MASTER_VIEW)
|
||||
toolTipRelativeLayout.showToolTipForView(toolTip, binding.edtSendTo)
|
||||
checkResult = false
|
||||
}
|
||||
|
||||
if (checkResult) { // 检查通过
|
||||
// 检查attachment是否为本地数据,如果是本地则弹出对话框尝试上传
|
||||
val localAttachmentList = mutableListOf<Attachment>()
|
||||
if (messageData?.imageUrl?.startsWith("http") == false) {
|
||||
val imageAttachment = Attachment("", messageData.imageUrl!!, AttachmentType.PIC)
|
||||
localAttachmentList.add(imageAttachment)
|
||||
}
|
||||
if (messageData?.mediaUrl?.startsWith("http") == false) {
|
||||
val audioAttachment = Attachment("", messageData.mediaUrl!!, AttachmentType.AUDIO)
|
||||
localAttachmentList.add(audioAttachment)
|
||||
}
|
||||
if (localAttachmentList.isNotEmpty()) {
|
||||
MaterialAlertDialogBuilder(context!!)
|
||||
.setTitle("提示")
|
||||
.setMessage("当前照片及音频内容需首先上传,是否尝试上传?")
|
||||
.setPositiveButton("确定", DialogInterface.OnClickListener { dialogInterface, i ->
|
||||
dialogInterface.dismiss()
|
||||
for (attachment in localAttachmentList) {
|
||||
obtainMessageViewModel.uploadAttachment(File(attachment.pathUrl), attachment.attachmentType)
|
||||
}
|
||||
})
|
||||
.setNegativeButton("取消", DialogInterface.OnClickListener {
|
||||
dialogInterface, i -> dialogInterface.dismiss()
|
||||
})
|
||||
.show()
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
// 检查发送时间
|
||||
val sendDate = DateUtils.str2Date(messageData?.sendDate, dateSendFormat)
|
||||
val cal = Calendar.getInstance()
|
||||
cal.time = Date()
|
||||
cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE)+1)
|
||||
if (cal.time.time < sendDate.time) { // 发送时间设置小于当前时间1分钟前,Toast提示用户并自动设置发送时间
|
||||
messageData?.sendDate = DateUtils.date2Str(cal.time, dateSendFormat)
|
||||
ToastUtils.showToast("自动调整发送时间为1分钟后发送")
|
||||
}
|
||||
|
||||
// 开始网络提交数据
|
||||
if (obtainMessageViewModel.getMessageLiveData().value?.id==0L) { // 如果网络id为空,则调用更新操作
|
||||
obtainMessageViewModel.insertCardByApp()
|
||||
} else {
|
||||
obtainMessageViewModel.updateCardByApp()
|
||||
}
|
||||
}
|
||||
}
|
||||
// 点击照片名称
|
||||
binding.tvPhotoName.setOnClickListener {
|
||||
val viewData = ViewData()
|
||||
viewData.imageSrc = obtainMessageViewModel.getMessageLiveData().value!!.imageUrl
|
||||
viewData.targetX = Utils.dp2px(context, 10F).toFloat()
|
||||
viewData.targetWidth = DisplayUtils.getScreenWidthPixels(activity) - Utils.dp2px(context, 20F)
|
||||
viewData.targetHeight = Utils.dp2px(context, 200F)
|
||||
val viewDataList = listOf(viewData)
|
||||
binding.imageViewer.overlayStatusBar(true) // ImageViewer 是否会占据 StatusBar 的空间
|
||||
.viewData(viewDataList) // 图片数据
|
||||
.imageLoader(PhotoLoader()) // 设置图片加载方式
|
||||
.showIndex(true) // 是否显示图片索引,默认为true
|
||||
.watch(0) // 开启浏览
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -395,4 +577,6 @@ class ObtainMessageFragment: Fragment() {
|
||||
super.onDestroy()
|
||||
lifecycle.removeObserver(recorderLifecycleObserver)
|
||||
}
|
||||
|
||||
companion object
|
||||
}
|
||||
@ -1,22 +1,30 @@
|
||||
package com.navinfo.volvo.ui.fragments.message
|
||||
|
||||
import androidx.lifecycle.*
|
||||
import com.easytools.tools.FileIOUtils
|
||||
import com.easytools.tools.FileUtils
|
||||
import com.easytools.tools.ToastUtils
|
||||
import com.elvishew.xlog.XLog
|
||||
import com.navinfo.volvo.database.entity.Attachment
|
||||
import com.navinfo.volvo.database.entity.AttachmentType
|
||||
import com.navinfo.volvo.database.entity.GreetingMessage
|
||||
import com.navinfo.volvo.http.DownloadCallback
|
||||
import com.navinfo.volvo.http.DownloadManager
|
||||
import com.navinfo.volvo.http.DownloadState
|
||||
import com.navinfo.volvo.http.NavinfoVolvoCall
|
||||
import com.navinfo.volvo.utils.SystemConstant
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.MediaType
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.MultipartBody
|
||||
import okhttp3.RequestBody
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class ObtainMessageViewModel @Inject constructor() : ViewModel() {
|
||||
class ObtainMessageViewModel: ViewModel() {
|
||||
private val msgLiveData: MutableLiveData<GreetingMessage> by lazy {
|
||||
MutableLiveData<GreetingMessage>()
|
||||
}
|
||||
@ -37,52 +45,42 @@ class ObtainMessageViewModel @Inject constructor() : ViewModel() {
|
||||
|
||||
// 更新消息附件中的照片文件
|
||||
fun updateMessagePic(picUrl: String?) {
|
||||
var hasPic = false
|
||||
// var hasPic = false
|
||||
|
||||
for (attachment in this.msgLiveData.value!!.attachment) {
|
||||
if (attachment.attachmentType == AttachmentType.PIC) {
|
||||
if (picUrl == null || picUrl.isEmpty()) {
|
||||
this.msgLiveData.value!!.attachment.remove(attachment)
|
||||
} else {
|
||||
attachment.pathUrl = picUrl
|
||||
}
|
||||
hasPic = true
|
||||
}
|
||||
}
|
||||
if (!hasPic && picUrl != null) {
|
||||
this.msgLiveData.value!!.attachment.add(
|
||||
Attachment(
|
||||
UUID.randomUUID().toString(),
|
||||
picUrl,
|
||||
AttachmentType.PIC
|
||||
)
|
||||
)
|
||||
}
|
||||
this.msgLiveData.value?.imageUrl = picUrl
|
||||
// for (attachment in this.msgLiveData.value!!.attachment) {
|
||||
// if (attachment.attachmentType == AttachmentType.PIC) {
|
||||
// if (picUrl==null||picUrl.isEmpty()) {
|
||||
// this.msgLiveData.value!!.attachment.remove(attachment)
|
||||
// } else {
|
||||
// attachment.pathUrl = picUrl
|
||||
// }
|
||||
// hasPic = true
|
||||
// }
|
||||
// }
|
||||
// if (!hasPic&&picUrl!=null) {
|
||||
// this.msgLiveData.value!!.attachment.add(Attachment(UUID.randomUUID().toString(), picUrl, AttachmentType.PIC))
|
||||
// }
|
||||
this.msgLiveData.postValue(this.msgLiveData.value)
|
||||
}
|
||||
|
||||
// 更新消息附件中的录音文件
|
||||
fun updateMessageAudio(audioUrl: String?) {
|
||||
var hasAudio = false
|
||||
for (attachment in this.msgLiveData.value!!.attachment) {
|
||||
if (attachment.attachmentType == AttachmentType.AUDIO) {
|
||||
if (audioUrl == null || audioUrl.isEmpty()) {
|
||||
this.msgLiveData.value!!.attachment.remove(attachment)
|
||||
} else {
|
||||
attachment.pathUrl = audioUrl
|
||||
}
|
||||
hasAudio = true
|
||||
}
|
||||
}
|
||||
if (!hasAudio && audioUrl != null) {
|
||||
this.msgLiveData.value!!.attachment.add(
|
||||
Attachment(
|
||||
UUID.randomUUID().toString(),
|
||||
audioUrl,
|
||||
AttachmentType.AUDIO
|
||||
)
|
||||
)
|
||||
}
|
||||
// var hasAudio = false
|
||||
// for (attachment in this.msgLiveData.value!!.attachment) {
|
||||
// if (attachment.attachmentType == AttachmentType.AUDIO) {
|
||||
// if (audioUrl==null||audioUrl.isEmpty()) {
|
||||
// this.msgLiveData.value!!.attachment.remove(attachment)
|
||||
// } else {
|
||||
// attachment.pathUrl = audioUrl
|
||||
// }
|
||||
// hasAudio = true
|
||||
// }
|
||||
// }
|
||||
// if (!hasAudio&&audioUrl!=null) {
|
||||
// this.msgLiveData.value!!.attachment.add(Attachment(UUID.randomUUID().toString(), audioUrl, AttachmentType.AUDIO))
|
||||
// }
|
||||
this.msgLiveData.value?.mediaUrl = audioUrl
|
||||
this.msgLiveData.postValue(this.msgLiveData.value)
|
||||
}
|
||||
|
||||
@ -104,21 +102,59 @@ class ObtainMessageViewModel @Inject constructor() : ViewModel() {
|
||||
this.msgLiveData.postValue(this.msgLiveData.value)
|
||||
}
|
||||
|
||||
fun uploadAttachment(attachmentFile: File) {
|
||||
// // 获取照片url
|
||||
// fun getImageAttachment(attachementList: List<Attachment>): Attachment? {
|
||||
// for (attachment in attachementList) {
|
||||
// if (attachment.attachmentType == AttachmentType.PIC) {
|
||||
// return attachment
|
||||
// }
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
//
|
||||
// // 获取音频url
|
||||
// fun getAudioAttachment(attachementList: List<Attachment>): Attachment? {
|
||||
// for (attachment in attachementList) {
|
||||
// if (attachment.attachmentType == AttachmentType.AUDIO) {
|
||||
// return attachment
|
||||
// }
|
||||
// }
|
||||
// return null
|
||||
// }
|
||||
|
||||
// 上传附件文件
|
||||
fun uploadAttachment(attachmentFile: File, attachmentType: AttachmentType) {
|
||||
// 启用协程调用网络请求
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val requestFile: RequestBody =
|
||||
RequestBody.create("multipart/form-data".toMediaTypeOrNull(), attachmentFile)
|
||||
val body = MultipartBody.Part.createFormData(
|
||||
"picture",
|
||||
attachmentFile.getName(),
|
||||
requestFile
|
||||
)
|
||||
val body = MultipartBody.Part.createFormData("picture", attachmentFile.getName(), requestFile)
|
||||
val result = NavinfoVolvoCall.getApi().uploadAttachment(body)
|
||||
XLog.d(result.code)
|
||||
if (result.code == 200) { // 请求成功
|
||||
// 获取上传后的结果
|
||||
val fileKey = result.data?.get("fileKey")
|
||||
val newFileName = fileKey!!.substringAfterLast("/")
|
||||
// 修改缓存文件名
|
||||
if (attachmentType == AttachmentType.PIC) { // 修改当前文件在缓存文件夹的名称
|
||||
val destFile = File(SystemConstant.CameraFolder, newFileName)
|
||||
if (destFile.exists()) {
|
||||
FileUtils.deleteFile(destFile)
|
||||
}
|
||||
val copyResult = FileIOUtils.writeFileFromIS(destFile, FileInputStream(attachmentFile))
|
||||
XLog.e("拷贝结果:"+copyResult)
|
||||
} else {
|
||||
val destFile = File(SystemConstant.SoundFolder, newFileName)
|
||||
if (destFile.exists()) {
|
||||
FileUtils.deleteFile(destFile)
|
||||
}
|
||||
val copyResult = FileIOUtils.writeFileFromIS(destFile, FileInputStream(attachmentFile))
|
||||
XLog.e("拷贝结果:"+copyResult)
|
||||
}
|
||||
if (fileKey!=null) {
|
||||
downloadAttachment(fileKey, attachmentType)
|
||||
}
|
||||
} else {
|
||||
ToastUtils.showToast(result.msg)
|
||||
}
|
||||
@ -128,4 +164,139 @@ class ObtainMessageViewModel @Inject constructor() : ViewModel() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 下载附件文件
|
||||
fun downloadAttachment(fileKey: String, attachmentType: AttachmentType) {
|
||||
// 启用协程调用网络请求
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val downloadParam = mapOf("fileKey" to fileKey)
|
||||
val result = NavinfoVolvoCall.getApi().downLoadAttachment(downloadParam)
|
||||
XLog.d(result.code)
|
||||
if (result.code == 200) { // 请求成功
|
||||
// 获取上传后的结果
|
||||
val imageUrl = result.data
|
||||
if (imageUrl!=null) {
|
||||
XLog.d("downloadAttachment-imageUrl:${imageUrl}")
|
||||
// 获取到图片的网络地址
|
||||
if (attachmentType == AttachmentType.PIC) {
|
||||
updateMessagePic(imageUrl)
|
||||
} else {
|
||||
updateMessageAudio(imageUrl)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ToastUtils.showToast(result.msg)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ToastUtils.showToast(e.message)
|
||||
XLog.d(e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun downLoadFile(url: String, destFile: File, downloadCallback: DownloadCallback){
|
||||
viewModelScope.launch {
|
||||
DownloadManager.download(
|
||||
url,
|
||||
destFile
|
||||
).collect {
|
||||
when (it) {
|
||||
is DownloadState.InProgress -> {
|
||||
XLog.d("~~~", "download in progress: ${it.progress}.")
|
||||
downloadCallback.progress(it.progress)
|
||||
}
|
||||
is DownloadState.Success -> {
|
||||
XLog.d("~~~", "download finished.")
|
||||
downloadCallback.success(it.file)
|
||||
}
|
||||
is DownloadState.Error -> {
|
||||
XLog.d("~~~", "download error: ${it.throwable}.")
|
||||
downloadCallback.error(it.throwable)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun insertCardByApp() {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
// TODO 首先保存数据到本地
|
||||
val message = msgLiveData.value
|
||||
val insertData = mapOf(
|
||||
"name" to message?.name,
|
||||
"imageUrl" to message?.imageUrl,
|
||||
"mediaUrl" to message?.mediaUrl,
|
||||
"who" to message?.who,
|
||||
"toWho" to message?.toWho,
|
||||
"sendDate" to message?.sendDate
|
||||
)
|
||||
val result = NavinfoVolvoCall.getApi().insertCardByApp(insertData as Map<String, String>)
|
||||
XLog.d("insertCardByApp:${result.code}")
|
||||
if (result.code == 200) { // 请求成功
|
||||
// 获取上传后的结果
|
||||
val netId = result.data
|
||||
message?.id = netId!!.toLong()
|
||||
ToastUtils.showToast("保存成功")
|
||||
// TODO 尝试更新本地数据
|
||||
|
||||
} else {
|
||||
ToastUtils.showToast(result.msg)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ToastUtils.showToast(e.message)
|
||||
XLog.d(e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateCardByApp() {
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
val message = msgLiveData.value
|
||||
val updateData = mapOf(
|
||||
"id" to message?.id,
|
||||
"name" to message?.name,
|
||||
"imageUrl" to message?.imageUrl,
|
||||
"mediaUrl" to message?.mediaUrl,
|
||||
"who" to message?.who,
|
||||
"toWho" to message?.toWho,
|
||||
"sendDate" to message?.sendDate
|
||||
)
|
||||
val result = NavinfoVolvoCall.getApi().updateCardByApp(updateData as Map<String, String>)
|
||||
XLog.d("updateCardByApp:${result.code}")
|
||||
if (result.code == 200) { // 请求成功
|
||||
// 数据更新成功
|
||||
ToastUtils.showToast("更新成功")
|
||||
// 尝试保存数据到本地
|
||||
} else {
|
||||
ToastUtils.showToast(result.msg)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
ToastUtils.showToast(e.message)
|
||||
XLog.d(e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据网络地址获取本地的缓存文件路径
|
||||
* */
|
||||
fun getLocalFileFromNetUrl(url: String, attachmentType: AttachmentType):File {
|
||||
if (url.startsWith("http")) {
|
||||
val folder = when(attachmentType) {
|
||||
AttachmentType.PIC-> SystemConstant.CameraFolder
|
||||
else -> SystemConstant.SoundFolder
|
||||
}
|
||||
var name = if (url.contains("?")) {
|
||||
url.substring(url.lastIndexOf("/")+1, url.indexOf("?"))
|
||||
} else {
|
||||
url.substringAfterLast("/")
|
||||
}
|
||||
return File(folder, name)
|
||||
} else {
|
||||
return File(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
50
app/src/main/java/com/navinfo/volvo/util/PhotoLoader.java
Normal file
50
app/src/main/java/com/navinfo/volvo/util/PhotoLoader.java
Normal file
@ -0,0 +1,50 @@
|
||||
package com.navinfo.volvo.util;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.target.CustomViewTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
|
||||
import indi.liyi.viewer.ImageLoader;
|
||||
|
||||
public class PhotoLoader extends ImageLoader {
|
||||
@Override
|
||||
public void displayImage(final Object src, ImageView imageView, final LoadCallback callback) {
|
||||
Glide.with(imageView.getContext())
|
||||
.load(src)
|
||||
.into(new CustomViewTarget<ImageView, Drawable>(imageView) {
|
||||
|
||||
@Override
|
||||
protected void onResourceLoading(@Nullable Drawable placeholder) {
|
||||
super.onResourceLoading(placeholder);
|
||||
if(callback!=null){
|
||||
callback.onLoadStarted(placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
|
||||
if(callback!=null) {
|
||||
callback.onLoadSucceed(resource);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFailed(@Nullable Drawable errorDrawable) {
|
||||
if(callback!=null) {
|
||||
callback.onLoadFailed(errorDrawable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResourceCleared(@Nullable Drawable placeholder) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -103,7 +103,7 @@ class EasyMediaFile {
|
||||
fun selectAudio(activity: Activity) {
|
||||
isCrop = false
|
||||
val intent = Intent(Intent.ACTION_PICK, null).apply {
|
||||
setDataAndType(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, "audio/*")
|
||||
setDataAndType(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, "*/*")
|
||||
}
|
||||
if (Looper.myLooper() == Looper.getMainLooper()) {
|
||||
selectFileInternal(intent, activity, 1)
|
||||
@ -131,7 +131,7 @@ class EasyMediaFile {
|
||||
* 选择文件
|
||||
*/
|
||||
private fun selectFileInternal(intent: Intent, activity: Activity, type: Int) {
|
||||
val resolveInfoList = activity.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
|
||||
var resolveInfoList = activity.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
|
||||
if (resolveInfoList.isEmpty()) {
|
||||
error?.invoke(IllegalStateException("No Activity found to handle Intent "))
|
||||
} else {
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
app:counterEnabled="true"
|
||||
app:counterMaxLength="10"
|
||||
app:errorEnabled="true"
|
||||
android:hint="请输入问候信息"
|
||||
android:hint="问候信息"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
@ -121,9 +121,11 @@
|
||||
android:orientation="horizontal">
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/tv_photo_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:textColor="@android:color/holo_blue_dark"
|
||||
android:padding="@dimen/default_widget_padding"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""></com.google.android.material.textview.MaterialTextView>
|
||||
android:layout_weight="1"></com.google.android.material.textview.MaterialTextView>
|
||||
<Space
|
||||
android:layout_width="@dimen/default_widget_padding"
|
||||
android:layout_height="wrap_content"></Space>
|
||||
@ -147,7 +149,6 @@
|
||||
|
||||
<com.nhaarman.supertooltips.ToolTipRelativeLayout
|
||||
android:id="@+id/tt_pic"
|
||||
app:layout_constraintTop_toBottomOf="@id/ti_layout_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
@ -156,6 +157,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginVertical="@dimen/default_widget_padding"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
@ -180,7 +182,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Widget.Material3.Button.ElevatedButton"
|
||||
app:icon="@drawable/ic_baseline_fiber_manual_record_24"
|
||||
android:text="录制音频"
|
||||
android:text="长按录音"
|
||||
android:padding="@dimen/default_widget_padding"></com.google.android.material.button.MaterialButton>
|
||||
<Space
|
||||
android:layout_width="@dimen/default_widget_padding"
|
||||
@ -204,8 +206,11 @@
|
||||
android:orientation="horizontal">
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/tv_audio_name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@android:color/holo_blue_dark"
|
||||
android:padding="@dimen/default_widget_padding"
|
||||
android:layout_weight="1"
|
||||
android:text=""></com.google.android.material.textview.MaterialTextView>
|
||||
<Space
|
||||
android:layout_width="@dimen/default_widget_padding"
|
||||
@ -219,16 +224,36 @@
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/img_sound_play"
|
||||
android:layout_width="wrap_content"
|
||||
<!--增加音频播放按钮-->
|
||||
<LinearLayout
|
||||
android:id="@+id/ll_audio_play"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_baseline_volume_up_24"
|
||||
android:layout_gravity="center"
|
||||
android:visibility="gone"
|
||||
android:layout_gravity="center"></com.google.android.material.imageview.ShapeableImageView>
|
||||
android:orientation="horizontal">
|
||||
<me.jagar.chatvoiceplayerlibrary.VoicePlayerView
|
||||
android:id="@+id/voicePlayerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:enableVisualizer="true"
|
||||
app:visualizationPlayedColor="@color/teal_200"
|
||||
app:visualizationNotPlayedColor="@color/teal_700"
|
||||
app:playPauseBackgroundColor="@color/teal_700"
|
||||
app:timingBackgroundColor="@color/purple_200"
|
||||
app:seekBarProgressColor="@color/purple_500"
|
||||
app:showShareButton="false"
|
||||
app:shareCornerRadius="100"
|
||||
app:playPauseCornerRadius="100"
|
||||
app:showTiming="true"
|
||||
app:viewCornerRadius="100"
|
||||
app:viewBackground="@android:color/transparent"
|
||||
app:progressTimeColor="@color/purple_500"
|
||||
app:seekBarThumbColor="@color/teal_200"/>
|
||||
</LinearLayout>
|
||||
|
||||
<com.nhaarman.supertooltips.ToolTipRelativeLayout
|
||||
android:id="@+id/tt_audio"
|
||||
app:layout_constraintTop_toBottomOf="@id/ti_layout_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
@ -283,7 +308,6 @@
|
||||
|
||||
<com.nhaarman.supertooltips.ToolTipRelativeLayout
|
||||
android:id="@+id/tt_send_from"
|
||||
app:layout_constraintTop_toBottomOf="@id/ti_layout_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
@ -379,4 +403,11 @@
|
||||
android:layout_weight="1"
|
||||
android:text="确认提交"></com.google.android.material.button.MaterialButton>
|
||||
</LinearLayout>
|
||||
|
||||
<indi.liyi.viewer.ImageViewer
|
||||
android:id="@+id/imageViewer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/transparent"
|
||||
app:ivr_dragMode="agile" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
Loading…
x
Reference in New Issue
Block a user