Detecting network connectivity on Android? - android

OS: Android
Given: User has stated that they wish to remain connected to app's server to receive updates, etc.
Goal: To ensure that users are connected to app's server even when app is in background state.
Question: One problem has been occasional disconnects from the network. If a user loses data network connectivity (loss of 2G, 3G, WiFi) and then later regains connectivity, our app is left without a connection. I am currently trying to make use of PhoneStateListener's in order to detect various network changes and thereby restart connectivity with the server when appropriate. On my Nexus One (2.1), I find that onSignalStrengthsChanged and onDataConnectionStateChanged aren't called except when the listeners are originally registered, but not afterwards. The listeners are registered inside of a Service so they are continuously listening as long as the Service is alive (which we can assume to be 'forever' for purposes of this question). Has anyone else had any issues with listening to the state of the Data Connection?
onServiceStateChanged seems to be the most reliable so far, but I wanted to know if people have had success with the other listeners as well.

I guess you'll have to send keepalive messages at regular intervals to check whether the connection is still there. If not, reestablish it. There is a smorgasbord of reasons why your connection might drop, and you won't be able to check all of those client side.
Might consider using google's cloud service for what you're doing though, since they already keep an connection open for that. That way your user's phones won't have the overhead of keeping yet another connection around (which can be quite expensive)

Since StackOverflow doesn't allow me to close the question otherwise, I will provide the answer to why my PhoneStateListeners were not working:
I discovered that my problem was simply that I wasn't registering my listeners in a bitwise manner, but rather successively (i.e.
telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
telephonyManager.listen(listener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
.
.
.
instead of (the correct):
telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE..............);)
I will close this question and perhaps later open a different question asking for design suggestion on maintaining 'always alive' connections to a server on Android. Thanks.

As far as i know listeners could not be called when app is in background. You should try use services not activity.
And also remember to retrieve TelephonyManager in proper way
TelephonyManager mTelephonyMgr = (TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE);

I would think you would use the ConnectivityManager for this.
Class that answers queries about the state of network connectivity. It also notifies applications when network connectivity changes. Get an instance of this class by calling Context.getSystemService(Context.CONNECTIVITY_SERVICE).
http://developer.android.com/reference/android/net/ConnectivityManager.html
per the docs, it monitors network connectivity and sends broadcast intents on change to applications.

Related

Android JmDNS how to remove service

im currently writing an android app, which should keep track of other devices in the same wifi network using JmDNS.
The discovery process works correctly, but i don't know how to keep track of other devices especially noticing their removing.
As mentioned in
JmDNS device removal detection it seems like i have to implement this callback myself but I dont have any clue how to do this. It seems like the JmDNS Api doesn't provide any method to publish service messages myself.
My ideas so far:
Use the discovered socket connection to keep track of changes
Use JmDNS.requestServiceInfo() from time to time to check if the service is still available
Un-/Register services + listeners so they can find each other again
Does anyone know another way to solve this issue or could tell me how to trigger the serviceRemoved() callback?
PS: before taking this approach I tried Androids-NSD API, which seems to be quite unstable
So here are some things i figured out while experimenting:
The DNS-cache is set to one hour, which means that listeners won't remove a service as long as that counter didn't finish.
The mistake i made was unregistering my service after the wifi was switched off. Services send broadcast message that they aren't available anymore. This message can't be sent if the wifi connection was shutdown.
So instead of calling JmDNS.unregisterAllServices() after the wifi connection I have to call it when it's available. This leads to the onServiceRemoved() callback beeing fired in the listener

Reading data from Microsoft Band sudenly stops [Android]

Inside an android Service I connect to the Microsoft Band 2 and read data from all the sensors.(I want to receive data even if the screen is locked).
However, after a while I stop receiving any data (no more callback are called). Also, there is not event coming on the connection callback - where I should expect connection states changes to be signaled.
I should also mention that I am registering for all possible sensor events.
My code is similar to the one in the documentation examples, but I can provide snippets if useful (the documentation contains samples for connecting inside activities but it should work the same).
Has anybody encountered this issue or a similar behavior?
You should probably enable WakeLock. I had my MBand2 transfer realtime data (via a Service) throughout the day/night with no data loss or connection issues.

Long running client-server connection between two devices

If two (or more) devices are connected to the same network, and each has my apk installed, how might one device efficiently 'talk' to the other? Google Play services, Wifi Direct, and bluetooth is unfortunately not available on these devices.
I thought of using a 3rd party push notification service, but ideally I need the response between either device to be as fast as possible, and long-lived.
I have managed to get two devices sending messages to one another using the old client-server Network Discovery Sample app in the docs. However, if either of the apps is closed or leaves memory, the connection is obviously broken. Therefore I'm trying to figure out if this is possible through a Service, which I understand exists outside of the Activity lifecycle.
I understand how an Activity might connect to a Service to send a message (good sample on that located here), but from what I gather this all happens locally on the device. Is it possible to have this exchange happen over a local network, from one app to another? I guess what I'm saying is how can I set up a basic client server socket relationship between two apps that won't die?
It has been a long time but it should still work.
The problem here, as I understand it, is to have something that keeps running when the app is gone.
I remember using IntentService for this purpose. In the onHandleIntent() we made it loop while(!stopCondition) {...}
It was a stable solution then but it was around kitkat's time.
I'd try with the solution in your first paragraph being executed and managed by the IntentService which should keep it available.

How to wait for WifiManager connect, and determine if OK/failed?

I am building an app that can use WifiManager to automagically add/connect our WiFi hosting hardware, so that the user can easily get to its webinterface.
The wifiManager.enableNetwork(i.networkId, true); part works. It returns immediately and in a few seconds wifi connects. But the webinterface activity is started right away and the WebView quickly timeouts: page could not be loaded.
This is because the WiFi connection takes a few seconds. I am also unable to inform the user about failed connection attempts.
I read up on this and it seems to me that a BroadcastReceiver could "poke" my wifi-connect activity into starting the webinterface activity. A bonus would be to also visualize a failed connect.
So, my questions:
I recon i need a BroadcastReceiver for WifiManager.SUPPLICANT_STATE_CHANGED_ACTION or WifiManager.NETWORK_STATE_CHANGED_ACTION ?
When to register and unregister it?
Can/may i just put a loop to check a statemachine (and timeout) in between, or would that be bad design and why?
I hope this can be done while staying inside my app instance .. or would that inherently result in bugs when exiting the app while wifi is trying to connect?
edit:
As for code; i use WifiManager exactly like so: How do I connect to a specific Wi-Fi network in Android programmatically?
Targeting Android 4.1.2, and am using fragments in activities to recycle view/state instances.
You should listen to WifiManager.NETWORK_STATE_CHANGED_ACTION and check on the NetworkInfo object contained in the Intent that your are connected.
When to register : it's difficult to say without seing your code, but you could probably register just before calling wifiManager.enableNetwork

Managing lifecycle for IP client application

I have IP client application which has the following objects:
Socket instance connected to IP server.
Thread instance, executing ThreadFunction. This function continuously reads the socket, when it is connected.
Now I am trying to understand, what should I do, when activity is recreated (for example, after changing screen orientation). Is Socket instance lost? What happens with ThreadFunction? Looking at the other side behavior (IP server), I see that the client, Android application, is not disconnected. So, what should be my strategy in this case: should I create these resources again, or try to restore them by some way?
The answer to your question related to what happens to the resources when the application is destroyed, is that everything goes away, including sockets and runnables.
Even from the server side, the socket will be gone as soon as the server try to communicate over it.
Your best solution, as said already is to manage it using a service. It's quite similar to use an activity, and I encorage you to see a couple of examples.
If you realy want to make what you have now consistent without using a service, you may disable the screen rotation adding android:configChanges="orientation" to AndroidManifest.xml
I recommend using a Service. It is designed to do what you are asking.

Categories

Resources