Postacıda iyi çalışan bir isteğim var:
ve bunu Güçlendirme ile yapmaya çalışıyorum. Genel olarak dosya boyutları >500MB olacaktır. Böyle bir yükleme yöntemi yaptım:
fun uploadFile(file:File) {
val client = OkHttpClient().newBuilder()
.build()
val mediaType: MediaType? = "text/plain".toMediaTypeOrNull()
val body: RequestBody = MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart(
"data", file.name,
file.asRequestBody()
)
.build()
val request: Request = Request.Builder()
.url("https://..../upload.php")
.method("POST", body)
.build()
val response: okhttp3.Response = client.newCall(request).execute()
println(response.message)
}
ama yüklenecek dosyaya ihtiyacım var. Bu şekilde geçici bir dosya oluşturabilirim:
val path = requireContext().cacheDir
val file = File.createTempFile(
name ?: "",
fileUri.lastPathSegment,
path
)
val os = FileOutputStream(file)
os.write(string)
os.close()
ama genelde alırım. outOfMemoryException
. Ayrıca Androidmanifest'e ekledim.xml yığın param:
android:largeHeap="true"
ama geçici dosya oluşturma sırasında bana hiç yardımcı olmadı. Postacının dosyaları nasıl yüklediğini bilmiyorum, ancak genel olarak yardım dosyasıyla yaklaşık 600Mb boyutunda yüklemeyi başardım. Seçilen dosyayı parçalarla da kesebilirim:
val data = result.data
data?.let {
val fileUri = data.data
var name: String? = null
var size: Long? = null
fileUri.let { returnUri ->
contentResolver?.query(returnUri!!, null, null, null, null)
}?.use { cursor ->
val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
cursor.moveToFirst()
name = cursor.getString(nameIndex)
size = cursor.getLong(sizeIndex)
}
val inputStream: InputStream? = fileUri?.let { it1 ->
contentResolver.openInputStream(
it1
)
}
val fileData = inputStream?.readBytes()
val mimeType = fileUri.let { returnUri ->
returnUri.let { retUri ->
if (retUri != null) {
contentResolver.getType(retUri)
}
}
}
fileData?.let {
val MAX_SUB_SIZE = 4194304 // 4*1024*1024 == 4MB
var start = 0 // From 0
var end = MAX_SUB_SIZE // To MAX_SUB_SIZE bytes
var subData: ByteArray // 4MB Sized Array
val max = fileData.size
if (max > 0) {
while (end < max) {
subData = fileData.copyOfRange(start, end)
start = end
end += MAX_SUB_SIZE
if (end >= max) {
end = max
}
println("file handling" + subData.size)
}
end-- // To avoid a padded zero
subData = fileData.copyOfRange(start, end)
println("file handling" + subData.size)
}
}
}
tüm eylemler aşağıdaki durumlarda yapılacaktır::
private val filesReceiver =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
}
}
bu yüzden normal şekilde herhangi bir dosya yolum olmayacak. Her neyse sanırım yanlış bir şey yaptım.
Güncelleme
şu anda ınputstream'den böyle bir dosya yüklüyorum:
private fun doSomeNetworkStuff(file:InputStream, name:String) {
GlobalScope.launch(Dispatchers.IO) {
val client = OkHttpClient()
.newBuilder()
.protocols(listOf(Protocol.HTTP_1_1))
.connectTimeout(10, TimeUnit.MINUTES)
.readTimeout(10, TimeUnit.MINUTES)
.build()
val mediaType: MediaType? = "text/plain".toMediaTypeOrNull()
val body: RequestBody = MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart(
"data", name,
file.readBytes().toRequestBody(mediaType)
)
.build()
val request: Request = Request.Builder()
.url("https://.../upload.php")
.method("POST", body)
.build()
val response: Response = client.newCall(request).execute()
println(response.body)
}
}
ve böyle bir hata alıyorum:
java.lang.OutOfMemoryError: Failed to allocate a 173410912 byte allocation with 25165824 free bytes and 89MB until OOM, max allowed footprint 199761800, growth limit 268435456
ancak bu kod dosyasını yaklaşık 90mb boyutunda yükleyebilirim