Sobes.tech
Middle

How would you implement the ability to upload and view files from the server?

sobes.tech AI

Answer from AI

To upload a file, I would use Retrofit with coroutines or Flow.

interface FileApi {
    @Streaming
    @GET("/files/{fileName}")
    suspend fun downloadFile(@Path("fileName") fileName: String): ResponseBody
}

In ViewModel or Interactor:

suspend fun downloadAndSaveFile(fileName: String): Result<File> {
    return try {
        val response = fileApi.downloadFile(fileName)
        if (response.isSuccessful) {
            val body = response.body() ?: throw IOException("Response body is null")
            val file = File(context.filesDir, fileName)
            body.byteStream().use { input ->
                FileOutputStream(file).use { output ->
                    input.copyTo(output)
                }
            }
            Result.success(file)
        } else {
            Result.failure(IOException("File download failed: ${response.code()}"))
        }
    } catch (e: Exception) {
        Result.failure(e)
    }
}

For displaying the file:

  • Images: ImageView, libraries like Coil or Glide.
  • Text: TextView, EditText (for large texts).
  • PDF: third-party libraries (PdfRenderer from Android SDK, MuPDF, PdfViewer library).
  • Video/Audio: MediaPlayer, ExoPlayer.
  • General: System Intent ACTION_VIEW with file URI.

Example of opening a PDF:

fun viewPdf(file: File) {
    val uri = FileProvider.getUriForFile(context, "${context.packageName}.provider", file)
    val intent = Intent(Intent.ACTION_VIEW).apply {
        setDataAndType(uri, "application/pdf")
        addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
    }
    try {
        context.startActivity(intent)
    } catch (e: ActivityNotFoundException) {
        // Handle case where no PDF viewer app is found
        Toast.makeText(context, "No PDF viewer app found", Toast.LENGTH_SHORT).show()
    }
}

Add FileProvider to AndroidManifest.xml and create an XML file with paths.

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

res/xml/file_paths.xml:

<paths>
    <files-path name="my_files" path="/" />
</paths>
How would you implement the ability to upload and… - sobes.tech