I need to create a function that through a loop reads from the buffer a string received via bluetooth, this is what i did so far but it doesn't work, and if I use a while loop it just gets stuck in the loop, maybe I'm missing the right condition.
private suspend fun getmeData(){
var bytes :Int
val buffer: ByteArray = ByteArray(1024)
var readMessage : String = ""
if (m_isConnected ) {
try {
while(){
//read bytes received and ins to buffer
bytes =_bluetoothSocket!!.inputStream.read(buffer)
//convert to string
readMessage = readMessage + String(buffer, 0,bytes)
}
} catch (ex: Exception) {
ex.printStackTrace()
}
} else {
val toast = Toast.makeText(
contesto, "Non connesso",
Toast.LENGTH_LONG
)
toast.show()
}
}
Hi guys after an interesting conversation with a colluege i found the solution, the while's condition inside the "try" code must be like this, since the string i m receving contains an end string symbol
while (!(readMessage.contains(';'))){
/*my code*/
}
Thanks to everyone for the effort! <3
Related
I want to receive sensor data from Arduino with HC-05 Bluetooth module in Kotlin.
I have a receiveData function and when I clicking on the start button , receiveData is called and data show on the text view ;
This is working correctly.
But I want to stop receive data when I clicking on the Stop button and keep that Previous data on my text view , but I don't have any idea for the stop button.
This is my start monitoring button setOnClickListener:
btn_startMonitoring.setOnClickListener { receiveData() }
My receiveData function is this :
private fun receiveData() {
val handler = Handler()
var stopWorker = false
var readMessage = ""
val buffer = ByteArray(1024)
val workerThread = Thread {
while (!Thread.currentThread().isInterrupted && !stopWorker) {
try {
val bytes = m_bluetoothSocket!!.inputStream.read(buffer)
if (bytes > 0) {
readMessage += String(buffer, 0, bytes)
handler.post {
mTxtReceive!!.append(readMessage)
scrollView.post(Runnable
{ scrollView.fullScroll(View.FOCUS_DOWN) })
}
}
else {
Toast.makeText(this , "bytes is less than zero" , Toast.LENGTH_SHORT).show()
}
} catch (ex: IOException) {
stopWorker = true
}
}
}
workerThread.start()
}
i am trying to parse a big json file (>76K character) and read two regions out of it for mapping those into a WebView.
My problem is that i receive JSONExceptions when parsing it and i cant reconstruct the error.
This is my callVM class which includes the functionality.
fun callVM()
var url: String = getString(R.string.app_name)//R.string.myHtml
try {
//read url via getTermsString
url = getTermsString()
val gson = Gson()
var decodedHtml = unescape(url)
readJson(decodedHtml)
wv_map.loadData(decodedHtml, "text/html; charset=UTF-8", null);
} catch (e: Exception) {
Log.e("FAIL", "Initializing failed")
e.printStackTrace()
}
}
The getTermsString()-function reads the "url", in this case its my api_response_jreal.json and no url. The naming is old.
The api_response_jreal.json is in my raw folder.
private fun getTermsString(): String {
Log.e("gts", "Start getTermsString()")
val ist: InputStreamReader
try {
Log.e("Reader", "Start reader")
//R.raw.x - x equals the html file
ist = InputStreamReader(resources.openRawResource(R.raw.api_response_jreal))
val theString = IOUtils.toString(ist)
Log.e("gtsfin", "getTermsString() finished")
ist.close()
return theString
} catch (e: IOException) {
System.err.println(e.printStackTrace())
}
return "gts did not load anything."
}
My unescape function is there for replacing the escape character. I also tried to call the readJson-function without unescaping, but this is not working either...
fun unescape(str: String) : String
{
var strVar = str
strVar = strVar
// ADDED AFTER THE FIRST EXCEPTION.replace("\\u0","\\u003d")
.replace("\\u003d","=")
.replace("\\u003c","<")
.replace("\\u003e",">")
.replace("\\u0027","'")
.replace("\\\"", "")
.replace("\\t", " ")
.replace("\\u0023", "#")
.replace("\\u0024", "$")
.replace("\\u0025", "%")
.replace("\\u0026", "&")
.replace("\\u0028", "(")
.replace("\\u0029", ")")
.replace("\\u002A", "*")
.replace("\\u002B", "+")
.replace("\\u002C", ",")
.replace("\\u002D", "-")
.replace("\\u002E", ".")
.replace("\\u002F", "/")
.replace("\\u003A", ":")
.replace("\\u003B", ";")
.replace("\\u003F", "?")
.replace("\\u0040", "#")
.replace("/\\n/g", "\\n")
.replace("/\\'/g", "\\'")
.replace("/\\&/g", "\\&")
.replace("/\\r/g", "\\r")
.replace("/\\t/g", "\\t")
.replace("/\\b/g", "\\b")
.replace("/\\f/g", "\\f")
.replace("\\s+", " ")
.replace("\\\n","")
.replace("\\n","")
return strVar
}
Last but not least i try to transform my unescaped json to an Object to access the needed values (i just need "regionsToSvgMapping)
fun readJson(url : String){
val data = JSONObject(url)
Log.e("readjsn obj", "MyFile: " + data)
}
Now two exceptions appear.
The first was "Invalid escape sequence: 0"...
I copied the whole string in Notepad++ and take a look at character "3051"..
<polygon id\u0
03d12
Then i tried something stupid and thought the dumbest way would work and added the first .replace value in my unescape function. Well the dumbest way is not working ... ;)
Now its the time i dont have a solution for that problem and asking stackoverflow community.
I also tried to use a code beautifier to check if the json is complete so, this should be fine.
Thank you guys for help!
The solution was using StringBuilder.
When working with Strings >10k numbers and digits my Android studio has split the large string into multiple strings with around 1k numbers and digits.
To solve this i have used the stringbuilder like this,..
fun unescape(str: String) : String
{
var stringBuilder = StringBuilder()
var strVar = str
strVar = strVar
.replace("\\u003d","=")
.replace("\u003d","=")
.replace("\\u003c","<")
.... (see above)
stringBuilder.append(strVar)
return stringBuilder.toString()
}
I am currently making an android app that needs to read quotes in a text file. I have code to read everything from my file and display it through a toast, but I do not know how I can just read a specific line from it (eg. only displaying line 5 in a toast).
Here is my code:
var string: String? = ""
val stringBuilder = StringBuilder()
val `is`: InputStream = this.resources.openRawResource(R.raw.quotes)
val reader = BufferedReader(InputStreamReader(`is`))
while (true) {
try {
if (reader.readLine().also { string = it } == null) break
} catch (e: IOException) {
e.printStackTrace()
}
stringBuilder.append(string).append("\n")
Log.d("strings", stringBuilder.toString())
}
`is`.close()
Toast.makeText(baseContext, stringBuilder.toString(),
Toast.LENGTH_LONG).show()
Any help would be greatly appreciated, and thank you for any help in advance!
You can use useLines, which lets you work with a Sequence of the lines from within the lambda and automatically closes the stream afterwards:
val fifthLine = resources.openRawResource(R.raw.quotes)
.bufferedReader().useLines { it.elementAtOrNull(4) ?: "" }
Quite a few questions/answers and many I have tried without success. I receive a compressed string that uses a MemoryStream and DeflateStream to do so (c#). The following decompression function works fine
fun decompress(string: String): String? {
var decompressedString: String? = ""
try {
val bytes: ByteArray = Base64.decode(string, Base64.DEFAULT)
val inflater = Inflater(true)
val outputStream = ByteArrayOutputStream()
val buffer = ByteArray(1024)
inflater.setInput(bytes)
while (!inflater.finished()) {
val count = inflater.inflate(buffer)
outputStream.write(buffer, 0, count)
}
inflater.end()
outputStream.close()
decompressedString = outputStream.toString("UTF8")
} catch (e: IOException) {
e.printStackTrace()
}
return decompressedString
}
At a later time I need to compress the data and send it back. Attempts to compress the data have been unsuccessful. The server keeps telling me that the "block length does not match with its complement." I use the following function for compressing
fun compress(string: String): String? {
var compressedString: String? = null
try {
val bytes: ByteArray = string.toByteArray(charset("UTF-8"))
// Compress the bytes
val deflater = Deflater()
//val outputStream = ByteArrayOutputStream()
val buffer = ByteArray(1024)
deflater.setInput(bytes)
deflater.finish()
deflater.deflate(buffer)
deflater.end()
//outputStream.close()
compressedString = Base64.encodeToString(buffer, Base64.DEFAULT)
} catch (e: IOException) {
e.printStackTrace()
}
return compressedString
}
The problem isn't server side as it works fine with an iOS app but not Android. I've tried many variants of this all without success.
Anyone have any suggestions on what it is that I am doing incorrectly and what I need to do to get it to work?
Thanks ^.^
In case anyone else runs into this problem. I was able to solve it by changing the deflate function to
var compressedString: String? = ""
val bytes: ByteArray = string.toByteArray(charset("UTF-8"))
val deflater = Deflater(1, true)
deflater.setInput(bytes)
deflater.finish()
val outputStream = ByteArrayOutputStream(bytes.size)
try {
val bytesCompressed = ByteArray(Short.MAX_VALUE.toInt())
val numberOfBytesAfterCompression = deflater.deflate(bytesCompressed)
val returnValues = ByteArray(numberOfBytesAfterCompression)
System.arraycopy(bytesCompressed, 0, returnValues, 0, numberOfBytesAfterCompression)
compressedString = Base64.encodeToString(returnValues, Base64.DEFAULT)
} catch (e: IOException) {
e.printStackTrace()
} finally {
deflater.end()
outputStream.close()
}
Obtained from here deflater examples site.
Apparently using the prior function adds 2 additional bytes and this is what was causing the issue. After the change, the 2 bytes are not added. I don't quite understand how or why so if someone knows and wishes to share, please do so.
What I'm trying to is sending bytes to TCP socket.
Data format is byte array.
But BufferedWrite.write() doesn't have ByteArray. It has int or CharArray or String
Here is my code.
socket = Socket("192.168.9.34", 5000)
networkReader = BufferedReader(InputStreamReader(socket!!.getInputStream()))
networkWriter = BufferedWriter(OutputStreamWriter(socket!!.getOutputStream()))
val json = """
{"type":"REQ","code":"DP1200","key":"e7aa7f5e-15df-4ea1-9e7b-e4f05d2ac288","ip":"192.168.9.33","port":"31147","serviceid":"WINIXRND1D"}
""".trimIndent()
val jsonByte = json.toString().toByteArray()
val header: ByteArray = byteArrayOf(0x76,0x31,0x30,0x30,0x0,0x0,0x0,jsonByte.size.toByte())
val payload: ByteArray = header + jsonByte
try {
networkWriter!!.write(payload) //<== I want to write byte arra here! but write's argument no ByteArray
} catch (e: Exception) {
}
Please, correct give me advices.