HttpURLConnection.connect() fails after network reconnection on Android 10 - android

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.

Related

Flutter "Connection Refused" (errno=111) when trying to send an http get request to from physical device to pc

I built a flutter app which communicates with a web server that I wrote with flask. Everything works as intended without any errors if I use a virtual device. As soon as I try it in release mode on a physical device I get problems when it comes to the communication with the server
The only thing that I changed when using a physical device is the ip. I use 10.0.2.2 on the virtual device and my computers ip4 adress - that I get with ipconfig in windows 10 - on the physical device
Both devices are in the same network connected to the same router
Internet Permission is enabled in the AndroidManifest for all modes (Debug, Main, Profile)
I even disabled the firewall
The line that causes the issue is
await http.get(url).timeout(Duration(seconds: 15), onTimeout: () {
// Handle timeout
// This entire thing is in a try-catch block in an async function
});
In debug mode on the physical device when the HTTP get request is sent VSCode immediately says
Exception has occurred.
SocketException (SocketException: OS Error: Connection refused, errno = 111, address = 192.168.178.20, port = 43378)
First Question: Why Port 43378? Is that the port the HTTP request is sent to? Because when I run the flask app it says:
Running on http://127.0.0.1:5000/
Could that be the issue? I would have expected the exception to say the port is 5000 as declared in the URL. Or do I have to change something with how I set up the flask app? Currently it is the development server because I am still testing before I pay money and deploy
However I hope I didnt forget any important information. Any advice on what could be wrong or how to debug here is highly aprecciated
Pass an Uri object to http.get func. Uri classes let you specify the port as Documentation https://api.dart.dev/stable/2.12.0/dart-core/Uri-class.html

Expo - Network Response Time Out Error (create-react-native-app) (Windows 10)

I have the exact same problem as here: Network Response Time Out Error (create-react-native-app) (expo). Every time I try to scan the QR code from my phone on LAN, I get the network response timeout error.
I've gone through every single response in both the linked stackoverflow post and the associated github thread: https://github.com/react-community/create-react-native-app/issues/144#issuecomment-296631692 to no avail.
Everything I've tried
set REACT_NATIVE_PACKAGER_HOSTNAME='my-custom-ip-address-or-hostname' with my static ip
disable all connections aside from my wifi (The only other connection I had to disable was "Local Area Connection 4", I didn't have virtualbox like others)
set my wifi connection to private
completely disable windows firewall
make exceptions to 19000, 19001, 19002 (entirely redundant given I disabled firewall, but I was desperate)
restart computer multiple times
use same network on phone as on computer
put the line, "android": "set REACT_NATIVE_PACKAGER_HOSTNAME={your wifi ip address} && react-native-scripts android" in my package.json
Note: A friend on the same network (also using a windows 10 laptop) got expo over LAN to work perfectly fine to his phone, so it's probably specific to my computer.
Note #2: Tunnel qr scanning works fine, but is painstakingly slow to reload so not realistic to use. Local brings me directly to "Something went wrong", no timeout error.
I wasted my whole day searching for answer and finally i got solution accidentally. Just change connection from LAN to tunnel
Below is the image,
my case is to turn off any antivirus like ( Avast )

Android SocketTimeoutException on WiFi using Retrofit / OkHttpClient

I know similar questions have been asked but this one is slightly different.
We have an app that does some HTTP connectivity with our server.
While running the app on an LG Nexus 5X or Sumsung Galaxy 5, using any of our 3 WiFi routers, the connection times out ("SocketTimeoutException: timeout" due to "SocketException: Socket closed").
The connection doesn't timeout if we use cellular network, tethering between devices or the simulator on a laptop connected to the same (problematic) WiFi routers.
Just to point out, the routers are connected to different ISPs.
Did anyone ever experience anything like it or have an idea?
Thanks
SOLVED: Trying a GET instead of a POST (with a JSON body of ~4K bytes) seemed to work fine. So, after a session with tcpdump, server side, it turned out that the request does reach the server but it's "corrupted". The first ~300 bytes and the last ~1000 bytes do reach the server but the middle ~2500 bytes are missing (could be due to some service provider infrastructure/ shaper or whatever).
In any case, lowering the buffer size of the OKHttpClient instance (providing it with a new SocketFactory) to 512, did the trick.
Thanks to all of those who tried to assist.

Android: Nearby api, No Connection

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

AIR for Android checking internet connection issue ( actionscript 3 )

I'm developing a simple app for my school which will show you the newest updates from the website, but checking the internet connection seems a little problem in AIR.
I'll be more specific:
I'm using Adobe Flash CS6 to develop the app (Using AIR for android)
The app contains a menu, and the "internet frame", of which the code doesn't really work.
I've tried a couple of things already: URLMonitor(like is available = true), URLLoader(and cathing the IOError if it occurs when there's no internet connection) and something like HTMLLoader (long time ago :P, no success)
The URLLoader works "fine", but I also need to know if the webpage just isn't available (404) when there IS an active internet connection, but in either those cases it will just throw the same "stream error" , so I can distinguish them. That's why it doesn't suit my needs.
The URLMonitor also works "fine", but here comes to problem:
When testing the app on the emulator, it can without a problem detect that there is no internet connection. BUT, when exporting to .apk and running on my android device, it won't succeed in detecting the internet connectivity.
Here's my code:
var monitor:URLMonitor = new URLMonitor(new URLRequest("http://www.google.nl"));
monitor.addEventListener(StatusEvent.STATUS, netConnectivity);
monitor.start();
function netConnectivity(e:StatusEvent):void
{
if(e.target.available)
{
//checking the content
output_txt.text += "\ninternet available";
loader = new URLLoader(new URLRequest(webURL));
loader.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorLoader);
loader.addEventListener(Event.COMPLETE, onCompleteLoader);
}
else
{
//
//
// NO INTERNET CONNECTION AVAILABLE!
//
//
output_txt.text += "\nno internet available";
popupnoconnection_mc.alpha = 100;
popupnoconnection_mc.play();
popupnoconnection_mc.addEventListener(MouseEvent.MOUSE_DOWN, BackToMenu);
}
monitor.stop();
}
As you can see, it adds an EventListener to the URLMonitor, starts the checking, and the function checks the availability of the internet connection. WORKS ON THE EMULATOR, NOT PROPERLY ON MY DEVICE.
What's even more interesting:
What DOES work on my device, is when the internet IS connected. It will just show the text in my output field, but it won't when there is no internet connection!
Also, when lauching the app with an internet connection set up, then entering this frame, then going back to the main menu, then turning the internet off, and then entering this frame again, this code suddently works great!
So it has got to do something with the creation of the URLMonitor, and checking the connection at the same frame I guess, but I need a little hand here!
I think this can't be too difficult!
Thank you so much in advance! (sorry for typos)
You can use NetworkInfo to detect whether there is an internet connection - it works on Android.

Categories

Resources