i'm writing a client-server application which uses TCP socket connection. In my android project, Service creates a thread for listening the TCP socket.
Everything seems OK. But i have got one problem.. My network service running in background fine; But some time later (10-15 min..), when i try to open my application (main activity) again, I can't get responses from the socket connection. It freezes or something?? i cant send or get TCP messages from the socket.. What can be the reason of this? I'm working on my phone, via 3G connection.
(Besides, the app running in the emulator hasn't got such this problem; I assume Its connection is stable, long-during )
Thank you for your answering.
Due to power optimizations and perhaps changes in connectivity (GPRS/HSDPA/Wifi) it's very likely your connection is being dropped.
In order to maintain a connection, your background service needs to claim a wakelock using the PowerManager class. This prevents the device from going to power-saving mode and thus disconnecting your socket. But beware, this significantly lowers the battery life of the device.
Also, you need to handle changes in connectivity which break your open connection. Android sends out a broadcast message named android.net.conn.CONNECTIVITY_CHANGE to notify of changes in connectivity.
Depending on your use-case I would poll with when the device is in the sleep-mode and only build a connection when the device is actively in use or just use C2DM push notifications
When I have experienced something like this in my apps, it has usually been because of power optimisations on the phone (which cant be overridden). If the socket has been idle for too long, it is automatically closed and needs to be reopened.
Are you sending data from time to time? Like implementing a heartbeat protocol ? if you are not, you should...or maybe it has to do with socket READ/WRITE TIMEOUT
Related
I have a permanently running service app on the handset, one of the things it does is detect when there is an incoming phone call and send a message and some data to a companion app on a wearable device.
I'm wondering whether the app should establish the API to communicate with the wearable when it launches, or only when there is an incoming call and then disconnect afterwards.
Has anybody with wear development experience got any pros or cons of these approaches?
The service automatically starts at device start-up, and I've noticed if an attempt is made to create the GoogleApiClient/Wearable.API and get the wearable device node soon after rebooting there's a high chance of failure, therefore a disadvantage of establishing the wearable connection at app launch is its probably fail and will need to re-try or wait etc.
In general, to save on battery life, you want to minimize usage of any network connection on a mobile device. The general rule of thumb is: establish a connection only when needed, if you expect to use it again "soon" (e.g. within a minute or so), then keep it around, and close the connection when you are not going to use it for a longer while.
So in your case, since you are responding to phone calls (which should not happen every couple of minutes!), you should re-establish the connection every time. I am not sure though about the delay incurred in this case.
Situation:
I'm developing an Android app using a socket for communication with a server via the websocket protocol.
The starting point to open the socket is a Service started from the application context. Opening and communicating with the server works fine.
Problem / Question:
The socket is not closed, when the device is going in mode SCREEN_OFF.
So my question / concern is, what is really going on with my process when the device is in such power state? Should i react and close the socket to save battery? The websocket is also using ping/pong mechanism to keep the connection alive. So if the system never "stops" my process i will always communicate until the battery is down or the OS kills my app?
Or am i understanding something wrong?
When device go in sleep mode, you have to close all service, thread to save battery.
After searching a lot on Internet we have came to one conclusion in order to ensure an persist connection with XMPP server we have to create a service,
We have created one which uses Smack library to connect with XMPP server and it is working fine with mobile and wi-fi network.
Every time you make something design approach always matter!!!, Smack have this reconnection mechanism already implicitly implemented in there library which listen to connection and if connection drops Smack try to reconnect with XMPP server at some interval of time.
Our use case scenario::
INTERNET connectivity can be because of wifi or data network,here if connection go is idle state of someone turn off screen cpu goes to sleep now any data is sent to server on this connection there will be no response because server is no more listening to client ,on client side XMPP connection is already in connected mode connection listener is not detecting any disconnection from server,so here flow gets completed.
After searching on INTERNET we found that possible solution to solve this is to ping server after a fix (we are using 1 min as fix period),after ping fail detected ,we have implemented reconnection mechanism same as smack(idea taken from Smack reconnection mechanism itself)by making use of timer task.
Problem:: only problem we have is battery draining ,if user is still connected with INTERNET and reconnection interval increases it will drain batty.
1). What is the possible solution of above problem?
2). Should we have to take another approach?
How To Create Service In Android Which Makes Persist Xmpp Connection
With XMPP Server?
Two things
Reestablish the connection, by listening for CONNECTIVITY_CHANGED intents and determine if the currently used data connection went down (and was replaced by another).
Ensure that the connection is established by pinging the server
Remarks about
Listening for CONNECTIVY_CHANGED is not enough, you need to compare the previously active connection with the now active one. And if it's not the same, re-establish the XMPP connection.
Smack 4.1 comes with ServerPingWithAlarmManager, which will check if a ping is required according to the settings of PingManager every 30 mintues. This value is hardcoded an can not be changed.
Using 1 minute as Ping interval is way to much! As you have experienced, it will drain you battery very fast. A reasonable ping interval is something > 15 minutes and I recommend 30 minutes. Smack 4.1 will also ensure that a ping is only send if there was no received stanza withing the Ping interval.
Also use XEP-0198: Stream Management when possible.
I recommend looking at the various open source apps that follow these guidelines and achieve a stable, permanent connection without draining the users battery1.
1: Just following these advises can not guarantee that the battery will drained. There are more factors to take into consideration.
I'm working on an Android application that runs in the background and enables support for a Bluetooth accessory. I would like to be constantly listening in the background for the Bluetooth device to try and open a socket to the phone. My question is whether it is possible to achieve this without constantly keeping a partial wakelock, since that would obviously have severe battery consequences. So what I'm wondering is what effect Bluetooth has on the phone falling asleep. Does the phone stay awake when there is an open Bluetooth socket? Does the Bluetooth chip wake up Android automatically if a device tries to connect? I've attempted to do some testing to answer these questions, but it's difficult to isolate what is happening with wake locks; in addition, I don't know if I can rely on the behavior I observe or if it subject to change on other devices.
Yes, if your application is running and a thread is in serverSocket.accept() method, incoming connection wake up phone, so there is no need to use wakelocks. However, make sure that your service is in foreground and is not killed by system.
If you are developing it for devices target to marshmallow based or above, there is DOZE mode to treat such conditions. You then need not to worry about these thing. It can handle the WAKE_LOCK with appropriate mechanism.
The phone does not stay awake if there is an open Bluetooth socket, and neither does the Bluetooth chip wake up Android if a device tries to connect. Usually there is a background thread running to accept connections on the open port and as soon as a device tries to connect, it is this thread which reads the connection, gets some sort of authentication from the incoming device(I am assuming that there is a security protocol in place to accept any new incoming connections) and once the incoming connection is authenticated, an independent thread is created/notified to handle subsequent information exchange with this thread.
So the background process would consume some power and battery drain and it is also responsible for keeping Android partially awake(partially as its a background process and you can always control how frequently it checks for incoming connections). Usually this background process is not run always, its run only when Bluetooth is turned on in Android. So you can also create a thread which should run only when Bluetooth is switched on in Android, else it should sleep.
I'm currently developping an Android application which connects to a server through TCP. The server is written in Qt and runs on a computer.
In server side, I use a QTcpServer and the signal QTcpServer::newConnection() to get the QTcpSocket newly connected with QTcpServer::nextPendingConnection(). I have implemented a class I called SocketManager, which manages the data received by this socket.
In Android side, I use java Socket to connect to the server.
All work great. When the Android side disconnects from the server, my SocketManager object is well notified and destroys itself. But I would like to manage properly the case when for example the Android device goes to offline or is turned off. In that case, I'm not notified of the disconnection of Android. I connect these signals of my QTcpSocket:
QAbstractSocket::disconnected(),
QAbstractSocket::stateChanged(QAbstractSocket::SocketState)
QAbstractSocket::error(QAbstractSocket::SocketError)
QObject::destroyed(QObject*), thinking that perhaps the QTcpSocket is internally destroyed by the QTcpServer.
But no signal is received when the Android device goes offline or is turned off.
When the QTcpSocket will be released by the QTcpServer? Only when the socket is explicitely disconnected? So in my case, will it never be destroyed? Should I manage the disconnection in all cases in the Android side?
Thanks everyone.
TCP will not notify you of disconnections unless the remote peer explicitly sends disconnect request (by using close() or shutdown() methods) or you try to write to a disconnected socket (in which case you get a broken pipe signal)
The classical way to solve this problem is implementing a heartbeat messaging system where after a certain amount of heartbeat inactivity you close the socket concluding that the remote peer has died suddenly or there is a network problem.