1
0
mirror of https://github.com/owncloud/android-library.git synced 2025-06-07 16:06:08 +00:00

Add transfer listeners to content uri worker

This commit is contained in:
Abel García de Prada 2022-05-26 15:08:12 +02:00
parent dc7022c531
commit ba37bce0e1

View File

@ -31,13 +31,23 @@ import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody import okhttp3.RequestBody
import okio.BufferedSink import okio.BufferedSink
import okio.Source
import okio.source import okio.source
import timber.log.Timber
import java.io.IOException import java.io.IOException
class ContentUriRequestBody( class ContentUriRequestBody(
private val contentResolver: ContentResolver, private val contentResolver: ContentResolver,
private val contentUri: Uri private val contentUri: Uri
) : RequestBody() { ) : RequestBody(), ProgressiveDataTransferer {
private val dataTransferListeners: MutableSet<OnDatatransferProgressListener> = HashSet()
val fileSize: Long = contentResolver.query(contentUri, null, null, null, null)?.use { cursor ->
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
cursor.moveToFirst()
cursor.getLong(sizeIndex)
} ?: -1
override fun contentType(): MediaType? { override fun contentType(): MediaType? {
val contentType = contentResolver.getType(contentUri) ?: return null val contentType = contentResolver.getType(contentUri) ?: return null
@ -45,19 +55,63 @@ class ContentUriRequestBody(
} }
override fun contentLength(): Long { override fun contentLength(): Long {
contentResolver.query(contentUri, null, null, null, null)?.use { cursor -> return fileSize
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
cursor.moveToFirst()
return cursor.getLong(sizeIndex)
} ?: return -1
} }
override fun writeTo(sink: BufferedSink) { override fun writeTo(sink: BufferedSink) {
val inputStream = contentResolver.openInputStream(contentUri) val inputStream = contentResolver.openInputStream(contentUri)
?: throw IOException("Couldn't open content URI for reading: $contentUri") ?: throw IOException("Couldn't open content URI for reading: $contentUri")
inputStream.source().use { source -> val previousTime = System.currentTimeMillis()
sink.writeAll(source)
sink.writeAndUpdateProgress(inputStream.source())
inputStream.source().close()
val laterTime = System.currentTimeMillis()
Timber.d("Difference - ${laterTime - previousTime} milliseconds")
}
private fun BufferedSink.writeAndUpdateProgress(source: Source) {
var iterator: Iterator<OnDatatransferProgressListener>
try {
var totalBytesRead = 0L
var read: Long
while (source.read(this.buffer, BYTES_TO_READ).also { read = it } != -1L) {
totalBytesRead += read
this.flush()
synchronized(dataTransferListeners) {
iterator = dataTransferListeners.iterator()
while (iterator.hasNext()) {
iterator.next().onTransferProgress(read, totalBytesRead, fileSize, contentUri.toString())
}
}
}
} catch (e: Exception) {
Timber.e(e)
} }
} }
override fun addDatatransferProgressListener(listener: OnDatatransferProgressListener) {
synchronized(dataTransferListeners) {
dataTransferListeners.add(listener)
}
}
override fun addDatatransferProgressListeners(listeners: MutableCollection<OnDatatransferProgressListener>) {
synchronized(dataTransferListeners) {
dataTransferListeners.addAll(listeners)
}
}
override fun removeDatatransferProgressListener(listener: OnDatatransferProgressListener) {
synchronized(dataTransferListeners) {
dataTransferListeners.remove(listener)
}
}
companion object {
private const val BYTES_TO_READ = 4_096L
}
} }