mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-18 13:00:18 +03:00
Remove usage of GlobalScope
This commit is contained in:
parent
1f7482922d
commit
535d266cc2
3 changed files with 101 additions and 88 deletions
|
@ -43,8 +43,7 @@ import im.vector.app.R
|
||||||
import im.vector.app.features.notifications.NotificationUtils
|
import im.vector.app.features.notifications.NotificationUtils
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
import okio.sink
|
import okio.sink
|
||||||
import okio.source
|
import okio.source
|
||||||
|
@ -57,6 +56,7 @@ import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
|
import java.lang.IllegalStateException
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
@ -344,90 +344,93 @@ private fun appendTimeToFilename(name: String): String {
|
||||||
return """${filename}_$dateExtension.$fileExtension"""
|
return """${filename}_$dateExtension.$fileExtension"""
|
||||||
}
|
}
|
||||||
|
|
||||||
fun saveMedia(context: Context, file: File, title: String, mediaMimeType: String?, notificationUtils: NotificationUtils) {
|
suspend fun saveMedia(context: Context, file: File, title: String, mediaMimeType: String?, notificationUtils: NotificationUtils) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
withContext(Dispatchers.IO) {
|
||||||
val filename = appendTimeToFilename(title)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
val filename = appendTimeToFilename(title)
|
||||||
|
|
||||||
val values = ContentValues().apply {
|
val values = ContentValues().apply {
|
||||||
put(MediaStore.Images.Media.TITLE, filename)
|
put(MediaStore.Images.Media.TITLE, filename)
|
||||||
put(MediaStore.Images.Media.DISPLAY_NAME, filename)
|
put(MediaStore.Images.Media.DISPLAY_NAME, filename)
|
||||||
put(MediaStore.Images.Media.MIME_TYPE, mediaMimeType)
|
put(MediaStore.Images.Media.MIME_TYPE, mediaMimeType)
|
||||||
put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis())
|
put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis())
|
||||||
put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
|
put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis())
|
||||||
}
|
}
|
||||||
val externalContentUri = when {
|
val externalContentUri = when {
|
||||||
mediaMimeType?.isMimeTypeImage() == true -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
mediaMimeType?.isMimeTypeImage() == true -> MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||||
mediaMimeType?.isMimeTypeVideo() == true -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
mediaMimeType?.isMimeTypeVideo() == true -> MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
||||||
mediaMimeType?.isMimeTypeAudio() == true -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
|
mediaMimeType?.isMimeTypeAudio() == true -> MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
|
||||||
else -> MediaStore.Downloads.EXTERNAL_CONTENT_URI
|
else -> MediaStore.Downloads.EXTERNAL_CONTENT_URI
|
||||||
}
|
}
|
||||||
|
|
||||||
val uri = context.contentResolver.insert(externalContentUri, values)
|
val uri = context.contentResolver.insert(externalContentUri, values)
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
Toast.makeText(context, R.string.error_saving_media_file, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, R.string.error_saving_media_file, Toast.LENGTH_LONG).show()
|
||||||
} else {
|
throw IllegalStateException(context.getString(R.string.error_saving_media_file))
|
||||||
val source = file.inputStream().source().buffer()
|
} else {
|
||||||
context.contentResolver.openOutputStream(uri)?.sink()?.buffer()?.let { sink ->
|
val source = file.inputStream().source().buffer()
|
||||||
source.use { input ->
|
context.contentResolver.openOutputStream(uri)?.sink()?.buffer()?.let { sink ->
|
||||||
sink.use { output ->
|
source.use { input ->
|
||||||
output.writeAll(input)
|
sink.use { output ->
|
||||||
|
output.writeAll(input)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
notificationUtils.buildDownloadFileNotification(
|
||||||
|
uri,
|
||||||
|
filename,
|
||||||
|
mediaMimeType ?: MimeTypes.OctetStream
|
||||||
|
).let { notification ->
|
||||||
|
notificationUtils.showNotificationMessage("DL", uri.hashCode(), notification)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
notificationUtils.buildDownloadFileNotification(
|
} else {
|
||||||
uri,
|
saveMediaLegacy(context, mediaMimeType, title, file)
|
||||||
filename,
|
|
||||||
mediaMimeType ?: MimeTypes.OctetStream
|
|
||||||
).let { notification ->
|
|
||||||
notificationUtils.showNotificationMessage("DL", uri.hashCode(), notification)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
saveMediaLegacy(context, mediaMimeType, title, file)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("DEPRECATION")
|
@Suppress("DEPRECATION")
|
||||||
private fun saveMediaLegacy(context: Context, mediaMimeType: String?, title: String, file: File) {
|
private fun saveMediaLegacy(context: Context,
|
||||||
|
mediaMimeType: String?,
|
||||||
|
title: String,
|
||||||
|
file: File) {
|
||||||
val state = Environment.getExternalStorageState()
|
val state = Environment.getExternalStorageState()
|
||||||
if (Environment.MEDIA_MOUNTED != state) {
|
if (Environment.MEDIA_MOUNTED != state) {
|
||||||
context.toast(context.getString(R.string.error_saving_media_file))
|
context.toast(context.getString(R.string.error_saving_media_file))
|
||||||
return
|
throw IllegalStateException(context.getString(R.string.error_saving_media_file))
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
val dest = when {
|
||||||
val dest = when {
|
mediaMimeType?.isMimeTypeImage() == true -> Environment.DIRECTORY_PICTURES
|
||||||
mediaMimeType?.isMimeTypeImage() == true -> Environment.DIRECTORY_PICTURES
|
mediaMimeType?.isMimeTypeVideo() == true -> Environment.DIRECTORY_MOVIES
|
||||||
mediaMimeType?.isMimeTypeVideo() == true -> Environment.DIRECTORY_MOVIES
|
mediaMimeType?.isMimeTypeAudio() == true -> Environment.DIRECTORY_MUSIC
|
||||||
mediaMimeType?.isMimeTypeAudio() == true -> Environment.DIRECTORY_MUSIC
|
else -> Environment.DIRECTORY_DOWNLOADS
|
||||||
else -> Environment.DIRECTORY_DOWNLOADS
|
}
|
||||||
|
val downloadDir = Environment.getExternalStoragePublicDirectory(dest)
|
||||||
|
try {
|
||||||
|
val outputFilename = if (title.substringAfterLast('.', "").isEmpty()) {
|
||||||
|
val extension = mediaMimeType?.let { MimeTypeMap.getSingleton().getExtensionFromMimeType(it) }
|
||||||
|
"$title.$extension"
|
||||||
|
} else {
|
||||||
|
title
|
||||||
}
|
}
|
||||||
val downloadDir = Environment.getExternalStoragePublicDirectory(dest)
|
val savedFile = saveFileIntoLegacy(file, downloadDir, outputFilename)
|
||||||
try {
|
if (savedFile != null) {
|
||||||
val outputFilename = if (title.substringAfterLast('.', "").isEmpty()) {
|
val downloadManager = context.getSystemService<DownloadManager>()
|
||||||
val extension = mediaMimeType?.let { MimeTypeMap.getSingleton().getExtensionFromMimeType(it) }
|
downloadManager?.addCompletedDownload(
|
||||||
"$title.$extension"
|
savedFile.name,
|
||||||
} else {
|
title,
|
||||||
title
|
true,
|
||||||
}
|
mediaMimeType ?: MimeTypes.OctetStream,
|
||||||
val savedFile = saveFileIntoLegacy(file, downloadDir, outputFilename)
|
savedFile.absolutePath,
|
||||||
if (savedFile != null) {
|
savedFile.length(),
|
||||||
val downloadManager = context.getSystemService<DownloadManager>()
|
true)
|
||||||
downloadManager?.addCompletedDownload(
|
addToGallery(savedFile, mediaMimeType, context)
|
||||||
savedFile.name,
|
|
||||||
title,
|
|
||||||
true,
|
|
||||||
mediaMimeType ?: MimeTypes.OctetStream,
|
|
||||||
savedFile.absolutePath,
|
|
||||||
savedFile.length(),
|
|
||||||
true)
|
|
||||||
addToGallery(savedFile, mediaMimeType, context)
|
|
||||||
}
|
|
||||||
} catch (error: Throwable) {
|
|
||||||
GlobalScope.launch(Dispatchers.Main) {
|
|
||||||
context.toast(context.getString(R.string.error_saving_media_file))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} catch (error: Throwable) {
|
||||||
|
context.toast(context.getString(R.string.error_saving_media_file))
|
||||||
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1745,20 +1745,19 @@ class RoomDetailFragment @Inject constructor(
|
||||||
session.coroutineScope.launch {
|
session.coroutineScope.launch {
|
||||||
val result = runCatching { session.fileService().downloadFile(messageContent = action.messageContent) }
|
val result = runCatching { session.fileService().downloadFile(messageContent = action.messageContent) }
|
||||||
if (!isAdded) return@launch
|
if (!isAdded) return@launch
|
||||||
result.fold(
|
result.mapCatching {
|
||||||
{
|
saveMedia(
|
||||||
saveMedia(
|
context = requireContext(),
|
||||||
context = requireContext(),
|
file = it,
|
||||||
file = it,
|
title = action.messageContent.body,
|
||||||
title = action.messageContent.body,
|
mediaMimeType = action.messageContent.mimeType ?: getMimeTypeFromUri(requireContext(), it.toUri()),
|
||||||
mediaMimeType = action.messageContent.mimeType ?: getMimeTypeFromUri(requireContext(), it.toUri()),
|
notificationUtils = notificationUtils
|
||||||
notificationUtils = notificationUtils
|
)
|
||||||
)
|
}
|
||||||
},
|
.onFailure {
|
||||||
{
|
if (!isAdded) return@onFailure
|
||||||
showErrorInSnackbar(it)
|
showErrorInSnackbar(it)
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.airbnb.mvrx.args
|
import com.airbnb.mvrx.args
|
||||||
import com.airbnb.mvrx.fragmentViewModel
|
import com.airbnb.mvrx.fragmentViewModel
|
||||||
import com.airbnb.mvrx.withState
|
import com.airbnb.mvrx.withState
|
||||||
|
@ -36,6 +37,7 @@ import im.vector.app.databinding.FragmentRoomUploadsBinding
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
import im.vector.app.features.home.AvatarRenderer
|
||||||
import im.vector.app.features.notifications.NotificationUtils
|
import im.vector.app.features.notifications.NotificationUtils
|
||||||
import im.vector.app.features.roomprofile.RoomProfileArgs
|
import im.vector.app.features.roomprofile.RoomProfileArgs
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
import org.matrix.android.sdk.api.util.toMatrixItem
|
import org.matrix.android.sdk.api.util.toMatrixItem
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -76,13 +78,22 @@ class RoomUploadsFragment @Inject constructor(
|
||||||
shareMedia(requireContext(), it.file, getMimeTypeFromUri(requireContext(), it.file.toUri()))
|
shareMedia(requireContext(), it.file, getMimeTypeFromUri(requireContext(), it.file.toUri()))
|
||||||
}
|
}
|
||||||
is RoomUploadsViewEvents.FileReadyForSaving -> {
|
is RoomUploadsViewEvents.FileReadyForSaving -> {
|
||||||
saveMedia(
|
lifecycleScope.launch {
|
||||||
context = requireContext(),
|
runCatching {
|
||||||
file = it.file,
|
saveMedia(
|
||||||
title = it.title,
|
context = requireContext(),
|
||||||
mediaMimeType = getMimeTypeFromUri(requireContext(), it.file.toUri()),
|
file = it.file,
|
||||||
notificationUtils = notificationUtils
|
title = it.title,
|
||||||
)
|
mediaMimeType = getMimeTypeFromUri(requireContext(), it.file.toUri()),
|
||||||
|
notificationUtils = notificationUtils
|
||||||
|
)
|
||||||
|
}.onFailure { failure ->
|
||||||
|
if (!isAdded) return@onFailure
|
||||||
|
showErrorInSnackbar(failure)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Unit
|
||||||
}
|
}
|
||||||
is RoomUploadsViewEvents.Failure -> showFailure(it.throwable)
|
is RoomUploadsViewEvents.Failure -> showFailure(it.throwable)
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
|
|
Loading…
Add table
Reference in a new issue