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.
Related
i want request to Flask server.
so, i converted a img to JSON data in Kotlin(Android Studio)
Although JSON data is well sent and received from the server, the size of the transmitted data is five times larger than the original data.
what should i do to get exact data from server??
Simple Server Code(python)...
print(len(request.json['file']))
img_data = base64.b64decode(request.json['file'])
filename = 'received_now_starry_night.png'
with open(filename, 'wb') as f:
f.write(img_data)
dic = {
"msg":"hello"
}
return jsonify(dic)
Android Studio, kotlin Code...
val bitmap:Bitmap = BitmapFactory.decodeResource(resources, R.drawable.starry_night)
val bos:ByteArrayOutputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, bos)
val image:ByteArray = bos.toByteArray()
val base64Encoded = java.util.Base64.getEncoder().encodeToString(image)
val rootObject = JSONObject()
rootObject.put("file", base64Encoded)
To convert an image to Base64 String :
You can also create a resized Bitmap and compress it to decrease the size
private fun CreateImageStringFromBitmap(): String {
val bitmap:Bitmap = BitmapFactory.decodeResource(resources, R.drawable.starry_night)
val resized = Bitmap.createScaledBitmap(
bitmap:Bitmap, (desired width).toInt(),
(desired height).toInt(), true
)
val stream = ByteArrayOutputStream()
resized.compress(Bitmap.CompressFormat.PNG, 75, stream)
val byteArray: ByteArray = stream.toByteArray()
return Base64.encodeToString(byteArray, Base64.DEFAULT)
}
I have configured Bluetooth Device that send data to Android App.
But I am receiving data in unreadable format.
Data I received from Bluetooth is below format.
���
��
���
Here is my android code
private val mmInStream: InputStream?
private val mmOutStream: OutputStream?
init {
var tmpIn: InputStream? = null
var tmpOut: OutputStream? = null
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = mmSocket.inputStream
tmpOut = mmSocket.outputStream
} catch (e: IOException) {
Log.e(TAG, ": " + e.message)
}
mmInStream = tmpIn
mmOutStream = tmpOut
}
override fun run() {
val buffer = ByteArray(1024) // buffer store for the stream
var bytes = 0 // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
bytes = mmInStream?.read(buffer) ?:0
val readMessage = String(buffer, 0, bytes)
Log.e("Arduino Message", readMessage.toString())
handler?.obtainMessage(MESSAGE_READ, readMessage)?.sendToTarget()
} catch (e: IOException) {
handler?.obtainMessage(CONNECTING_STATUS, 0, -1)?.sendToTarget()
e.printStackTrace()
break
}
}
}
Pls convert the received bytes to hex string via bytesToHex extension method and log it
fun ByteArray.bytesToHexString(
spaces: Boolean = false
): String {
val format = if (spaces) "%02x " else "%02x"
val sb = StringBuilder()
for (i in 0 until size) {
sb.append(format.format(this[i]))
}
return sb.toString()
}
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
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.
I have already done with java but find difficult with Kotlin.
I have already search with google but none of them work for me.
/**
* Get the json data from json file.
*
* #param context the context to acces the resources.
* #param fileName the name of the json file
* #return json as string
*/
public static String getJsonFromAsset(Context context, String fileName) {
String json = "";
try {
InputStream stream = context.getAssets().open(fileName);
int size = stream.available();
byte[] buffer = new byte[size];
stream.read(buffer);
stream.close();
json = new String(buffer, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return json;
}
I want this code in Kotlin.
Reading json file from assets folder in Kotlin is very easy, just use the following code
val fileInString: String =
applicationContext.assets.open(fileName).bufferedReader().use { it.readText() }
Java codes can be converted to Kotlin from Android Studio too.
Here is the converted solution with the extension function of Context.
#Throws(IOException::class)
fun Context.readJsonAsset(fileName: String): String {
val inputStream = assets.open(fileName)
val size = inputStream.available()
val buffer = ByteArray(size)
inputStream.read(buffer)
inputStream.close()
return String(buffer, Charsets.UTF_8)
}
You can use the following
class LocalJSONParser {
companion object {
fun inputStreamToString(inputStream: InputStream): String {
try {
val bytes = ByteArray(inputStream.available())
inputStream.read(bytes, 0, bytes.size)
return String(bytes)
} catch (e: IOException) {
return ""
}
}
}
}
// jsonFileName = "data.json"
inline fun <reified T> Context.getObjectFromJson(jsonFileName: String): T {
val myJson =LocalJSONParser.inputStreamToString(this.assets.open(jsonFileName))
return Gson().fromJson(myJson, T::class.java
}