I want to change the Android bluetooth connection parameters to be the CONNECTION_PRIORITY_LOW_POWER from the beginning of connection between an Android phone and BLE.
I have tried to add
"mBluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER)"
after the Gatt connection ("mBluetoothGatt = bluetoothDevice.connectGatt(mContext, false, callback)") or before the paring/bonding.
But it seems that the commection interval when the connection starts remains to be 50ms, which is the default value set by CONNECTION_PRIORITY_BALANCED.
Could you tell me to change the connection interval from the beginning of the connection?
Thanks in advance!
Best regards
Delay your connection priority request (requestConnectionPriority()) until after discovering services.
I believe Android will request a fast connection interval for the service discovery and then switch back to a "standard" interval. It assumes the "start" of your connection is after discovering services, so you must as well.
According to Android docs,
boolean requestConnectionPriority (int connectionPriority)
Request a connection parameter update.
This function will send a connection parameter update request to the remote device.
You shall choose to connect and immediately choose to request the connection priority even after which you can discover services and subscribe to a notification. This way you do not get notifications at undesired connection intervals.
Related
I have two apps
Client App
and
Server App
in android
What i want
To check in my server app that weather client app has internet connection or not.
What i have done
I had read this post
I have used BroadcastReciever to Listen weather internet is available or not. All is well. When internet connection goes right , i am saving value online to Firebase "true"
But
When internet connection goes off ,
i am using Firebase onDisconnect() method to save ServerValue.TIMESTAMP
It works sometime in two minute but sometime it doesn't update firebase and value remains true.
Note what i want when client app is connected ,on firebase it should save true and when it is not connected it should save false . Though in my server app i will retreive those values to show to client is online or offline
is there any other technique to do such a scenario in android ?
What do you suggest any improvement in my current scenario. ?
Help will highly appreciated.
Thanks
leave this onDisconnect(), write an API that will do nothing but will just ping the server after a fixed time continuously, let's say after each 2 seconds the API will be called(through service), so in case the net is disconnected or the cell phone is even off, since API will not respond to the server, here you will write a code in case app did't ping to the server after 2 seconds(or you can say after 5 seconds), the response(online status) should be FALSE automatically!
so in case the app is again connected to internet, since the service is running so service will update your false into TRUE again
that's too simple!
i think this is your required function!
I want to change user status to show either he is online or not. I want to change user status to false in database when User close application or when he loses connection with server.
As a method is available named as onDisconnect() .I have used that method to update user status by using following code .
HashMap<String,Object> user_online_status=new HashMap<String,Object>();
user_online_status.put("online",true);
DatabaseReference firebaseDatabase=FirebaseDatabase.getInstance().getReference().child("Users").child(userId);
firebaseDatabase.updateChildren(user_online_status);
//then to show user offline
user_online_status.put("online",false);
firebaseDatabase.onDisconnect().updateChildren(user_online_status);
I do that task but as it is on client side and If we want to monitor user connection with server and when connection is terminated node should be updated by Server Instead of Client.How can we change node value from server as User lose connection with server?
There are two ways the user can get disconnected from the Firebase Database.
a clean disconnect, where the client sends a signal to the server before it disconnects.
a dirty (for lack of a better term) disconnect, where the connection gets closed before the client can send a signal.
In the case of a clean disconnect, your onDisconnect handlers will immediately fire and thus your database will immediately be updated.
In the case of a dirty disconnect, Firebase depends on the socket layer to signal when the remote client is gone. This may take anywhere up to a few minutes. But eventually the server will detect/decide that the client is gone, and your onDisconnect handlers will fire.
A small note in your data structure: you that there is a 1:1 relation between a user and a connection. That is unfortunately not the case.
A user may be connected from multiple devices. If they now disconnect from one of those devices, the onDisconnect from that device will set online to false while they may still be connected on another device.
Mobile devices/networks have a habit of going through occasional disconnect/reconnect cycles. This means that you may have multiple connections, even on a single device. In case of a dirty disconnect, the onDisconnect handler may be fired much later, when you've already set online to true for the new connection. In such a case, your lingering onDisconnect handler will set online to false while the user may already be reconnected.
All this is to say that you should not rely on having a 1:1 relation between a user and their connection(s). The samples in the Firebase documentation treat connections as a collection and assume that the user is connected as long as there is any "connect ID" (generated by push()) left for that user. I recommend you do the same to prevent hard to debug race conditions and connection problems.
My BLE server permanently measures a sensor value and sends a notification with 20 byte user data after each measurement. The goal is to generate as much throughput as possible.
On the client side, the value sent by the server is received and processed.
rxBleConnection.setupNotification(setDescriptorEnableNotification(characteristic))
.flatMap(notificationObservable -> notificationObservable)
.observeOn(Schedulers.newThread())
.buffer(1)
.subscribe(bytes -> {
onNotificationReceived(bytes, buffer);
} , throwable -> {
// Handle an error here.
onNotificationSetupFailure(throwable);
}
);
If I set the Connection intervall to 11.25ms, I receive all values. However, if I set the connection interval to 30ms, I receive a few values and then the connection is closed.
In the Android Log i see the followed message:
BleGattException status=8 (0x8),
bleGattOperationType=BleGattOperation{description='CONNECTION_STATE'
Why is the connection interrupted and what is the trigger?
With the help of a BLE Sniffer this is not recognizable. The set connection parameters are accepted and the transfer begins. Suddenly the transmission ends and the error message appears.
Update:
BLE Sniffer screenshot has been added:
30ms, this is connection interval you set in server or android?
Btw, on android you can set speed mode
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
mBluetoothGatt.requestConnectionPriority(BluetoothGatt.CONNECTION_PRIORITY_HIGH);
}
Error 8 means the connection timed out. There is nothing wrong on the Android side. The problem is with the communication between the two Bluetooth controllers. If you have a sniffer then you should be able to see who is the one that fails to send packets.
Here is an Image from BLE Sniffer.
BLE Sniffer
I have the similar problem. On Android 7.0 there were two ways to keep connection:
1) If devices are bonded and there is a charachteristic reading callback with constant thread of packets. If there are no packets by some time, then connection fails.
2) If devides are not bonded, but I do TXCharacheristic.read every few seconds. If don't do that some time, then connection fails.
But now in Android 7.1.2 this way doesn't work.
May be the first way will work for you.
On your Android device you should make bonding, on your kit you should handle this bonding.
On Nexus 6P and Samsung S7 it doesn't work anymore, but I didn't try it on the other devices.
I suppose, you have min connection interval 7.5 on your BLE kit, but now it is deprecated on Android.
Try to set min connection interval to 11.25 on your BLE kit and set connection priority
gatt.requestConnectionPriority(CONNECTION_PRIORITY_HIGH);
where CONNECTION_PRIORITY_HIGH = 1
in onConnectionStateChange.
It had worked for me when I had changed min connection interval in my nordic from 7.5 to 11.25.
I'm using Nearby Connections API in Android. It's working fine except cases where there is a sudden disconnections.
The client again succeed in finding the endpoint, using the discovery process, yet when he uses sendConnectionRequest() Connections.ConnectionResponseCallback never called no matter if I restart the app both on the client and on the endpoint. Only when I restart both devices the connection start to work again.
I have 20+ devices on the client side so there might be connection between the two things.
Any help on issue or where to start debugging the issue would be great.
For making a connection in Nearby Connection API, the client don't just sends connection request, but Host also has to accept it-
Nearby.Connections.acceptConnectionRequest(mGoogleApiClient, remoteEndpointId, myPayload, this);
or reject it-
Nearby.Connections.rejectConnectionRequest(mGoogleApiClient, remoteEndpointId);
try this, and in your connection response callback have conditions to do stuff
if(status.isSuccess()){
// Successful connection
} else {
// Failed connection
}
Hope it helped
You need to properly disconnect the connection when needed with;
Nearby.Connections.disconnectFromEndpoint(mGoogleApiClient, remoteEndpointId);
or;
Nearby.Connections.stopAllEndpoints(mGoogleApiClient);
https://developers.google.com/nearby/connections/android/manage-connections
I had implemented ASP.NET SignalR with Android App. App works great but there is a problem. when i off the data connections, It takes time SignalR to disconnect the connection id created while onConnected() because it try to make connections till the time reach up to disconnection time it try to keep making connections, as a result the period of approx 1.5 min the app become useless. which i don't want. I want if a connection gets break due to loss of connection should be disconnected immediately. Has anyone a solution for that.
You should create your own method to stop the clients connection on such an event. You would probably use something similar to this
connection.hub.stop();
But if you really want the server to not wait you'll adjust the disconnect timeout, but if you do you'll have to adjust the keep-alive timeout accordingly if that was set manually.
DisconnectTimeout
www.asp.net/signalr/overview/guide-to-the-api/handling-connection-lifetime-events#disconnecttimeout
This setting represents the amount of time to wait after a transport connection is lost before raising the Disconnected event. The default value is 30 seconds. When you set DisconnectTimeout, KeepAlive is automatically set to 1/3 of the DisconnectTimeout value.
// Wait a maximum of 30 seconds after a transport connection is lost
// before raising the Disconnected event to terminate the SignalR connection.
GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(30);