I wanted to ask what is the best way to handle an exception when you are calling a XMLRPC function and the server is down or not responding. I have the following code:
try
{
mXmlRpcClient.call(mRequestVariantsFunc, SessionID, newID, "1970-01-01T00:00:00+00" ,"1970-01-01T00:00:00+00");
}
catch (Exception e)
{
e.printStackTrace();
}
The code above works alright when the server is running but when its down I get a black screen and the phone freezes. The rest of the code is running while in black screen but no exception is thrown. Is there a way to handle this problem in case the server is down not to go into a black screen?
For me, in another tool there is a message going via a handler to indicate progress. Also, a seperate class to handle exceptions is nice to have.
If you have the same library as me, here my example for what it's worth:
package hha.zhongcan.communication;
import java.net.URI;
import android.os.Handler;
import android.util.Log;
import hha.zhongcan.framework.Citem;
import hha.zhongcan.framework.Configuration;
import hha.zhongcan.framework.CtimeFrame;
import hha.zhongcan.framework.Ctransaction;
import hha.zhongcan.microfood.AskTableDialog;
import hha.zhongcan.resources.Global;
import org.apache.http.conn.HttpHostConnectException;
interface XMLRPCMethodCallback
{
void callFinished(Object result);
}
/** Messages to send to the PC at high level. Receive the menu items, pages, transactions.
* Create fake data for the demo.
*
* #author mensfort
*
*/
public class Cmessage
{
static private Cmessage m_message =null;
private static URI m_uri;
public static XMLRPCClient m_client;
private final static String TAG="message";
private boolean m_connected =false;
private int m_pingId =0;
private int m_lost =0;
private int m_wait =0;
private boolean m_sendTransactions =true;
private Handler m_updateHandler = new Handler();
boolean m_getItems = false;
boolean m_getPages = false;
private static Global m_global =null;
private int m_countTransactions =10;
private int transactionMessageCount =0;
private long getValue( String s)
{
try
{
if ( s.startsWith("0x") || s.startsWith("0X"))
{
s =s.substring(2);
while (s.startsWith("0"))
{
s=s.substring(1);
}
if ( s.length() ==0)
{
return 0;
}
return Long.parseLong(s, 16);
}
if ( s=="")
{
return 0;
}
return Long.parseLong(s);
}
catch(Exception e)
{
e.printStackTrace();
return 0;
}
}
/// #brief New thread for running ask-table.
private Runnable messageTask = new Runnable()
{
//#override
public void run()
{
if ( m_getItems)
{
m_getItems =false;
getMenuItems();
}
else if ( m_getPages)
{
m_getPages =false;
getMenuPages();
}
else if ( m_sendTransactions)
{
// If I have sth to send and I'm not in page mode, then start sending items.
sendTransactions();
m_wait =2;
}
else if ( Configuration.getInstance().isDemo())
{
m_connected =true;
next();
}
else if ( m_wait>0)
{
m_wait--;
next();
}
else if ( --m_countTransactions<=0)
{
sendMessage_getTransactions();
m_countTransactions =5;
}
else
{
// Update this screen every 10 seconds.
sendConnected();
}
}
};
/** #brief At startup start the first message after a second.
*/
private Cmessage()
{
m_updateHandler.postDelayed( messageTask, 1000);
}
/** #brief Set the address and port.
*
* #param address [in] Address to use.
* #param port [in] Port to use.
*/
public void setPath( String address, Integer port)
{
m_uri = URI.create("http://192.168.0.105:9876");
m_client =new XMLRPCClient( m_uri);
}
/** #brief Singleton implementation, only this instance can send messages.
*
* #return Pointer to the singleton.
*/
public static Cmessage getInstance()
{
if ( m_message ==null)
{
m_message =new Cmessage();
m_global =Global.getInstance();
}
return m_message;
}
/** #brief In a second, the next command can be send to the PC.
*/
public void next()
{
m_updateHandler.postDelayed( messageTask, 1000);
}
/** #brief Check if we are connected to the PC.
*
* #return true when connected.
*/
public boolean isConnected()
{
return m_connected;
}
/** #brief Send Ping message, just to check the connection status.
*/
public void sendConnected()
{
{
XMLRPCMethod method =new XMLRPCMethod( "ping", new XMLRPCMethodCallback() {
public void callFinished(Object result)
{
try
{
String s = (String) (result);
if ( s.equals("bart"))
{
m_lost =0;
m_connected =true;
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
m_lost++;
}
}
});
Object[] params ={ m_pingId++ }; // {};
method.call(params);
}
if ( ++m_lost>2)
{
m_connected =false;
}
}
public void sendMessage_getConfiguration()
{
// TODO Auto-generated method stub
}
private void createMenuFrom( Object [] arrY)
{
if ( arrY.length >0)
{
m_global.itemDB.clean();
}
int v=(int)(arrY.length/9);
int lvl=1;
for (int y=0; y<arrY.length; y++)
{
if ( y==lvl*v)
{
setSlider(lvl++);
}
Log.i(TAG, "item " + y);
Object[] arrX = (Object[]) arrY[y];
int id =(Integer) arrX[0];
String alias =(String) arrX[1];
String local =(String) arrX[2];
String chinese =(String) arrX[3];
int restaurant_price =(Integer) arrX[4];
int takeaway_price =(Integer) arrX[5];
int level =(Integer) arrX[6];
int page =(Integer) arrX[7];
int sequence =(Integer) arrX[8];
int colour_text = (int)(getValue( (String) arrX[9])&0xffffffff);
int colour_background = (int)(getValue( (String) arrX[10])&0xffffffff);
int colour_selected_text = (int)(getValue( (String) arrX[11])&0xffffffff);
int colour_selected_background = (int)(getValue( (String) arrX[12])&0xffffffff);
int colour_background2 = (int)(getValue( (String) arrX[13])&0xffffffff);
int colour_selected_background2 = (int)(getValue( (String) arrX[14])&0xffffffff);
if ( m_global.mainMenuHandler !=null)
{
// m_global.mainMenuHandler.obtainMessage( y, "UPDATE_MENU_SLIDEBAR "+y).sendToTarget();
}
m_global.itemDB.insert( id, alias, local, chinese, restaurant_price,
takeaway_price, (byte)level, (byte)page, (short)sequence,
colour_text, colour_background, colour_selected_text,
colour_selected_background, colour_background2,
colour_selected_background2);
}
m_global.itemDB.complete();
Log.i(TAG, "Items received correct.");
}
/** Indicate that we want to get the menu card.
*/
public void sendMessage_getMenuItems()
{
m_getItems = true;
m_getPages = true;
}
/** #brief Get the menu items. */
public void getMenuItems()
{
boolean demo =Configuration.getInstance().isDemo();
if (demo ==true)
{
createMenuFrom( demoMenu.items);
next();
}
else
{
XMLRPCMethod method =new XMLRPCMethod( "items", new XMLRPCMethodCallback() {
public void callFinished(Object result)
{
try
{
m_global.itemDB.deleteAll();
m_global.itemDB.clean();
Object[] arrY = (Object[]) result;
createMenuFrom( arrY);
m_connected =true;
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
});
Object[] params = {};
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 1, "UPDATE_MENU_SLIDEBAR 1").sendToTarget();
}
method.call(params);
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 1, "UPDATE_MENU_SLIDEBAR 5").sendToTarget();
}
}
}
/** Call to get all transactions from the server, including payments, items and time-frames. */
public void sendMessage_sendTransactions()
{
m_sendTransactions =true;
}
/** Set slider to a value 1..10
*
* #param n [in] 0..10
*/
private void setSlider( int n)
{
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 0, "UPDATE_MENU_SLIDEBAR "+n).sendToTarget();
}
}
/** After sending the orders, the database can be cleaned...
*/
private void cleanDatabase()
{
try
{
m_global.transactionDB.clean();
m_global.timeFrameDB.clean();
m_global.transactionItemDB.clean();
m_connected =true;
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
/** Send all transaction */
private void sendTransactions()
{
if ( m_global.transactionDB.size() ==0)
{
m_sendTransactions =false;
cleanDatabase();
next();
return;
}
if ( Configuration.getInstance().isDemo())
{
cleanDatabase();
try
{
m_global.askTableHandler.obtainMessage( AskTableDialog.MESSAGE_DATA_SENT,-1,-1, -1).sendToTarget();
}
catch (Exception e)
{
e.printStackTrace();
}
m_sendTransactions =false;
}
XMLRPCMethod method =new XMLRPCMethod( "orders", new XMLRPCMethodCallback()
{
public void callFinished(Object result)
{
cleanDatabase();
m_global.askTableHandler.obtainMessage( AskTableDialog.MESSAGE_DATA_SENT,-1,-1, -1).sendToTarget();
m_sendTransactions =false;
}
});
Object[][] transaction =m_global.transactionDB.get();
Object[][] timeFrame =m_global.timeFrameDB.get();
Object[][] item =m_global.transactionItemDB.get();
Object[] params ={ transaction,timeFrame,item };
//{
// transaction, timeFrame, item
//}/;
if ( transaction ==null || timeFrame ==null || item ==null)
{
cleanDatabase();
Log.e( TAG,"Database problem!!");
}
method.call( params);
}
/// Call to get all transactions from the server, including payments, items and time-frames.
public void sendMessage_getTransactions()
{
if ( m_global.transactionDB.size() >0)
{
return;
}
if ( m_global.timeFrameDB.size() >0)
{
return;
}
if ( m_global.transactionItemDB.size() >0)
{
return;
}
XMLRPCMethod method =new XMLRPCMethod( "get_transactions", new XMLRPCMethodCallback()
{
public void callFinished(Object result)
{
m_countTransactions =10;
m_connected =true;
if ( m_global.transactionDB.size() >0)
{
Log.i(TAG, "Transaction DB not empty.");
return;
}
if ( m_global.timeFrameDB.size() >0)
{
Log.i(TAG, "Time Frame DB not empty.");
return;
}
if ( m_global.transactionItemDB.size() >0)
{
Log.i(TAG, "Transaction Item DB not empty.");
return;
}
try
{
m_global.transactionList.clean();
Object[] arrY = (Object[]) result;
Object[] transactions =(Object[]) arrY[0];
Object[] timeFrames =(Object[]) arrY[1];
Object[] items =(Object[]) arrY[2];
//Object[] payments =(Object[]) arrY[3];
for (int y=0; y<transactions.length; y++)
{
Object[] trx = (Object[]) transactions[y];
int id = Integer.valueOf(trx[0].toString());
String tme =trx[1].toString();
String name =trx[2].toString();
int customer_id =Integer.valueOf( trx[3].toString());
int status =Integer.valueOf( trx[4].toString());
int total =Integer.valueOf( trx[5].toString());
Ctransaction t=new Ctransaction( id, name, tme, status, customer_id, total);
m_global.transactionList.insert( t);
}
for (int y=0; y<timeFrames.length; y++)
{
Object[] trx = (Object[]) timeFrames[y];
int id = Integer.valueOf( trx[0].toString());
int tfi =Integer.valueOf( trx[1].toString());
int waiter =Integer.valueOf( trx[2].toString());
String start_time =trx[3].toString();
String end_time =trx[4].toString();
int transaction_id =Integer.valueOf( trx[5].toString());
int device_id =Integer.valueOf( trx[6].toString());
CtimeFrame c =new CtimeFrame( id, (short)tfi, waiter,
start_time, end_time,
transaction_id, device_id);
m_global.transactionList.insert( c);
}
for (int y=0; y<items.length; y++)
{
Object[] trx = (Object[]) items[y];
//int id = (Integer) trx[0];
long menu_item_id =Long.valueOf( trx[1].toString());
int sequence =Integer.valueOf( trx[2].toString());
int time_frame_index =Integer.valueOf( trx[3].toString());
int deleted_time_frame_index =Integer.valueOf( trx[4].toString());
long transaction_id =Long.valueOf( trx[5].toString());
int quantity =Integer.valueOf( trx[6].toString());
int level =Integer.valueOf( trx[7].toString());
int deleted =Integer.valueOf( trx[8].toString());
int portion =Integer.valueOf( trx[9].toString());
int orig_price =Integer.valueOf( trx[10].toString());
int unit_price =Integer.valueOf( trx[11].toString());
String time =trx[12].toString();
Citem i=new Citem( menu_item_id, y, (short)sequence,
(short)time_frame_index,
(short)deleted_time_frame_index,
transaction_id, quantity,
(byte)level, deleted, (byte)portion, unit_price, orig_price, time);
m_global.transactionList.insert( i);
}
//for (int y=0; y<payments.length; y++)
//{
//Object[] pay = (Object[]) payments[y];
//int id = (Integer) pay[0];
//String time =(String) pay[1];
//int money_received =(Integer) pay[2];
//int customer_id =(Integer) pay[3];
//int pay_method =(Integer) pay[4];
//int partial_index =(Integer) pay[5];
//global.paymentsDB.insert( id, time, money_received, customer_id, pay_method, partial_index);
//}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
});
Object[] params = { transactionMessageCount++ };
method.call(params);
}
/// Call, but not in main thread, answer comes in a thread.
private void getMenuPages()
{
if ( Configuration.getInstance().isDemo())
{
decodePages( demoMenu.pages);
next();
return;
}
XMLRPCMethod method =new XMLRPCMethod( "pages", new XMLRPCMethodCallback()
{
public void callFinished(Object result)
{
decodePages( result);
}
});
setSlider(7);
Object[] params = {};
method.call(params);
setSlider(8);
}
/**
* #brief Convert an array to page data.
* #param result [in] array with local, chinese names.
*/
private void decodePages( Object result)
{
try
{
m_global.pageDB.clean();
Object[] arrY = (Object[]) result;
setSlider(9);
for (int y=0; y<arrY.length; y++)
{
Object[] arrX = (Object[]) arrY[y];
int id = (Integer) arrX[0];
String local =(String) arrX[1];
String chinese =(String) arrX[2];
String lc =local.replace( "'", "''");
String ch =chinese.replace( "'", "''");
m_global.pageDB.insert( id, lc, ch);
}
m_connected =true;
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 0, "UPDATE_MENU_READY").sendToTarget();
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
class XMLRPCMethod extends Thread
{
private String method;
private Object[] params;
private Handler handler;
private XMLRPCMethodCallback callBack;
public XMLRPCMethod(String method, XMLRPCMethodCallback callBack)
{
this.method = method;
this.callBack = callBack;
handler = new Handler();
}
public void call()
{
call(null);
}
public void call(Object[] params)
{
this.params = params;
start();
}
//#Override
public void run()
{
synchronized(this)
{
try
{
final long t0 = System.currentTimeMillis();
final Object result = m_client.callEx(method, params);
final long t1 = System.currentTimeMillis();
handler.post(new Runnable()
{
public void run()
{
Log.i(TAG, "XML-RPC call took " + (t1-t0) + "ms");
callBack.callFinished(result);
next();
}
});
}
catch (final XMLRPCFault e)
{
handler.post(new Runnable()
{
public void run()
{
Log.e(TAG, "Fault message: " + e.getFaultString() + "\nFault code: " + e.getFaultCode());
Log.d("Test", "error", e);
next();
}
});
}
catch (final XMLRPCException e)
{
next();
handler.post(new Runnable()
{
public void run()
{
Throwable couse = e.getCause();
if (couse instanceof HttpHostConnectException)
{
Log.e(TAG, "Cannot connect to " + m_uri.getHost() + "\nMake sure server.py on your development host is running !!!");
}
else
{
Log.e(TAG, "Error " + e.getMessage());
}
Log.d(TAG, "error", e);
}
});
}
catch (Exception e)
{
next();
e.printStackTrace();
}
}
}
}
}
Related
I have designed a code which leads to application not responding.
I have used okhttp3.WebSocket for continuous input stream of data on which i am deciding to start an IntentService which will be fetching data from server.
I have an IntentService; in onHandleIntent i am giving an service call for fetching data from the server(roughly 3 calls).
For Service call i am using AsyncTask of android inside which my WebConnectionManger class runs on different thread.
Inside websocket i am getting details of a particular record for which i am going to fetch the details from the service call.
For 5-6 such records my application runs fine, but if records get 80-100 my application do not respond at all and i get ANR.
I am using simple plain TCP request for this.
can any on tells me what is the actual issue and how i can get rid of it?
any help is appreciated.
i am pasting the code of WebSocket, AsyncTask(rest two have same implementation), WebConnectionManger class and IntentService class.
WebSocket.class
public class WebSocket {
public static boolean isConnected;
public static String TO_UPDATE = "toOrderUpdate";
#SuppressLint("StaticFieldLeak")
private static WebSocket _instance;
private static OkHttpClient client;
private static WebSocket webSocket = null;
private Context mContext;
private AppPreferences preferences;
private WebSocket() {
client = new OkHttpClient();
}
public WebSocket(Context context) {
client = new OkHttpClient();
mContext = context;
preferences = new AppPreferences(mContext);
init(mContext);
}
public static WebSocket getInstance(Context mContext) {
if (_instance == null) {
_instance = new WebSocket(mContext);
}
return _instance;
}
public static void closeWebSocket() {
if (isConnected) {
webSocket.close(1001, LOGOUT);
_instance = null;
webSocket = null;
isConnected = false;
}
}
public void init(Context context) {
if (webSocket == null) {
preferences = new AppPreferences(context);
Request request = new Request.Builder()
.url(preferences.getWSUrl() + ":" + preferences.getWSPort() + "/" + preferences.getUserID())
.build();
WebSocketMessageListener messageListener = new WebSocketMessageListener();
webSocket = client.newWebSocket(request, messageListener);
isConnected = true;
}
}
private class WebSocketMessageListener extends WebSocketListener {
// private static final int NORMAL_CLOSURE_STATUS = 1000;
#Override
public void onOpen(WebSocket webSocket, Response response) {
super.onOpen(webSocket, response);
Log.i("******", "Socket Open");
}
#Override
public void onMessage(WebSocket webSocket, String response) {
try {
super.onMessage(webSocket, response);
Log.i("******", "Message Received " + response);
// Logger.log("OnMessage : " + response);
ModelAdvertisements modelAdvertisements = DecoderJSONWebSocket.decode(response);
Intent intentForService = new Intent(mContext, WebSocketService.class);
int transCode = Integer.parseInt(modelAdvertisements.getTC());
Intent mwBroadcastIntent = new Intent();
switch (transCode) {
case 1005:
mwBroadcastIntent.setAction(Constants.IntentKeys.KEY_LOGICAL_SESSION_START_END);
mContext.sendBroadcast(mwBroadcastIntent);
break;
case 1004:
case 1006:
case 1007:
intentForService.putExtra(TO_UPDATE, true);
mContext.startService(intentForService);
break;
case 1008:
try {
mwBroadcastIntent.putExtra(KEY_AUCTION_FLOOR_SNAPSHOT, modelAdvertisements);
mwBroadcastIntent.setAction(Constants.IntentKeys.KEY_MARKET_DATASNAPSHOT);
mContext.sendBroadcast(mwBroadcastIntent);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
} catch (Exception e) {
// e.printStackTrace();
}
}
#Override
public void onClosing(WebSocket webSockett, int code, String reason) {
super.onClosing(webSockett, code, reason);
Log.i("******", "Socket Closing Reason: " + reason);
}
#Override
public void onClosed(WebSocket webSockett, int code, String reason) {
super.onClosed(webSockett, code, reason);
Log.i("******", "Socket closed reason: " + reason);
webSocket = null;
isConnected = false;
}
#Override
public void onFailure(WebSocket webSockett, Throwable t, Response response) {
super.onFailure(webSockett, t, response);
isConnected = false;
webSocket = null;
Logger.log(e);
}
}
}
WebSocketService.class
public class WebSocketService extends IntentService {
String securityId;
private Context mContext;
private String tokenId;
private String contractCode;
private int transCode;
private boolean toUpdate;
private String mktCode;
public WebSocketService() {
super("WebSocketService");
}
public WebSocketService(String name) {
super(name);
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
if (intent != null) {
tokenId = intent.getStringExtra(KEY_TOKEN_ID);
transCode = intent.getIntExtra(KEY_TRANSCODE, 0);
toUpdate = intent.getBooleanExtra(NeMLWebSocket.TO_UPDATE, false);
contractCode = intent.getStringExtra(KEY_SYMBOL);
mktCode = intent.getStringExtra(KEY_ADV_REF_ID);
}
securityId = DatabaseUtils.getSecurityIdFromFOOrders(mContext, tokenId);
performTokenMasterTask();
}
#Override
public void onCreate() {
super.onCreate();
mContext = this;
}
#Override
public int onStartCommand(#Nullable Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
protected void performTokenMasterTask() {
synchronized (this) {
TokenMasterTask tokenMasterTask = new TokenMasterTask(mContext, new RequestCallback() {
#Override
public void onStart() {
}
#Override
public void onComplete(Object object) {
if (transCode == TC_1004_WEB_SOCKET) {
Intent mwBroadcastIntent = new Intent();
mwBroadcastIntent.setAction(Constants.IntentKeys.KEY_TOKEN_SESSION_START_END);
mContext.sendBroadcast(mwBroadcastIntent);
// stopSelf();
} else if (transCode == TC_TIME_WEB_SOCKET || transCode == TC_AUCTION_WEB_SOCKET) {
performTimeSessionTask();
}
}
#Override
public void onProgress(int current, int total) {
}
#Override
public void onError(int transCode, String msg) {
try {
Logger.log(transCode + "--->" + msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}, mktCode);
tokenMasterTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, tokenId);
if (transCode == TC_TIME_WEB_SOCKET || transCode == TC_AUCTION_WEB_SOCKET) {
performTimeSessionTask();
}
}
}
public void performTimeSessionTask() {
synchronized (this) {
TimeSessionMapTask timeSessionMapTask = new TimeSessionMapTask(mContext, new RequestCallback() {
ProgressDialog progressDialog;
private boolean m_ConnectionErr = false;
#Override
public void onStart() {
}
#Override
public void onComplete(Object object) {
if (!m_ConnectionErr) {
if (transCode == TC_AUCTION_WEB_SOCKET) {
performFoOrderTask();
}
}
}
#Override
public void onProgress(int current, int total) {
}
#Override
public void onError(int transCode, String msg) {
try {
Logger.log("Received ErrorMessage :" + msg + " \n ErrorCode :" + transCode);
} catch (Exception e) {
e.printStackTrace();
}
}
}, modelMarket);
timeSessionMapTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, TIME_SESSION);
if (transCode == TC_AUCTION_WEB_SOCKET) {
performFoOrderTask();
}
}
}
private synchronized void performFoOrderTask() {
synchronized (mContext) {
FOOrdersTask foOrdersTask = new FOOrdersTask(mContext, new RequestCallback() {
#Override
public void onStart() {
}
#Override
public void onComplete(Object object) {
}
#Override
public void onProgress(int current, int total) {
}
#Override
public void onError(int transCode, String msg) {
}
});
foOrdersTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, tokenId);
}
}
}
TokenMasterTask.class
public class TokenMasterTask extends AsyncTask<Object, Void, ModelToken> {
private final String mktCode;
private RequestCallback _callback;
#SuppressLint("StaticFieldLeak")
private Context context;
private boolean isConnectionError;
private ModelToken modelToken;
private boolean isServerDown;
public TokenMasterTask(Context context, RequestCallback requestCallback, String mktCode) {
this.context = context;
this.mktCode = mktCode;
if (requestCallback == null) {
requestCallback = new RequestCallback() {
#Override
public void onStart() {
}
#Override
public void onComplete(Object object) {
}
#Override
public void onProgress(int current, int total) {
}
#Override
public void onError(int transCode, String msg) {
}
};
}
this._callback = requestCallback;
}
#Override
protected ModelToken doInBackground(Object... voids) {
if (voids != null && voids.length > 0) {
String tokenId = String.valueOf(voids[0]);
isConnectionError = false;
transactionCall(tokenId);
}
return modelToken;
}
private void transactionCall(String tokenId) {
try {
WebConnectionManager connectionManager = new WebConnectionManager(context, new ConnectionListener() {
#Override
public void notifyReadCompleted(String f_Response) {
modelToken = DecoderTokenRequest.decode(f_Response);
synchronized (TokenMasterTask.this) {
TokenMasterTask.this.notify();
}
}
#Override
public void notifySocketError(boolean isServerDown) {
if (!isServerDown) {
isConnectionError = true;
}
TokenMasterTask.this.isServerDown = isServerDown;
synchronized (TokenMasterTask.this) {
TokenMasterTask.this.notify();
}
}
#Override
public void onReceivePacket(int total, int current) {
_callback.onProgress(current, total);
}
});
connectionManager.modifiedHandleRequest(EncoderTokenRequest.encode(context, tokenId,mktCode).getBytes());
} catch (Exception e) {
e.printStackTrace();
Logger.log(e);
}
synchronized( TokenMasterTask.this) {
try {
TokenMasterTask.this.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
protected void onPostExecute(ModelToken modelToken) {
if (isServerDown) {
_callback.onError(Constants.ErrorCode.TC_ERROR_SERVER_DOWN, "");
} else if (isConnectionError) {
_callback.onError(0, "Connection Error.");
} else if (modelToken!=null && modelToken.getErrorCode() != null && !TextUtils.isEmpty(modelToken.getErrorCode()) && !modelToken.getErrorCode().equalsIgnoreCase("200")) {
_callback.onError(Integer.parseInt(modelToken.getErrorCode()), modelToken.getError());
} else {
_callback.onComplete(modelToken);
}
super.onPostExecute(modelToken);
}
}
WebConnectionManager.class
public class WebConnectionManager {
private String m_Response = "";
byte[] m_RequestData;
boolean m_Read_Response_Completed = false;
Thread l_WorkerThread;
ConnectionListener m_ConnectionListener;
boolean m_IsFetchCompleted;
Context context;
AppPreferences preferences;
Socket mWebSocket;
public WebConnectionManager(Context mcontext, ConnectionListener f_LoginListener) {
m_ConnectionListener = f_LoginListener;
m_IsFetchCompleted = false;
context = mcontext;
preferences = new AppPreferences(context);
}
public String modifiedHandleRequest(byte[] f_RequestData) {
m_RequestData = f_RequestData;
Logger.log("" + Constants.TIME_OUT);
l_WorkerThread = new Thread(new Runnable() {
#Override
public void run() {
String encodedIP = null;
try {
if (mWebSocket == null || !mWebSocket.isBound()
|| mWebSocket.isClosed() ) {
mWebSocket = new Socket(ip, port);
mWebSocket.setKeepAlive(true);
mWebSocket.setSoTimeout(Constants.TIME_OUT);
}
if (m_RequestData == null) {
m_Read_Response_Completed = true;
if (!mWebSocket.isClosed()) {
m_ConnectionListener.notifyReadCompleted("Connected");
return;
} else {
m_ConnectionListener.notifyReadCompleted("Disconnected");
return;
}
} else {
String request = new String(m_RequestData);
Logger.log(Utils.encodePackets(request));
}
InputStream inputStream = mWebSocket.getInputStream();
try {
mWebSocket.getOutputStream().write(m_RequestData);
} catch (Exception e) {
Logger.log(e);
}
ByteArrayOutputStream byteArrayOutputStream =
new ByteArrayOutputStream(1048576);
byte[] buffer = new byte[1048576];
int bytesRead = 0;
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
m_Response = byteArrayOutputStream.toString();
}
inputStream.close();
byteArrayOutputStream.close();
mWebSocket.close();
if (TextUtils.isEmpty(m_Response.toString().trim())) {
throw new IOException("Empty Response");
} else {
m_ConnectionListener.notifyReadCompleted(m_Response.toString());
}
} catch (UnknownHostException e) {
Logger.log(e);
m_ConnectionListener.notifySocketError(true);
mWebSocket = null;
} catch (SocketTimeoutException e) {
Logger.log(e);
m_ConnectionListener.notifySocketError(false);
mWebSocket = null;
e.printStackTrace();
} catch (SocketException e) {
Logger.log(e);
m_ConnectionListener.notifySocketError(true);
mWebSocket = null;
e.printStackTrace();
} catch (IOException e) {
Logger.log(e);
m_ConnectionListener.notifySocketError(true);
mWebSocket = null;
e.printStackTrace();
} catch (Exception e) {
Logger.log(e);
m_ConnectionListener.notifySocketError(true);
mWebSocket = null;
e.printStackTrace();
}
}
});
l_WorkerThread.start();
return m_Response;
}
}
And the interfaces.
public interface ConnectionListener {
void notifyReadCompleted(String f_Response);
void notifySocketError(boolean isServerDown);
void onReceivePacket(int total, int current);
}
public interface RequestCallback {
void onStart();
void onComplete(Object object);
void onProgress(int current, int total);
void onError(int transCode, String msg);
}
You may want to check what is blocking the main thread for more than 6 seconds.
Usually ANR happens when main thread is blocked for some time. 6-10 seconds.
I am trying to access a file twice in my program.
First I am reading from the file, which runs fine.
The second time, I am trying to delete the same file from which I read.
Strangely the second time no records are present in the file. In fact when I try to run the command file.exists it returns false. Why is this happening?
Following is my code:
public class ControlLights extends AppCompatActivity {
private RoomListAdapter adapter;
private List<ROOM> mRoomList;
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.popup,menu);
}
public void filedel(int pos) {
Toast.makeText(getApplicationContext(), String.valueOf(pos), Toast.LENGTH_LONG).show();
File filemain = new File("roomdata.txt");
try {
File temp = File.createTempFile("file",".txt",filemain.getParentFile());
String charset = "UTF-8";
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(temp), charset));
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(temp), charset));
int p=0;
for(String line; (line=reader.readLine())!=null;) {
if(p == pos) {
line = line.replace(line,"");
writer.println(line);
}
writer.println(line);
}
reader.close();
writer.close();
filemain.delete();
temp.renameTo(filemain);
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.Edit:
return true;
case R.id.Delete:
filedel(info.position);
mRoomList.remove(info.position);
adapter.notifyDataSetChanged();
return true;
default:
return super.onContextItemSelected(item);
}
}
public void loadrooms() {
int block = 1024;
try {
boolean exists = (new File("roomdata.txt").exists());
Toast.makeText(getApplicationContext(), String.valueOf(exists), Toast.LENGTH_LONG).show();
FileInputStream fis = openFileInput("roomdata.txt");
InputStreamReader isr = new InputStreamReader(fis);
char[] data = new char[block];
String roomdata = "";
int size;
try {
while ((size = isr.read(data)) > 0) {
String read_data = String.copyValueOf(data, 0, size);
roomdata += read_data;
data = new char[block];
}
} catch (IOException e) {
e.printStackTrace();
}
String[] room_display = roomdata.split("\n");
String[] tempstring;
ListView lsv = (ListView) findViewById(R.id.Room_list);
mRoomList = new ArrayList<>();
for (int b = 0; b < room_display.length; b++) {
tempstring = room_display[b].split(":");
mRoomList.add(new ROOM(tempstring[0], tempstring[1], tempstring[2], tempstring[3], tempstring[4], tempstring[5], tempstring[6], tempstring[7], tempstring[8], tempstring[9]));
}
adapter = new RoomListAdapter(getApplicationContext(), mRoomList);
lsv.setAdapter(adapter);
registerForContextMenu(lsv);
int count = mRoomList.size();
final ArrayList<Integer> disabledpos = new ArrayList<Integer>();
for (int q = 0; q < count; q++) {
ROOM temp_room1 = mRoomList.get(q);
String IP = temp_room1.getRoom_IP_Address();
String online = null;
ConnectionTest CT = new ConnectionTest();
try {
online = CT.execute(IP, "a", "b").get();
Boolean b1 = Boolean.valueOf(online);
if (!b1) {
disabledpos.add(q);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
try {
isr.reset();
isr.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
if (new File("roomdata.txt").delete()) {
Toast.makeText(getApplicationContext(), "deleted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "not deleted", Toast.LENGTH_LONG).show();
// Not deleted
}
lsv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
int temp_position = position;
Intent p = new Intent(ControlLights.this, Electrical_equipment_list.class);
if (!(disabledpos.contains(position))) {
ROOM temp_room = mRoomList.get(temp_position);
p.putExtra("EE1", temp_room.getEE1());
p.putExtra("EE2", temp_room.getEE2());
p.putExtra("EE3", temp_room.getEE3());
p.putExtra("EE4", temp_room.getEE4());
p.putExtra("EE5", temp_room.getEE5());
p.putExtra("EE6", temp_room.getEE6());
p.putExtra("EE7", temp_room.getEE7());
p.putExtra("EE8", temp_room.getEE8());
p.putExtra("IPaddress", temp_room.getRoom_IP_Address());
startActivity(p);
}
}
});
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_control_lights);
loadrooms();
}
public class ConnectionTest extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
Boolean online;
String tempstring = null;
try {
InetAddress roomaddress = InetAddress.getByName(params[0]);
online = roomaddress.isReachable(100);
tempstring = String.valueOf(online);
} catch (IOException e) {
e.printStackTrace();
}
return tempstring;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
}
Keep your File as a class' member, since it is an essential component of what the class does
Move your inner logic and file reference initialization to onStart()
public class ControlLights extends AppCompatActivity {
private RoomListAdapter adapter;
private List mRoomList;
private File filemain;
...
public void filedel(int pos) {
Toast.makeText(getApplicationContext(), String.valueOf(pos), Toast.LENGTH_LONG).show();
try {
File temp = File.createTempFile("file",".txt", filemain.getParentFile());
...
}
}
public void loadrooms() {
int block = 1024;
try {
boolean exists = filemain.exists();
...
if (filemain.delete()) {
Toast.makeText(getApplicationContext(), "deleted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "not deleted", Toast.LENGTH_LONG).show();
// Not deleted
}
} ...
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_control_lights);
}
#Override
protected void onStart() {
super.onStart();
filemain = new File("roomdata.txt");
loadrooms();
}
}
Foot note
I apologize for the horrible code format, but apparently they changed the parsing algorithm to a point where you have to manually type all the code again here instead of just being able to copy-paste it. Anyone being to edit it accordingly is welcome.
I know that the purpose of the AsyncTask is to run asynchronously with other tasks of the app and finish in the background, but apparently I need to do this, I need to start an activity from AsyncTask and since I cant extend an activity in this class I can not use startactivityforresult, so how can I wait till my activity finishes?
Here is my code:
public class ListSpdFiles extends AsyncTask<Void, Void, String[]> {
public AsyncResponse delegate = null;
private static final String TAG = "ListSpdFiles: ";
Context applicationContext;
ContentResolver spdappliationcontext;
public final CountDownLatch setSignal= new CountDownLatch(1);
private final ReentrantLock lock = new ReentrantLock();
String username = "";
/**
* Status code returned by the SPD on operation success.
*/
private static final int SUCCESS = 4;
private boolean createbutt;
private boolean deletebutt;
private String initiator;
private String path;
private String pass;
private String url;
private SecureApp pcas;
private boolean isConnected = false; // connected to PCAS service?
private String CurrentURL = null;
private PcasConnection pcasConnection = new PcasConnection() {
#Override
public void onPcasServiceConnected() {
Log.d(TAG, "pcasServiceConnected");
latch.countDown();
}
#Override
public void onPcasServiceDisconnected() {
Log.d(TAG, "pcasServiceDisconnected");
}
};
private CountDownLatch latch = new CountDownLatch(1);
public ListSpdFiles(boolean createbutt, boolean deletebutt, String url, String pass, Context context, String initiator, String path, AsyncResponse asyncResponse) {
this.initiator = initiator;
this.path = path;
this.pass= pass;
this.url= url;
this.createbutt= createbutt;
this.deletebutt=deletebutt;
applicationContext = context.getApplicationContext();
spdappliationcontext = context.getContentResolver();
delegate = asyncResponse;
}
private void init() {
Log.d(TAG, "starting task");
pcas = new AndroidNode(applicationContext, pcasConnection);
isConnected = pcas.connect();
}
private void term() {
Log.d(TAG, "terminating task");
if (pcas != null) {
pcas.disconnect();
pcas = null;
isConnected = false;
}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
init();
}
#Override
protected String[] doInBackground(Void... params) {
CurrentURL = getLastAccessedBrowserPage();
// check if connected to PCAS Service
if (!isConnected) {
Log.v(TAG, "not connected, terminating task");
return null;
}
// wait until connection with SPD is up
try {
if (!latch.await(20, TimeUnit.SECONDS)) {
Log.v(TAG, "unable to connected within allotted time, terminating task");
return null;
}
} catch (InterruptedException e) {
Log.v(TAG, "interrupted while waiting for connection in lsdir task");
return null;
}
// perform operation (this is where the actual operation is called)
try {
return lsdir();
} catch (DeadServiceException e) {
Log.i(TAG, "service boom", e);
return null;
} catch (DeadDeviceException e) {
Log.i(TAG, "device boom", e);
return null;
}
}
#Override
protected void onPostExecute(String[] listOfFiles) {
super.onPostExecute(listOfFiles);
if (listOfFiles == null) {
Log.i(TAG, "task concluded with null list of files");
} else {
Log.i(TAG, "task concluded with the following list of files: "
+ Arrays.toString(listOfFiles));
}
term();
delegate.processFinish(username);
}
#Override
protected void onCancelled(String[] listOfFiles) {
super.onCancelled(listOfFiles);
Log.i(TAG, "lsdir was canceled");
term();
}
/**
* Returns an array of strings containing the files available at the given path, or
* {#code null} on failure.
*/
private String[] lsdir() throws DeadDeviceException, DeadServiceException {
Result<List<String>> result = pcas.lsdir(initiator, path); // the lsdir call to the
boolean crtbut = createbutt;
boolean dlbut= deletebutt;
ArrayList<String> mylist = new ArrayList<String>();
final Global globalVariable = (Global) applicationContext;
if (crtbut==false && dlbut == false){
if ( globalVariable.getPasswordButt()==false ) {
final boolean isusername = globalVariable.getIsUsername();
if (isusername == true) {
Log.i(TAG, "current url: " + CurrentURL);
if (Arrays.toString(result.getValue().toArray(new String[0])).contains(CurrentURL)) {
String sharareh = Arrays.toString(result.getValue().toArray(new String[0]));
String[] items = sharareh.split(", ");
for (String item : items) {
String trimmed;
if (item.startsWith("[" + CurrentURL + ".")) {
trimmed = item.replace("[" + CurrentURL + ".", "");
if (trimmed.endsWith(".txt]")) {
trimmed = trimmed.replace(".txt]", "");
mylist.add(trimmed.replace(".txt]", ""));
} else if (trimmed.endsWith(".txt")) {
trimmed = trimmed.replace(".txt", "");
mylist.add(trimmed.replace(".txt", ""));
}
Log.i(TAG, "list of files sharareh: " + trimmed);
} else if (item.startsWith(CurrentURL + ".")) {
trimmed = item.replace(CurrentURL + ".", "");
if (trimmed.endsWith(".txt]")) {
trimmed = trimmed.replace(".txt]", "");
mylist.add(trimmed.replace(".txt]", ""));
} else if (trimmed.endsWith(".txt")) {
trimmed = trimmed.replace(".txt", "");
mylist.add(trimmed.replace(".txt", ""));
}
Log.i(TAG, "list of files sharareh: " + trimmed);
}
}
}
globalVariable.setPopupdone(false);
Intent i = new Intent(applicationContext, PopUp.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("EXTRA_SESSION_ID", mylist);
applicationContext.startActivity(i);
username = globalVariable.getUsername();
}
else if (isusername == false)
Log.i(TAG, "Wrong Input Type For Username.");
}
if (result.getState() != SUCCESS) {
Log.v(TAG, "operation failed");
return null;
}
if (result.getValue() == null) {
Log.v(TAG, "operation succeeded but operation returned null list");
return null;
}
return result.getValue().toArray(new String[0]);
}
//}
if (result.getState() != SUCCESS) {
Log.v(TAG, "operation failed");
return null;
}
if (result.getValue() == null) {
Log.v(TAG, "operation succeeded but operation returned null list");
return null;
}
return result.getValue().toArray(new String[0]);
}
public String getLastAccessedBrowserPage() {
String Domain = null;
Cursor webLinksCursor = spdappliationcontext.query(Browser.BOOKMARKS_URI, Browser.HISTORY_PROJECTION, null, null, Browser.BookmarkColumns.DATE + " DESC");
int row_count = webLinksCursor.getCount();
int title_column_index = webLinksCursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE);
int url_column_index = webLinksCursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL);
if ((title_column_index > -1) && (url_column_index > -1) && (row_count > 0)) {
webLinksCursor.moveToFirst();
while (webLinksCursor.isAfterLast() == false) {
if (webLinksCursor.getInt(Browser.HISTORY_PROJECTION_BOOKMARK_INDEX) != 1) {
if (!webLinksCursor.isNull(url_column_index)) {
Log.i("History", "Last page browsed " + webLinksCursor.getString(url_column_index));
try {
Domain = getDomainName(webLinksCursor.getString(url_column_index));
Log.i("Domain", "Last page browsed " + Domain);
return Domain;
} catch (URISyntaxException e) {
e.printStackTrace();
}
break;
}
}
webLinksCursor.moveToNext();
}
}
webLinksCursor.close();
return null;
}
public String getDomainName(String url) throws URISyntaxException {
URI uri = new URI(url);
String domain = uri.getHost();
return domain.startsWith("www.") ? domain.substring(4) : domain;
}}
My Activity class:
public class PopUp extends Activity {
private static final String TAG = "PopUp";
ArrayList<String> value = null;
ArrayList<String> usernames;
#Override
protected void onCreate(Bundle savedInstanceState) {
final Global globalVariable = (Global) getApplicationContext();
globalVariable.setUsername("");
Bundle extras = getIntent().getExtras();
if (extras != null) {
value = extras.getStringArrayList("EXTRA_SESSION_ID");
}
usernames = value;
super.onCreate(savedInstanceState);
setContentView(R.layout.popupactivity);
final Button btnOpenPopup = (Button) findViewById(R.id.openpopup);
btnOpenPopup.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View arg0) {
LayoutInflater layoutInflater = (LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
View popupView = layoutInflater.inflate(R.layout.popup, null);
final PopupWindow popupWindow = new PopupWindow(popupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
Button btnSelect = (Button) popupView.findViewById(R.id.select);
Spinner popupSpinner = (Spinner) popupView.findViewById(R.id.popupspinner);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(PopUp.this, android.R.layout.simple_spinner_item, usernames);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
popupSpinner.setAdapter(adapter);
popupSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
globalVariable.setUsername(usernames.get(arg2));
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
btnSelect.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
globalVariable.setPopupdone(true);
popupWindow.dismiss();
finish();
}
}
);
popupWindow.showAsDropDown(btnOpenPopup, 50, -30);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.poupup_menu, menu);
return true;
}}
I am working on an instant chat application.My problem is that when i am sending message through my chat application,Message is displayed two times instead of one.Screen shot is given below :
As you can see in the acreenshot that the message hiii is displayed two times but i have sent only once.
1.Adapter_Message.java
public class Adapter_Message extends BaseAdapter {
private Context context;
private List<Bean_Message> messagesItems;
public Adapter_Message(Context context, List<Bean_Message> navDrawerItems) {
this.context = context;
this.messagesItems = navDrawerItems;
}
#Override
public int getCount() {
return messagesItems.size();
}
#Override
public Object getItem(int position) {
return messagesItems.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#SuppressLint("InflateParams")
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Bean_Message m = messagesItems.get(position);
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
// Identifying the message owner
if (messagesItems.get(position).isSelf()) {
// message belongs to you, so load the right aligned layout
convertView = mInflater.inflate(R.layout.list_item_message_right, null);
} else {
// message belongs to other person, load the left aligned layout
convertView = mInflater.inflate(R.layout.list_item_message_left, null);
}
TextView lblFrom = (TextView) convertView.findViewById(R.id.lblMsgFrom);
TextView txtMsg = (TextView) convertView.findViewById(R.id.txtMsg);
txtMsg.setText(m.getMessage());
lblFrom.setText(m.getFromName());
return convertView;
}
}
2.Chat_Activity.java
public class ChatActivity extends FragmentActivity implements
EmojiconGridFragment.OnEmojiconClickedListener, EmojiconsFragment.OnEmojiconBackspaceClickedListener {
public static final String TAG = ChatActivity.class.getSimpleName();
// EditText edMessage;
EmojiconEditText edMessage;
Button sendMessage;
private Socket mSocket;
String sID, lID, md5StringRoomID, message, friendName, loggedInUser;
String frndID;
int smallerID, largerID;
//AlmaChatDatabase almaChatDatabase;
// Chat messages list adapter
private Adapter_Message adapter;
private List<Bean_Message> listBeanMessages;
private ListView listViewMessages;
boolean isSelf; // to check whether the message is owned by you or not.true means message is owned by you .
Bean_Message msg;
int loggedInUserID;
private String URL_FEED_Message = "";
APIConfiguration apiConfiguration;
SharedPreferences preferences;
HashMap<String, Integer> emoticons;
// instance initialization block
{
try {
mSocket = IO.socket(Constants.CHAT_SERVER_URL);
Log.e("Socket", String.valueOf(mSocket));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
sendMessage = (Button) findViewById(R.id.btnSendMessage);
preferences = getApplicationContext().getSharedPreferences(Prefs_Registration.prefsName, Context.MODE_PRIVATE);
//Handling emoticons
/* emoticons = new HashMap<String,Integer>();
emoticons.put(":-)",R.drawable.s1);*/
String id = preferences.getString(Prefs_Registration.get_user_id, null);
// Converting String id to integer
loggedInUserID = Integer.parseInt(id);
//loggedInUserID = almaChatDatabase.getUserID(); // Getting ID of the Logged in user from the database
Log.e("UserID", "Id of Logged in user " + loggedInUserID);
listBeanMessages = new ArrayList<Bean_Message>();
adapter = new Adapter_Message(getApplicationContext(), listBeanMessages);
listViewMessages = (ListView) findViewById(R.id.list_view_messages);
listViewMessages.setAdapter(adapter);
// Getting the ID of the friend from the previous screen using getExtras
Bundle bundle = getIntent().getExtras();
frndID = bundle.getString("ID");
Log.e("FriendID", frndID);
final int friendID = Integer.parseInt(frndID);
friendName = bundle.getString("name");
Log.e("FriendName", friendName);
loggedInUser = preferences.getString(Prefs_Registration.get_user_name, null);
//loggedInUser = almaChatDatabase.getUserName(); // Name of logged in user
Log.e("LoggedInUser", loggedInUser);
// Converting first lowercase letter of every word in Uppercase
final String loggedInUpper = upperCase(loggedInUser);
//To find the current time
Date d = new Date();
final long time = d.getTime();
// Comparing the loggedInUserId and friendID
if (friendID < loggedInUserID) {
smallerID = friendID;
largerID = loggedInUserID;
} else {
smallerID = loggedInUserID;
largerID = friendID;
}
sID = String.valueOf(smallerID);
lID = String.valueOf(largerID);
String combinedID = sID + lID;
Log.e("combined ID", combinedID);
md5StringRoomID = convertPassMd5(combinedID); // Encrypting the combinedID to generate Room ID
Log.e("md5StringRoomID", md5StringRoomID);
// Using the API for loading old chat messages
apiConfiguration = new APIConfiguration();
String api_message = apiConfiguration.getApi_message(); // Getting the API of messages
URL_FEED_Message = api_message + md5StringRoomID; // md5String is the encrypted room ID here
Log.e("URL_FEED_MESSAGE", URL_FEED_Message);
Log.e("Network request", "Fresh Request");
// We first check for cached request
Cache cache = AppController.getInstance().getRequestQueue().getCache();
Cache.Entry entry = cache.get(URL_FEED_Message);
if (entry != null) {
// fetch the data from cache
try {
String data = new String(entry.data, "UTF-8");
try {
parseJsonFeed(new JSONArray(data));
} catch (JSONException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else {
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(URL_FEED_Message, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
Log.e("JsonArray", String.valueOf(jsonArray));
if (jsonArray != null) {
parseJsonFeed(jsonArray);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.e("ErrorResponse", String.valueOf(volleyError));
}
}
);
// Adding request to volley request queue
AppController.getInstance().addToRequestQueue(jsonArrayRequest);
}
edMessage = (EmojiconEditText) findViewById(R.id.edtMessage);
//Listening on Events
mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectionError);
mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
mSocket.on("send:notice", onReceive); // Listening event for receiving messages
mSocket.connect(); // Explicitly call connect method to establish connection here
mSocket.emit("subscribe", md5StringRoomID);
sendMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
message = edMessage.getText().toString().trim();
Log.e("Sending", "Sending data-----" + message);
if (!message.equals("")) {
edMessage.setText(" ");
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("room_id", md5StringRoomID);
jsonObject.put("user", loggedInUpper);
jsonObject.put("id", friendID);
jsonObject.put("message", message);
jsonObject.put("date", time);
jsonObject.put("status", "sent");
} catch (JSONException e) {
e.printStackTrace();
}
isSelf = true; // Boolean isSelf is set to be true as sender of the message is logged in user i.e. you
attemptToSend(loggedInUpper, message, isSelf);
mSocket.emit("send", jsonObject); // owner i.e LoggedIn user is sending the message
} else {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "Please enter some text", Toast.LENGTH_LONG).show();
}
});
}
}
});
setEmojiconFragment(false);
}
/* public Spannable getSmiledText(String text) {
SpannableStringBuilder builder = new SpannableStringBuilder(text);
if (emoticons.size() > 0) {
int index;
for (index = 0; index < builder.length(); index++) {
if (Character.toString(builder.charAt(index)).equals(":")) {
for (Map.Entry<String, Integer> entry : emoticons.entrySet()) {
int length = entry.getKey().length();
if (index + length > builder.length())
continue;
if (builder.subSequence(index, index + length).toString().equals(entry.getKey())) {
builder.setSpan(new ImageSpan(getApplicationContext(), entry.getValue()), index, index + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
index += length - 1;
break;
}
}
}
}
}
return builder;
}*/
private void setEmojiconFragment(boolean useSystemDefault) {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.emojicons, EmojiconsFragment.newInstance(useSystemDefault))
.commit();
}
//Adding message in the arrayList
public void attemptToSend(String senderName, String message, boolean isSelf) {
msg = new Bean_Message(senderName, message, isSelf);
listBeanMessages.add(msg);
adapter.notifyDataSetChanged();
playBeep();
}
// Playing sound when the message is sent by the owner
public void playBeep() {
try {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
}
// encrypting string into MD5
public static String convertPassMd5(String pass) {
String password = null;
MessageDigest mdEnc;
try {
mdEnc = MessageDigest.getInstance("MD5");
mdEnc.update(pass.getBytes(), 0, pass.length());
pass = new BigInteger(1, mdEnc.digest()).toString(16);
while (pass.length() < 32) {
pass = "0" + pass;
}
password = pass;
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
return password;
}
// Converting first lowercase letter of every word in Uppercase
String upperCase(String source) {
StringBuffer res = new StringBuffer();
String[] strArr = source.split(" ");
for (String str : strArr) {
char[] stringArray = str.trim().toCharArray();
stringArray[0] = Character.toUpperCase(stringArray[0]);
str = new String(stringArray);
res.append(str).append(" ");
}
return res.toString().trim();
}
// Event Listeners
private Emitter.Listener onConnect = new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.e("Socket", "Connected");
}
};
private Emitter.Listener onConnectionError = new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.e("Error", "Error in connecting server");
}
};
private Emitter.Listener onDisconnect = new Emitter.Listener() {
#Override
public void call(Object... args) {
Log.e("Disconnect", "Socket Disconnected");
}
};
// Event Listener for receiving messages
private Emitter.Listener onReceive = new Emitter.Listener() {
#Override
public void call(final Object... args) {
Log.e("Receive", "Bean_Message received");
runOnUiThread(new Runnable() {
#Override
public void run() {
JSONObject data = (JSONObject) args[0];
Log.e("DATA", String.valueOf(data));
try {
JSONArray ops = data.getJSONArray("ops");
for (int i = 0; i < ops.length(); i++) {
JSONObject object = ops.getJSONObject(i);
String roomID = object.getString("room_id");
Log.e("RoomID", roomID); // Getting room ID from JSON array
Log.e("Md5RoomID", md5StringRoomID); // Getting room id which we have created using logged in user ID and room id of the user through which chat has to be done
//Comparing the room IDs
if (md5StringRoomID.equals(roomID)) {
String senderName = object.getString("user");
Log.e("Sender Name", senderName);
String senderID = object.getString("id");
Log.e("SenderID", senderID);
// JSONObject message = object.getJSONObject("message");
String messageReceived = object.getString("message");
Log.e("Bean_Message Received", messageReceived);
String loggedInUSerNAme = preferences.getString(Prefs_Registration.get_user_name, null);
//String loggedInUSerNAme = almaChatDatabase.getUserName();
//If the message is sent by the owner to other from webapp ,then we need to check whether the sender is the loggedinUSer in the App or not and we will right align the messages .
if (loggedInUSerNAme.equalsIgnoreCase(senderName)) {
isSelf = true;
msg = new Bean_Message(senderName, messageReceived, isSelf);
listBeanMessages.add(msg);
// Log.e("List Elements", String.valueOf(listBeanMessages));
adapter.notifyDataSetChanged();
playBeep();
} else {
isSelf = false;
msg = new Bean_Message(senderName, messageReceived, isSelf);
listBeanMessages.add(msg);
Log.e("List Elements", String.valueOf(listBeanMessages));
adapter.notifyDataSetChanged();
playBeep();
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
// Playing sound when the message is sent by other
public void playBeep() {
try {
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
r.play();
} catch (Exception e) {
e.printStackTrace();
}
}
};
// Parsing JSon Array which corresponds to the old chat messages
public void parseJsonFeed(JSONArray jsonArray) {
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String roomID = jsonObject.getString("room_id");
Log.e("RoomID", roomID);
Log.e("Md5RoomID", md5StringRoomID);
// If Room ID(created using id of logged in user and id of friend) matches with the room id obtained from JSON String
if (md5StringRoomID.equals(roomID)) {
String userName = jsonObject.getString("user");
Log.e("Name", userName);
String loggedInUSerNAme = preferences.getString(Prefs_Registration.get_user_name, null);
//String loggedInUSerNAme = almaChatDatabase.getUserName();
Log.e("LoggedInUSer", loggedInUSerNAme);
//If the message is sent by the owner to other from webapp ,then we need to check whether the sender is the loggedinUSer in the App or not and we will right align the messages .
if (loggedInUSerNAme.equalsIgnoreCase(userName)) {
String message = jsonObject.getString("message");
Log.e("message", message);
isSelf = true;
msg = new Bean_Message(userName, message, isSelf);
listBeanMessages.add(msg);
adapter.notifyDataSetChanged();
//playBeep();
} else {
JSONObject jsonMessage = jsonObject.getJSONObject("message");
String message = jsonMessage.getString("text");
isSelf = false;
msg = new Bean_Message(userName, message, isSelf);
listBeanMessages.add(msg);
adapter.notifyDataSetChanged();
// playBeep();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
// notify data changes to list adapter
//adapter.notifyDataSetChanged();
}
}
#Override
public void onEmojiconBackspaceClicked(View view) {
EmojiconsFragment.backspace(edMessage);
}
#Override
public void onEmojiconClicked(Emojicon emojicon) {
EmojiconsFragment.input(edMessage, emojicon);
}
}
3.Bean_Message.java
public class Bean_Message {
private String fromName, message;
private boolean isSelf; // isSelf is used to check whether the message is owned by you or not
public Bean_Message() {
}
public Bean_Message(String fromName, String message, boolean isSelf) {
this.fromName = fromName;
this.message = message;
this.isSelf = isSelf;
}
public String getFromName() {
return fromName;
}
public void setFromName(String fromName) {
this.fromName = fromName;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public boolean isSelf() {
return isSelf;
}
public void setSelf(boolean isSelf) {
this.isSelf = isSelf;
}
}
On clicking "Send Message" button ,message is sent to he server and the following code is used:
public void attemptToSend(String senderName, String message, boolean isSelf) {
msg = new Bean_Message(senderName, message, isSelf);
listBeanMessages.add(msg);
adapter.notifyDataSetChanged();
playBeep();
}
Message is stored in the Bean and Bean is added in the ArrayList .Now i am notifying my adapter that the ArrayList is updated using adapter.notifyDataSetChanged() method.But the problem is List view is displaying my sent message two times.Please help me to solve the issue .
I writed a robotium test that runs a test on a apk file. The test runs on a apk file in a debug mode. the test clicks and inserts data in the app.
The problem is, that sometimes a user hit on a link in a app, and opend a new app/website on the device, and now the root app is not visible.
there is a way to make it visible through the adb?
this is the main class of the test:
package genericTest.test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.content.Context;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.view.View;
import com.robotium.solo.Solo;
#SuppressWarnings("rawtypes")
public class Main extends ActivityInstrumentationTestCase2 {
private FunctonsForViews mFunctonsForViews;
private Random mRand;
private Solo mSolo;
private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.hobbyistsoftware.android.vlcremote_us.main";
private final int DELAY = 50;
private final int SCREEN_SIZE = 1280;
private final int ERROR_COUNT_LIMIT = 10;
private final int CLICK_ON_LOOP_LIMIT = 8;
private final int WHAITING_FOR_VIEWS_LIMIT = 10;
private final int LOOP_LIMIT = 10000;
private static Class launcherActivityClass;
private static int error_count = 0;
static {
try {
launcherActivityClass = Class
.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
#SuppressLint("NewApi")
#SuppressWarnings("unchecked")
public Main() throws ClassNotFoundException {
super(null, launcherActivityClass);
}
protected void setUp() throws Exception {
setActivityInitialTouchMode(true);
mSolo = new Solo(getInstrumentation(), getActivity());
Context context = getActivity();
KeyguardManager km =
(KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if (km.inKeyguardRestrictedInputMode())
{
KeyguardManager.KeyguardLock lock = km.newKeyguardLock("some_tag");
lock.disableKeyguard();
SystemClock.sleep(2000);
}
setActivityInitialTouchMode(true);
}
/*
* runs the test for the app.
*/
public void testMethod()
{
mFunctonsForViews = new FunctonsForViews(mSolo);
mSolo.sleep(DELAY * DELAY);
mRand = new Random();
/*
* the test will take place in the loop, and will be limit in time.
* in every iteration it will get the vies in activity's, and run a test on a random view.
*/
//for(int i=0 ; i<LOOP_LIMIT ; i++)
while(true)
{
mSolo.unlockScreen();
ArrayList Views = mSolo.getViews();
int arraySize = Views.size();
if (arraySize == 0)// now View in activity.
{
whenNoViewsInScreen(Views, arraySize);
}
if (arraySize != 0)
{
int ViewIndexInArray = mRand.nextInt(arraySize + 2);
if (ViewIndexInArray == arraySize)
{
mSolo.scrollDown();
}
else if (ViewIndexInArray == arraySize + 1)
{
if (!mSolo.getCurrentActivity().getClass().toString().split(" ")[1].equals
(LAUNCHER_ACTIVITY_FULL_CLASSNAME))
{
goingBack();
}
}
else
{
View randomView = (View)(Views.get(ViewIndexInArray));
runTestOnOneView(randomView);
}
}
}
}
/*
* performing clicks onScreen()
*/
public void myClickOnScreen()
{
try {
mSolo.unlockScreen();
mSolo.clickOnScreen(mRand.nextInt(SCREEN_SIZE), mRand.nextInt(SCREEN_SIZE));
} catch (Exception e) {
e.printStackTrace();
error_count++;
} catch (Error e2) {
error_count++;
e2.printStackTrace();
}
}
/*
* there is no Views available.
* we will try pressing on screen or the goBack function.
*/
public void whenNoViewsInScreen(ArrayList Views, int arraySize)
{
for (int j = 0; j < WHAITING_FOR_VIEWS_LIMIT; j++)
{
for (int k= 0; k < CLICK_ON_LOOP_LIMIT; k++)
{
myClickOnScreen();
}
Views = mSolo.getViews();
arraySize = Views.size();
if (arraySize != 0)
{
return;
}
mSolo.sleep(DELAY);
Views = mSolo.getViews();
arraySize = Views.size();
if (arraySize != 0)
{
return;
}
}
if (!mSolo.getCurrentActivity().getClass().toString().split(" ")[1].equals
(LAUNCHER_ACTIVITY_FULL_CLASSNAME))
{
goingBack();
}
mSolo.sleep(DELAY);
return;
}
public void runTestOnOneView(View randomView)
{
String rawViewName = randomView.getClass().getName();
String viewName = parseRawViewName(rawViewName);
if (viewName.contains("ActionBarContainer"))
{
return;
}
MyRunnable myRunnable = mFunctonsForViews.getMethodMap().get(viewName);
try{
if (myRunnable != null)
{
myRunnable.run((View)randomView);
}
else // view not in map.
{
boolean inMap = false;
Iterator it = mFunctonsForViews.getMethodMap().entrySet().iterator();
/*
* iterating in case the View is a version of one of View in map
* example:
* View is "CustomEditText", and map contains o view "EditText".
*/
while (it.hasNext())
{
Map.Entry pairs = (Map.Entry)it.next();
if ( viewName.contains((String)pairs.getKey()) )
{
inMap = true;
// next two lines changed
myRunnable = (MyRunnable)(pairs.getValue());
myRunnable.run((View)randomView);
break;
}
}
if (inMap == false)
{
if (viewName.contains("Layout"))
{
return;
}
mSolo.clickOnView((View)randomView);
}
error_count = 0;
}
}catch(Exception exception)
{
exception.printStackTrace();
if(error_count > ERROR_COUNT_LIMIT &&
!(mSolo.getCurrentActivity().getClass().toString().split(" ")[1].equals(LAUNCHER_ACTIVITY_FULL_CLASSNAME)))
{
goingBack();
error_count = 0;
}
return;
}catch(Error error)
{
error.printStackTrace();
error_count ++;
if(error_count > ERROR_COUNT_LIMIT &&
!(mSolo.getCurrentActivity().getClass().toString().split(" ")[1].equals(LAUNCHER_ACTIVITY_FULL_CLASSNAME)))
{
goingBack();
error_count = 0;
}
return;
}
mSolo.sleep(DELAY);
}
/*
* performs a goBack command surrounded with catch/try
*/
public void goingBack()
{
try {
String currentActivity = mSolo.getCurrentActivity().getClass().toString();
mSolo.goBack();
if (mSolo.getCurrentActivity().getClass().toString().equals(currentActivity))
{
for (int i = 0; i< 20; i++)
{
myClickOnScreen();
}
}
} catch (Exception e) {
e.printStackTrace();
} catch (Error e) {
e.printStackTrace();
}
}
/*
* extract the name of View from raw View name.
* example:
* raw View name: android.widget.TextView
* raw View name:TextView
*/
public String parseRawViewName(String rawViewName)
{
if (rawViewName.contains(" "))
{
String [] array = rawViewName.split(" ");
rawViewName = array [0];
}
if (rawViewName.contains(".") || rawViewName.contains("$"))
{
String [] array = rawViewName.split("\\.|$");
rawViewName = array [array.length-1];
}
return rawViewName;
}
public void tearDown() throws Exception {
mSolo.finishOpenedActivities();
}
}