I have an app that works fine on iOS. It uses Cordova and uses remote requests for some of its functions, however, on android, only on a device, it sometimes (pretty frequently) will not connect. It almost always works on the Genymotion emulator, except once, where I saw "NET CACHE ERR" or something similar to that in the Chrome dev tools console. (The default Android emulator cannot connect however.)
The calls are simple jQuery ajax post requests that work fine in the Genymotion emulator (all times except once), and fine in a browser and in the iOS Cordova app. Networking permissions are enabled and asked upon installation. Interestingly, it can still get the device id used for push notifications (which requires a network response, from what I can tell, however it could be misleading I suppose).
Example for the obligatory request:
function connect(){
$.post('https://example.com/stuff.php', {
'var': 'a variable!'
}, function(data) {
//internet request complete, confirm connection successful
window.connected = true;
});
}
window.connected = false;
setInterval(
function(){
if(window.connected==true){
//yeah you connected
}else{
//naw you not connected homie
connect();
}
},
3500
);
Related
Issue
I have an App built in backbone.js and Cordova. It is having issues making an Ajax request in a very niche situation - specifically this issue happens only on an LG G4 (and Samsung S7) with the Wifi On. It likely has issues on others but I've only tested 4 phone models so far. I am using jQuery to make an Ajax call.
What I mean by issues making an Ajax request is that the request actually fails. In my developer tools on the Network tab, the status shows (failed). If i console log the XHR.status it shows a 0.
If i console log the thrown error I get the following...
DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'https://mywebsite.com/Unicorn/API/FooBar.svc/JSON/DoThisPlease?var1=whatisone&var2=morestuff&clientInfo=Android%20undefined%206.0'
Code
The code for my request is as follows...
function doSomeAjaxCall(successCallback, failureCallback) {
var deviceInfo = getDeviceInfo();
var request_url = baseUrl + "DoThisPlease?var1=" + encodeURIComponent(varA) + "&var2=" + encodeURIComponent(varB) + "&deviceInfo=" + encodeURIComponent(deviceInfo);
$.ajax({
url:request_url,
async:false,
success:function (json) {
if (json === "") {
failureCallback("Invalid email and/or password");
} else {
successCallback(json);
}
},
error:function (jqXHR, textStatus, errorThrown) {
if (jqXHR.status === 404)
failureCallback('The API was not found at this URL');
else if (jqXHR.status === 0)
failureCallback('Cannot connect to PD, make sure your device is online.');
else
failureCallback('Server Responded with: ' + jqXHR.statusText);
}
});
}
Things I've Tried
It should be noted that if I take the request url and paste it into a web browser it will also not work on Wifi.
This all being said, the minute I disable Wifi and data takes over everything works. I have tried the app in the following data settings:
Wifi On Data On Result Fails
Wifi On Data Off Result Fails
Wifi Off Data On Result Works
Phones I've Tried
Samsung S6 Android 6.0.1 Works on all Data Configurations
LG G3 Android 6.0 Works on all Data Configurations
Lg G4 Android 6.0 FAILS (with Wifi On see above configurations)
Samsung S7 Android 6.0.1 FAILS (with Wifi On see above configurations)
Version of Chrome on all devices is 53.0.2785.124
I can't quite wrap my finger around why this issue is happening. Any feedback on this issue or debugging Cordova apps in general would be nice.
I am currently debugging using chrome's inspector over ADB with the phone plugged in to USB.
EDIT 10/20
As per #Gandhi's suggestion I tried hitting other APIs. I was able to hit an API on a different machine - I used the Federal Reserve Economic Data API. I tried hitting a different API on the SAME machine and it had the same errors as attempting to make an AJAX request to the original API did. I also did some testing on a Samsung Galaxy S7 and it's results are the same as the LG G4.
Thought 1: I have an IIS server and I am starting to wonder if there is some sort of configuration issue on new Android phones (models, not Android software version) or the IIS server that is causing this issue.
Thought 2: I am going to do some testing today and try getting out of the office with the phones and trying a Wifi connection on a different network. I wonder if the way network requests are made on certain phone models might interact differently with our network. I'm not much of an expert on the Android OS itself but I think phone model shouldn't matter as the OS (version of Android) would handle the requests (just using the phone model's hardware) and conform to some standard for the requests. Regardless I'm going to try this today and update with results.
I have a big problem with running worklight application without enabled wifi or mobile data connections. The application starts and then quit, i need to get to the home screen and then implement some logic.
wlCommonInit is never called in that case. I debugged application and saw that something is sending message "onMessage(exit,null)" and then calls onDestroy()
Steps to reproduce:
- Turn off wifi and mobile data and start the application
Used environments:
- Worklight 6.2
- Android
In Worklight 6.2.0.01 I've created a new Hybrid application with the Android environment.
This application performs the below. The application was installed in an Android Nexus 5 device running Android OS 5. The device was set to Airplane mode (no WiFi, no 3G). Upon launching the application the onFailure function was invoked, as expected. No crash.
Provide your implementation so that it could be debugged.
function wlCommonInit(){
WL.Client.connect({onSuccess: success, onFailure: failure});
}
function success() {
alert ("success");
}
function failure() {
alert ("failure");
}
I set up an openfire server on a server within our network and gave it a domain name. I want to connect to it via my phone in a phonegap app and therefore implemented a strophe.js client within my app.
It works fine on my Nexus 5 (Android 4.4.3), but as soon as I want to run it on my Samsung Galaxy S2 (Android 4.1.2) or the Samsung Galaxy Tab (GT-P7501 - Android 4.0.4) I don't get any response from the server. Here is the code snippet of my connect:
var BOSH_SERVICE = 'http://SERVERNAME:7070/http-bind/';
var connection = null;
$(document).ready(function () {
connection = new Strophe.Connection(BOSH_SERVICE);
connection.rawOutput = log;
connection.rawInput = log;
connection.connect('id#servername/resource', 'test', onConnect);
});
function log(msg) {
console.log(msg);
}
function rawInput(data) {
log('RECV: ' + data);
}
function rawOutput(data) {
log('SENT: ' + data);
}
the console log will be:
SENT: <body rid='367573377' xmlns='http://jabber.org/protocol/httpbind' to='servername' xml:lang='en' wait='60' hold='1' content='text/xml; charset=utf-8' ver='1.6' xmpp:version='1.0' xmlns:xmpp='urn:xmpp:xbosh'/>
This will be repeated a few times but I don't get any incoming messages. The servers version number is openfire 3.9.3. As all this code works on my nexus 5 I assume that the code is correct. I Also doubt that my server is configured wrong, nevertheless I included a screenshot of the config settings of the openfire server in the end.
The openfire xmpp server is running on a windows server and I access it via wifi/dyndns.
Do you have any ideas why this does not work on the samsung galaxy? Every help will be appreciated. Thanks in advance !
I could "solve" this by myself. It is really not a big deal, but it took me a really long time (3 days) to realize this, so in case anyone will ever come accross the same phenomena this info might help:
In my case all the configurations of the server and the strophe client above are correct. Indeed the only reason the connect did not work properly on all devices seemed to be that these devices could not even ping the server, even though they are in the same network. In my case I gave the server a static domain name, which was the key issue. Somehow the Google Nexus 5 is able to resolve this name to an ip adress via the dns-server, but both the elder samsung galaxy s2 and the samsung galaxy tab aren't.
Solution: I replaced the static domain name with the corresponding ip-adress in my strophe.js connection.
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.
I'm trying to implement an HTML5 app that will work on desktop, android, and iOS. The app's main function is to wirelessly send commands to the server about what scripts to run and to receive regular messages pushed from that server about the status of those scripts.
The server is running nodejs and I decided to use Server Sent Events to do the push notifications. This requires that I use Firefox on Android since the native Android browser doesn't support SSE.
My implementation all works fine: the node server is publishing the events as it should and my client-side HTML5/javascript is picking it up fine on desktop chrome/firefox/safari, on my iPod iOS6, and my Android 2.2 phone.
However, there are 4 common situations that I need to handle:
the device loses its wi-fi signal
nodejs server crash (hopefully this isn't common!)
put browser into the background on iPod/Android while browsing another app, etc.
lock screen on iPod/Android while browser is running
Chrome/Safari behave perfectly on both desktop and iPod, as follows: if the server crashes, the site automatically reconnects and gets the pushed messages as soon as the server is up again, and if the browser app goes into the background for whatever reason, it is still getting those messages while in the background, or at the very least automatically reconnects as soon as it comes back into the foreground.
Firefox, however, both on desktop and on Android, is all too eager to close down that EventSource connection permanently. As soon as the browser loses connection to the server, either from server crash, from putting the firefox app into the background or from locking the screen, the EventSource connection is killed and does not ever try to reconnect. Of course, you can just reload the page when you come back to it, but this is annoying, especially in the case where you need to lock the screen because you need to put the phone in your pocket (this app needs to be used in some trekking situations).
Can anyone recommend any solution for this aside from just having to reload the page in Android Firefox all the time? Below is my dummy implementation, just sending random numbers every 5 seconds.
Server at /main/src
src : function(req, res) {
req.socket.setTimeout(Infinity);
// send headers for event-stream connection
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive'
});
res.write('\n');
var messageCount = 0;
var process;
function printEvent() {
messageCount++;
rand = Math.floor((Math.random()*10000)+1);
res.write('id: ' + messageCount + '\n');
res.write("data: " + rand + '\n\n');
process = setTimeout(printEvent, 5000);
}
printEvent();
res.socket.on('close', function () {
res.end();
clearTimeout(process);
});
}
Client
var source = new EventSource('/main/src');
source.onopen = function(e){
$("#test").html("Connected to server. Waiting for data...");
}
source.onmessage = function(e){
$("#test").html("MSG: " + e.data);
}
source.onerror = function(e){
var txt;
switch(e.target.readyState){
case EventSource.CONNECTING:
txt = 'Reconnecting...';
break;
case EventSource.CLOSED:
txt = 'Connection failed. Will not retry.';
break;
}
$("#test").html("Error: " + txt);
}
Thanks!!
i know only one solution, that is already used in many libs:
"heartbeat" messages - on the client side you may check, if the "random number" is not received from the server in 10 seconds (5000 seconds + some lag) - the connection is seems to be broken and you should do the reconnection
(with native EventSource you may use "close" method, than create new EventSource OR you can try https://github.com/Yaffle/EventSource )