androidkotlinminecraftandroid-download-manager

I can not open downloaded from the server on android add-on files minecraft


I have a task, I need to download from the server add-on files for minecraft (.mcaddon, .mcpack, etc.) on android. For this I use DownloadManager. It downloads the files, but I can't open them in minecraft. I assumed that the problem is in MimeType, so I tried several solutions (application/x-freearc, application/octet-stream, application/zip, multipart/x-zip, application/x-zip-compressed) but they did not work. I attach my code and the file I use.

val FILE_PATH = Environment.getExternalStorageDirectory().path + "addons"

fun downloadFile(addon: Addon): Long {
    if (addon.fileUrl.isNullOrBlank()) return 0
    val manager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
    val uri: Uri = Uri.parse(addon.fileUrl)
    val request = DownloadManager.Request(uri)
    request.setDestinationInExternalFilesDir(context, FILE_PATH, getFileName(addon))
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION)
    request.setMimeType("application/octet-stream")
    val id = manager.enqueue(request)

    return id
}

fun openFile(addon: Addon) {
    val file = File(FILE_PATH, getFileName(addon))
    val photoURI = FileProvider.getUriForFile(Objects.requireNonNull(context),
        BuildConfig.APPLICATION_ID + ".provider",
        file)
    val intent = Intent(Intent.ACTION_VIEW)
    // set the content type and data of the intent
    intent.setDataAndType(photoURI, "application/octet-stream")
    intent.flags = Intent.FLAG_ACTIVITY_NO_HISTORY
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
    // start the intent as a new activity
    try {
        startActivity(context, intent, null)
    } catch (e: ActivityNotFoundException) {
        Toast.makeText(context, "There is no necessary program", Toast.LENGTH_SHORT).show()
    }
}

private fun getFileName(addon: Addon): String {
    val fileExtension = MimeTypeMap.getFileExtensionFromUrl(addon.fileUrl)
    return "${addon.title}_${addon.id}.${fileExtension}"
}

Solution

  • The problem was solved by using the FileLoader library and manually overwriting the data in the desired file. The code is attached.

    fun downloadFile(addon: Addon) {
        FileLoader.with(context)
            .load(addon.fileUrl,
                false) //2nd parameter is optioal, pass true to force load from network
            .fromDirectory(FILE_PATH, FileLoader.DEFAULT_DIR_TYPE)
            .asFile(object : FileRequestListener<File?> {
                override fun onLoad(request: FileLoadRequest, response: FileResponse<File?>) {
                    val loadedFile = response.body
                    val file: File = File(Environment.getExternalStorageDirectory(), getFileName(addon))
    
                    val inputStream: InputStream = loadedFile!!.inputStream()
                    val outputStream: OutputStream =
                        FileOutputStream("$FILE_PATH/${getFileName(addon)}")
                    val buffer = ByteArray(1024)
                    var length: Int
                    while (inputStream.read(buffer)
                            .also { length = it } > 0
                    ) outputStream.write(buffer, 0, length)
                    outputStream.flush()
                    outputStream.close()
    
                    inputStream.close()
                }
    
                override fun onError(request: FileLoadRequest, t: Throwable) {
                    Log.e("error load file", t.message.toString(), t)
                }
            })
    }