新增图片发送
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
package com.aiosman.riderpro.ui.chat
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
@@ -29,6 +34,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -66,6 +72,7 @@ import com.aiosman.riderpro.exp.formatChatTime
|
||||
import com.aiosman.riderpro.ui.composables.CustomAsyncImage
|
||||
import com.aiosman.riderpro.ui.composables.StatusBarSpacer
|
||||
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
||||
import com.tencent.imsdk.v2.V2TIMMessage
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
||||
@@ -158,7 +165,13 @@ fun ChatScreen(userId: String) {
|
||||
.background(Color(0xfff7f7f7))
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
ChatInput() {
|
||||
ChatInput(
|
||||
onSendImage = {
|
||||
it?.let {
|
||||
viewModel.sendImageMessage(it, context)
|
||||
}
|
||||
},
|
||||
) {
|
||||
viewModel.sendMessage(it, context)
|
||||
}
|
||||
}
|
||||
@@ -230,17 +243,35 @@ fun ChatSelfItem(item: ChatItem) {
|
||||
.padding(vertical = 8.dp, horizontal = 16.dp)
|
||||
.padding(bottom = 3.dp)
|
||||
) {
|
||||
when (item.messageType) {
|
||||
V2TIMMessage.V2TIM_ELEM_TYPE_TEXT -> {
|
||||
Text(
|
||||
text = item.message,
|
||||
style = TextStyle(
|
||||
color = Color.White,
|
||||
fontSize = 16.sp,
|
||||
),
|
||||
textAlign = TextAlign.Start,
|
||||
|
||||
textAlign = TextAlign.Start
|
||||
)
|
||||
}
|
||||
|
||||
V2TIMMessage.V2TIM_ELEM_TYPE_IMAGE -> {
|
||||
CustomAsyncImage(
|
||||
imageUrl = item.imageList[1].url,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentDescription = "image"
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
Text(
|
||||
text = "Unsupported message type",
|
||||
style = TextStyle(
|
||||
color = Color.White,
|
||||
fontSize = 16.sp,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
Box(
|
||||
@@ -308,14 +339,35 @@ fun ChatOtherItem(item: ChatItem) {
|
||||
.padding(vertical = 8.dp, horizontal = 16.dp)
|
||||
.padding(bottom = 3.dp)
|
||||
) {
|
||||
when (item.messageType) {
|
||||
V2TIMMessage.V2TIM_ELEM_TYPE_TEXT -> {
|
||||
Text(
|
||||
text = item.message,
|
||||
style = TextStyle(
|
||||
color = Color.Black,
|
||||
fontSize = 16.sp
|
||||
fontSize = 16.sp,
|
||||
),
|
||||
textAlign = TextAlign.Start
|
||||
)
|
||||
}
|
||||
V2TIMMessage.V2TIM_ELEM_TYPE_IMAGE -> {
|
||||
CustomAsyncImage(
|
||||
imageUrl = item.imageList[1].url,
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentDescription = "image"
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
Text(
|
||||
text = "Unsupported message type",
|
||||
style = TextStyle(
|
||||
color = Color.White,
|
||||
fontSize = 16.sp,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -335,7 +387,8 @@ fun ChatItem(item: ChatItem, currentUserId: String) {
|
||||
|
||||
@Composable
|
||||
fun ChatInput(
|
||||
onSend: (String) -> Unit = {}
|
||||
onSendImage: (Uri?) -> Unit = {},
|
||||
onSend: (String) -> Unit = {},
|
||||
) {
|
||||
val navigationBarHeight = with(LocalDensity.current) {
|
||||
WindowInsets.navigationBars.getBottom(this).toDp()
|
||||
@@ -367,6 +420,15 @@ fun ChatInput(
|
||||
}
|
||||
}
|
||||
|
||||
val imagePickUpLauncher = rememberLauncherForActivityResult(
|
||||
contract = ActivityResultContracts.StartActivityForResult()
|
||||
) {
|
||||
if (it.resultCode == Activity.RESULT_OK) {
|
||||
val uri = it.data?.data
|
||||
onSendImage(uri)
|
||||
}
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@@ -413,6 +475,24 @@ fun ChatInput(
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.rider_pro_images),
|
||||
contentDescription = "Emoji",
|
||||
modifier = Modifier
|
||||
.size(32.dp)
|
||||
.noRippleClickable {
|
||||
imagePickUpLauncher.launch(
|
||||
Intent.createChooser(
|
||||
Intent(Intent.ACTION_GET_CONTENT).apply {
|
||||
type = "image/*"
|
||||
},
|
||||
"Select Image"
|
||||
)
|
||||
)
|
||||
},
|
||||
tint = Color(0xff000000)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Crossfade(targetState = text.isNotEmpty(), animationSpec = tween(500)) { isNotEmpty ->
|
||||
Image(
|
||||
painter = rememberUpdatedState(
|
||||
|
||||
@@ -2,7 +2,10 @@ package com.aiosman.riderpro.ui.chat
|
||||
|
||||
import android.content.Context
|
||||
import android.icu.util.Calendar
|
||||
import android.net.Uri
|
||||
import android.provider.MediaStore
|
||||
import android.util.Log
|
||||
import android.webkit.MimeTypeMap
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
@@ -16,11 +19,15 @@ import com.aiosman.riderpro.entity.AccountProfileEntity
|
||||
import com.aiosman.riderpro.exp.formatChatTime
|
||||
import com.tencent.imsdk.v2.V2TIMAdvancedMsgListener
|
||||
import com.tencent.imsdk.v2.V2TIMCallback
|
||||
import com.tencent.imsdk.v2.V2TIMImageElem
|
||||
import com.tencent.imsdk.v2.V2TIMManager
|
||||
import com.tencent.imsdk.v2.V2TIMMessage
|
||||
import com.tencent.imsdk.v2.V2TIMSendCallback
|
||||
import com.tencent.imsdk.v2.V2TIMValueCallback
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
|
||||
|
||||
data class ChatItem(
|
||||
@@ -30,7 +37,10 @@ data class ChatItem(
|
||||
val userId: String,
|
||||
val nickname: String,
|
||||
val timeCategory: String = "",
|
||||
val timestamp: Long = 0
|
||||
val timestamp: Long = 0,
|
||||
val imageList: MutableList<V2TIMImageElem.V2TIMImage> = emptyList<V2TIMImageElem.V2TIMImage>().toMutableList(),
|
||||
val messageType : Int = 0,
|
||||
val textDisplay : String = ""
|
||||
)
|
||||
|
||||
class ChatViewModel(
|
||||
@@ -44,7 +54,7 @@ class ChatViewModel(
|
||||
var textMessageListener: V2TIMAdvancedMsgListener? = null
|
||||
var hasMore by mutableStateOf(true)
|
||||
var isLoading by mutableStateOf(false)
|
||||
var lastMessage : V2TIMMessage? = null
|
||||
var lastMessage: V2TIMMessage? = null
|
||||
fun init(context: Context) {
|
||||
// 获取用户信息
|
||||
viewModelScope.launch {
|
||||
@@ -61,7 +71,12 @@ class ChatViewModel(
|
||||
textMessageListener = object : V2TIMAdvancedMsgListener() {
|
||||
override fun onRecvNewMessage(msg: V2TIMMessage?) {
|
||||
super.onRecvNewMessage(msg)
|
||||
chatData = listOf(convertToChatItem(msg!!, context)) + chatData
|
||||
msg?.let {
|
||||
val chatItem = convertToChatItem(msg, context)
|
||||
chatItem?.let {
|
||||
chatData = listOf(it) + chatData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
V2TIMManager.getMessageManager().addAdvancedMsgListener(textMessageListener);
|
||||
@@ -70,7 +85,8 @@ class ChatViewModel(
|
||||
fun UnRegistListener() {
|
||||
V2TIMManager.getMessageManager().removeAdvancedMsgListener(textMessageListener);
|
||||
}
|
||||
fun clearUnRead(){
|
||||
|
||||
fun clearUnRead() {
|
||||
val conversationID = "c2c_${userProfile?.trtcUserId}"
|
||||
V2TIMManager.getConversationManager()
|
||||
.cleanConversationUnreadMessageCount(conversationID, 0, 0, object : V2TIMCallback {
|
||||
@@ -83,7 +99,8 @@ class ChatViewModel(
|
||||
}
|
||||
})
|
||||
}
|
||||
fun convertToChatItem(message: V2TIMMessage, context: Context): ChatItem {
|
||||
|
||||
fun convertToChatItem(message: V2TIMMessage, context: Context): ChatItem? {
|
||||
val avatar = if (message.sender == userProfile?.trtcUserId) {
|
||||
userProfile?.avatar ?: ""
|
||||
} else {
|
||||
@@ -97,16 +114,51 @@ class ChatViewModel(
|
||||
val timestamp = message.timestamp
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = timestamp * 1000
|
||||
|
||||
val imageElm = message.imageElem?.imageList
|
||||
when (message.elemType) {
|
||||
V2TIMMessage.V2TIM_ELEM_TYPE_IMAGE -> {
|
||||
val imageElm = message.imageElem?.imageList?.all {
|
||||
it.size == 0
|
||||
}
|
||||
if (imageElm != true) {
|
||||
return ChatItem(
|
||||
message = message.textElem.text,
|
||||
message = "Image",
|
||||
avatar = avatar,
|
||||
time = calendar.time.formatChatTime(context),
|
||||
userId = message.sender,
|
||||
nickname = nickname,
|
||||
timestamp = timestamp * 1000
|
||||
timestamp = timestamp * 1000,
|
||||
imageList = message.imageElem?.imageList
|
||||
?: emptyList<V2TIMImageElem.V2TIMImage>().toMutableList(),
|
||||
messageType = V2TIMMessage.V2TIM_ELEM_TYPE_IMAGE,
|
||||
textDisplay = "Image"
|
||||
)
|
||||
}
|
||||
return null
|
||||
|
||||
}
|
||||
|
||||
V2TIMMessage.V2TIM_ELEM_TYPE_TEXT -> {
|
||||
return ChatItem(
|
||||
message = message.textElem?.text ?: "Unsupported message type",
|
||||
avatar = avatar,
|
||||
time = calendar.time.formatChatTime(context),
|
||||
userId = message.sender,
|
||||
nickname = nickname,
|
||||
timestamp = timestamp * 1000,
|
||||
imageList = imageElm?.toMutableList()
|
||||
?: emptyList<V2TIMImageElem.V2TIMImage>().toMutableList(),
|
||||
messageType = V2TIMMessage.V2TIM_ELEM_TYPE_TEXT,
|
||||
textDisplay = message.textElem?.text ?: "Unsupported message type"
|
||||
)
|
||||
|
||||
}
|
||||
else -> {
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun onLoadMore(context: Context) {
|
||||
if (!hasMore || isLoading) {
|
||||
@@ -122,7 +174,7 @@ class ChatViewModel(
|
||||
override fun onSuccess(p0: List<V2TIMMessage>?) {
|
||||
chatData = chatData + (p0 ?: emptyList()).map {
|
||||
convertToChatItem(it, context)
|
||||
}
|
||||
}.filterNotNull()
|
||||
if ((p0?.size ?: 0) < 20) {
|
||||
hasMore = false
|
||||
}
|
||||
@@ -130,6 +182,7 @@ class ChatViewModel(
|
||||
isLoading = false
|
||||
Log.d("ChatViewModel", "fetch history message success")
|
||||
}
|
||||
|
||||
override fun onError(p0: Int, p1: String?) {
|
||||
Log.e("ChatViewModel", "fetch history message error: $p1")
|
||||
isLoading = false
|
||||
@@ -147,18 +200,85 @@ class ChatViewModel(
|
||||
override fun onProgress(p0: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onError(p0: Int, p1: String?) {
|
||||
Log.e("ChatViewModel", "send message error: $p1")
|
||||
}
|
||||
|
||||
override fun onSuccess(p0: V2TIMMessage?) {
|
||||
Log.d("ChatViewModel", "send message success")
|
||||
chatData = listOf(convertToChatItem(p0!!, context)) + chatData
|
||||
val chatItem = convertToChatItem(p0!!, context)
|
||||
chatItem?.let {
|
||||
chatData = listOf(it) + chatData
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun sendImageMessage(imageUri:Uri, context: Context) {
|
||||
val tempFile = createTempFile(context, imageUri)
|
||||
val imagePath = tempFile?.path
|
||||
if (imagePath != null) {
|
||||
val v2TIMMessage = V2TIMManager.getMessageManager().createImageMessage(imagePath)
|
||||
V2TIMManager.getMessageManager().sendMessage(
|
||||
v2TIMMessage,
|
||||
userProfile?.trtcUserId!!,
|
||||
null,
|
||||
V2TIMMessage.V2TIM_PRIORITY_NORMAL,
|
||||
false,
|
||||
null,
|
||||
object : V2TIMSendCallback<V2TIMMessage> {
|
||||
override fun onProgress(p0: Int) {
|
||||
Log.d("ChatViewModel", "send image message progress: $p0")
|
||||
}
|
||||
|
||||
override fun onError(p0: Int, p1: String?) {
|
||||
Log.e("ChatViewModel", "send image message error: $p1")
|
||||
}
|
||||
|
||||
override fun onSuccess(p0: V2TIMMessage?) {
|
||||
Log.d("ChatViewModel", "send image message success")
|
||||
val chatItem = convertToChatItem(p0!!, context)
|
||||
chatItem?.let {
|
||||
chatData = listOf(it) + chatData
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
fun createTempFile(context: Context, uri: Uri): File? {
|
||||
return try {
|
||||
val projection = arrayOf(MediaStore.Images.Media.DATA)
|
||||
val cursor = context.contentResolver.query(uri, projection, null, null, null)
|
||||
cursor?.use {
|
||||
if (it.moveToFirst()) {
|
||||
val columnIndex = it.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
|
||||
val filePath = it.getString(columnIndex)
|
||||
val inputStream: InputStream? = context.contentResolver.openInputStream(uri)
|
||||
val mimeType = context.contentResolver.getType(uri)
|
||||
val extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType)
|
||||
val tempFile = File.createTempFile("temp_image", ".$extension", context.cacheDir)
|
||||
val outputStream = FileOutputStream(tempFile)
|
||||
|
||||
inputStream?.use { input ->
|
||||
outputStream.use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
}
|
||||
tempFile
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun fetchHistoryMessage(context: Context) {
|
||||
V2TIMManager.getMessageManager().getC2CHistoryMessageList(
|
||||
userProfile?.trtcUserId!!,
|
||||
@@ -168,7 +288,7 @@ class ChatViewModel(
|
||||
override fun onSuccess(p0: List<V2TIMMessage>?) {
|
||||
chatData = (p0 ?: emptyList()).map {
|
||||
convertToChatItem(it, context)
|
||||
}
|
||||
}.filterNotNull()
|
||||
if ((p0?.size ?: 0) < 20) {
|
||||
hasMore = false
|
||||
}
|
||||
@@ -182,6 +302,7 @@ class ChatViewModel(
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun getDisplayChatList(): List<ChatItem> {
|
||||
return chatData
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -21,7 +20,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -46,7 +44,7 @@ import com.aiosman.riderpro.ui.composables.CustomAsyncImage
|
||||
import com.aiosman.riderpro.ui.composables.StatusBarMaskLayout
|
||||
import com.aiosman.riderpro.ui.imageviewer.ImageViewerViewModel
|
||||
import com.aiosman.riderpro.ui.modifiers.noRippleClickable
|
||||
import com.aiosman.riderpro.utils.File.saveImageToGallery
|
||||
import com.aiosman.riderpro.utils.FileUtil.saveImageToGallery
|
||||
import kotlinx.coroutines.launch
|
||||
import net.engawapg.lib.zoomable.rememberZoomState
|
||||
import net.engawapg.lib.zoomable.zoomable
|
||||
|
||||
@@ -304,7 +304,7 @@ fun ChatMessageList(
|
||||
Spacer(modifier = Modifier.height(6.dp))
|
||||
Row {
|
||||
Text(
|
||||
text = item.lastMessage,
|
||||
text = "${if (item.isSelf) "Me: " else ""}${item.displayText}",
|
||||
fontSize = 14.sp,
|
||||
maxLines = 1,
|
||||
color = Color(0x99000000),
|
||||
|
||||
@@ -9,32 +9,25 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.paging.Pager
|
||||
import androidx.paging.PagingConfig
|
||||
import androidx.paging.PagingData
|
||||
import androidx.paging.cachedIn
|
||||
import androidx.paging.map
|
||||
import com.aiosman.riderpro.data.AccountNotice
|
||||
import com.aiosman.riderpro.data.AccountService
|
||||
import com.aiosman.riderpro.entity.CommentEntity
|
||||
import com.aiosman.riderpro.entity.CommentPagingSource
|
||||
import com.aiosman.riderpro.data.CommentRemoteDataSource
|
||||
import com.aiosman.riderpro.data.CommentService
|
||||
import com.aiosman.riderpro.data.AccountServiceImpl
|
||||
import com.aiosman.riderpro.data.CommentServiceImpl
|
||||
import com.aiosman.riderpro.data.UserService
|
||||
import com.aiosman.riderpro.data.UserServiceImpl
|
||||
import com.aiosman.riderpro.exp.formatChatTime
|
||||
import com.aiosman.riderpro.ui.NavigationRoute
|
||||
import com.aiosman.riderpro.ui.index.tabs.profile.MyProfileViewModel
|
||||
import com.aiosman.riderpro.ui.navigateToChat
|
||||
import com.aiosman.riderpro.utils.TrtcHelper
|
||||
import com.tencent.imsdk.v2.V2TIMConversation
|
||||
import com.tencent.imsdk.v2.V2TIMConversationResult
|
||||
import com.tencent.imsdk.v2.V2TIMManager
|
||||
import com.tencent.imsdk.v2.V2TIMMessage
|
||||
import com.tencent.imsdk.v2.V2TIMValueCallback
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
@@ -44,7 +37,9 @@ data class Conversation(
|
||||
val lastMessage: String,
|
||||
val lastMessageTime: String,
|
||||
val avatar: String = "",
|
||||
val unreadCount: Int = 0
|
||||
val unreadCount: Int = 0,
|
||||
val displayText: String,
|
||||
val isSelf: Boolean
|
||||
)
|
||||
|
||||
object MessageListViewModel : ViewModel() {
|
||||
@@ -142,13 +137,24 @@ object MessageListViewModel : ViewModel() {
|
||||
timeInMillis = msg.lastMessage?.timestamp ?: 0
|
||||
timeInMillis *= 1000
|
||||
}
|
||||
var displayText = ""
|
||||
when (msg.lastMessage?.elemType) {
|
||||
V2TIMMessage.V2TIM_ELEM_TYPE_TEXT -> {
|
||||
displayText = msg.lastMessage?.textElem?.text ?: ""
|
||||
}
|
||||
V2TIMMessage.V2TIM_ELEM_TYPE_IMAGE -> {
|
||||
displayText = "[图片]"
|
||||
}
|
||||
}
|
||||
Conversation(
|
||||
nickname = msg.showName,
|
||||
lastMessage = msg.lastMessage?.textElem?.text ?: "",
|
||||
lastMessageTime = lastMessage.time.formatChatTime(context),
|
||||
avatar = msg.faceUrl,
|
||||
unreadCount = msg.unreadCount,
|
||||
trtcUserId = msg.userID
|
||||
trtcUserId = msg.userID,
|
||||
displayText = displayText,
|
||||
isSelf = msg.lastMessage.sender == MyProfileViewModel.profile?.trtcUserId
|
||||
)
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.aiosman.riderpro.utils
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.net.Uri
|
||||
@@ -9,7 +10,6 @@ import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import android.widget.Toast
|
||||
import coil.ImageLoader
|
||||
import coil.request.ImageRequest
|
||||
import coil.request.SuccessResult
|
||||
import com.aiosman.riderpro.utils.Utils.getImageLoader
|
||||
@@ -18,7 +18,7 @@ import kotlinx.coroutines.withContext
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.OutputStream
|
||||
|
||||
object File {
|
||||
object FileUtil {
|
||||
suspend fun saveImageToGallery(context: Context, url: String) {
|
||||
val loader = getImageLoader(context)
|
||||
|
||||
@@ -89,4 +89,17 @@ object File {
|
||||
}
|
||||
}
|
||||
|
||||
fun getRealPathFromUri(context: Context, uri: Uri): String? {
|
||||
var realPath: String? = null
|
||||
val projection = arrayOf(MediaStore.Images.Media.DATA)
|
||||
val cursor: Cursor? = context.contentResolver.query(uri, projection, null, null, null)
|
||||
cursor?.use {
|
||||
if (it.moveToFirst()) {
|
||||
val columnIndex = it.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
|
||||
realPath = it.getString(columnIndex)
|
||||
}
|
||||
}
|
||||
return realPath
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user