Checking for escape character(0x1B,\033) while reading from socket - android

Ok, so I'm designing an Android MUD client as part of my school project. I'm having an issue, however, while implementing ANSI color parsing. I read in the data on a byte-by-byte basis. I've tried setting the character "hex" as '\033', '27', and '0x1B' but I can never seem to get it to detect the escape character. Is there anything you guys can see wrong with my checking of it? Also, the line "char check = String.valueOf(j).charAt(0);" is temporary, I was originally trying to check the character variable "hex" against the byte "j". Is there possibly a better way of checking for the character?
while(isConnected) {
int j = 0;
try {
int i = arrayOfByte.length;
j = streamInput.read(arrayOfByte, 0, i);
char check = String.valueOf(j).charAt(0);
Log.d("Console","Char is - " + check);
if (j == -1)
{
Log.d("Console","j = -1");
throw new Exception("Error while reading socket.");
} else if (j == 0) {
Log.d("Console","Continuing");
continue;
} else if (check == hex) {
Log.d("Console","Yo, daddio!");
} else {
final String strData = new String(arrayOfByte, 0, j).replace("\r", "");
runOnUiThread(new Runnable() {
public void run() {
textContent.append(strData);
scrollToBottom();
}
});
}
} catch (Exception e) {
Handler handlerException = GameWindow.this.mHandler;
String strException = e.getMessage();
final String strMessage = "Error while receiving from server:\r\nConnection terminated";
Runnable rExceptionThread = new Runnable()
{
public void run()
{
Toast.makeText(context, strMessage, 3000).show();
}
};
handlerException.post(rExceptionThread);
if(strException.indexOf("reset") != -1 || strException.indexOf("rejected") != -1)
{
isConnected = false;
try
{
connectionSocket.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
isConnected = false;
}
}

Well, you're checking the number of bytes read instead of each individual byte.
j = streamInput.read(arrayOfByte, 0, i);
returns the number of bytes read and put in arrayOfByte those bytes.
Therefore you need to do the following:
for (int n=0; n < j; n++)
{
if (arrayOfByte[n] == hex) Log.d("Console", "Yo, daddio!");
}

Related

UsbDeviceConnection.requestWait() Issue - External Device Won't Reconnect

Some background: I have been trying to refactor this Android app's Usb system. Initially, in order to transfer data between endpoints, they used the UsbDeviceConnection.bulkTransfer() method. I refactored it to use the UsbRequest.initialize(), UsbRequest.queue(), and then UsbDeviceConnection.requestWait() methods. When the Android program is booted on the tablet, my new methods work fine (perhaps even better), but when there is a USB disruption/disconnection from the external device, once reconnected, it won't pick up where it left off. However, their old method, UsbDeviceConnection.bulkTransfer() DOES pick up communication upon reconnect.
Here is the code I refactored, along with the original method:
Original Method [bulkTransfer()] -
byte[] response = new byte[64];
int result = 0;
int tries = 0;
while (result < 1){
if (tries > 5) {
Log.d("PayloadTask", "PayloadTask Timed Out.");
return null;
} else if (isCancelled()) {
Log.w("PayloadTask", "PayloadTask Cancelled!");
return null;
}
/*synchronized (usbConnection)*/
result = usbConnection.bulkTransfer(usbFromAggBoard, response, response.length, 25);
tries += 1;
}
Log.i("PayloadTask", new Integer(response.length).toString() + " bytes received: ");
Log.d("PayloadTask", "doInBackground returning some payload from the aggboard.");
return Payload.CreatePayload(response);
Refactored Code [UsbRequest/requestWait()] -
byte[] response = new byte[64];
int result = 0;
int tries = 0;
while (result < 1){
if (tries > 5) {
Log.d("PayloadTask", "PayloadTask Timed Out.");
return null;
} else if (isCancelled()) {
Log.w("PayloadTask", "PayloadTask Cancelled!");
return null;
}
/*synchronized (usbConnection)*/
if (usbConnection != null) {
UsbRequest request = new UsbRequest();
ByteBuffer byteBuffer = ByteBuffer.wrap(response);
byteBuffer.rewind();
try {
request.initialize(usbConnection, usbFromAggBoard);
if (!request.queue(byteBuffer, response.length)) {
throw new IOException("Error queueing USB request.");
}
usbConnection.requestWait();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(usbConnection != null) {
result = request.hashCode();
request.close();
}
else{
Log.d("PayloadTask", "Request not received by usbConnection");
}
}
}
tries += 1;
}
Log.i("PayloadTask", new Integer(response.length).toString() + " bytes received: ");
Log.d("PayloadTask", "doInBackground returning some payload from the aggboard.");
return Payload.CreatePayload(response);

Custom TCPListener closing TCPClient before reply

I am using the following TCPListener in Xamarin.Android that has served me well in the past, but only have one problem with it...
In the following piece of code within startListener() (Full code below)
while (!NS.DataAvailable && sta)
{
System.Threading.Thread.Sleep(50);
if (cntr > 20)
{
TCPC.Close();
NS = null;
break;
}
cntr++;
}
The TCPClient gets closed if the NetworkSteam has not data to Send(Reply) or Receive for a period of time, which is not a problem and do need it to close this.
Problem is that I can set this "timeout" between changing Thread.Sleep(50) value and cntr > 20 value, but becomes very difficult to predict how long this timeout needs to be depending on what data was received, as I need to perform long running operations on the data before sending the reply (long running as in could be 3sec or 30sec), if I set it too short then it closes my TCP client before I am able to reply, if I set it too long the port is blocked for many seconds after sending the reply and I cannot send the next command until this timeout has expired. Is there a better way to handle this timeout, or a better implementation not using TCPListener
private static void startListener()
{
ListenStarted = true;
TCPL = new TcpListener(IPAddress.Any, 8012);
try
{
TCPL.Start();
sta = true;
}
catch (Exception e)
{
//Log Error
}
while (sta)
{
try
{
TCPC = TCPL.AcceptTcpClient();
TCPC.NoDelay = true;
NS = TCPC.GetStream();
while (NS.CanRead && NS.CanWrite && sta)
{
StringBuilder sb = new StringBuilder();
int cntr = 0;
while (!NS.DataAvailable && sta)
{
System.Threading.Thread.Sleep(50);
if (cntr > 20)
{
TCPC.Close();
NS = null;
break;
}
cntr++;
}
if (NS == null)
break;
while (NS.DataAvailable && sta)
{
int bte = NS.ReadByte();
if (bte == -1)
break;
if ((char)bte != (char)0x03)
{
sb.Append((char)bte);
}
else
{
processDataSets(sb);
break;
}
}
}
}
catch (Exception e)
{
sta = false;
}
}
ListenStarted = false;
NS = null;
}

Connecting with Blutooth Low Energy device. How to wait for BluetoothGattCallback methods to finish

I am new to Android and I have a project that connects an android device with other device with BLE. After connecting I have mBluetoothGatt.discoverServices() and I need to call mBluetoothGatt.getServices() after onServicesDiscovered is called. For now I am using this code:
#Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if(status == BluetoothGatt.GATT_SUCCESS){
servicesFound = true;
Log.i("Send", String.valueOf(gatt.getServices().size()));
}
}
and this is in the button click:
public void btnTestWriteOnClick(View v){
if(mBluetoothGatt != null) {
mBluetoothGatt.discoverServices();
byte[] allBytesToSend = new byte[]{...};//Test byte array.
List<BluetoothGattService> serviceList = mBluetoothGatt.getServices();
while(!servicesFound){
}
servicesFound = false;
displayGattServicesTest(serviceList, allBytesToSend);
}
}
EDIT
My displayGattServicesTest:
private void displayGattServicesTest(List<BluetoothGattService> gattServices, byte[] allBytesToSend) {
if (gattServices == null) return;
//Sets the interval for printing.
//ChangeIntervalAndTimeout();
// Enable notification for characteristic.
EnableNotificationInFFF4(gattServices);
// Loops through available GATT Services.
for (BluetoothGattService gattService : gattServices) {
if (gattService.getUuid().toString().contains(serviceUUID)) {
for (final BluetoothGattCharacteristic characteristic : gattService.getCharacteristics()) {
if (characteristic.getUuid().toString().contains(characUUID)) {
long startTime = System.currentTimeMillis();
Log.i("Send", "===========================BEGINNING===========================");
int size = 19;
int times = allBytesToSend.length / size;
if (allBytesToSend.length > times * size) {
times++;
}
params = new byte[times][];
int tmp;
for (tmp = 0; tmp < 1000; tmp++) {
int logCount = 0;
for (int i = 0; i < allBytesToSend.length; i++) {
if(allBytesToSend.length < i + size){
size = allBytesToSend.length - i;
}
params[logCount] = new byte[size];
System.arraycopy(allBytesToSend, i, params[logCount], 0, size);
i += size - 1;
Log.i("Send", "====Sending command No " + logCount + "====");
logCount++;
}
WriteIntoPrinter t = new WriteIntoPrinter(characteristic);
t.execute(params);
try {
t.get(2000, TimeUnit.MILLISECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
t.cancel(true);
break;
}
}
Log.i("Send", "===========================DONE===========================");
Log.i("Send", "Tmp = " + tmp);
long difference = System.currentTimeMillis() - startTime;
Log.i("Send", "Time - " + (double) (difference / 1000) + " sec.");
break;
}
}
break;
}
}
}
My AsyncTask:
private class WriteIntoPrinter extends AsyncTask<byte[], Void, Void>{
BluetoothGattCharacteristic characteristic;
WriteIntoPrinter(BluetoothGattCharacteristic characteristic){
this.characteristic = characteristic;
//characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
}
#Override
protected Void doInBackground(final byte[]... params) {
for (int i = 0; i < params.length ; i++) {
Log.i("Send", "Sending - " + i + " part. Number of bytes: " + params[i].length);
characteristic.setValue(params[i]);
mBluetoothGatt.writeCharacteristic(characteristic);
final int finalI = i;
Thread t = new Thread(new Runnable() {
#Override
public void run() {
if (finalI == params.length - 1) {
Log.i("Send", "WaitingThread final - " + finalI);
while (!isWritingOnPaper) {
//SystemClock.sleep(20);
}
Log.i("Send", "WaitingThread final - " + finalI + " Done.");
}
else{
while (!isSuccessful) {
//SystemClock.sleep(20);
}
}
}
});
t.start();
try {
t.join(); // wait for thread to finish
} catch (InterruptedException e) {
e.printStackTrace();
}
isWritingOnPaper = false;
isSuccessful = false;
}
return null;
}
}
NOTE This is only a test don't mind the for loops and the new Thread in the AsyncTask. Basecally in displayGattServicesTest I am splitting a byte[] into 19 byte arrays and sending it 1000 times to test the speed.
NOTE 2 Dept Description: displayGattServicesTest take byte[] that is exactly 4*19 bytes long. After that it makes byte[4][19] and gives byte[4][19] to a AsyncTask that starts writing into the characteristic. Every time waits for onCharacteristicWrite to return true and when it writes the last [19] bytes waits for onCharacteristicChanged to return true and then writes the next byte[4][19]. This is the goal.
I do the same think when reading and writing.
This is working but I don't think this is the right way to do it. :) Is there any other way to wait onServicesDiscovered, onCharacteristicWrite and onCharacteristicChanged to finish successful.
In your btnTestWriteOnClick just show progress bar, then wait for result in onServicesDiscovered , if you got result then hide progress bar and do your stuff (call displayGattServicesTest in onServicesDiscovered), you can disable button while discovering is in progress to prevent user from clicking it and starting new discover.

FTDI Android - create new activity

This code is able to make the android device as a USB host for the hardware model. It also can read data from the hardware correctly in Main Activity. However, as soon as I moved it to another activity, everything still works but the data reading is incorrect.
For instance, I'm trying to write the data read into file. First activity is to input filename and just a button to send to another activity. The code below is in the second activity
public class Temp extends Activity {
private FileOutputStream outputStream;
public static D2xxManager ftD2xx= null;
Handler mHandler = new Handler();
FT_Device ftDev = null;
int devCount = 0;
UsbDevice device = null;
TextView Text =null;
String temp = null;
_4DPoint P = null;
int rd = 0;
byte[] byt = null;
byte[] Fdata = null;
String outp = "";
String From_Serial = "";
int Min = -1;
String fileName;
Context c;
final Runnable updateResults = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Text.setText("" + Min + '\n' + temp);
}
};
public void getData(){
try {
outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
byt = new byte[256];//{(byte)'a','b','c','d',};
Toast.makeText(getBaseContext(), "start " + fileName , Toast.LENGTH_LONG).show();
Text = (TextView)findViewById(R.id.test2);
device = (UsbDevice) getIntent().getParcelableExtra("USB");
ftD2xx = D2xxManager.getInstance(c);
ftD2xx.addUsbDevice(device);
devCount = ftD2xx.createDeviceInfoList(c);
if (devCount > 0) {
ftDev = ftD2xx.openByUsbDevice(c, device);
}
if( ftDev.isOpen() == true ) {
ftDev.setBitMode((byte)0 , D2xxManager.FT_BITMODE_RESET);
ftDev.setBaudRate(38400);
ftDev.setDataCharacteristics(D2xxManager.FT_DATA_BITS_8, D2xxManager.FT_STOP_BITS_1, D2xxManager.FT_PARITY_NONE);
ftDev.setFlowControl(D2xxManager.FT_FLOW_NONE, (byte) 0x0b, (byte) 0x0d);
Thread t = new Thread() {
public void run() {
int i;
while(true){
rd=0;
while (rd==0){
rd = ftDev.read(byt, 14);
}
for(i=0; i<rd; i++)
outp += (char)byt[i];
From_Serial = new String(outp);
P = new _4DPoint(From_Serial);
temp = String.format("%s: %f %f %f %f %d\n", From_Serial, P.R, P.G, P.B, P.L, P.camera);
try {
outputStream.write(temp.getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outp = "";
mHandler.post(updateResults);
}
}
};
t.start();
}
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (D2xxException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_color);
// Show the Up button in the action bar.
setupActionBar();
Intent intent = getIntent();
fileName = intent.getStringExtra("File Name");
c = this;
getData();
}
The set up should be fine since it's reading data from hardware, but the data read is incorrect.
Also, I'm wondering why we need to create new thread while reading data. I tried not creating new thread and it didn't work well, but still have no idea why? I tried to contact the person who wrote the code to read data but no reply.
Any help would be really appreciated :)
You state that you receive data, therefor I think you should look at your ftDev settings. Try for example to set ftDev.setBaudRate(115200) (this worked for me) or try playing with your other ftDev Settings a little bit.
The settings I use in my programm are:
int baudRate = 115200;
byte stopBit = 1; /*1:1stop bits, 2:2 stop bits*/
byte dataBit = 8; /*8:8bit, 7: 7bit*/
byte parity = 0; /* 0: none, 1: odd, 2: even, 3: mark, 4: space*/
byte flowControl = 1; /*0:none, 1: flow control(CTS,RTS)*/
If this won't work, it is wise to first check this data communication with a computer program e.g. or to analyse the incomming 'wrong' data.

Can't create handler inside thread that has not called Looper.prepare(). RuntimeExcetion while uploading file to DropBox

I m getting exception "Can't create handler inside thread that has not called Looper.prepare()
in the function doFirstTime().
I m trying to upload my data at Dropbox using Dropbox API
Can you tell me how to fix it?
public class DownloadFile extends AsyncTask<Void, Long, Boolean>
`{
private Context mContext;
private DropboxAPI<?> mApi;
private String mPath;
private FileOutputStream mFos;
private String mErrorMsg;
private StringBuilder xmlcode,newXMLCode;
private final static String FILE_NAME = "fuelrecords.xml";
private final static String ZIP_FILE_NAME = "fuelpad.zip";
private String dropbox_xml_records[];
private ArrayList<ArrayList<String>> dropbox_records;
private ArrayList<ArrayList<String>> database_records;
private ExpenseOperations eop;
private UploadFile up;
private boolean no_file;
public DownloadFile(Context context, DropboxAPI<?> api,String dropboxPath)
{
// We set the context this way so we don't accidentally leak activities
mContext = context.getApplicationContext();
mApi = api;
mPath = dropboxPath;
dropbox_records = new ArrayList<ArrayList<String>>();
database_records = new ArrayList<ArrayList<String>>();
eop = new ExpenseOperations(mContext);
xmlcode=new StringBuilder("");
newXMLCode=new StringBuilder("");
no_file = false;
}
#Override
protected Boolean doInBackground(Void... params)
{
Log.d("yes1", " in do in back of download..");
try
{
// Get the metadata for a directory
Entry dirent = mApi.metadata(mPath, 1000, null, true, null);
if (!dirent.isDir || dirent.contents == null)
{
// It's not a directory, or there's nothing in it
mErrorMsg = "Could not locate the file...";
return false;
}
String cachefilePath = mContext.getCacheDir().getAbsolutePath() + "/" + FILE_NAME;
String cachezipPath = mContext.getCacheDir().getAbsolutePath() + "/" + ZIP_FILE_NAME;
try
{
mFos = new FileOutputStream(cachezipPath);
}
catch (FileNotFoundException e)
{
mErrorMsg = "Couldn't create a local file to store the image";
return false;
}
Notification("SmartExpense", "Now syncing to dropbox");
mApi.getFile("/SmartExpenses.zip",null,mFos,null);
try
{
FileInputStream fin = new FileInputStream(cachezipPath);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
if((ze = zin.getNextEntry()) != null)
{
Log.v("Decompress", "Unzipping " + ze.getName());
if(ze.isDirectory())
{
}
else
{
FileOutputStream fout = new FileOutputStream(cachefilePath);
for (int c = zin.read(); c != -1; c = zin.read())
{
fout.write(c);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
}
catch(Exception ee)
{
Log.d("In unzip:", ""+ee);
}
try
{
FileInputStream fs =new FileInputStream(cachefilePath);
byte buff[] =new byte[1024];
while(fs.read(buff)>0)
{
xmlcode.append(new String(buff));
}
fs.close();
Log.d("Hhhhhhhhhhhaaaaaaaaaaaaa : ",""+xmlcode);
Looper.prepare();
if(!(xmlcode.toString().contains("<expenserecord>")) && getDBRecords())
{
doFirstTime();
Log.d("1","1");
}
else if((xmlcode.toString().contains("<expenserecord>")) && getDBRecords())
{
Log.d("2","2");
makeDropboxRecordArray();
performSync();
}
else if((xmlcode.toString().contains("<expenserecord>")) && !getDBRecords())
{
Log.d("3","3");
makeDropboxRecordArray();
fillDBwithDropboxRecords();
}
else if(!(xmlcode.toString().contains("<expenserecord>")) && !getDBRecords())
{
Log.d("4","4");
mErrorMsg ="No records exist to sync";
}
}
catch (Exception e)
{
Log.d("Exception in doback: ",""+e);
}
return true;
}
catch (DropboxUnlinkedException e)
{
mErrorMsg = "Error :Dropbox unliked";
// The AuthSession wasn't properly authenticated or user unlinked.
}
catch (DropboxPartialFileException e)
{
// We canceled the operation
mErrorMsg = "Download canceled";
}
catch (DropboxServerException e)
{
// Server-side exception. These are examples of what could happen,
// but we don't do anything special with them here.
if (e.error == DropboxServerException._304_NOT_MODIFIED)
{
mErrorMsg = "Server Error.....";
// won't happen since we don't pass in revision with metadata
}
else if (e.error == DropboxServerException._401_UNAUTHORIZED)
{
mErrorMsg = "Server Error : Unautherized user...";
// Unauthorized, so we should unlink them. You may want to
// automatically log the user out in this case.
}
else if (e.error == DropboxServerException._403_FORBIDDEN)
{
mErrorMsg = "Server Error : Access denied";
// Not allowed to access this
}
else if (e.error == DropboxServerException._404_NOT_FOUND)
{
no_file = true;
doFirstTime();
// path not found
}
else if (e.error == DropboxServerException._406_NOT_ACCEPTABLE)
{
mErrorMsg = "Server Error : Congestion...";
// too many entries to return
}
else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE)
{
// user is over quota
mErrorMsg = "Server Error : Insufficient Storage...";
}
else
{
// Something else
mErrorMsg = "Server Error...";
}
// This gets the Dropbox error, translated into the user's language
mErrorMsg = e.body.userError;
if (mErrorMsg == null)
{
mErrorMsg = e.body.error;
}
}
catch (DropboxIOException e)
{
// Happens all the time, probably want to retry automatically.
mErrorMsg = "Network error. Try again.";
}
catch (DropboxParseException e)
{
// Probably due to Dropbox server restarting, should retry
mErrorMsg = "Dropbox error. Try again.";
}
catch (DropboxException e)
{
// Unknown error
mErrorMsg = "Unknown error. Try again.";
}
return false;
}
public void fillDBwithDropboxRecords()
{
Log.d("In fill db","yetoy");
try
{
for(int i=0 ; i<dropbox_records.size()-1 ; i++)
{
{
eop.addRecord(Integer.parseInt(dropbox_records.get(i).get(0)), dropbox_records.get(i).get(1), dropbox_records.get(i).get(2), Integer.parseInt(dropbox_records.get(i).get(3)));
}
}
}
catch (Exception e)
{
Log.d("In fill db", ""+e);
}
}
private void doFirstTime()
{
Log.d("yes2", " in do first time of download..");
try
{
if(!getDBRecords())
{
mErrorMsg = "No records exist to sync";
return;
}
newXMLCode.append("<smartexpense>");
for(int i=0 ; i<database_records.size() ; i++)
{
newXMLCode.append("<expenserecord>");
newXMLCode.append("<c_id>"+database_records.get(i).get(0)+"</c_id>");
newXMLCode.append("<title>"+database_records.get(i).get(1)+"</title>");
newXMLCode.append("<date>"+database_records.get(i).get(2)+"</date>");
newXMLCode.append("<amount>"+database_records.get(i).get(3)+"</amount>");
newXMLCode.append("</expenserecord>");
}//for
newXMLCode.append("</smartexpense>");
up = new UploadFile(mContext,mApi,newXMLCode.toString());
up.execute();
}
catch(Exception e)
{
Log.d("Exception in doFirtstTime : ",""+e);
}
}//doFirstTime
public void makeDropboxRecordArray()
{
Log.d("yes3", " in make record array of download..");
try
{
dropbox_xml_records = (xmlcode.toString()).split("</expenserecord>");
for(int i=0 ; i< dropbox_xml_records.length ; i++)
{
dropbox_records.add(new ArrayList<String>());
dropbox_records.get(i).add(dropbox_xml_records[i].substring(
((dropbox_xml_records[i].indexOf("<c_id>"))+
("<c_id>".length())),
dropbox_xml_records[i].indexOf("</c_id>")
));
dropbox_records.get(i).add(dropbox_xml_records[i].substring(
((dropbox_xml_records[i].indexOf("<title>"))+
("<title>".length())),
dropbox_xml_records[i].indexOf("</title>")
));
dropbox_records.get(i).add(dropbox_xml_records[i].substring(
((dropbox_xml_records[i].indexOf("<date>"))+
("<date>".length())),
dropbox_xml_records[i].indexOf("</date>")
));
dropbox_records.get(i).add(dropbox_xml_records[i].substring(
((dropbox_xml_records[i].indexOf("<amount>"))+
("<amount>".length())),
dropbox_xml_records[i].indexOf("</amount>")
));
}
}
catch (Exception e)
{
Toast.makeText(mContext,"In fill records :"+e , 2000).show();
}
}
public boolean getDBRecords()
{
Log.d("yes4", " in get dbrecords of download..");
try
{
Cursor cc = eop.getRecords();
if(cc.getCount() == 0)
return false;
int i=0;
if(cc.moveToFirst())
{
do
{
database_records.add(new ArrayList<String>());
database_records.get(i).add(cc.getString(cc.getColumnIndex("c_id")));
database_records.get(i).add(cc.getString(cc.getColumnIndex("title")));
database_records.get(i).add(cc.getString(cc.getColumnIndex("date")));
database_records.get(i).add(cc.getString(cc.getColumnIndex("amount")));
i++;
}while(cc.moveToNext());
}
cc.close();
}
catch(Exception ee)
{
Toast.makeText(mContext,"getDBRecords :"+ee , 2000).show();
}
return true;
}
public void performSync()
{
try
{
//compare database records with dropbox records
newXMLCode.append("<smartexpense>");
for(int i=0 ; i<database_records.size() ; i++)
{
newXMLCode.append("<expenserecord>");
newXMLCode.append("<c_id>"+database_records.get(i).get(0)+"</c_id>");
newXMLCode.append("<title>"+database_records.get(i).get(1)+"</title>");
newXMLCode.append("<date>"+database_records.get(i).get(2)+"</date>");
newXMLCode.append("<amount>"+database_records.get(i).get(3)+"</amount>");
newXMLCode.append("</expenserecord>");
}
for(int i=0 ; i<dropbox_records.size()-1 ; i++)
{
eop.addRecord(Integer.parseInt(dropbox_records.get(i).get(0)),
dropbox_records.get(i).get(1),
dropbox_records.get(i).get(2),
Integer.parseInt(dropbox_records.get(i).get(3)));
newXMLCode.append("<expenserecord>");
newXMLCode.append("<c_id>"+dropbox_records.get(i).get(0)+"</c_id>");
newXMLCode.append("<title>"+dropbox_records.get(i).get(1)+"</title>");
newXMLCode.append("<date>"+dropbox_records.get(i).get(2)+"</date>");
newXMLCode.append("<amount>"+dropbox_records.get(i).get(3)+"</amount>");
newXMLCode.append("</expenserecord>");
}
//}
newXMLCode.append("</smartexpense>");
Log.d("Comming : ","yetoy..");
up = new UploadFile(mContext,mApi,newXMLCode.toString());
up.execute();
}
catch (Exception e)
{
Log.d("Perform sync: ",""+e);
}
}
#Override
protected void onPostExecute(Boolean result)
{
//mDbHelper.close();
if (result)
{
//showToast("File successfully downloaded");
}
else
{
if(!no_file)
{
// Couldn't download it, so show an error
showToast("Error in sync.Check notification.");
Notification("SmartExpense", mErrorMsg);
}
}
}
private void showToast(String msg)
{
Toast error = Toast.makeText(mContext, msg, Toast.LENGTH_LONG);
error.show();
}
// Notification Function
private void Notification(String notificationTitle, String notificationMessage)
{
NotificationManager notificationManager = (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(android.R.drawable.ic_menu_save, "Dropbox Sync", System.currentTimeMillis());
Intent notificationIntent = new Intent(mContext, UploadFile.class);
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notificationIntent, 0);
notification.setLatestEventInfo(mContext, notificationTitle, notificationMessage, pendingIntent);
notificationManager.notify(10001, notification);
}
}
This error is received while you try and update your UI from a background thread. In your case the doInBackground method.
It appears that you are trying to post a notification from doInBackground from the following line.
Notification("SmartExpense", "Now syncing to dropbox");
This might be causing the issue. Try commenting this and any other UI updates you might be doing in doInBackground
This Exception indicates that you are trying to access UI elements in a non UI thread. From your code probably the problem is caused by these two lines inside your doInBackground method (you are accessing the Activity's context):
String cachefilePath = mContext.getCacheDir().getAbsolutePath() + "/" + FILE_NAME;
String cachezipPath = mContext.getCacheDir().getAbsolutePath() + "/" + ZIP_FILE_NAME;
If you declare this two variables outside the doInBackgroud method and instatiate them in your constructor, you should be ok. Also, remove the lines in your code that you are calling Looper.prepare() since they will not fix the problem.

Categories

Resources