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
Related
My app connects to an external device using it's WiFi (the device works as a server). With introduction of Android 10 I needed to implement separate WiFi connectivity flow for different plaftorms (WifiNetworkSpecifier for Android 10+ and wifiManager.enableNetwork for < Android 10). The connectivity flow itself works fine, but I have some problems with stream communication.
In the app I have the ability to upload files to that external device. To do that I need to use HttpURLConnection. So I run:
val url = URL(UPDATE_FIRMWARE_URL)
val connection = (url.openConnection() as HttpURLConnection)
with(connection) {
doInput = true
doOutput = true
useCaches = false
requestMethod = METHOD_POST
//setRequestProperty(HEADER_CONNECTION, "Keep-Alive")
setRequestProperty("Connection", "close")
connectTimeout = 6000
setRequestProperty(HEADER_USER_AGENT, "Android Multipart HTTP Client 1.0")
setRequestProperty(HEADER_CONTENT_TYPE, "multipart/form-data; boundary=$boundary")
}
connection.connect()
val outputStream = connection.outputStream
DataOutputStream(outputStream).use { outputStream ->
// actual file upload
}
Now, the actual update consists of two files, and after first upload the device restarts, and I need to reconnect to it's wifi and upload the second file.
On Android < 9 the entire upload flow (with two files) works fine but on Android 10, after I send the first file and reconnect to the device's WiFi, when I call connection.connect() I get ConnectExcpetion with internal cause connect failed: ENETUNREACH (Network is unreachable) (which really makes no sense, cause I'm connected to that network...)
java.net.ConnectException: Failed to connect to (...)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:1409)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:1359)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:221)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:144)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:106)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:400)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:333)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:483)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:135)
Initially I had a problem also with connecting for the first time on Android 10, but I found this article, and adding the connectTimeout helped, but now the connection still fails when I try to connect for the second (and every next) time. The only thing that helps is restaring the entire app (which is no real solution).
What may be the problem, that the next connections fail despite I always execute the same code?
After a few days I finally found an answer to my question. It turns out that on Android 10 when you connect to the Access Point that does not offer the internet (eg. my external device) the standard API calls (using Retrofit) works fine, but when trying to use HttpURLConnection the system tries to use some network with internet connection, and as there is none, the connection fails.
The only way for the connection to work is to force the system to use our network by using ConnectivityManager.bindProcessToNetwork(network). This solution was proposed here and I've got no idea why someone downvoted that answer. It's correct.
What's interesting is that if we connect to the no-internet network via device settings, the connection works just fine even without binding.
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.
I'm trying to get TXT Records from Wifi Direct Printers nearby. So far, I can discover peers and establish a connection. But no luck with TXT Records.
I tried Wifi Direct Service Discovery, and I believe I did everything properly since I compared lots of codes from different resources including sample projects from Google and some open source Wifi Direct Wrappers in GitHub. But I couldn't make it work.
I've also seen some weird issues while trying to achieve that. e.g in some devices, when I start the peer discovery, Wifi Connection started to be turned off and on constantly.
Can someone explain how this actually works ? are DnsSdServiceResponseListener and DnsSdTxtRecordListener made for Android devices rather than Printers ?
I've also tried to listen the MultiCast DNS IP Address (224.0.0.251) with a MulticastSocket after establishing the connection between Android and Wifi Direct Printer, but I couldn't receive any data as well.
Thanks.
I used "DnsSdServiceResponseListener" and "DnsSdTxtRecordListener" successfully in my current project. Both listeners are associated to discovering local services nearby.
To use them properly, you have to do the following:
Implement your listeners
WifiP2pManager.DnsSdServiceResponseListener dnsListener = new WifiP2pManager.DnsSdServiceResponseListener() {
#Override
public void onDnsSdServiceAvailable(String instanceName, String registrationType, WifiP2pDevice device) {
// instanceName is service name and device is the print information
}};
WifiP2pManager.DnsSdTxtRecordListener txtListener = new WifiP2pManager.DnsSdTxtRecordListener() {
#Override
public void onDnsSdTxtRecordAvailable(String fullDomain, Map record, WifiP2pDevice device) {
// here we get the service published information in the record map object
}};
Add the listeners to your WiFiManager object
wifiP2PManagerObj.setDnsSdResponseListeners(mChannel, dnsListener, txtListener);
Add service request
WifiP2pDnsSdServiceRequest serviceRequest = WifiP2pDnsSdServiceRequest.newInstance();
wifiP2PManagerObj.addServiceRequest(mChannel,serviceRequest, actionListener);
Finally, discover services
wifiP2PManagerObj.discoverServices(mChannel,actionListener);
After discover services is executed successfully, the listeners should receive the nearby services information.
Hope this helps.
Goodluck.
Update
Wifi direct supported printers don't have any published services by default. To use them you have to connect to them via wifi direct and print normally as its a printer connected to your network. Note that those listeners are meant to capture published services (i.e will not capture anything for any device unless its publishing a service).
I think you will need to run Bonjour discovery once the connection is established. You can see NSD and look for "_ipp._tcp" as the service type. By the way,
for "I've also seen some weird issues while trying to achieve that. e.g in some devices, when I start the peer discovery, Wifi Connection started to be turned off and on constantly." if you're testing on a 7.1 device you might be seeing this issue, for which a patch should be coming soon.
I am attempting to get Google Nearby API working on my handset (an s5).
I am building and running the stock project from github Google Nearby API GIT.
The app builds and runs, with no errors. Having exported the app onto two S5s (amongst other handsets I have attempted to test it with) and connecting to a WLAN from a D-Link DSL-3680. Multicasting is enabled and set to v3.
However the app refuses to connect with the neighbouring phone when corresponding 'advertise' and 'discover' instructions have been given.
Is there an effective way in which to debug this behaviour? If I can provide an effective information dump of information that might help someone identify the issue then please let me know how.
What do you mean by 'refuse to connect'?
are you getting connection status- 'Rejected'?
If you are able to advertise and discover other devices, I'm assuming all your base conditions (like connected to local network) are fulfilled
Now,
You can try logging your status in Connection call back when you try to connect
Nearby.Connections.sendConnectionRequest(mGoogleApiClient, myName,
remoteEndpointId, myPayload, new Connections.ConnectionResponseCallback() {//response conditions}
using--
inside connection callback function write
if(status.isSuccess()){
// Successful connection
} else {
// Failed connection
}
similarly, if you are not doing this, you need to accept the connection request
Nearby.Connections.acceptConnectionRequest(mGoogleApiClient, remoteEndpointId, myPayload, this)
and inside Onresult callback add-
if(status.isSuccess()){
// Successful connection
} else {
// Failed connection
}
Hope it helped
Dearl ALL,
I created one xamarin app.It using web service. Every connection is ok if use only wifi or 3g. But time out error come out when switching wifi to 3G OR 3G to wifi.
A list of steps to is as follows:
1.) Start the application on a phone using wifi.
2.) Attempt to retrieve data. The result is successful retrieval.
3.) Using the quick settings bar (pulling down from top of screen), turn wifi off so you're on 3G data.
4.) Attempt to retrieve data again and can't retrieve. The error message is
"The operation has timeout". Try again in 1 or 2 minutes, result is the
same.
5.) After attempting to retrieve data and receiving a failure on the first attempt, try again and can't succeed.
I'm using Channel Model for web service. Below is sample
nMobileSoapClient client = new nMobileSoapClient(
new BasicHttpBinding(),
new EndpointAddress("Web Service URL"));
client.InnerChannel.OperationTimeout = new TimeSpan(0, 0, 10);
client.InnerChannel.Open();
public nMobileSoapClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}
Same issue in IOS applicaiton.
Please, help me for this issue.
When you swicth the connection, the mobilesoapclient need to be completely reintialised for it to work. So, you would need to catch any network errors, and then reinitialise the soapclient and then try again.
Hopefully that works for you.