Decoding data from Card reader - android

I am trying to communicate with a USB Accessory (Magnetic Strip Card reader, Model- E-Seek M250), with a Nexus 7 acting as a USBHost.
Use case : When a card is swiped , I need to get the details from the card and convert it to a user readable format.
I have been able to successfully get the device, its interface and the input endpoint.
After that this is what I am doing to get the data:
int receivedBytes = mConnection.bulkTransfer(usbEndpointIN, readBytes, readBytes.length, 3000);
if (receivedBytes > 2) {
dataString = new String(readBytes);
Log.v(Util.TAG, " :: Received Byte Count ::" + receivedBytes);
Log.v(Util.TAG, " :: Final Value Bytes" + readBytes);
Log.v(Util.TAG, " :: Final Value String" + dataString);
}
After several tries, I could not find a way to get the data in user readable format, below is the way the data is shown in the logs.
Can anybody let me know how to convert this data into user readable format?

That reader is not encrypted, so it is probably an encoding issue. Check the documentation for the reader to see what type of encoding they use for the card data and use that encoding when pass the byte array to it. Below is an example if UTF-8 is used.
int receivedBytes = mConnection.bulkTransfer(usbEndpointIN, readBytes, readBytes.length, 3000);
if (receivedBytes > 2) {
String dataString = null;
Log.v(Util.TAG, " :: Received Byte Count ::" + receivedBytes);
Log.v(Util.TAG, " :: Final Value Bytes" + readBytes);
try {
dataString = new String( readBytes, "UTF-8");
Log.v(Util.TAG, " :: Final Value String" + dataString);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}

Related

Android send audio file via Bluetooth using BluetoothChat example

I am trying to send audio file via Bluetooth using the sample BluetoothChat code.
I have created a class that converts audio into bytes and vise-versa.
Here are the modifications I have made in the sample code
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(getActivity(), R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
//Convert noti.mp3 into byte array (noti.mp3 is an audio file I am using for testing)
try{send = Converter.convertAudioToBytes(path+"noti.mp3");}
catch(Exception e){Logger.append("Error while converting audio into bytes", e);}
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
I am also adding some bytes at the end of the audio to identify the endOfFile on the receiving end.
On the receiving end I have updated the mHandler
//List to store bytes received from the other device
private List<Byte> list = new ArrayList<Byte>();
case Constants.MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
//Status for end of data
boolean endOfData = false;
//Add bytes to the Array list
for(int i=0;i<msg.arg1;i++){list.add(readBuf[i]);}
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
mConversationArrayAdapter.add(mConnectedDeviceName + ": " + readMessage);
//Check if the received message contains this string
//Also check if the length of the data is less than 990
if(readMessage.contains("END OF AUDIO FILE") && msg.arg1<990){
endOfData = true;
}
//Check if all the data has been received
if(endOfData)
{
try{
Converter.convertBytesToAudio(list,path);
mConversationArrayAdapter.add(mConnectedDeviceName + ": Audio saved!");
}
catch(Exception e){
Logger.append("Error while converting bytes to audio", e);
}
finally{
list.clear();
}
}
break;
The code works fine for small audio files but when I send a file that is bigger than 3KB it does not properly receive the data and does not transfer it to audio properly.
I tried to send some long text like this
String str = "Message number ";
for(int i=0;i<1000;i++){message += str+i+" ,\n";}
byte[] send = message.getBytes();
mChatService.write(send);
on the receiving end I noticed, the messages received are not synchronized.
Can someone please help me solve this issue, or any other way to transfer audio messages via Bluetooth. I am trying to do something like WhatsApp audio messages but via Bluetooth.
Any help is appreciated.Thanks
Still waiting for an answer :( Please help

Sending data from Arduino BLE to Android , how to combine small chunks of received UART data in Android App

I am sending gps location data from the Arduino BLE to my android app as small chunks(less than 20bytes). I am getting the data in my android app , but how can i combine the small chunks to a string.
This is the code in my arduino program to send the location data to android app.
String msg = "lat:";
msg += GPS.latitude;
msg += ",";
msg.toCharArray(sendBuffer, 20);
ble.print("AT+BLEUARTTX=");
ble.println(sendBuffer);
String msg1 = "lon:";
msg1 += GPS.longitude;
msg1 += ",";
msg1.toCharArray(sendBuffer, 20);
ble.print("AT+BLEUARTTX=");
ble.println(sendBuffer);
String msg2 = "speed:";
msg2 += GPS.speed;
msg2.toCharArray(sendBuffer, 20);
ble.print("AT+BLEUARTTX=");
ble.println(sendBuffer);
And in my android app this is the code to get the UART data
if (action.equals(UartService.ACTION_DATA_AVAILABLE)) {
final byte[] txValue = intent.getByteArrayExtra(UartService.EXTRA_DATA);
try {
String receivedData = new String(txValue, "UTF-8");
Log.i(TAG, "receivedData:" + receivedData);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
Please see my log, how i am getting the data.
I/ContentValues: receivedData:lat:28.907892,lon:45
I/ContentValues: receivedData:.789005,speed:0.02
Please , how can i get the latitude, longitude, speed as one string from the received data. Thank you for any help!
The idea is to accumulate received data in a field variable. Process substrings of accumulated data split by delimiter.
Here is a sample code:
//Field variable
String mReceivedData = "";
if (action.equals(UartService.ACTION_DATA_AVAILABLE)) {
final byte[] txValue = intent.getByteArrayExtra(UartService.EXTRA_DATA);
try {
mReceivedData += new String(txValue, "UTF-8");
int delim;
while((delim = mReceivedData.indexOf('\n')) > -1) {
String dataToProcess = mReceivedData.subString(0, delim);
// Process the data
Log.i(TAG, "dataToProcess:" + dataToProcess);
mReceivedData = mReceivedData.subString(delim + 1);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
Also it may be possible to properly format received data in UartService and then send it to your Activity.

Front-end datagram truncation UDP Android

Thanks in advance to any support,
I'm trying to broadcast a UDP message on the local network. After sending a particular string, responders send back metadata about their location, IP address, status etc.
I've gotten communication to occur, but the issue is in the string response itself.
TLDR: My udp receive packet is cutting off front elements of the datagram.
I dont think this is a buffer size issue. My buff is 2048, much larger than the data I'm looking to receive (about 50-200 characters).
I have worked with this setup before and gotten the first part no problem (with iOS). A wireshark (equivalent) console also confirms. Wireshark and Android output have been attached for comparison.
Proper data coming in via packet app
Front-truncated packet in logcat (notice that everything up until "[Red]" has been omitted)
inside onCreate:
try{
socket = new DatagramSocket();
socket.setBroadcast(true);
socket.setSoTimeout(3000);
broadcastPacket = new DatagramPacket(
broadcastString.getBytes(),
broadcastString.length(),
getBroadcastAddress(),
30303);
}catch (IOException e) {
Log.e("MYAPP", "socket error", e);
}
inside an AsyncTask:
try {
while(true) {
byte[] buffer = new byte[2048];
DatagramPacket receivePacket = new DatagramPacket(buffer, buffer.length);
socket.receive(receivePacket);
String receiveString = new String(receivePacket.getData(), 0, receivePacket.getLength() );
Log.d("a", "Received response " + receiveString );
Log.d("a", "From host " + receivePacket.getAddress() );
Log.d("a", "With offset " + receivePacket.getOffset() );
}
}catch (java.io.IOException e) {
Log.d("a", "Receive timed out");
}
note that before using receivePacket.getLength() I'd just get a bunch of ?'s after the partial response
This did end up being an Android Studio bug.
String[] deviceElements = receiveString.split("\r\n");
Log.d("a", deviceElements[0]);
returned the data I was looking for; intially printing the full receiveString returned only a portion of the string.

Send PCL commands to bluetooth printer

I make android app which will send PCL commands to BT printer (HP Officejet 100). Problem is when I send string data(PCL command) printer don't recognized these commands and print all these commands like normal strings. Any idea why printer don't recognize commands? My full code here: CODE
I also try change charset to US-ASCII, UTF-8 but PCL command was not recognized.
Second question: is there any way how I can convert PDF file to PCL or how I can do way when I need print PDF files on this printer?
Now I can print strings but I cannot print pdf or images etc and I find way how do this. THX for any help.
Part of code:
void sendCustomData() throws IOException {
try {
String msg =
"<ESC>%-12345X#PJL COMMENT *Start Job* <CR><LF>\n" +
"#PJL JOB NAME = \"Sample Job #1\" <CR><LF>\n" +
"#PJL SET COPIES = 1 <CR><LF>\n" +
"#PJL SET RET = OFF <CR><LF>\n" +
"#PJL ENTER LANGUAGE = PCL <CR><LF>\n" +
"<ESC>E. . . . PCL job . . . .<ESC>E\n" +
"~<ESC>%-12345X#PJL <CR><LF>\n" +
"#PJL EOJ<CR><LF>\n" +
"<ESC>%-12345X";
mOutputStream.write(msg.getBytes("ASCII"));
tvStatus.setText("Custom data sent");
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeBT();
Toast.makeText(this, "BT conn closed", Toast.LENGTH_SHORT).show();
}
}
You shouldn't be using the string literal "<ESC>" because it is expecting the ASCII/UTF-8 escape character (Decimal 27, or Hex 1B). Rather, you should declare a char variable:
public final static char CHAR_ESC = 0x1B;
and use that instead
String msg = CHAR_ESC + "%-12345X#PJL COMMENT Start Job \n" + ...
CR and LF also should be replaced with ASCII Characters.

How to get last created file from an FTP directory?

I first want to get a list of files stored in an FTP directory and then get the name of last created file using timestamp. And I'm getting an alert box: Activity is not responding. After checking logcat entry, I notice that the code never reach line :
Log.e("FTP", "number of filenames: " + count);
But I get to Log.e("FTP", "Connexion successful "); So connexion to the server seems ok.
It Seems like something going wrong out there. Can someone help me deal with it. Or show me a simple way to get the last created file from an the FTP server director?
FTPClient ftpClient = new FTPClient();
try
{
ftpClient.connect(InetAddress.getByName(Fonctions.address), Integer.parseInt(Fonctions.port));
if (ftpClient.login(Fonctions.login, Fonctions.pass))
{
Log.e("FTP", "Connexion successful ");
String workDir = ftpClient.printWorkingDirectory();
//Log.e("FTP", "workdir:" + workDir);
int count = ftpClient.listNames().length;
Log.e("FTP", "number of filenames: " + count);
FTPFile [] dossier = new FTPFile[count];
FTPFile back = new FTPFile();
dossier = ftpClient.listDirectories("Sarelo_FTP");
back = dossier[0];
Log.e("FTP", "Avant boucle " + back);
int buf = 0;
for (int i=0;i<(dossier.length) - 1;i++)
{
for (int j=1;j<dossier.length;j++)
{
buf = back.getTimestamp().compareTo(dossier[j].getTimestamp());
if (buf == -1)
back = dossier[j];
}
}
Log.e("FTP", "fichier final le plus récent: " + back.getName());
}
else{
Log.e("Restore FTP", "Error while connecting to FTP server");
}
}
catch(IOException e)
{
String title = "Error connecting to FTP server";
String msg = "Please check your parameters and connexion info: login, password,port number";
f.alert(c, title, msg).show();
Log.e("Restore FTP", "Error while connecting to FTP server", e);
}
P.S: I can't get the list of files in the directory so, I don't know if my code to retrieve the last created file is working. Any help on that would also be appreciated.
[Edit] This is my AsyncTask to retrieve the list of files in the directory. But it's still not working. I'm not getting Application Not Responding anymore, but It not seems to do anything else. Execution get stuck at the same point (can't reach Log.e("FTP", "number of filenames: " + count); )
class getFilesFromFtp extends AsyncTask
{
#Override
protected String doInBackground(Object... params)
{
int count = 0;
try
{
Log.e("FTP", "avant names: " + count);
count = ftpClient.listNames().length;
Log.e("FTP", "names: " + count);
handler.sendMessage(handler.obtainMessage());
}
catch (IOException e) {
Log.e("FTP", "Error getting number of files ", e);
}
return null;
}
}
Thanks for help.
You must not execute long running code on UI thread. Thia blocks UI redraw and event handling. It also produces ANR.
You should run it in the background thread, preferably via 'AsyncTask'.
First problem solved. I just needed to activate FTP data connection passive mode like that:
ftpClient.enterLocalPassiveMode();
before line int count = ftpClient.listNames().length;.
Hope this will help other people. Thanks to #Peter Knego driving me to AsynkTask. I learned something new. :)

Categories

Resources