I've written a simple app the uses the Android Wear Messaging API. I followed a number of guides that all use a similar style of code for sending the message with some data which should be in byte[] form.
The code sending the message is
Wearable.MessageApi.sendMessage(client, nodeId, message, "test".getBytes());
and the receiving code is
final String messageData = new String(messageEvent.getData());
This seems to fit with a number of different guides and some of the official documentation - however the variable messageData ends up containing [B#4b0ad22 rather than test which is the data that was sent.
I've also tried explicit encoding/decoding with
String messageData = new String(messageEvent.getData(), "UTF-8");
but that throws a java.io.UnsupportedEncodingException
What's going wrong with the encoding or decoding?
You have to define the encoding/decoding but also wrap it in a try/catch block so the receiving code looks like this,
String messageData = "";
try {
messageData = new String(messageEvent.getData(), "UTF-8");
}
catch(Exception e)
{
Log.e("DecodingError", e.toString());
}
The sending code looks like this;
try {
Wearable.MessageApi.sendMessage(client, nodeId, message, "test".getBytes("UTF-8"));
}
catch(Exception e)
{
Log.e("EncodingError", e.toString());
}
Related
Whenever i am trying to encode or decode a string using UTF - 8 it is showing me Unhandled Exception: UnsupportedEncodingException.
So Android Studio is giving me two solution, which are
1) Use throws UnsupportedEncodingException
2) put that piece of code between try catch with UnsupportedEncodingException as catch argument..
So which one is good practice to use and why ?
public static String getEncodedString(String strOriginal) throws UnsupportedEncodingException {
byte[] dataFirstName = strOriginal.getBytes("UTF-8");
return Base64.encodeToString(dataFirstName, Base64.DEFAULT);
}
OR
public static String getEncodedString(String strOriginal) {
byte[] dataFirstName = new byte[0];
try {
dataFirstName = strOriginal.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return Base64.encodeToString(dataFirstName, Base64.DEFAULT);
}
I would go for the second snippet, UTF-8 is one of the standard character encodings supported by every platform so the exception can actually never happen. It does not make sense to propagate it further.
If you are developing for API 19 or later, you can also use
strOriginal.getBytes(StandardCharsets.UTF_8)
which does not throw an exception.
I am using this example to communicate between arduino and android, and it works well.
The problem is that i would make sure all data has been received before outputting it.
As it is now android will simply output everything when it is being received.
I need to collect whatever is received so that i for example can compare it to another string.
Currently it works like this
UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { //Defining a Callback which triggers whenever data is read.
#Override
public void onReceivedData(byte[] arg0) {
String data = null;
try {
data = new String(arg0, "UTF-8");
data.concat("/n");
tvAppend(textView, data);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
};
And arduino:
void setup()
{
Serial.begin(9600);
}
void loop()
{
char c;
if(Serial.available())
{
c = Serial.read();
Serial.print(c);
}
}
Example:
Sent to arduino:
TEST
Received from arduino:
TEST
However in reality its more like this
Sent to arduino:
TEST
Received from arduino:
T E ST
So the received "TEST" will come in bytes of one or two which then needs to be gathered into a string.
I assume the reason for this is due to the rate/speed of incoming bytes so that it will just output it as soon as it gets the data.
I would like to make sure that all incoming data is received before I output it, so that I can work with the incoming data.
In theory in need something like while(serial.available())... for android.
Any help is appreciated
I want to ask if there's some way to split data obtained from server by some unique separator.
Here is an example:
I use AsyncTask to send data to server and then I use echo command for sending those back to my application and in onPostExecute I split these data to needed result.
So let's say, that I want to get from server data for Name and Surname, so echo command on server will look like this: echo $name."&".$surname;
And then in onPostExecute I will split this data by "&" separator, but problem occurs when user writes to name or surname my separator "&" which I am using for split.
How can I avoid this issue?
Look into using JSON. It's a life saver for sending data.
Android has native JSON support using a JSONObject.
Documentation
It essentially provides a formatter and parser for information placed within the object that are then accessible via keywords.
To write a json:
public String writeJSON() {
JSONObject object = new JSONObject();
try {
object.put("name", "John");
object.put("surname", "Doe");
return object.toString();
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
This will return a string that looks like:
{"name":"John","surname":"Doe"}
To read:
public void readJSON(String jsonString){
try {
JSONObject object = new JSONObject(jsonString);
String name = object.getString("name");
String surname = object.getString("surname");
} catch (JSONException e){
e.printStackTrace();
}
}
You need to escape the character you are using to separate the different entries in the content you are transmitting [1]. For example:
My\&FirstName&MySecondName (In this case \ is used as escape character)
However, you don't need to reinvent all this stuff. There are several formats that you could use to transmit your data:
json
xml
csv
[1] https://en.wikipedia.org/wiki/Escape_character
I'm developing an Android real-time-data app that sends data (floats and ints) to a server on the local subnet via a TCP socket. The problem I'm facing is that after sending some data simultaneously the socket doesn't send anymore data at all. I debugged the app and it shows that data is being sent but doesn't show up on the server. After this happens if I close the connection the server doesn't even get the notification that the connection has been terminated which it should according to my design model. Meanwhile I get an exception on the app saying it can not write to a broken pipe. This tells me that the problem is with the app because I also did test using a desktop app and I can send huge amounts of data to the server and it gets delivered.
And please keep in mind that the data size I'm talking about here is 252 bytes per packet.
Here's my class I'm using. (This runs in an AsyncTask object )
public class Network
{
private Socket handle;
public static enum TASK
{
TASK_CONNECT, TASK_SEND, TASK_CLOSE
}
public Network()
{
}
public String lastError = "";
public boolean Connect(String host, int port)
{
try
{
lastError = "Connecting to server.";
handle = new Socket(host, port);
handle.setTcpNoDelay(true); //
handle.setSendBufferSize(SIZE_OF_PACKET); ///==> These don't seem to help at all
handle.setKeepAlive(true); ///
return true;
}catch(IOException e)
{
lastError += e.getMessage() != null ? " "+ e.getMessage() : "";
return false;
}
}
private void err(String e){
System.err.println(e);
}
private boolean SendPacket(byte buffer[])
{
OutputStream oStream = null;
err("sending: " + buffer.length + " bytes");
try
{
lastError = "Obtaining output stream.";
oStream = handle.getOutputStream();
lastError = "Error sending data.";
oStream.write(buffer);
oStream.flush();
return true;
}catch(Exception e)
{
lastError += e.getMessage() != null ? " "+ e.getMessage() : "";
}
return false;
}
public void Close()
{
try{ handle.close(); handle = null; }catch(Exception e){} // swallow exception
}
}
I send my data in a loop depending on how many numbers I have. I tried a Google search but didn't find anything relevant. Has anyone experienced this before? It's making me mad now.
EDIT: Wireshark shows incoming "red" packets that don't reach the desktop app (server)
Look at this picture.
You can see the first few have Len > 0 the red ones have 0.
I think it's time Google interfaced the USB so we can use it. At least that'd would have been my first option.
Should you not be calling oStream.close() after you flush the stream, given that you never use it again?
Also, you say that this is being run in an AsyncTask object. Is it possible that multiple threads could be attempting to send packets at the same time? If so, you might need some form of synchronisation around the SendPacket method.
Ok. I solved the issue by using UDP instead. Thank you all.
But I still didn't find the source of the problem.
I have a big problem with parsing some json data which I get as response from a web server. The thing that I'm doing is I get the response via POST and than convert the response as string and parse it. But in some devices I get OutOfMemoryError , which I'm trying to fix. Here is how I'm converting the response to string :
public static String convertStreamToString(InputStream is) throws Exception {
ByteArrayOutputStream into = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
for (int n; 0 < (n = is.read(buf));) {
into.write(buf, 0, n);
}
into.close();
return new String(into.toByteArray(), "UTF-8");
}
and here is how I'm using this piece of code :
InputStream response = new BufferedInputStream(connection.getInputStream());
try {
String responsee = convertStreamToString(response);
jsonParser(responsee);
} catch (Exception e) {
e.printStackTrace();
cancelDialog("Error occurred! Please try again later.");
}
Any suggestions how can I fix that problem so don't happen in all devices?
Thanks in advance for any kind of help or advices.
The mobile has limited internal memory.
I have also face same issue. The solution that we found is that download only the necessary information. So you please confirm your requirement how much data you want to inside the mobile. If you filter the unnecessary data then the problem will get resolved.
Before testing the program on extreme condition first check whether simple download happening if it is happening then check the limit of your data means up to how extent it will not give out of memory error. and accordingly that rework your requirement.