Android application is freezed - Socket Exception - android

I made android application that connects to remote server and send some data.
Remote server is Windows application.
Connection method:
private void ConnectToMonitor() {
try {
s = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
This works perfectly if server is online. Application is sending data and server is receiving. But if server is offline android app. is blocked. My question is how to handle this? How to continue with application and avoid error even the server is down?

Remember to call this outside the UIThread.
Follow this tutorial. In android all connections need to be managed outside the UIThread, in the tutorial I linked you will find easy ways to post your results back to the UI (handlers, asynctasks...)
Of course we don't know if the problem is about the thread with just the given code, but it is the most usual error.

First remember to set the socket timeout :
mSocket.setSoTimeout(timeout); //in milliseconds
You can however specify different timeout for connection and for all other I/O operations through the socket:
private void connectToMonitor() {
try {
socket = new Socket();
InetAddress[] iNetAddress = InetAddress.getAllByName(SERVER_ADDRESS);
SocketAddress address = new InetSocketAddress(iNetAddress[0], TCP_SERVER_PORT);
socket.setSoTimeout(10000); //timeout for all other I/O operations, 10s for example
socket.connect(address, 20000); //timeout for attempting connection, 20 s
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Second, in Android, you should perform any network I/O in separate threads!
As an example, using regular Java Threads :
String threadName = getClass().getName() + "::connect";
new Thread(new Runnable() {
#Override
public void run() {
connectToMonitor();
}
}, threadName).start();

You can set A timeout for the socket. Use Socket.setSoTimeout method
socket.setSoTimeout(timesinmilis);
by using this your socket will throw a socket timout exception. You can catch that and do what you want

Related

how to implement smack for xmpp

I'm trying to have my android app to be able to send and receive xmpp message using smack but it does not work and the connect command does not return. I have seen several code example but Smack has new versions and the syntax has changed so I might be doing something wrong :
in my build.graddle file I use :
compile "org.igniterealtime.smack:smack-android-extensions:4.3.0"
compile "org.igniterealtime.smack:smack-tcp:4.3.0"
I'm trying to send a message from myaccount321#xabber.org to myaccount456#xabber.org
I'm trying to connect using hot-chilli.net (Idon't mind using some other server))
everything seems to go well until connection.connect() after which the script does not return without triggering any exception.
Please tell me what I'm doing wrong
TIA
public void sendxmpp(){
XMPPTCPConnectionConfiguration config = null;
try {
XMPPTCPConnectionConfiguration.Builder configbuilder = XMPPTCPConnectionConfiguration.builder();
configbuilder.setUsernameAndPassword("myaccount321","myaccount321pw");
DomainBareJid serviceName = JidCreate.domainBareFrom("hot-chilli.net");
configbuilder.setServiceName(serviceName);
configbuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
configbuilder.setHost("jabber.hot-chilli.net");
configbuilder.setPort(8222);
config=configbuilder.build();
AbstractXMPPConnection connection = new XMPPTCPConnection(config);
try {
connection.connect();
}
catch (SmackException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
catch (XMPPException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
connection.login();
ChatManager chatManager = ChatManager.getInstanceFor(connection);
EntityBareJid jid = JidCreate.entityBareFrom("myaccount321pw#xabber.org");
Chat chat = chatManager.createChat(jid);
chat.sendMessage("Hello");
}
catch (Exception e) {
}
}
OK I got it, the connection process has to be done in its own thread.

Openfire Android PubSub Subscription request aproval

I am new to Openfire and smack, therefore I have questions regarding pubsub feature. Actually, I have created a node with setAccessModel as authorize, shown below.
PubSubManager mgr = new PubSubManager(xmpp.getConnection());
try {
LeafNode leaf = mgr.createNode("testNode");
ConfigureForm form = new ConfigureForm(DataForm.Type.submit);
form.setAccessModel(AccessModel.authorize);
form.setDeliverPayloads(true);
form.setNotifyRetract(true);
form.setPersistentItems(true);
form.setPublishModel(PublishModel.open);
leaf.sendConfigurationForm(form);
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
My question is that when somebody wants to subscribe to above node, how the owner of this node can handle the subscription request? Subscription part is as follows:
PubSubManager mgr = new PubSubManager(xmpp.getConnection());
// Get the node
LeafNode node = null;
try {
node = mgr.getNode("testNode");
node.addItemEventListener(new ItemEventCoordinator());
node.subscribe(senderUser+"#desi.loc");
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
class ItemEventCoordinator implements ItemEventListener {
#Override
public void handlePublishedItems(ItemPublishEvent items) {
final ItemPublishEvent itemstemp=items;
runOnUiThread(new Runnable() {
#Override
public void run() {
//stuff that updates ui
dspySub.setText("Item: " + itemstemp.getItems());
}
});
}
}
When I set form.setAccessModel(AccessModel.open) every thing works fine. Users can publish and subscribe easily but when its AccessModel is authorize, owner don't listen, or might be I don't know how to handle subscription request at owner side with above piece of code. Kindly guide me.
Jawad, I've just replied another guy' question about listening subscription requests. Please take a look:
How can i listen incoming subscription request in smack openfire android
I really hope that it can help you.
Good luck!
PS.: Sorry, but I haven't enough reputation to do a comment :(

Method "lock" the entire screen when a socket server is started

Below is the receive method that implements a socket server and works perfectly.
private void Receive(){
log.info("Server started - waiting for the clients.");
try {
Boolean end = false;
ServerSocket ss = new ServerSocket(12345);
while(!end){
//Server is waiting for client here, if needed
Socket s = ss.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter output = new PrintWriter(s.getOutputStream(),true); //Autoflush
String st = input.readLine();
JSONObject jsonObj;
try {
jsonObj = new JSONObject(st);
long id = jsonObj.optLong("DeviceID", count.addAndGet(1) );
String name = jsonObj.toString();
table.put(id, name);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
etResult.setText(st);
Log.d("Tcp Example", "From client: "+st);
output.println("Response from Sever: Connectivity ok");
s.close();
if (st != null ){ end = true; }
}
ss.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The only problem is, when I hit the button to call that method, the socket starts listening and waits for a client messages. While it does not happen, the app remains freezes and I try to hit any other button, the app may crashes.
Does anyone have a hint about how could handle it and leave the socket listening in "background" withou locking the entire screen?
thank you
Make a thread or AsyncTask and do all the socket functions on that. IF it's something you're going to rarely do and want to fire it off and process the results, use an AsyncTask. If it's something you're going to want to do constantly and don't want to run multiple workers at the same time or have multiple workers queued up, use a Thread.

TCPsending crashes the App if server is down

i wrote a Server for our global Leadbord which actually works now.
I can send data to it if it's active. But if it's down my app does not stop. I dont get a solution for it i hope you can help me. Here is the sending:
public void saveToDatabase(LeadboardElement element2) {
final LeadboardElement element = element2;
send = false;
// Need to be a thread! else android blocks it because it could take to
// long to send!
this.thread = new Thread() {
public void run() {
try {
Socket soc = new Socket(Config.TCP_SERVERNAME_IP,
Config.TCP_PORT);
DataOutputStream out = new DataOutputStream(
soc.getOutputStream());
DataInputStream in = new DataInputStream(
new BufferedInputStream(soc.getInputStream()));
// to call the save statement!
out.writeInt(0);
// give the stuff
out.writeUTF(element.getName());
out.writeInt(element.getLevel());
out.writeInt(element.getKillPoints());
// close it
out.close();
in.close();
soc.close();
send = true;
//join at every error
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
};
// start it
thread.start();
// join thread
if (!send) {
boolean retry = true;
while(retry)
try {
this.thread.join();
retry = false;
Log.w(TAG, "sending to server stopped!");
} catch (InterruptedException e2) {
Log.w(TAG, "Thread could not be joined");
}
}
}
I noticed that i need to do it in a thread since API 5 so it works like this. It's called at the end of an Game if the player touches the screen. Everything get stopped and the data is sent to the Server. If hes down it does not work we stuck in the fade to black.
I guess i need something like a timeout. I tried it with a CountDownTimer but this acutally does not solve the problem.
Thanks alot!
Changing the way you initialize the socket, you can set a timeout.
Socket s1 = new Socket();
s1.setSoTimeout(200);
s1.connect(new InetSocketAddress("192.168.1." + i, 1254), 200);
Add a timeout when creating a new Socket

Android connect to Blackberry 655+ bluetooth headset

I'm trying to write a test app which connects to BlackBerry 655+ bluetooth headset. Basically what i want to do in this app is connect to the headset and catch button pressures on it. I think that could be done by reading the socket's inputstream. Anyway, i get some errors right when i try to connect to the socket. Here's the code:
BluetoothSocket tmp = null;
try {
tmp = mDevice.createRfcommSocketToServiceRecord(
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
} catch(IOException e) {}
mSocket = tmp;
mBtAdapter.cancelDiscovery();
try {
mSocket.connect(); // THIS ONE GIVES A "Service discovery failed" exception
} catch (IOException e1) {
Method m = null;
try {
m = mDevice.getClass().getMethod(
"createRfcommSocket", new Class[] {int.class});
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
tmp = (BluetoothSocket) m.invoke(mDevice, 1);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
mSocket = tmp;
try {
mSocket.connect(); // THIS ONE GIVES A "Connection refused" EXCEPTION
} catch (IOException e) {
e.printStackTrace();
}
}
What am i doing wrong? I already tried different ports in the m.invoke(mDevice, X) instruction but it always gives "Connection refused"
I worked with Bluetooth before but with python and Java ME so I understand the basics. I don't know much about the android API though.
Where did you get the UUID code from? That could be one of the reasons for the Service discovery failed.
Each bluetooth device may have several services each of them associated to one port (or channel). If you are running ubuntu try using the hci tools to know to which channel connect or which service to search for.
Here you have an official list with UUIDs from Bluetooth SIG. For Headset Profile the UUID is 0x1108, the UUID used by you it is Base Universally Unique Identifier and it is used for SDP.

Categories

Resources