How do I take the byte value out of this class? - java

I want to take the byte value out of this class so I can parse it, or if it's possible parse it inside and get the 5th and 6th byte value out.
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
// This is special handling for the Heart Rate Measurement profile. Data parsing is
// carried out as per profile specifications:
// http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data)
stringBuilder.append(String.format("%02X", byteChar));
intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString());
} else {
// For all other profiles, writes the data formatted in HEX.
}
}
sendBroadcast(intent);
}
How this works is that I step on a scale and it sends me these bytes:
00 00 00 00 02 02 00 00 00 00 00 00 00 00 00 00
Which is stored at the variable 'data'. How do I take 'data' out to use in another class?
The weight data is on bytes 5 and 6. If you convert the hex values of bytes 5 and 6, in that example is '0202' it becomes 514 in decimal (51.4kg).
I need to take the bytes data to use in another class to get the kg data. How would I go around doing so?

You can simply get those two bytes and apply below:
int result = ByteBuffer.wrap(bytes).getInt();
If you want more info: HERE1, HERE 2

Related

Java scanner delimiter causes my integer to not be read properly

So I'm creating a scanner to read off of a simple text file:
import java.io.*;
import java.util.Scanner;
public class Weather {
public static void main(String[] args) throws FileNotFoundException {
int a;
File weatherData = new File("C:\\Users\\taddi\\eclipse-workspace\\COS_160_ASSIGNMENT_10\\src\\PortlandWeather1941to2018.txt");
Scanner scnr = new Scanner(weatherData);
scnr.useDelimiter("//");
int totalCount = scnr.nextInt();// this reads the number at the beginning and uses it so I know how many times to run the loop
String throwAway1 = scnr.nextLine();//these statement are used to throw a way the rest of line 1, and all of line 2 and 3
String throwAway2 = scnr.nextLine();
String throwAway3 = scnr.nextLine();
int[] month = new int[totalCount];
int[] day = new int[totalCount];
int[] year = new int[totalCount];
int[] tmax = new int[totalCount];
int[] tmin = new int[totalCount];
for(a = 0; a < totalCount; a ++) {
month[a] = scnr.nextInt();
System.out.println(month[a]);
day[a] = scnr.nextInt();
System.out.println(day[a]);
year[a] = scnr.nextInt();
tmax[a] = scnr.nextInt();
tmin[a] = scnr.nextInt();
}
}
}
The first part of the text file is an integer I'm trying to read. For some reason, it only reads that integer when I comment out the scnr.useDelimiter("//"); line, otherwise I get an InputMismatchException
I'd love to just get rid of all the unnecessary words and slashes in the text file but that wouldn't satisfy the assignment. What's going wrong with the delimiter? How do I read the integer?
Your delimiter is a string, and it will not work in your use case the way you want.
I assume your sample data is like this (ignoring the header lines) ...
01/01/1941 38 25
01/02/1941 32 20
... so you are looking to get each number - the date elements and the tmax/tmin values - so a single delimiter character of '/' would only break up the date.
For example:
final String data =
"01/01/1941 38 25 \n"+
"01/02/1941 32 20 \n";
Scanner scnr = new Scanner(data);
scnr.useDelimiter("/");
while(scnr.hasNext()) {
System.out.println(scnr.next());
}
scnr.close();
outputs the following ...
01
01
1941 38 25
01
02
1941 32 20
showing that it splits on the date d/m/y slashes, but the year and tmax and tmin are bundled together.
Adjusting the scanner to use a Pattern delimiter allows us to split on the slashes and the spaces.
final String data =
"01/01/1941 38 25 \n"+
"01/02/1941 32 20 \n";
Scanner scnr = new Scanner(data);
scnr.useDelimiter(Pattern.compile("[/ ]+"));
while(scnr.hasNext()) {
System.out.println(scnr.next());
}
scnr.close();
}
giving the output I think you want:
01
01
1941
38
25
01
02
1941
32
20
However, note that in my example data I have trailing whitespace on each line and they are thus also returned as empty String tokens. If I was scanning for nextInt() I would get an java.util.InputMismatchException error. Depending on the exact formatting of your input you may need to cater for that.

Strange StringIndexOutofBoundsException caused when converting hex string to binary

I'm not sure what is causing this exception, and the stack trace isn't being helpful as it states it was caused by an unknown source.
The method below takes two hexadecimal strings, one representing an opcode and one representing an operand, and converts them to binary before concatenating them and adding them to an arraylist. Simple enough. In order to ensure each binary string includes the full 8 bits I'm using a small utility method called hexToBinary, for some reason, when I attempt to use this method to convert my hexadecimal strings it causes the exception.
The opcode and operands, which are taken from the asmLine objects give this input below:
A9 10
90 C6
0A 00
11 FF
38 00
7D FF
81 FF
A1 09
AA 00
20 11
58 00
6C 09
FE 10
All of the above hexadecimal values should be converted to binary. But this is not happening. The strange thing is that when I explicitly state the hexadecimal value to be converted by the utility method, as I do with the line String beginBinary = Utils.hexToBinary("FA"); works completely normally. I just can't understand why this isn't working when I'm using the values pulled from the asmLine objects.
public void constructBinaryOutput()
{
ArrayList<String> binaryOut = new ArrayList<String>();
String beginBinary = Utils.hexToBinary("FA"); //This works normally
String endBinary = Utils.hexToBinary("FF"); //This works normally
String twoByteString = beginBinary.concat(" " + beginBinary);
binaryOut.add(twoByteString);
for(AssemblyLine asmLine : lineObjects)
{
String opcodeHex = asmLine.getOpcodeHEX();
String operandHex = asmLine.getOperandHEX();
System.out.println("Hex opcode/operand: " + opcodeHex + " " + operandHex);
String opcodeBinary = Utils.hexToBinary(opcodeHex); //This causes an exception
String operandBinary = Utils.hexToBinary(operandHex);
System.out.println("Hex opcode " + asmLine.getOpcodeHEX() + " converted into binary " + opcodeBinary);
System.out.println("Hex operand " + asmLine.getOperandHEX() + " converted into binary " + operandBinary);
twoByteString = opcodeBinary.concat(" " + operandBinary);
System.out.println("2 Byte instruction: " + twoByteString);
binaryOut.add(twoByteString);
}
}
Utility method hexToBinary
public static String hexToBinary(String hex)
{
String bin = Integer.toBinaryString(Integer.parseInt(hex,16));
int length = bin.length();
return length == 8 ? bin : "00000000".substring(length - 8) + bin;
}
Just a simple mistake in your util function. It should be:
public static String hexToBinary(String hex) {
String bin = Integer.toBinaryString(Integer.parseInt(hex, 16));
int length = bin.length();
return length == 8 ? bin : "00000000".substring(length) + bin;
}
notice the substring.
HTH,
Gal

Difference between C# and Java when converting DateTime to byte array

I have a Java program that reads each value from a database and converts it to a byte array. I am currently trying to write an equivalent program in C#. However, I'm having difficulties with DateTimes. The Java code and the C# code produce different byte values.
Here is the Java code:
ResultSet rs = stmt.executeQuery("select * from " + query);
while (rs.next())
{
for (int j = 1; j <= rs.getMetaData().getColumnCount(); j++)
{
byte[] b = rs.getBytes(j);
if (!rs.wasNull() && b != null)
{
for(int i = 0; i < b.length; i++)
System.out.print(b[i] + " ");
}
}
}
Output for the DateTime 2/19/2016 3:12:21 PM:
-71 -3 65 70 116 -74 -28 64
Here is the C# code:
OleDbCommand cmd = new OleDbCommand("select * from " + name, conn);
OleDbDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
for (int i = 0; i < rdr.FieldCount; i++)
{
if (rdr[i] != DBNull.Value && rdr[i] is DateTime)
{
DateTime date = (DateTime)rdr[i];
byte[] b = BitConverter.GetBytes((long)date.Ticks);
foreach (byte bt in b)
Console.Write(unchecked((sbyte) bt) + " ");
}
}
}
Output for the DateTime 2/19/2016 3:12:21 PM:
-128 -72 98 16 63 57 -45 8
I am not sure how to get these to match. According to the Java documentation for ResultSet's getBytes(int columnIndex) method, "the bytes represent the raw values returned from the driver". So it seems that, unlike the standard C# protocol, it is NOT using the ticks value in order to produce the bytes. This becomes apparent when attempting to translate the byte array back into a DateTime. Converting -71 -3 65 70 116 -74 -28 64 into a long gives you 4676062923628608953. But that value exceeds the maximum tick value for a DateTime, so it cannot be converted into a valid DateTime.
So how does Java end up with those particular byte values then?
I need a way of converting DateTime to byte[ ] in C# that will ALWAYS have the same behavior as Java's getBytes(int columnIndex) method. I cannot modify the Java code. The C# output must match the Java output. Is this possible?
getBytes() is not defined for non-binary data, e.g. it may return driver-specific data.
The bytes represent the raw values returned by the driver.
It would seem that the particular database / JDBC driver you are using is sending the value as a double.
-71 -3 65 70 116 -74 -28 64 is actually b9 fd 41 46 74 b6 e4 40 in hex, which is the double value 42419.633576388886 in Little-Endian order.
byte[] b = { -71, -3, 65, 70, 116, -74, -28, 64 };
System.out.println(ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN).getDouble());
42419.633576388886
If you paste that into Excel and format it as m/d/yyyy h:mm:ss AM/PM, you get 2/19/2016 3:12:21 PM.
See here for how to convert in C#.

how to parse floating hexadecimal string in java

my hexadecimal string
string s=new String("FF7900002481201132570943440402151302961500080054021E000040FFFFFBFF79000024812011");
i want particular data in string..
my format : 2481201132570943440402151302961500080054021E000040FFFFFBFF790000
it's must starting value in string 24 .
and it's split at end of 62 . values(2481201132570943440402151302961500080054021E000040FFFFFBFF790000=62)
and finally to split the string ?
12 content value in hexadecimal
24 ---> (1)
8120113257 --(5)
094047 ---(3)
040215 ---(3)
13029615 ----- (4)
00 ------- (1)
080054021E -------(5)
000040 ---- (3)
FFFFFBFF -- (4)
79 ---(1)
00 ------(1)
00 ----- (1)
how to solve it in java code?
Thanks
You can parse the String as a series of Strings.
class StringParser {
final StringReader sr;
public StringParser(String text) {
sr = new StringReader(text);
}
public String next(int n) {
char[] chars = new char[n];
sr.read(chars);
return new String(chars);
}
public String nextAsLong(int n) {
return Long.parseInt(next(n));
}
}
StringParser sp = new StringParser("FF7900002481201132570943440402151302961500080054021E000040FFFFFBFF79000024812011");
sp.next(8); // ignored
long first= sp.nextAsLong(2);
long second = sp.nextLong(10);
// etc
You can use
Long.parseLong(string, 16);
Size of content is fixed or floating?
If yes you can use substring and: Long.parseLong("FFFFFBFF", 16);

How do I get java to store a text file in a 2D array and locate a specific point in said array?

I'm using Eclipse for this program and I'm trying to do is get the program to read the text file "ClimateDataA" and then find the date of the first time the temperature is under 80 degrees and I have to use for & while loops.
This is what the text file "ClimateDataA" contains:
14939 20140801 86
14939 20140802 90
14939 20140803 93
14939 20140804 87
14939 20140805 93
14939 20140806 83
14939 20140807 81
14939 20140808 83
14939 20140809 85
14939 20140810 85
14939 20140811 80
14939 20140812 81
14939 20140813 87
14939 20140814 89
14939 20140815 76
14939 20140816 87
14939 20140817 92
14939 20140818 91
14939 20140819 93
14939 20140820 96
14939 20140821 90
14939 20140822 93
14939 20140823 95
14939 20140824 91
14939 20140825 83
14939 20140826 81
14939 20140827 77
14939 20140828 82
14939 20140829 75
14939 20140830 87
14939 20140831 92
Column 1 is an ID number. Column 2 is the date. Column 3 is the temperature.
This is my code so far:
import java.util.Scanner;
import java.io.*;
public class ClimateSummary
{
public static void main (String [] args) throws FileNotFoundException
{
Scanner userInfo = new Scanner (new File("MyInfo.txt"));
Scanner weatherData = new Scanner (new File("ClimateDataA.txt"));
String userName = userInfo.nextLine();
String userBirthPlace = userInfo.nextLine();
int userBirthDay = userInfo.nextInt();
String userBirthMonth = userInfo.next();
int userBirthYear = userInfo.nextInt();
String dataLocation = userInfo.next();
int [][] myArray = new int[31][3];
for (int i = 0; i < myArray.length; i++) {
}
System.out.println("Welcome " + userName + "! This is the Super Computing Weathernator 3000!");
System.out.println();
System.out.println("Name: " + userName);
System.out.println("Date of birth: " + userBirthDay + " " + userBirthMonth + " " + userBirthYear );
System.out.println("Place of birth: " + userBirthPlace);
System.out.println("Data collected at: " + dataLocation);
System.out.println();
System.out.println("The first day under 80 degrees is ");
userInfo.close();
}
}
Without these lines of code the program can run.
Scanner weatherData = new Scanner (new File("ClimateDataA.txt"));
int [][] myArray = new int[31][3];
for (int i = 0; i < myArray.length; i++) {
}
This is the output I'm trying to get:
Welcome Eric Hornberger! This is the Super Computing Weathernator 3000!
Name: Eric Hornberger
Date of birth: 18 February 1960
Place of birth: Columbus, Nebraska
Data collected at: Columbus
The first day under 80 degrees is 15/08/2014
The first five lines are using data from the "MyInfo" text file.
I'm going to have to parse to get the date exactly like that in the output but I only need help with getting the data I'm looking for.
Can anyone help me do this properly?
Thanks for your time!
You should think of each line in your file as a separate string. Then you can split those strings into parts (id, date, temperature) and get the data from each column. Here is an older question about splitting up strings:
How to split a string in Java
And here is info on how to read the lines from your file:
Java read line from file
So putting it together:
Loop thorugh the lines in your file
Treat each line as a String that you split (on blank space in your case) to get the data
If the temperature value is lower than the previously found minimum, save the values in some variables
Hope that will at least help you get started!
Another thing also:
Since you are using Java, you might want to consider using an array of objects for you data instead of a 2D array, something along the line of:
public Class WeatherData {
private int id;
private Date date;
private int temperature;
/** Getters, setter, contructor etc */
}
That will make your program easier to read and modify when needed.

Categories