This strange thing just happens: whenever a startDiscovery() is called, the application is (as you would expect) still responding during the next initial 10-12 seconds. But whenever a Http Request is fired during this period it is stalled (no data could be requested or downloaded on a http connection).
I use the DefaultHttpClient.execute() method to request data from over the wifi network.
I not only see this happening in my own application. I also see this when the application is doing bluetooth discovery in the background and I want to download something off the Google Market place.
Had someone experienced something similar?
UPDATE 18-aug-'11:
When listening to a stream on the internet: I noticed the stream was dropping out on me whenever discovery was activated. I looked at the active network traffic and indeed I could confirm the two drops. The things that wonders me, as this was the network traffic from my computer and not my android device. Soo it seems the android devices somehow conflicts with the active wifi network?
Anybody familiar with this?
Related
I'm working on an Android app that communicates with a custom bluetooth device. After calling BluetoothGatt.Disconnect() I am seeing that the OnConnectionStateChange callback is called, and the new state is Disconnected, however, there seems to be a lag between when that happens and when the Device itself is actually disconnected. For example, if I call BluetoothManager.GetConnectionState(...) with the device that was connected, it still returns Connected. Sometimes it takes several seconds before GetConnectionState returns Disconnected. Is this normal? Is it possible that I am doing something wrong in my application that could be causing this? e.g. disconnecting from a non-UI tread, or something like that? Or, is it possible that the physical bluetooth device itself is not handling the disconnect properly and maybe not completing the disconnect event promptly?
Android's BLE system is so messed up. I've seen what you've described, except much worse - where you disconnect from Android, but under the hood it maintains a persistent connection with your peripheral.
Usually takes 30 seconds to finally disconnect, sometimes takes minutes! All depending on which phone you were using at the time.
If you have the ability, I highly recommend adding a disconnection characteristic to the peripheral, so that you actually disconnect by writing a disconnection request, and letting the peripheral force the disconnection - and then Android will pick it up.
The benefit I've seen is that it ALWAYS works (because a 'hard' disconnection is always picked up by Android, whereas a 'soft' disconnection request can cause some issues on certain phones). Typically 'good' phones don't exhibit this behaviour (especially Marshmallow and on), but back in those KitKat days.... Wow....
Another benefit... If you're using iOS, you can scan for or re-connect to disconnected peripherals much faster.
When you call "disconnect()" you only disconnect your client object (BluetoothGatt object). You can have multiple BluetoothGatt objects connected to the same physical device. Multiple apps can also have own BluetoothGatt objects connected to the same device.
As soon as you call "disconnect()" the request is processed in the Bluetooth stack in the system and it immediately then calls the onConnectionStateChange callback in your app when it has completed processing the request. However, it will not disconnect the link until all other clients have disconnected. Newer versions of Android also delay the physical disconnection a few seconds (not sure why). Also, once the disconnect request has been sent to the Bluetooth controller it may take some time to actually disconnect since the remote device needs to acknowledge the disconnection (or time out). The default time out was 20 seconds until it was recently changed to 5 seconds in the latest Android version.
I have a simple async client application for android that connects to a server on my desktop. Now over wifi the application works fine(unless the client network is super slow). But when I try to use it over the mobile network it randomly disconnects with the classic "connection reset by peer" error. I think the highest chance of it happening is connecting and then leaving it for a few seconds to do nothing over the connection. But the thing is sometimes it "survives" and happens later on, and maybe one in a hundred times doesn't disconnect at all. It makes no sense and there are a lot of applications on the appstore that work fine across mobile network so it can't be that hard...
EDIT: This also happens if i just put my phone on a table, great signal, no movement, or anything that would distrubt the connection.
This is not because of mobile's movement. You should check your setting in mobile network and keep only one setting 3g or 4g. Don't put this on "Both" connections.
Hope this will help.
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.
Using both Android 4.3/Samsung BLE 2.0 SDK, it is observed that when a peripheral is turned off, the SDK will receive onConnectionStateChange (DEVICE_DISCONNECTED) either immediately or after ~20s delay. From my experience this depends on the peripheral implementation, some of them will tried to report they are being turned off and some just doesn't, so the SDK have to wait for ~20s for the timeout.
To remove this behaviour, I tried to use a Timer to check if I can read a certain characteristic. If the read timed out, I will call disconnect(Android 4.3)/cancelConnection(Samsung) to terminate the connection. The call itself is successful and the onConnectionStateChange callback return a status GATT_SUCCESS. Then I turned the peripheral on and connect to it immediately, discover the services , and encounter problem when I tried to read/write/notify any notification. By using LightBlue in iOS I can confirm that the peripheral is not connected.
After exactly 20s from turning off the peripheral, I will receive a DEVICE_DISCONNECTED callback. I connect again afterwards, and everything operates just fine.
There are two question :
1. Are we supposed to connect to the peripheral during the 20s delay?
2. Is there any way to get notified when a peripheral is turned off?
Thanks in advance.
Are we supposed to connect to the peripheral during the 20s delay?
No, It seems from you result itself that OS is doing some actions within the phone to control DEVICE_CONNECTED or DEVICE_DISCONNECTED events, This may be due to several reasons like device architecture, security reasons or callback itself is delayed to save energy
Is there any way to get notified when a peripheral is turned off?
No I dont think so, The event received for any action is broadcasted so its waiting for a signal from the device it self but its not getting one, the only thing that you can do here is to send it via some other broadcast(or HTTP request) from the other end of the device to achieve it
I have a service which polls every hour attempts to sync data automatically to the web from the device.
I have it working but I need to find a way to establish an internet connection if there is not one available.
For example - If my phone is in standby mode (screen locked for a period of time) the internet connection is dropped and it is unable to sync when it needs to.
I would like to attempt to connect via wifi if available, then using 3G if required.
Is there a reliable way to do this?
UPDATE -
I found an article online which uses this code to attempt connection via 3G if there is no wifi available :
int resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI");
unfortunately it doesn't seem to work on all devices, maybe I need to try other options than "enableHIPRI" ??
Any ideas?
OK, although I haven't been able to solve this problem I have discovered that the main cause for the delay in between sync attempts is because the cpu gets stopped during sleep mode, this means my timer task was paused..
My workaround was to rewrite the service using a wakeful intent to get around the timer issue.
This makes my solution much more reliable so I am closing this question! :)
You should be able to do most of that using ConnectivityManager. It allows you to query the available types of networks and using requestRouteToHost you should be able to ensure there's a connection set up that you need for syncing.
I think you cannot rely on such thing on mobile phone, as in any embedded device you cannot be sure if the device will connect and stay connected when you want. You can only leave a message for the user that data was not synchronized or try to minimize it by checking if there is connection and then synchronizing not just in one hour.