Arduino - Android Bluetooth connecting getting 1st character wrong sometimes - java

i'm design an app that gets values from an Arduino via bluetooth connection and it can get the data but some times it gets the data but with the 1st digit wrong.
Like it gets 840,564,0,0,0,0 instead of 540,564,0,0,0,0.
this only happens in my app. Via USB it works perfect.
here is the code for the arduino.
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(38400);
pinMode(7, INPUT);
pinMode(6, INPUT);
pinMode(5, INPUT);
pinMode(4, INPUT);
}
void loop() {
// read the input on analog pin 1:
int pot1 = analogRead(A1);
// read the input on analog pin 0:
int pot2 = analogRead(A0);
int switch1 = digitalRead(7);
int switch2 = digitalRead(6);
int switch3 = digitalRead(5);
int switch4 = digitalRead(4);
// print out the value you read:
Serial.print(pot1);
Serial.print(",");
Serial.print(pot2);
Serial.print(",");
Serial.print(switch1);
Serial.print(",");
Serial.print(switch2);
Serial.print(",");
Serial.print(switch3);
Serial.print(",");
Serial.println(switch4);
delay(100); // delay in between reads for stability
}
and here is some of the code for my app
h = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case RECIEVE_MESSAGE: // if receive massage
byte[] readBuf = (byte[]) msg.obj;
String strIncom = new String(readBuf, 0, msg.arg1); // create string from bytes array
sb.append(strIncom); // append string
int endOfLineIndex = sb.indexOf("\r\n"); // determine the end-of-line
if (endOfLineIndex > 0) { // if end-of-line,
String sbprint = sb.substring(0, endOfLineIndex); // extract string
sb.delete(0, sb.length()); // and clear
// update TextView
dataFromArd=sbprint;
String segments[]=dataFromArd.split(",");
//angle1= -90 + (Integer.getInteger(segments[0]) - -333) * (90 - -90) / (333 - -333);
if (segments[0].length()>2 && segments[0].length()<4) {
int segmentInt1= Integer.parseInt(segments[0]);
int segmentInt2= Integer.parseInt(segments[1]);
if (segmentInt1 > 180 || segmentInt1 < 900) {
//angle1 = Integer.parseInt(segments[0]) - 529;
//angle1= -90 + (Integer.parseInt(segments[0]) - (515-333)) * (90 - -90) / (515+333) - (515-333);
int data1= (int) (0.27 * segmentInt1 - 139);
int data2=(int) (0.27 * segmentInt2 - 151);
if (data1!=angle1 && Math.abs(data1-angle1)<10){
angle1 = data1;
speedView.speedTo(angle1,5);
Log.d("int", segments[0] + "-" + Math.abs(data1-angle1) + "-" + angle1 + " " + segments[1] + "-" + Math.abs(data2-angle2) + "-" + angle2);
}
if (data2!=angle2 && Math.abs(data2-angle2)<25){
speedView2.speedTo(angle2,5);
angle2 = data2;
Log.d("int2", segments[0] + "-" + Math.abs(data1-angle1) + "-" + angle1 + " " + segments[1] + "-" + Math.abs(data2-angle2) + "-" + angle2);
}
//Log.d("int", Math.abs(data1-angle1) + "-" + angle1 + " " + Math.abs(data2-angle2) + "-" + angle2);
teste.setText("Data from Arduino: " + segments[0] + segments[1]);
}
}
}
//Log.d(TAG, "...String:"+ sb.toString() + "Byte:" + msg.arg1 + "...");
break;
}
};
};
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
public ConnectedThread(BluetoothSocket socket) {
InputStream tmpIn = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
}
public void run() {
byte[] buffer = new byte[256]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer); // Get number of bytes and message in "buffer"
h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget(); // Send to message queue Handler
} catch (IOException e) {
break;
}
}
}
}

It seems that the problem was excess usage of memory and that made the app skip frames and not getting the correct data.
I solved it by adding a dummy value for the first segment of data as a String and after filtering out the corrupt data (if the 1st segment != to String don't get data).
After that I made a lot of performance improvements that fixed the problem.

Related

how get current CPU temperature programmatically in all Android Versions?

I am using this code for get current CPU Temperature :
and saw it too
private float getCurrentCPUTemperature() {
String file = readFile("/sys/devices/virtual/thermal/thermal_zone0/temp", '\n');
if (file != null) {
return Long.parseLong(file);
} else {
return Long.parseLong(batteryTemp + " " + (char) 0x00B0 + "C");
}
}
private byte[] mBuffer = new byte[4096];
#SuppressLint("NewApi")
private String readFile(String file, char endChar) {
// Permit disk reads here, as /proc/meminfo isn't really "on
// disk" and should be fast. TODO: make BlockGuard ignore
// /proc/ and /sys/ files perhaps?
StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
FileInputStream is = null;
try {
is = new FileInputStream(file);
int len = is.read(mBuffer);
is.close();
if (len > 0) {
int i;
for (i = 0; i < len; i++) {
if (mBuffer[i] == endChar) {
break;
}
}
return new String(mBuffer, 0, i);
}
} catch (java.io.FileNotFoundException e) {
} catch (java.io.IOException e) {
} finally {
if (is != null) {
try {
is.close();
} catch (java.io.IOException e) {
}
}
StrictMode.setThreadPolicy(savedPolicy);
}
return null;
}
and use it like it :
float cpu_temp = getCurrentCPUTemperature();
txtCpuTemp.setText(cpu_temp + " " + (char) 0x00B0 + "C");
it is work like a charm but for android M and under. For Android N and above (7,8,9) Do not Work and Show The Temp like this :
57.0 in android 6 and under (6,5,4)
57000.0 in android 7 and above (7,8,9)
I try this code too :
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
txtCpuTemp.setText((cpu_temp / 1000) + " " + (char) 0x00B0 + "C");
}
but do not work :(
How can I get the Temp in all android versions??
UPDATE:
I change The code like it and work on some devices
Except Samsung:
float cpu_temp = getCurrentCPUTemperature();
txtCpuTemp.setText(cpu_temp + " " + (char) 0x00B0 + "C");
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
txtCpuTemp.setText(cpu_temp / 1000 + " " + (char) 0x00B0 + "C");
}
Divide the value by 1000 on newer API:
float cpu_temp = getCurrentCPUTemperature();
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
cpu_temp = cpu_temp / 1000;
}
I'd just wonder where batteryTemp comes from and how it should be related to the CPU.

Read and Write to USB Device on Raspberry Pi 3 using Java

I'm using Raspbian on a Raspberry Pi 3. I'm learning how to code in Java (SE runtime version 1.8.0_65), and I need to communicate raw data with a USB connected Bill Acceptor. According to the manufacturer's documentation, the USB unit mimics a serial-type interface. When I plug the device in, it appears in /dev/serial/by-id. I wrote C code 20+ years ago using modems on SCO Unix setups. If memory serves, I basically treated the modems /dev/ttyxx as a file for reading and writing. I wrote a C++ program 10+ years ago on Windows XP using a similar Bill Acceptor unit (same manufacturer and model) connected to a serial port instead of USB. The documentation shows both USB and serial units use the same data strings for input and output, so I know the SendString data should be correct for triggering a valid response. However, I'm not getting a reply from the unit, so I'm guessing I'm not connecting properly to it.
Here is the code...
public static void main(String[] args) {
try
{
System.out.println("*****************************");
System.out.println("***** Starting Program *****");
System.out.println("*****************************");
String strUsbDeviceDir = "/dev/serial/by-id";
File myUsbDeviceDir = new File(strUsbDeviceDir);
if(myUsbDeviceDir.exists())
{
String[] myUsbDevices = myUsbDeviceDir.list();
for(int i=0; i<myUsbDevices.length; i++)
{
if(myUsbDevices[i].contains("EBDS_over_USB"))
{
System.out.println("Connecting to " + myUsbDevices[i]);
funcBillAcceptor(strUsbDeviceDir + "/" + myUsbDevices[i]);
}
else
{
System.out.println("Not using " + myUsbDevices[i]);
}
}
}
}
catch (Exception ex)
{
System.err.println(ex.toString());
}
}
public static void funcBillAcceptor(String strBillAcceptor)
{
boolean bOddCount = false;
byte[] SendString = new byte[8];
byte[] RecvString = new byte[10];
byte CheckDigit;
int iSendStringCount, iRecvStringCount, iRecvEmptyCount;
try
{
File fBillAcceptor = new File(strBillAcceptor);
if(!fBillAcceptor.canRead())
{
System.out.println("No Read Permission for " + strBillAcceptor);
return;
}
if(!fBillAcceptor.canWrite())
{
System.out.println("No Write Permission for " + strBillAcceptor);
return;
}
RandomAccessFile rafBillAcceptor = new RandomAccessFile(strBillAcceptor, "rwd");
if(rafBillAcceptor != null)
{
System.out.println("Successfully opened " + strBillAcceptor);
}
while(fBillAcceptor.exists())
{
SendString[0] = (byte) 0x02; //STX
SendString[1] = (byte) 0x08;
if(bOddCount)
{
SendString[2] = (byte) 0x10;
bOddCount = false;
}
else
{
SendString[2] = (byte) 0x11;
bOddCount = true;
}
SendString[3] = (byte) 0x1F;
SendString[4] = (byte) 0x0C;
SendString[5] = (byte) 0x00;
SendString[6] = (byte) 0x03; //ETX
//CheckDigit skips STX (byte 0) with byte 1 as seed/initial value
//To calculate the check digit, start with next byte (2)
CheckDigit = SendString[1];
iSendStringCount = 2;
while(SendString[iSendStringCount] != 0x03)
{
CheckDigit = (byte) (SendString[iSendStringCount]^CheckDigit); //XOR current CheckDigit value with next byte
iSendStringCount++;
}
iSendStringCount++; //advance one more so we don't overwrite ETX
SendString[iSendStringCount] = (byte) CheckDigit;
try
{
rafBillAcceptor.write(SendString);
System.out.println("Sent: " + DatatypeConverter.printHexBinary(SendString));
}
catch (Exception ex)
{
System.err.println("Write exception: " + ex.toString());
}
System.out.println("Reading...");
iRecvStringCount = iRecvEmptyCount = 0;
try
{
do
{
iRecvStringCount = rafBillAcceptor.read(RecvString);
System.out.println("Read " + iRecvStringCount + " bytes.");
if(iRecvStringCount < 0)
{
iRecvEmptyCount++;
Thread.sleep(5);
}
} while (iRecvStringCount < 0 && iRecvEmptyCount < 100);
if(iRecvStringCount > 0)
{
System.out.println("Received: " + DatatypeConverter.printHexBinary(RecvString));
}
}
catch (Exception ex)
{
System.err.println("Read exception: " + ex.toString());
}
}
}
catch (Exception ex)
{
System.err.println(ex.toString());
}
}
Here is the output I'm getting...
*****************************
***** Starting Program *****
*****************************
Connecting to usb-Silicon_Labs_Series_2000_Bill_Acceptor__EBDS_over_USB__46580120748-if00-port0
Successfully opened /dev/serial/by-id/usb-Silicon_Labs_Series_2000_Bill_Acceptor__EBDS_over_USB__46580120748-if00-port0
Sent: 0208111F0C00030A
Reading...
Am I missing something obvious, or just going about this all wrong? Thanks for any suggestions!
I was able to successfully communicate with the Bill Acceptor from a Raspberry Pi 3 (running Raspbian) using the RXTXComm library. When communicating with the device from an old Windows XP computer using a 9-pin serial/RS232 harness, I had to use 9600/7/E/1. If I don't use those values for setSerialPortParams (in my sample code), I'm not able to correctly send/receive data. So, you need to know what the device is expecting in order to use this approach with other "serial" hardware connected via USB. Below is code with the basic functionality. I started with one of the sample programs that come with the RXTXComm library and built out from there. Since this is a sample program, I haven't yet added logic to verify the checksum digit for data coming from the device.
You may notice at the bottom of the code that I'm able to determine the /dev/ttyUSBx using the canonical name of the device that I pull from the /dev/serial/by-id directory/folder. It finds the correct device name regardless of which USB port the unit is plugged in to or what order the USB devices get initialized by the system. I have a card dispenser that is also a USB serial device, so I was able to test and confirm this functionality.
public TwoWaySerialComm()
{
super();
}
static boolean bReadyToSend = false;
void connect ( String portName ) throws Exception
{
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
if ( portIdentifier.isCurrentlyOwned() )
{
System.out.println("Error: " + portName + " is currently in use.");
}
else
{
CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000);
if ( commPort instanceof SerialPort )
{
SerialPort serialPort = (SerialPort) commPort;
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_7, SerialPort.STOPBITS_1, SerialPort.PARITY_EVEN);
InputStream in = serialPort.getInputStream();
OutputStream out = serialPort.getOutputStream();
// Thread handling logic
// https://www.javaspecialists.eu/archive/Issue056.html
Thread readThread = new Thread(new SerialReader(in));
readThread.start();
Thread writeThread = new Thread(new SerialWriter(out));
writeThread.start();
// Running threads for 10 seconds then stopping to ensure threads are shutting down
long threadCurrTime = System.currentTimeMillis();
long threadStartTime = System.currentTimeMillis();
while( (threadCurrTime - threadStartTime) < 10000)
{
try
{
Thread.sleep(100);
}
catch (InterruptedException ex)
{
Logger.getLogger(TwoWaySerialComm.class.getName()).log(Level.SEVERE, null, ex);
}
threadCurrTime = System.currentTimeMillis();
}
if(writeThread.isAlive())
{
//System.out.println("Sending interrupt to SerialWriter thread...");
writeThread.interrupt();
writeThread.join();
//System.out.println("SerialWriter thread is shut down.");
}
//else
//{
// System.out.println("SerialWriter thread is already shut down.");
//}
if(readThread.isAlive())
{
//System.out.println("Sending interrupt to SerialReader thread...");
readThread.interrupt();
readThread.join();
//System.out.println("SerialReader thread is shut down.");
}
//else
//{
// System.out.println("SerialReader thread is already shut down.");
//}
commPort.close();
}
else
{
System.out.println("Error: " + portName + " is not recognized as a valid serial device.");
}
}
}
/* SerialReader thread logic */
public static class SerialReader implements Runnable
{
InputStream in;
boolean bShuttingDown = false;
public SerialReader ( InputStream in )
{
this.in = in;
}
public void run ()
{
byte[] RecvString = new byte[12];
String strResponse;
int len = -1;
try
{
while (!bShuttingDown)
{
len = this.in.read(RecvString);
if( len > -1 )
{
strResponse = "";
if(RecvString[0] == 0x02 && RecvString[9] == 0x03)
{
if(RecvString[3] == 0x00 && RecvString[4] == 0x00 && RecvString[5] == 0x00 && RecvString[6] == 0x00)
{
strResponse = "Device not ready.";
}
else
{
//-- RecvString[3]------------------
if(RecvString[3] == 0x01)
strResponse = " - Idling";
else
if(RecvString[3] == 0x02)
strResponse = " - Accepting";
else
if(RecvString[3] == 0x04)
{
strResponse = " - Escrowed";
if(RecvString[5] == 0x08)
strResponse += " $1";
else
if(RecvString[5] == 0x10)
strResponse += " $2";
else
if(RecvString[5] == 0x18)
strResponse += " $5";
else
if(RecvString[5] == 0x20)
strResponse += " $10";
else
if(RecvString[5] == 0x28)
strResponse += " $20";
else
strResponse += " unrecognized bill inserted";
}
else
if(RecvString[3] == 0x08)
strResponse = " - Stacking";
else
if(RecvString[3] == 0x10)
strResponse = " - Stacked";
else
if(RecvString[3] == 0x11)
strResponse = " - Returning";
else
if(RecvString[3] == 0x12)
strResponse = " - Returned";
//-- RecvString[4]------------------
if(RecvString[4] == 0x01)
strResponse += " - Cheated";
else
if(RecvString[4] == 0x02)
strResponse += " - Rejected";
else
if(RecvString[4] == 0x04)
strResponse += " - Jammed";
else
if(RecvString[4] == 0x08)
strResponse += " - Bill Stacker Full";
else
if(RecvString[4] == 0x10)
strResponse += " - Removable Cassette Installed";
else
if(RecvString[4] == 0x11)
strResponse += " - Reserved";
else
if(RecvString[4] == 0x12)
strResponse += " - Calibration mode";
//-- RecvString[5]------------------
if(RecvString[5] == 0x01)
strResponse += " - Power Up Reset";
else
if(RecvString[5] == 0x02)
strResponse += " - Invalid Command";
else
if(RecvString[5] == 0x04)
strResponse += " - Non-recoverable fault";
}
if(!strResponse.contains("Idling"))
System.out.println("Recv: " + DatatypeConverter.printHexBinary(RecvString) + strResponse);
}
else
{
System.out.println("Recv (invalid): " + DatatypeConverter.printHexBinary(RecvString));
}
try
{
Thread.sleep(100); // need this delay before we send next polling message, otherwise the data doesn't come in correctly
bReadyToSend = true;
}
catch (InterruptedException ex)
{
Thread.currentThread().interrupt();
//System.out.println("Shut down SerialReader thread.");
bShuttingDown = true;
break;
}
}
}
}
catch ( IOException ex )
{
System.out.println("Recv exception: " + ex.toString());
}
}
}
/* SerialWriter thread logic */
public static class SerialWriter implements Runnable
{
OutputStream out;
long lastSendTime = System.currentTimeMillis() - 1001;
long currSendTime;
byte[] SendString = new byte[8];
byte CheckDigit;
int iSendStringCount;
boolean bOddCount = true;
boolean bShuttingDown = false;
public SerialWriter ( OutputStream out )
{
this.out = out;
}
public void run ()
{
while(!bShuttingDown)
{
currSendTime = System.currentTimeMillis();
if(currSendTime - lastSendTime > 1000) // if it's been more than a second, send query string
bReadyToSend = true;
if(bReadyToSend)
{
SendString[0] = (byte) 0x02; //STX
SendString[1] = (byte) 0x08;
if(bOddCount)
{
SendString[2] = (byte) 0x10;
bOddCount = false;
}
else
{
SendString[2] = (byte) 0x11;
bOddCount = true;
}
SendString[3] = (byte) 0x7F;
SendString[4] = (byte) 0x1C;
SendString[5] = (byte) 0x00;
SendString[6] = (byte) 0x03; //ETX
//CheckDigit skips STX (byte 0) with byte 1 as seed/initial value
//To calculate the check digit, start with next byte (2)
CheckDigit = SendString[1];
iSendStringCount = 2;
while(SendString[iSendStringCount] != 0x03)
{
CheckDigit = (byte) (SendString[iSendStringCount]^CheckDigit); //XOR current CheckDigit value with next byte
iSendStringCount++;
}
iSendStringCount++; //advance one more so we don't overwrite ETX
SendString[iSendStringCount] = (byte) CheckDigit;
try
{
lastSendTime = System.currentTimeMillis();
this.out.write(SendString);
//System.out.println("Sent: " + DatatypeConverter.printHexBinary(SendString));
}
catch ( IOException ex )
{
System.out.println("Send exception: " + ex.toString());
}
try
{
Thread.sleep(1); // this is hear simply to catch an external interrupt
}
catch (InterruptedException ex)
{
Thread.currentThread().interrupt();
//System.out.println("Shut down SerialWriter thread.");
bShuttingDown = true;
break;
}
bReadyToSend = false;
}
}
}
}
public static void main ( String[] args )
{
try
{
System.out.println("*****************************");
System.out.println("***** Starting Program *****");
System.out.println("*****************************");
String strUsbDeviceDir = "/dev/serial/by-id";
File myUsbDeviceDir = new File(strUsbDeviceDir);
if(myUsbDeviceDir.exists())
{
String[] myUsbDevices = myUsbDeviceDir.list();
for(int i=0; i<myUsbDevices.length; i++)
{
if(myUsbDevices[i].contains("EBDS_over_USB"))
{
File tempFile = new File(strUsbDeviceDir + "/" + myUsbDevices[i]);
String usbCanonicalName = tempFile.getCanonicalFile().toString(); //gives me /dev/ttyUSBx where 'x' is the USB device number
System.out.println("Connecting to " + usbCanonicalName + " (" + myUsbDevices[i] + ")");
(new TwoWaySerialComm()).connect(usbCanonicalName);
}
else
{
System.out.println("Not using " + myUsbDevices[i]);
}
}
}
}
catch ( Exception ex )
{
System.out.println("Connect exception: " + ex.toString());
}
System.out.println("*****************************");
System.out.println("***** Program Finished ******");
System.out.println("*****************************");
}
Output when I put a $1 bill in (I'm developing/compiling from NetBeans IDE 8.2 on Windows 10 Pro and running using remote debugging on the RPi3. I'm guessing that's the source of the RXTX Version mismatch warning):
*****************************
***** Starting Program *****
*****************************
Connecting to /dev/ttyUSB0 (usb-Silicon_Labs_Series_2000_Bill_Acceptor__EBDS_over_USB__46580120748-if00-port0)
Stable Library
=========================================
Native lib Version = RXTX-2.2pre2
Java lib Version = RXTX-2.1-7
WARNING: RXTX Version mismatch
Jar version = RXTX-2.1-7
native lib Version = RXTX-2.2pre2
Recv (invalid): 020000000000000000000000
Recv (invalid): 0B2001100800503603540000
Recv: 020B20041008005036035100 - Escrowed $1 - Removable Cassette Installed
*****************************
***** Program Finished ******
*****************************
I hope this description and sample code can help someone else.

TextView.setText not working inside for loop

public void bytesToHex(byte[] in) {
final StringBuilder builder = new StringBuilder();
int count=0;
final int BATCHSIZE=20;
sendingData = true;
Log.d("byteToHex", "sendingData = true, start sending data.");
sendSerial("w"); //write command
Log.d("byteToHex", "sending w");
for(byte b : in) {
//mBluetoothGatt.setCharacteristicNotification(characteristicRX, enabled);
//byte[] a = mBluetoothGatt.readCharacteristic(characteristicRX);
while(!newData){
if(resendData == true){//resends previously sent string
sendSerial(sendByte);
Log.d("byteToHex", "resendData = true, resending: " + sendByte);
resendData = false; //reset resendData flag
}
} //wait for next w from mcu
builder.append(String.format("%02x", b));
if(builder.length()== BATCHSIZE ){
sendByte= builder.toString();
sendSerial(sendByte);
newData = false;
Log.d("byteToHex", "newData = false");
count+=BATCHSIZE;
Log.d("byteToHex", "Sent " + count/2 + " bytes");
textViewFileProgress.setText(count/2 + "/" + fileLength); //<- THIS SETTEXT DOES NOT WORK
builder.setLength(0); //reset the string builder
}
} //for(byte b : in)
//send remaining bytes
sendByte= builder.toString();
sendSerial(sendByte);
newData = false;
Log.d("byteToHex", "newData = false");
count+=builder.length();
Log.d("byteToHex", "Sent " + count/2 + " byte");
textViewFileProgress.setText(count/2 + "/" + fileLength);//<- THIS SETTEXT WORKS
builder.setLength(0); //reset the string builder
sentTerminator = true; //flag to tell BLE service to check if terminator is received on mcu
sendSerial("||"); //terminating command, tell teensy last hex has been sent
while(sentTerminator == true){ //while terminator not yet received
if(resendTerminator == true){ //
sendSerial("||");
Log.d("byteToHex", "resending terminator");
resendTerminator = false; //Resend complete. reset resendTerminator flag.
}
}
sendingData = false;
//return builder.toString();
}//public void bytesToHex(byte[] in)
I am trying to set the text to my textview to display the current number of bytes sent.
Somehow, i have 2 of the exact same setText code in my function. textViewFileProgress.setText(count/2 + "/" + fileLength);
one of them is inside a for loop, which does not work.
the other is outside the for loop, which works.
I am sure the program ran that code, as I am able to see the debug messages before it in Android monitor.
Any idea what is the problem?
Try this .
Log.e("TAG",builder.length()+"");
if(builder.length()== BATCHSIZE ){
sendByte= builder.toString();
sendSerial(sendByte);
newData = false;
Log.d("byteToHex", "newData = false");
count+=BATCHSIZE;
Log.d("byteToHex", "Sent " + count/2 + " bytes");
textViewFileProgress.setText(count/2 + "/" + fileLength); //<- THIS SETTEXT DOES NOT WORK
builder.setLength(0); //reset the string builder
} else {
Log.e("TAG","length != 20");
}
And you can see the Logcatinfo
Consider this simple code. You implement your for loop in another background thread then set the text in main thread using onPostExecute()
Note that onPostExecute() run in the main thread while doInBackground() run in the background thread so you cannot set the text in doInBackground()
public void outSideFunction()
{
//pass a string to doInBackground()
new TextSetterTask.execute("");
}
//implement an inner class
private class TextSetterTask extends AsyncTask<String,Void,String>
{
#Override
protected String doInBackground(String... params)
{
//loop
return //the string you want to set the text
//if the background thread is done it will call the onPostExecute
}
#Override
protected void onPostExecute(String result)
{
//set the text
}
}

Java - Serialization - Grabbing number of objects

Java - Serialization - Grabbing number of objects in file
I'm trying to retrieve my objects from my serialized file and re-add them to my file. There seems to be an issue, no exception is being thrown but nothing is being printed in my console when running my method. Before continuing here is my code:
public boolean openCollection(){
try {
FileInputStream e = new FileInputStream("profiles.ser");
ObjectInputStream inputStream = new ObjectInputStream(e);
List<Profile> profiles = (List<Profile>) inputStream.readObject();
//De-obscure
for(Profile p : profiles){
String unObcName = deobscure(p.getName()); //Original name
String unObcSurname = deobscure(p.getSurname()); //Original surname
String unObcUsername = deobscure(p.getUsername()); //Original username
String unObcPassword = deobscure(p.getPassword()); //Original password
p.setName(unObcName);
p.setSurname(unObcSurname);
p.setUsername(unObcUsername);
p.setPassword(unObcPassword);
//Debugging
System.out.println("DE-OBSCURE - Profile name: " + p.getName() +"\n"+
"Profile surname: " + p.getSurname() +"\n"+
"Profile username: " + p.getUsername() +"\n"+
"Profile password: " + p.getPassword());
this.profiles.add(p);
}
} catch (FileNotFoundException var3) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JOptionPane.showMessageDialog(null, "No profiles found, please create a profile!");
final CreateProfile createProfile = new CreateProfile();
createProfile.setVisible(true);
}
});
return false;
} catch (IOException var4) {
var4.printStackTrace();
JOptionPane.showMessageDialog(null, "IO Exception");
return false;
} catch (ClassNotFoundException var5) {
var5.printStackTrace();
JOptionPane.showMessageDialog(null, "Required class not found");
return false;
}
return true;
}
This is the serialization method
public void saveCollection(){
//Obscure the data
List<Profile> saveProfiles = new ArrayList<>();
for(Profile p : profiles){
String obcName = obscure(p.getName());
String obcSurname = obscure(p.getSurname());
String obcUsername = obscure(p.getUsername());
String obcPassword = obscure(p.getPassword());
p.setName(obcName);
p.setSurname(obcSurname);
p.setUsername(obcUsername);
p.setPassword(obcPassword);
//Debugging
System.out.println("DEBUG - Profile name: " + p.getName() + "\n" +
"Profile surname: " + p.getSurname() + "\n" +
"Profile username: " + p.getUsername() + "\n" +
"Profile password: " + p.getPassword());
saveProfiles.add(p);
}
//Save it
try {
FileOutputStream e = new FileOutputStream("profiles.ser");
ObjectOutputStream outputStream = new ObjectOutputStream(e);
outputStream.writeObject(saveProfiles);
outputStream.flush();
outputStream.close();
} catch (IOException var3) {
var3.printStackTrace();
JOptionPane.showMessageDialog(null, "Error. Cannot save database.");
}
}
When creating a profile the details are being obscured properly, here are the results:
DEBUG - Profile name: OBF:1u2a1toa1w8v1tok1u30
Profile surname: OBF:1u2a1toa1w8v1tok1u30
Profile username: OBF:1u2a1toa1w8v1tok1u30
Profile password: OBF:1u2a1toa1w8v1tok1u30
However when running openCollection() nothing is being printed into the console.
NOTE: The profile details were all 'admin' which is why all the data looks the same
After a while checking things out I figured out that the issue was simply with my deobscuring method. I have now edited it and replace it with the following:
/**
* #param str Obscured String
* #return Unobscured String
*/
private String deobscure(String s){
if (s.startsWith(__OBFUSCATE)) s = s.substring(4);
byte[] b = new byte[s.length() / 2];
int l = 0;
for (int i = 0; i < s.length(); i += 4)
{
if (s.charAt(i)=='U')
{
i++;
String x = s.substring(i, i + 4);
int i0 = Integer.parseInt(x, 36);
byte bx = (byte)(i0>>8);
b[l++] = bx;
}
else
{
String x = s.substring(i, i + 4);
int i0 = Integer.parseInt(x, 36);
int i1 = (i0 / 256);
int i2 = (i0 % 256);
byte bx = (byte) ((i1 + i2 - 254) / 2);
b[l++] = bx;
}
}
return new String(b, 0, l,StandardCharsets.UTF_8);
}
Original Profile name: "Admin"
Obscured Profile name: "OBF:1npu1toa1w8v1tok1nsc
After de-obscuring Profile name: "Admin"
Thus the method now works as intended.

Why does this image not display correctly when I put it through my HTTP server?

I wrote the following HTTP server:
import processing.net.*;
import java.io.FileInputStream;
import javax.activation.MimetypesFileTypeMap;
Client client = null;
Server server = null;
MimetypesFileTypeMap mimeMap = new MimetypesFileTypeMap();
void setup()
{
server = new Server(this, 80);
println(1);
size(700, 700);
fill(0);
mimeMap.addMimeTypes("application/bmp bmp BMP Bmp");
}
void draw()
{
background(255);
while ( (client = server.available ()) == null) {
}
println(2);
String req = "";
String fileN;
byte[] fileC;
while (client.available () != 0) {
req += client.readString();
try {
Thread.sleep(100);
}
catch (Throwable t) {
}
}
println(req);
fileN = URLDecoder.decode(req.split(" ")[1].substring(1));
if (!fileN.equals("")) {
try
{
FileInputStream fileS = new FileInputStream("C:\\" + fileN);
fileC = new byte[fileS.available()];
fileS.read(fileC);
server.write(
concatSB(
"HTTP/1.0 200 OK\r\nContent-Type: " +
mimeMap.getContentType(fileN.substring( fileN.lastIndexOf("/") + 1 )) +
"\r\nContent-Length: " +
fileC.length +
"\r\n\r\n",
fileC
)
);
println(3);
println(fileN);
}
catch (Exception e)
{
server.write("HTTP/1.0 404 Not Found\r\n".getBytes());
println(fileN + ": " + e.toString());
}
}
exit();
}
void mouseClicked()
{
server.stop();
exit();
}
private byte[] concatSB(final String strng, final byte[] bytes) {
final StringBuilder sb = new StringBuilder(strng);
for (byte b : bytes) {
sb.append((char)b);
}
println(strng);
return sb.toString().getBytes();
}
It works quite well for text, but when I sent this BMP:
I got this BMP out, which opened automatically in Paint:
When I converted the original to a GIF in Paint, the result was not readable through the server and in IE, I got the bad image icon (red X);
How can I fix this?
I do not think that it is a good idea passing fileC which is binary through a StringBuilder. I would rather do something like this:
server.write(
"HTTP/1.0 200 OK\r\nContent-Type: " +
mimeMap.getContentType(fileN.substring( fileN.lastIndexOf("/") + 1 )) +
"\r\nContent-Length: " +
fileC.length +
"\r\n\r\n"
);
server.write(
fileC
);

Categories