How to fix my errors at okHttp3 webscocket android? - android

I receive such error at my websocket:
Error: [okio.RealBufferedSource.require(RealBufferedSource.kt:201), okio.RealBufferedSource.readByte(RealBufferedSource.kt:210), okhttp3.internal.ws.WebSocketReader.readHeader(WebSocketReader.kt:119), okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.kt:102), okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.kt:293), okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.kt:195), okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:504), java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162), java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636), java.lang.Thread.run(Thread.java:764)]
It happens when I try to send chunked string files to server. For example when I send file in string with size 14B everything goes well, but when I send file up to 10kB I receive such error. When I try to send chunked 120kB file I receive such error:
Error: [okio.RealBufferedSource.require(RealBufferedSource.kt:201), okio.RealBufferedSource.readByte(RealBufferedSource.kt:210), okhttp3.internal.ws.WebSocketReader.readHeader(WebSocketReader.kt:119), okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.kt:102), okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.kt:293), okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.kt:195), okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:504), java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162), java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636), java.lang.Thread.run(Thread.java:764)]
Place where I send file:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when {
requestCode == 1 && resultCode == Activity.RESULT_OK -> {
if (data != null) {
val fileUri = data.data!!
val partSize = 10000
val fileString = readTextFile(fileUri)
var name = ""
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)
}
if (size!! <= partSize) {
ws.send(ChatRequestMessages.sendFile(fileString!!,
name,
selectedContactId.toString(),
size!!,
0))
} else {
val partsCount = if (size!!.rem(partSize).toInt() == 0) {
size!!.div(partSize)
} else {
size!!.div(partSize)
}
for (currentPart in 0..size!!.div(partSize)) {
val slicedString = if ((currentPart + 1) * partSize <= size!!.toInt()) {
fileString!!.substring(currentPart.toInt() * partSize..(currentPart + 1).toInt() * partSize)
} else {
fileString!!.substring(currentPart.toInt() * partSize until fileString.length)
}
Timber.i("${fileString.length.toLong()} ${currentPart * partSize} ${slicedString.length} $slicedString $name")
ws.send(ChatRequestMessages.sendFile(slicedString,
name,
selectedContactId.toString(),
fileString.length.toLong(),
(currentPart * partSize).toInt()))
}
}
}
}
}
I don't understand why it doesn't happen with small files and how to solve these errors :(

It looks like an empty response. The javadoc from RealBufferedSource.require says Returns when the buffer contains at least byteCount bytes. Throws an
[java.io.EOFException] if the source is exhausted before the required bytes can be read.
okhttp.internal.ws.WebSocketReader tries to read the first byte from the response, but doesn't get it.

Related

how to preview video and upload that video file to firebase in android kotlin

I am trying to upload a video file to firebase.:-
this is the code:-
lateinit var file: Any
private fun selectingVideo() {
val videoPickIntent = Intent(Intent.ACTION_PICK)
videoPickIntent.type = "video/*"
startActivityForResult(Intent.createChooser(videoPickIntent, "Please pick a video"), videoRequest )
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == videoRequest && resultCode == Activity.RESULT_OK && null != data) {
feedImageSelect.visibility = View.GONE
feedVideoSelect.visibility = View.VISIBLE
val pickedVideoUrl = getRealPathFromUri(applicationContext, data.data!!)
file = pickedVideoUrl
feedVideoSelect.setVideoPath(pickedVideoUrl)
// Default Media-Controller
feedVideoSelect.setMediaController(MediaController(this))
// start playing
feedVideoSelect.start()
}
}
// Retrieve Video Path from URI.
private fun getRealPathFromUri(context: Context, contentUri: Uri): String {
var cursor: Cursor? = null
try {
val proj = arrayOf(MediaStore.Images.Media.DATA)
cursor = context.contentResolver.query(contentUri, proj, null, null, null)
val columnIndex = cursor!!.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)
cursor.moveToFirst()
return cursor.getString(columnIndex)
} finally {
cursor?.close()
}
}
I am getting this as the error.:-
java.lang.ClassCastException: java.lang.String cannot be cast to android.net.Uri
I have tried all the possible ways to solve it. But Still I am getting this error. I tried other methods as well still they are not working for my requirements.
Make these changes to the code:-
val pickedVideoUrl = data.data
feedVideoSelect.setVideoPath(pickedVideoUrl.toString())

I had this crash several times now, I have seen a few ways to solve this issue but first I would like to make this crash happen again

Fatal Exception: android.database.CursorIndexOutOfBoundsException
Index 0 requested, with a size of 0
This is my function that I have in my FileHelper class:
fun downloadFile(url: String, fileName: String, completion: (DataResponse<File>) -> Unit) {
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val uri = Uri.parse(url)
val request = DownloadManager.Request(uri).apply {
setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle(fileName)
.setDescription("")
.setDestinationInExternalFilesDir(
context,
Environment.DIRECTORY_DOWNLOADS,
fileName
)
}
val downloadId = downloadManager.enqueue(request)
val query = DownloadManager.Query().setFilterById(downloadId)
Thread {
var downloading = true
var downloadRepeatCount = 0
while (downloading) {
val cursor: Cursor = downloadManager.query(query)
cursor.moveToFirst()
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
if (status == DownloadManager.STATUS_SUCCESSFUL) {
val file =
File("${context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)}${fileName}")
downloading = false
completion(getSuccessResponseData(file))
} else if (status == DownloadManager.STATUS_FAILED) {
downloading = false
sendFirebaseError("status STATUS_FAILED", url, fileName, uri)
completion(getErrorResponseData())
} else {
if (downloadRepeatCount < 10 && status == DownloadManager.STATUS_PAUSED) {
Thread.sleep(1000)
downloadRepeatCount++
} else if (status == DownloadManager.PAUSED_QUEUED_FOR_WIFI) {
downloading = false
sendFirebaseError("status PAUSED_QUEUED_FOR_WIFI", url, fileName, uri)
completion(getErrorResponseData())
} else if (status == DownloadManager.ERROR_INSUFFICIENT_SPACE && status == DownloadManager.ERROR_DEVICE_NOT_FOUND) {
downloading = false
sendFirebaseError("status ERROR_INSUFFICIENT_SPACE and ERROR_DEVICE_NOT_FOUND", url, fileName, uri)
completion(getErrorResponseData())
} else if (status > 10) {
downloading = false
sendFirebaseError("status > 10", url, fileName, uri)
completion(getErrorResponseData())
} else {
downloading = true
}
}
cursor.close()
}
}.start()
}
When I searched for this crash I have received the information about how to fix this issue. However, I want to make that crash in purpose in order to be sure about the reason of it. In addition I wonder that if possible, cursor did not crash but the non fatal error would cause download manager to go the DownloadManager.STATUS_FAILED condition. I want to discuss about those topics.
Make sure you have a null check and as #laalto said call the function only if it's true.
if( cursor != null && cursor.moveToFirst() ){
status =cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
cursor.close();
}
Your query matched no rows. You need to check the return value of cursor.moveToFirst() and call cursor.getInt() only if it returned true.
You can check cursor's size using this method :
if (cursor != null && cursor.getCount() > 0){
// Do your stuff
}

get File from Uri cause FileNotFoundException in kotlin, how to get real file path [duplicate]

This question already has answers here:
Android Kotlin: Getting a FileNotFoundException with filename chosen from file picker?
(5 answers)
Create a file from a photo URI on Android
(1 answer)
Closed 2 years ago.
I want to upload a logo picked in gallery to our api via multipart.
I am using multipartFile method from the networking library witch take a File in parameter: uploading a file to server
The File object can take an Uri as constructor.
With the uri received from the gallery return, i can display the image in a ImageView, but the uri or uri.path cause FileNotFoundException when passed in FileConstructor. (internet, read, write permissions are declared in manifest)
there is all code concerning this feature:
//selected image uri
private var imageUri: Uri? = null
set(value) {
field = value
field?.let { //value after picking image is : content://com.android.providers.media.documents/document/image%3A25
uploadImageFile(imageUri= it,
route = "uploadImageRoute/",
onProgression = { progress ->
Log.d("upload", "progress= $progress")
},
onSuccess = {
Log.d("upload", "upload success !")
},
onError = { errorMessage ->
Log.d("upload", "error= $errorMessage")
})
}
}
//select image button clicked, go to image gallery to pick an image
override fun onClick(v: View?) {
val intent = Intent()
intent.type = "image/*"
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0)
}
//comeback from image gallery
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 0 && resultCode == Activity.RESULT_OK && data != null) {
val selectedPhotoUri = data.data!!
imageUri = selectedPhotoUri
}
}
//prepare request headers
private fun configureHeaders(): MutableMap<String,Any> {
var headerMap = mutableMapOf<String, Any>()
headerMap["Content-Type"] = "multipart/form-data"
headerMap["Accept"] = "application/json, text/plain"
return headerMap
}
private fun uploadImageFile(imageUri: Uri, route: String, onProgression: (Double) -> Unit, onSuccess: () -> Unit, onError: (String?) -> Unit) {
val headers = configureHeaders()
var file = File(imageUri.path)
AndroidNetworking.upload("https://api.ourDomain.com/$route")
.addMultipartFile("file", file)
.addHeaders(headers)
.build()
.setUploadProgressListener { uploaded, total ->
val percentage = 100 * uploaded / total as Double
onProgression(percentage)
}
.getAsJSONObject(object : JSONObjectRequestListener {
override fun onResponse(response: JSONObject?) {
onSuccess()
}
override fun onError(anError: ANError?) {
onError(anError.toString())
}
})
}
How to get the real path to the file to put in parameter of File constructor ?

Could not upload multiple images into the database

I am getting these errors when I am uploading images. The path is storing in database table, But the image folder does not have image.
These are the errors
E/ErrorUtil: Error: /document/primary:DCIM/Camera/20190804_111501.jpg (No such file or directory)
W/System.err: java.io.FileNotFoundException: /document/primary:DCIM/Camera/20190804_111501.jpg (No such file or directory)
Here I shared my code.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == PICK_IMAGE_MULTIPLE && resultCode == Activity.RESULT_OK
&& null != data) {
if(data.getClipData() != null) {
val count = data.getClipData().getItemCount(); //evaluate the count before the for loop --- otherwise, the count is evaluated every loop.
for(i in 0..count-1) {
val imageUri : Uri = data.getClipData().getItemAt(i).uri
// getRealPathFromURI(applicationContext,imageUri)
imageUri.let {
Log.d("imageUri",it.toString())
Log.d("imagePath",it.path)
file = File(it.path)
val jj=Gson()
Log.d("fileIS",jj.toJson(file))
fileType = EnumUtils.FileType.IMAGE.value
val name = file!!.name
Log.d("fimenameis",name)
multipartArray!!.add(MultipartBody.Part.createFormData("files[]", file!!.name, RequestBody.create(MediaType.parse(file!!.path.getMimeType()?: ""), file!!)))
val s = Gson()
Log.d("multipartArray",s.toJson(multipartArray).toString())
}
}
//do something with the image (save it to some directory or whatever you need to do with it here)
} else if(data.getData() != null) {
val imagePath = data.getData().getPath();
fileType = EnumUtils.FileType.IMAGE.value
file = File(imagePath)
multipartArray!!.add(MultipartBody.Part.createFormData("files[]", file!!.name, RequestBody.create(MediaType.parse(file!!.path.getMimeType()?: ""), file!!)))
Log.d("imagePath",imagePath.toString())
//do something with the image (save it to some directory or whatever you need to do with it here)
}
}
yes it happen some time due to file path does not get the absolute path and failed to convert it into file
` private fun getRealPathFromURI(contentURI: Uri): String? {
val result: String?
val cursor = contentResolver.query(contentURI, null, null, null, null)
if (cursor == null) { // Source is Dropbox or other similar local file path
result = contentURI.path
} else {
cursor.moveToFirst()
val idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)
result = cursor.getString(idx)
cursor.close()
}
return result
}`
val file: File = File(getRealPathFromURI(Uri.parse(imagePath)))

select multiple images from gallery in KOTLIN (want image path) [duplicate]

This question already has answers here:
Error "must not be null" in Kotlin
(3 answers)
Closed 4 years ago.
I am working on an Application for making a video from multiple images in kotlin. I got many code of java but can not convert it in propare way to kotlin code. Alwayse got an error cursor.getString(column_index) must not be null. I am just beginner at Kotlin. so can anyone give a brief solution for my problem.
val cursor = contentResolver.query(uri, filePathColumn, null, null, null)
cursor!!.moveToFirst()
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
Hey I m also suffering with same issue nd got the solution. just follow my code.
private var context: Context? = null
var PICK_IMAGE_MULTIPLE = 1
lateinit var imagePath: String
var imagesPathList: MutableList<String> = arrayListOf()
call gallery intent first
if (Build.VERSION.SDK_INT < 19) {
var intent = Intent()
intent.type = "image/*"
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
intent.action = Intent.ACTION_GET_CONTENT
startActivityForResult(
Intent.createChooser(intent, "Select Picture")
, PICK_IMAGE_MULTIPLE
)
} else {
var intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
intent.addCategory(Intent.CATEGORY_OPENABLE)
intent.type = "image/*"
startActivityForResult(intent, PICK_IMAGE_MULTIPLE);
}
now check onActivityResult
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// When an Image is picked
if (requestCode == PICK_IMAGE_MULTIPLE && resultCode == Activity.RESULT_OK
&& null != data
) {
if (data.getClipData() != null) {
var count = data.clipData.itemCount
for (i in 0..count - 1) {
var imageUri: Uri = data.clipData.getItemAt(i).uri
getPathFromURI(imageUri)
}
} else if (data.getData() != null) {
var imagePath: String = data.data.path
Log.e("imagePath", imagePath);
}
displayImageData()
}
}
private fun getPathFromURI(uri: Uri) {
var path: String = uri.path // uri = any content Uri
val databaseUri: Uri
val selection: String?
val selectionArgs: Array<String>?
if (path.contains("/document/image:")) { // files selected from "Documents"
databaseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
selection = "_id=?"
selectionArgs = arrayOf(DocumentsContract.getDocumentId(uri).split(":")[1])
} else { // files selected from all other sources, especially on Samsung devices
databaseUri = uri
selection = null
selectionArgs = null
}
try {
val projection = arrayOf(
MediaStore.Images.Media.DATA,
MediaStore.Images.Media._ID,
MediaStore.Images.Media.ORIENTATION,
MediaStore.Images.Media.DATE_TAKEN
) // some example data you can query
val cursor = contentResolver.query(
databaseUri,
projection, selection, selectionArgs, null
)
if (cursor.moveToFirst()) {
val columnIndex = cursor.getColumnIndex(projection[0])
imagePath = cursor.getString(columnIndex)
// Log.e("path", imagePath);
imagesPathList.add(imagePath)
}
cursor.close()
} catch (e: Exception) {
Log.e(TAG, e.message, e)
}
}
This is a solution using Github repo for your requirement.
In your app gradle file add these lines
implementation 'com.github.esafirm.android-image-picker:imagepicker:1.13.1'
// for experimental rx picker
implementation 'com.github.esafirm.android-image-picker:rximagepicker:1.13.1'
// If you have a problem with Glide, please use the same Glide version or simply open an issue
implementation 'com.github.bumptech.glide:glide:4.8.0'
in Java class call this to pick or take image
startActivityForResult(ImagePicker.create(getActivity())
.multi()
.folderMode(true)
.returnMode(ReturnMode.ALL)
.getIntent(getActivity()), IpCons.RC_IMAGE_PICKER);
and in onActivityResult() get the arraylist of selected images
#Override
protected void onActivityResult(int requestCode, final int resultCode, Intent data) {
if (ImagePicker.shouldHandle(requestCode, resultCode, data)) {
// Get a list of picked images
List<Image> images = ImagePicker.getImages(data)
// do your stuff here
// or get a single image only
//Image image = ImagePicker.getFirstImageOrNull(data)
}
super.onActivityResult(requestCode, resultCode, data);
}
This code is less complex and no need to handle image multiple selection , just adding multi() to enable multiple selection.
Note:- Copy this code and paste in your kotlin project , the converter will
automatically convert it to kotlin

Categories

Resources