Last active
October 15, 2020 10:57
-
-
Save kirmartuk/caa5a8ad5812994ace7b4dca4a97f189 to your computer and use it in GitHub Desktop.
Android(Kotlin) VideoRepository
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Sealed class for showing result in progressBar, mainThread | |
sealed class DownloadResult { | |
object Success : DownloadResult() | |
data class Error(val message: String) : DownloadResult() | |
data class Progress(val progress: Int) : DownloadResult() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private val PROJECTION = arrayOf(MediaStore.Video.Media._ID) | |
private const val QUERY = MediaStore.Video.Media.DISPLAY_NAME + " = ?" | |
private const val AUTHORITY = "${BuildConfig.APPLICATION_ID}.provider" | |
class VideoRepository(private val context: Context) { | |
private val ok = OkHttpClient() | |
private val collection = | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) MediaStore.Video.Media.getContentUri( | |
MediaStore.VOLUME_EXTERNAL | |
) else MediaStore.Video.Media.EXTERNAL_CONTENT_URI | |
suspend fun getLocalUri(filename: String): Uri? = | |
withContext(Dispatchers.IO) { | |
val resolver = context.contentResolver | |
resolver.query(collection, PROJECTION, QUERY, arrayOf(filename), null) | |
?.use { cursor -> | |
if (cursor.count > 0) { | |
cursor.moveToFirst() | |
return@withContext ContentUris.withAppendedId( | |
collection, | |
cursor.getLong(0) | |
) | |
} | |
} | |
null | |
} | |
suspend fun download(url: String, name: String): Flow<DownloadResult> { | |
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) downloadQ( | |
url, | |
name | |
) | |
else downloadLegacy(url, name) | |
} | |
private suspend fun downloadQ(url: String, name: String): Flow<DownloadResult> { | |
return flow { | |
try { | |
val response = ok.newCall(Request.Builder().url(url).build()).execute() | |
if (response.isSuccessful) { | |
val values = ContentValues().apply { | |
put(MediaStore.Video.Media.DISPLAY_NAME, name) | |
put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/YourFolder") | |
put(MediaStore.Video.Media.MIME_TYPE, "video/mp4") | |
put(MediaStore.Video.Media.IS_PENDING, 2) | |
} | |
val resolver = context.contentResolver | |
val uri = resolver.insert(collection, values) | |
uri?.let { | |
resolver.openOutputStream(uri)?.use { outputStream -> | |
val sink = Okio.buffer(Okio.sink(outputStream)) | |
response.body()?.source()?.let { | |
sink.writeAll(it) | |
} | |
sink.close() | |
} | |
values.clear() | |
values.put(MediaStore.Video.Media.IS_PENDING, 0) | |
resolver.update(uri, values, null, null) | |
emit(DownloadResult.Success) | |
} ?: throw RuntimeException("MediaStore failed for some reason") | |
uri | |
} else { | |
emit(DownloadResult.Error("Error")) | |
throw RuntimeException("OkHttp failed for some reason") | |
} | |
} catch (exception: Exception) { | |
emit(DownloadResult.Error("Error")) | |
} | |
} | |
} | |
private suspend fun downloadLegacy( | |
url: String, | |
name: String | |
): Flow<DownloadResult> { | |
return flow { | |
try { | |
val dir = Environment.getExternalStoragePublicDirectory( | |
Environment.DIRECTORY_MOVIES + "/YourFolder" | |
) | |
dir.mkdirs() | |
val file = File( | |
dir, | |
"$name.mp4" | |
) | |
file.createNewFile() | |
val response = ok.newCall(Request.Builder().url(url).build()).execute() | |
if (response.isSuccessful) { | |
val sink = Okio.buffer(Okio.sink(file)) | |
response.body()?.source()?.let { sink.writeAll(it) } | |
sink.close() | |
emit(DownloadResult.Success) | |
} else { | |
throw RuntimeException("OkHttp failed for some reason") | |
} | |
} catch (exception: Exception) { | |
Log.e("error", exception.toString()) | |
emit(DownloadResult.Error("Error")) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment