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 (
PdfRendererfrom Android SDK, MuPDF, PdfViewer library). - Video/Audio:
MediaPlayer, ExoPlayer. - General: System Intent
ACTION_VIEWwith 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>