0

This may sound like a trivial question, but I'm having a really hard time trying to figure it out. Basically I'm sending a string from my Android to my PC. All the connection is ok, and the string is transfered successfully. This is the Android code (sends string to computer):

  try
  {
    println(scSocket + "");
    if (scSocket!=null) 
    {
    SendReceiveBytes sendReceiveBT = new SendReceiveBytes(scSocket);
    String red = rotZ + " \n";
    byte[] myByte = stringToBytesUTFCustom(red);
    sendReceiveBT.write(myByte);
    }
  }
  catch(Exception e)
  {
    println(e);
  }

Where rotZ is what I want to send, it is a "float" value. I need to put the " \n" on the end of the message so that it will be recognized as a full message on the PC. So far so good. Now I want to read this on my PC, which is achieved by:

  //BlueTooth
  String lineRead = "";
  try
  {
    lineRead = new String(sampleSPPServer.readFromDevice());
    if(lineRead != null && !lineRead.isEmpty())
    {
      String lineTransf = lineRead.replace("\n", "").replace("\r", "").replace(" ", "").replace("\"", "").trim();
      println("LineTransf: " + lineTransf);
      rotZ += 0.01*(Float.parseFloat(lineTransf));
      println("Zrotation: " + rotZ); //Never gets here, throws and error before...
    }
    else
      rotZ += 0;
  }
  catch(Exception e)
  {
    println("Exception: " + e);
  }

Which gives me the error:

NumberFormatException: invalid float value: "1.1400002"

In my code you can see I check for null, empty, etc. So that's not the problem. I've already tried:

  NumberFormat nf = NumberFormat.getInstance(Locale.US);
  rotZ += 0.01*(nf.parse(lineTransf).floatValue());

Got the same result... In stackoverflow there is a similar question: Here

There is one more strange thing, If I try the code:

  for(int i = 0; i < lineTransf.length(); i++)
    println(lineTransf.substring(i,1));

I get that the string's length is 19, but it only prints the first two and gives the message:

Exception: java.lang.StringIndexOutOfBoundsException: String index out of range: -1

Even more strange thing, when I did ctrl-c, ctrl-v on the number "1.1400002" that appears in the console, it only pastes "1" here on stack overflow. I know that the number is right, but somewhere the conversion is not. I think that's because the string is sent as a byte and read as a String, but how do I solve this problem? Thanks in advance!!

Community
  • 1
  • 1

2 Answers2

0

Nothing strange. that's the expected behavior of substring. It throws an IndexOutOfBoundsException, if the startIndex is negative, the endIndex is greater than the string's length or if startIndex is greater the endIndex (which is your case). To me it looks like you want to print the char at index. Try with

for(int i = 0; i < lineTransf.length(); i++)
    println(lineTransf.charAt(i));
Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • I'm sorry, you are right, I made the change, and it prints: lineTransf: 1.8399 and then 1 . 8 3 9 9, but still gives me the length 19 and the Exception: java.lang.NumberFormatException: For input string: – Mateus Berruezo Mar 07 '15 at 13:33
  • no worries. Which part is not working? Both "1.8399" and "1.1400002" are valid *parsable*-like float – Blackbelt Mar 07 '15 at 13:41
  • Exactly, that's what I'm not understanding. The line println("LineTransf: " + lineTransf); prints those numbers, but rotZ += 0.01*(Float.parseFloat(lineTransf)); gives me the NumberFormatException no matter what i do. – Mateus Berruezo Mar 07 '15 at 13:46
  • I see. But also those 19 chars are strange, aren't they? Can you print `println("LineTransf: " + lineTransf + " size " + lineTransf.length());` ? – Blackbelt Mar 07 '15 at 13:49
  • It prints exactly this to the console: LineTransf: 9.959991 size 15 For other numbers, it prints the number and a bigger size (just like above) – Mateus Berruezo Mar 07 '15 at 14:06
0

I found a work around, but I really, really would like an explanation (if possible), because this is just too ugly... I changed the code to:

//BlueTooth
  String lineRead = "";
  try
  {
    lineRead = new String(sampleSPPServer.readFromDevice());
    if(lineRead != null && !lineRead.isEmpty())
    {
      String lineTransf = lineRead.replace("\n", "").replace("\r", "").replace(" ", "").replace("\"", "").trim();
      println("LineTransf: " + lineTransf + " " + lineTransf.length());
      String lastTry = "";
      for(int i = 0; i < lineTransf.length(); i++)
      {
        if(lineTransf.charAt(i) != ' ' && lineTransf.charAt(i) != '\u0000')
        {
          println(lineTransf.charAt(i));
          lastTry += lineTransf.charAt(i);
        }
      }
      println("LastTry: " + lastTry);
      rotZ += 0.01*(Float.parseFloat(lastTry));
      println("Zrotation: " + rotZ);
    }
    else
      rotZ += 0;
    //System.out.println("Line Read:" + lineRead);
  }
  catch(Exception e)
  {
    println("Exception: " + e);
  }

I'm basically creating a new String called lastTry and then checking if each of the bluetooth read characters are not empty(?) null(?) (since I'm testing for:)

if(lineTransf.charAt(i) != ' ' && lineTransf.charAt(i) != '\u0000')

And if they pass this test I individually "assemble" the lastTry String. It seems that the bluetooth is sending a null character between each of the characters of the whole string. I don't understand why this happens and it actually consumes some time while reading the incoming string. I really would love another answer if someone have another idea...