I'm working with TCP communication and use Ktor library.
I have packets that come, and the first byte is the packet's lengths.
Likewise, I read the packet from what is documented on the protocol API, and sometimes I have to skip the remaining bytes of the packet, so I subtract what I have read to this message length.
At the present time, I call also { messageLength -= length } on each reading, but the code is unreadable.
#Test
fun ktorTests() {
runBlocking {
val selectorManager = SelectorManager(Dispatchers.IO)
val socket = aSocket(selectorManager).tcp().connect("server.slsknet.org", 2242)
val openReadChannel = socket.openReadChannel()
val openWriteChannel = socket.openWriteChannel(autoFlush = true)
val login = "Test"
val pwd = "159753"
openWriteChannel.write {
it.put(
ByteMessage().writeInt32(1)
.writeStr(login)
.writeStr(pwd)
.writeInt32(160)
.writeStr((login + pwd).toMD5())
.writeInt32(1)
.getBuff()
)
}
while (true) {
var messageLength = openReadChannel.readIntLittleEndian()
val code = openReadChannel.readIntLittleEndian()
println("ServerClient received: Message code:" + code + " Packet Size:" + (messageLength + 4))
when (code) {
1 -> {
if (openReadChannel.readBoolean().also { messageLength -= 1 }) {
val greetingLength = openReadChannel.readIntLittleEndian().also { messageLength -= 4 }
val greeting = ByteArray(greetingLength)
openReadChannel.readFully(greeting, 0, greetingLength)
.also { messageLength -= greetingLength }
val ip = openReadChannel.readIntLittleEndian().also { messageLength -= 4 }
println("Logged In.")
}
openReadChannel.discardExact(messageLength.toLong())
}
}
}
Any ideas on ho could it be done ?
Related
I'm working on Splay Tree. I have a lot of command input (add, delete and etc), Hence the output is also huge (32MB of text in a txt file)
I have a memory problem, I am currently using two MultitableList and I have 200 MB of virtual memory (128 MB is needed for the project)
I run on Linux with the command:
$ kotlinc Kotlin.kt -include-runtime -d outPutFile.jar
$ /usr/bin/time -v java -jar outPutFile.jar
result: Maximum resident set size (kbytes): 249732 (With each launch different sizes but about 200)
how can i reduce the size? I need to change the size after each cycle
class SplayTree {
var ROOT: Node? = null
class Node(val key: Long, var value: String?) {
var _parent: SplayTree.Node? = null
var _RightChild: SplayTree.Node? = null
var _LeftChild: SplayTree.Node? = null
... there is a code here ...
// for output
override fun toString(): String {
if (_parent == null) {
return "[${key} ${value}]"
} else {
return "[${key} ${value} ${_parent!!.key}]"
}
}
}
... there is a code here ...
override fun toString(): String {
if (ROOT == null) {
return "_"
}
println(ROOT)
var NOWqueueList: List<Node?> = listOf(ROOT)
var BABYqueue: MutableList<Node?> = MutableList(0) { null }
//var NOWqueueList = Array<Node?>(1, {ROOT}) // Array
//var BABYqueue = Array<Node?>(1, {null}) // Array
//var n = 1 // Array
for (h in 1 until height(ROOT)) {
// for Array
//var pos = -1
//n *= 2
//BABYqueue = Array<Node?>(n, {null}) //for future line
for (ROOTList in NOWqueueList) {
//pos++ // Array
if ( ROOTList != null){
//left
if (ROOTList.haveLeftBaby()) {
//BABYqueue[pos] = ROOTList._LeftChild // Array
BABYqueue.add(ROOTList._LeftChild)
print(ROOTList._LeftChild.toString())
print(" ")
} else {
//BABYqueue[pos] = null // Array
BABYqueue.add(null)
print("_ ")
}
//pos++ // Array
//right
if (ROOTList.haveRightBaby()) {
//BABYqueue[pos] = ROOTList._RightChild // Array
BABYqueue.add(ROOTList._RightChild)
print(ROOTList._RightChild.toString())
print(" ")
} else {
//BABYqueue[pos] = null
BABYqueue.add(null)
print("_ ")
}
} else{ //если пустой то + 2 "_"
//BABYqueue[pos] = null // Array
//pos++ // Array
//BABYqueue[pos] = null // Array
BABYqueue.add(null)
BABYqueue.add(null)
print("_ _ ")
}
}
//NOWqueueList.clear() //worked when was MultitableList
NOWqueueList = BABYqueue.toList() // equate
//NOWqueueList = BABYqueue.clone() // Array
//println(NOWqueueList.joinToString(" ")) // вывожу готовый
println()
BABYqueue.clear()
}
//NOWqueueList.clear()
BABYqueue.clear()
return " end="
}
}
fun main() {
... there is a code here ...
}
I tried using Array, it still came out as with MultitableList
private fun moveMarkerAnimation(key: String, newData: AnimationModel, marker: Marker?, from: String, to: String) {
if (!newData.isRun)
{
compositeDisposable.add(
iGoogleAPI.getDirections(
"driving",
"less_driving",
from, to,
getString(R.string.google_api_key1)
)!!.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { returnResult ->
Log.d("API_RETURN",returnResult,)
try {
val jsonObject = JSONObject(returnResult)
val jsonArray = jsonObject.getJSONArray("routes")
for ( i in 0 until jsonArray.length())
{
val route = jsonArray.getJSONObject(i)
val poly = route.getJSONObject("overview_polyLine")
val polyLine = poly.getString("points")
polylineList = Common.decodePoly(polyLine) as java.util.ArrayList<LatLng?>
}
handler = Handler()
index = -1
next = 1
val runnable = object :Runnable{
override fun run() {
if (polylineList!!.size > 1)
{
if (index< polylineList!!.size)
{
index ++
next = index+1
start = polylineList!![index] !!
end = polylineList!![next]!!
}
val valueAnimator = ValueAnimator.ofInt(0,1)
valueAnimator.duration = 3000
valueAnimator.interpolator = LinearInterpolator()
valueAnimator.addUpdateListener { value ->
v = value.animatedFraction
lat = v*end !!.latitude + (1-v) * start!!.latitude
lng = v*end !!.longitude+ (1-v) * start!!.longitude
val newPos = LatLng(lat,lng)
marker!!.position = newPos
marker!!.setAnchor(0.5f,0.5f)
marker!!.rotation = Common.getBearing(start!!,newPos)
}
valueAnimator.start()
if (index < polylineList!!.size-2)
{
handler!!.postDelayed(this,1500)
}else if (index < polylineList!!.size-1)
{
newData.isRun = false
Common.driversSubscrib.put(key,newData)
}
}
}
}
handler!!.postDelayed(runnable,1500)
}
catch (e:java.lang.Exception){
Snackbar.make(requireView(),e.message!!,Snackbar.LENGTH_LONG).show()
}
When the site changes from from firebase this result appears
022-04-26 13:19:30.912 23482-23482/com.example.bustrackerriderapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.bustrackerriderapp, PID: 23482
io.reactivex.exceptions.OnErrorNotImplementedException: The exception was not handled due to missing onError handler in the subscribe() method call. Further reading
what should I do to fix this problem
I am using the requestj api to send and receive the data from server and setting up the alarm on time that i received from server and alarm calls two hours ago from received time but issue is that when alarm fire on exact time it also fire every time when api calls till that 2 hours didn't completed. Any one know how to prevent it?
1.API code is here
fun getAllFriendsReminders(context: Context) {
val getReminderHttpRequest = HttpRequest()
// val myList = ArrayList<FriendsRemindersListModel>()
getReminderHttpRequest.setOnResponseListener { getReminderListResponse ->
Log.e("getReminders List", getReminderListResponse.code.toString())
Log.e("getReminders List", getReminderListResponse.text)
if (getReminderListResponse.code == HttpResponse.HTTP_OK) {
Log.e("getReminders List", getReminderListResponse.code.toString())
val jsonArray = getReminderListResponse.toJSONArray()
getReminderListModel.clear()
Log.e("list", jsonArray.length().toString())
Log.e("list", jsonArray.toString())
val loggedInUser = appGlobals.getValueString("loginUsername")
for (i in 0 until jsonArray!!.length()) {
if (!onForeGround) {
progressBar!!.progress = i
}
Log.e("listi", i.toString())
val jsonObject = jsonArray.getJSONObject(i)
friendReminderText = jsonObject.getString("reminder")
friendReminderFromName = jsonObject.getString("reminder_from")
friendReminderToName = jsonObject.getString("reminder_to")
friendReminderDate = jsonObject.getString("date")
friendReminderStatus = jsonObject.getString("status")
friendReminderId = jsonObject.getString("id")
if (friendReminderFromName != loggedInUser) {
getReminderListModel.add(FriendsRemindersListModel(0, friendReminderId.toInt(),friendReminderText,
friendReminderDate, friendReminderFromName, friendReminderToName, friendReminderStatus))
//Received date time from server
val dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm:ss a")
// val dateFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy")
// val timeFormatter = DateTimeFormatter.ofPattern("hh:mm:ss a")
val instant = Instant.ofEpochMilli(friendReminderDate.toLong())
val instant1 = Instant.ofEpochMilli(friendReminderDate.toLong() - (120 * 60 * 1000))
val date = LocalDateTime.ofInstant(instant, ZoneId.systemDefault())
val date1 = LocalDateTime.ofInstant(instant1, ZoneId.systemDefault())
// val exactDate = dateFormatter.format(date)
// val exactTime = timeFormatter.format(date)
val exactDateTime = dateTimeFormatter.format(date)
val alarmDate = Date(friendReminderDate.toLong())
//Current date time
val dates = Date()
val stringFormat = SimpleDateFormat("dd-MM-yyyy hh:mm:ss a")
val dateTimeTo = stringFormat.format(dates.time)
//Set Alarm
if (alarmDate.after(dates)) {
Log.d("D", dates.toString())
Log.d("AlarmDate", alarmDate.toString())
Log.e("2 hour ago", dateTimeFormatter.format(date1))
println(friendReminderDate.toLong() - (120 * 60 * 1000))
Log.e("Set", exactDateTime)
val alarmManager: AlarmManager = context.getSystemService(
AppCompatActivity.ALARM_SERVICE) as AlarmManager
val alarmIntent = Intent(requireContext(), AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.e("Alarm", "Alarm")
alarmManager.setAlarmClock(AlarmManager.AlarmClockInfo(friendReminderDate.toLong() - 120*60*1000,
pendingIntent), pendingIntent)
} else {
Log.e("Alarm1", "${friendReminderDate.toLong() - (120 * 60 * 1000)}")
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
(friendReminderDate.toLong()) - 120 * 60 * 1000,
pendingIntent)
Log.e("Alarm2", "Alarm")
}
}
// if (exactDateTime > dateTimeTo) {
//
// }
}
}
if (friendReminderFromName != loggedInUser) {
if (friendReminderId != "") {
reminder = FriendsRemindersListModel(0, friendReminderId.toInt(), friendReminderText, friendReminderDate,
friendReminderFromName, friendReminderToName, friendReminderStatus)
}
}
if (getReminderListModel.size.toString() > remindersListModel.size.toString()) {
Log.e("serverListSize", getReminderListModel.size.toString())
Log.e("dbListSize", remindersListModel.size.toString())
Log.e("JsonListSize", jsonArray.length().toString())
for (i in 0 until getReminderListModel.size - 1) {
Log.e("present", getReminderListModel[i].reminderId.toString())
var isPresent = false
for (j in 0 until remindersListModel.size - 1) {
Log.e("present", remindersListModel.toString())
if (remindersListModel.isNotEmpty()) {
if (getReminderListModel[i].reminderId == remindersListModel[i].reminderId) {
isPresent = true
}
}
}
Log.e("presenting", "${!isPresent}")
if (isPresent) {
remindersViewModel.addingReminder(reminder)
}
}
}
else if (getReminderListModel.size.toString() < remindersListModel.size.toString()) {
for (i in 0 until remindersListModel.size - 1) {
for (j in 0 until getReminderListModel.size - 1) {
// var isRemoved = false
// Log.e("i's", i.toString())
Log.e("i's", getReminderListModel.size.toString())
Log.e("i'ss", remindersListModel.size.toString())
if (remindersListModel.isNotEmpty()) {
Log.e("delete3", remindersListModel[i].reminderId.toString())
Log.e("delete3", remindersListModel[i].reminderText)
Log.e("delete4", getReminderListModel[j].reminderId.toString())
Log.e("delete4", getReminderListModel[j].reminderText)
if (remindersListModel[i].reminderId != getReminderListModel[i].reminderId ) {
Log.e("delete2", remindersListModel[i].reminderId.toString())
remindersViewModel.deleteReminder(remindersListModel[i].reminderId)
// getReminderListAdapter.notifyItemRemoved(i)
}
}
}
}
}
// if (getReminderListModel.size.toString() != getRemindersDBList.size.toString()) {
// remindersViewModel.deleteReceivedReminders()
// remindersViewModel.addReminder(getReminderListModel)
// }
if (progressBar!= null) {
progressBar!!.visibility = View.GONE
}
}
}
getReminderHttpRequest.setOnErrorListener {
if (progressBar != null) {
progressBar!!.visibility = View.GONE
}
Log.e("getReminders error", "$it")
Log.e("Alarm1", "${friendReminderDate.toLong() - (120 * 60 * 1000)}")
}
val token = appGlobals.getValueString("userToken")
val headers = HttpHeaders("Authorization", "Token $token")
getReminderHttpRequest.get(AppGlobals.GET_REMINDERS_LIST_API, headers)
}
2. Alarm receiver class:
class AlarmReceiver: BroadcastReceiver() {
#RequiresApi(Build.VERSION_CODES.O)
#SuppressLint("UnsafeProtectedBroadcastReceiver")
override fun onReceive(context: Context?, intent: Intent?) {
showNotification(context!!, MessagingServiceFirebase.title, MessagingServiceFirebase.body)
Log.e("Checking notify", "Notification")
// Toast.makeText(context, "Alarm", Toast.LENGTH_SHORT).show()
Log.e("Checking ", "Notification")
// ringTone(context)
}
// private fun ringTone(context: Context) {
// val alert: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM)
// val ringtone: Ringtone = RingtoneManager.getRingtone(context, alert)
//
// ringtone.play()
// Toast.makeText(context, "Alarm Called", Toast.LENGTH_SHORT).show()
// }
fun showNotification(ctx: Context, title: String, message: String) {
val notificationManager =
ctx.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "channel"
val name: CharSequence = "channel"
val description = "The channel"
val importance = NotificationManager.IMPORTANCE_HIGH
val mChannel = NotificationChannel(channelId, name, importance)
mChannel.description = description
mChannel.enableLights(true)
mChannel.lightColor = Color.RED
mChannel.enableVibration(true)
mChannel.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
mChannel.setShowBadge(false)
notificationManager.createNotificationChannel(mChannel)
}
val builder: NotificationCompat.Builder = NotificationCompat.Builder(ctx, "channel")
.setSmallIcon(R.drawable.ic_baseline_access_alarm_24)
.setContentTitle(title)
.setContentText(message)
val resultIntent = Intent(ctx, HomeActivity::class.java)
val stackBuilder: TaskStackBuilder = TaskStackBuilder.create(ctx)
stackBuilder.addParentStack(HomeActivity::class.java)
resultIntent.putExtra("NotifyTitle", title)
resultIntent.putExtra("NotifyMessage", message)
stackBuilder.addNextIntent(resultIntent)
val resultPendingIntent: PendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
builder.setContentIntent(resultPendingIntent)
builder.setAutoCancel(true)
notificationManager.notify(12, builder.build())
}
}
3. Manifest code
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver
android:name=".AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />
</intent-filter>
</receiver>
You pull date from the JSON, and set an alarm for 2 hours before that? So if date is 6pm, you set an alarm for 4pm?
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
friendReminderDate.toLong()) - 120 * 60 * 1000, // date - 2hrs
pendingIntent)
If it's 5pm right now, and you set an alarm for 4pm, it will still set, and fire immediately:
If the stated trigger time is in the past, the alarm will be triggered immediately. If there is already an alarm for this Intent scheduled (with the equality of two intents being defined by Intent#filterEquals), then it will be removed and replaced by this one.
So if you only want to set the alarm if now <= alarmTime, and just skip it if now > alarmTime, you need to do that check before you set the alarm.
It looks like you're trying to do that:
if (alarmDate.after(dates)) {
but alarmDate is "date", not "date - 2hrs" (you're using 6pm instead of 4pm):
val alarmDate = Date(friendReminderDate.toLong())
So during that 2-hour period, you're always setting alarms that fire immediately. You need to use your actual alarm time instead:
// seriously, just do this calculation once and refer to the variable
val alarmTime = friendReminderDate.toLong() - (120 * 60 * 1000)
val alarmDate = Date(alarmTime)
You have a lot of date variables piling up in there, it's confusing and hard to tell what's going on - that's probably how this alarmDate bug crept in.
Also just in case, you know your "alarm receiver" also fires and shows a notification when the device boots and when it first unlocks, right?
The (-2hrs) above is only correct, when you are in:
(UTC +1) zone AND there is SUMMER (+1) or
(UTC +2) zone AND there is WINTER (+0)
The correct datetime is in millis (kotlin datetime to millisecond convert using local zone and daylight offset):
val myalarmdatetime: String = "2022-05-31 23:59:59"
val myalarmdatetimemillis: Long =
ZonedDateTime.of(
LocalDateTime.parse(
myalarmdatetime,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
), ZoneId.systemDefault()
).toInstant().toEpochMilli()
fun main () {
var integers = mutableListOf(0)
for (x in 1..9) {
integers.add(x)
}
//for or while could be used in this instance
var lowerCase = listOf("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
var upperCase = listOf('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z')
println(integers)
println(lowerCase)
println(upperCase)
//Note that for the actual program, it is also vital that I use potential punctuation
val passwordGeneratorKey1 = Math.random()*999
val passwordGeneratorKey2 = passwordGeneratorKey1.toInt()
var passwordGeneratorL1 = lowerCase[(Math.random()*lowerCase.size).toInt()]
var passwordGeneratorL2 = lowerCase[(Math.random()*lowerCase.size).toInt()]
var passwordGeneratorL3 = lowerCase[(Math.random()*lowerCase.size).toInt()]
var passwordGeneratorU1 = upperCase[(Math.random()*upperCase.size).toInt()]
var passwordGeneratorU2 = upperCase[(Math.random()*upperCase.size).toInt()]
var passwordGeneratorU3 = upperCase[(Math.random()*upperCase.size).toInt()]
val password = passwordGeneratorKey2.toString()+passwordGeneratorL1+passwordGeneratorL2+passwordGeneratorL3+passwordGeneratorU1+passwordGeneratorU2+passwordGeneratorU3
println(password)
//No, this isn't random, but it's pretty close to it
//How do I now run through every possible combination of the lists //lowerCase, integers, and upperCase?
}
How do I run through every possible permutation to eventually solve for the randomly generated password? This is in Kotlin.
I think you should append all the lists together and then draw from it by random index, this way you ensure that position of numbers, lower cases and uppercases is random too. Also you don't need to write all the characters, you can use Range which generates them for you.
fun main() {
val allChars = mutableListOf<Any>().apply {
addAll(0..9) // creates range from 0 to 9 and adds it to a list
addAll('a'..'z') // creates range from a to z and adds it to a list
addAll('A'..'Z') // creates range from A to Z and adds it to a list
}
val passwordLength = 9
val password = StringBuilder().apply {
for (i in 0 until passwordLength) {
val randomCharIndex =
Random.nextInt(allChars.lastIndex) // generate random index from 0 to lastIndex of list
val randomChar = allChars[randomCharIndex] // select character from list
append(randomChar) // append char to password string builder
}
}.toString()
println(password)
}
Even shorter solution can be achieved using list methods
fun main() {
val password = mutableListOf<Any>()
.apply {
addAll(0..9) // creates range from 0 to 9 and adds it to a list
addAll('a'..'z') // creates range from a to z and adds it to a list
addAll('A'..'Z') // creates range from A to Z and adds it to a list
}
.shuffled() // shuffle the list
.take(9) // take first 9 elements from list
.joinToString("") // join them to string
println(password)
}
As others pointed out there are less painful ways to generate the initial password in the format of: 1 to 3 digits followed by 3 lowercase characters followed by 3 uppercase characters.
To brute force this password, you will need to consider all 3-permutations of "a..z" and all 3-permitations of "A..Z". In both cases the number of such 3-permutations is 15600 = 26! / (26-3)!. In worst case you will have to examine 1000 * 15600 * 15600 combination, half of this on the average.
Probably doable in a few hours with the code below:
import kotlin.random.Random
import kotlin.system.exitProcess
val lowercaseList = ('a'..'z').toList()
val uppercaseList = ('A'..'Z').toList()
val lowercase = lowercaseList.joinToString(separator = "")
val uppercase = uppercaseList.joinToString(separator = "")
fun genPassword(): String {
val lowercase = lowercaseList.shuffled().take(3)
val uppercase = uppercaseList.shuffled().take(3)
return (listOf(Random.nextInt(0, 1000)) + lowercase + uppercase).joinToString(separator = "")
}
/**
* Generate all K-sized permutations of str of length N. The number of such permutations is:
* N! / (N-K)!
*
* For example: perm(2, "abc") = [ab, ac, ba, bc, ca, cb]
*/
fun perm(k: Int, str: String): List<String> {
val nk = str.length - k
fun perm(str: String, accumulate: String): List<String> {
return when (str.length == nk) {
true -> listOf(accumulate)
false -> {
str.flatMapIndexed { i, c ->
perm(str.removeRange(i, i + 1), accumulate + c)
}
}
}
}
return perm(str, "")
}
fun main() {
val password = genPassword().also { println(it) }
val all3LowercasePermutations = perm(3, lowercase).also { println(it) }.also { println(it.size) }
val all3UppercasePermutations = perm(3, uppercase).also { println(it) }.also { println(it.size) }
for (i in 0..999) {
println("trying $i")
for (l in all3LowercasePermutations) {
for (u in all3UppercasePermutations) {
if ("$i$l$u" == password) {
println("found: $i$l$u")
exitProcess(0)
}
}
}
}
}
In Kotlin I am having an issue with data not fully loading into the buffer in Android in one packet. I am sending <7:16> data packet from a HC-06 bluetooth module.
When i receive it's coming in as 2 packets. The micro is sending a CR and LF and the end of the transmission.
I/UI_Msg: <
I/UI_Msg: 7:16>
I/UI_Msg: <
I/UI_Msg: 7:16>
etc
If I add a sleep command for a second, then query the buffer it comes in completed in one packet. The problem is I want to send more than one packet in a second..
How can i fix this issue to or can i just build a string until '>' is received from the buffer.
private fun beginListenForData() {
val handler = Handler()
stopThread = false
buffer = ByteArray(10)
val thread = Thread(Runnable {
while (!Thread.currentThread().isInterrupted && !stopThread) {
try {
val byteCount = inputStream!!.available()
if (byteCount > 0) {
//Thread.sleep(1000) // wait for buffer finish filling
val rawBytes = ByteArray(byteCount)
inputStream!!.read(rawBytes)
val string = String(rawBytes, StandardCharsets.UTF_8)
//handler.post {txt_message.text=""}
Log.i(TAG,""+ string)
//handler.post {txt_message.append(string)}
// processInput(string)
}
} catch (ex: IOException) {
stopThread = true
}
}
})
thread.start()
}
Figgured it out. Read the buffer one byte at a time and build the string character at a time. Check for the < and the > character for a valid transmission
private fun beginListenForData() {
stopThread = false
val thread = Thread(Runnable {
while (!Thread.currentThread().isInterrupted && !stopThread) {
try {
val byteCount = inputStream!!.available()
if (byteCount > 0) {
val rawBytes = ByteArray(1)
inputStream!!.read(rawBytes,0,1)
val string = String(rawBytes, StandardCharsets.UTF_8)
if (string== "<") {
m_Headder=true
}
if (m_Headder==true){
stringBuilder = stringBuilder.plus(string)
if (string ==">") {
m_Received=stringBuilder
Log.i(TAG, "string:" + stringBuilder)
stringBuilder = ""
m_Headder = false
ProcessMessage(m_Received)
}
}
}
} catch (ex: IOException) {
stopThread = true
}
}
})
thread.start()
}