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}"
}
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)
}
})
}