Problem:
I'm trying to avoid the "web page not found", or at least to display a customized error page.
Context:
I use the cordova trick:
if (navigator.network.connection.type == Connection.NONE)
{
window.location="offline/index.html";
}
else
{
window.location="http://myurl.com";
}
But in my tablet, if there's no connection, I have the ugly "WebPage not found".
There's maybe something wrong in my code, but in all case I would like to find a way to avoid this page and to show my own.
I will be very happy if somebody here can tell me where to give a look.
Stef
PS : the "Page Not found" appears when the website is down. It's not related to the event offline. You can have internet, and the server can be down. In that case, I want to display my own error page. Thanks!
There is an event offline available in Cordova. You could add event listeners to this and do required changes in its callback. If you are using deviceready event it will be called only once when your app is done loading. But if you add offline & online listeners you can alert user each time network goes down/up.
document.addEventListener("offline", onOffline, false);
function onOffline() {
// Handle the offline event
}
http://docs.phonegap.com/en/2.9.0/cordova_events_events.md.html#offline
Related
I have been working on a hybrid android application. Currently a WebView in our application is pointing to an AngularJS 1.5.7 application. When the user hits a button inside of the application that changes the route I was expecting the shouldOverrideUrlLoading function to be called inside of my WebViewClient. However, this is not the case. It looks like shouldOverrideUrlLoading does not get hit on Angualar route changes.
This being the case I have gone down the following rabbit holes:
onPageFinished - Overriding this function in the WebViewClient works, however, it is not being called until after the new route is getting hit. Which is adding to the application loading time and creating a choppy experience. ` #Override
public void onPageFinished(WebView view, String url) {
if (url.endsWith("/#/")) {
signOut();
} else if (url.endsWith("/login")) {
// TODO: show some sort of failure message?
Log.i("Login Route", "The webview just attempted to go to the login route.");
signOut();
} else if (url.endsWith("/security")) {
Intent intent = new Intent(getApplicationContext(), SecurityActivity.class);
startActivity(intent);
}
}`
shouldInterceptRequest - Overriding this function allows you to watch for requests. However, by the time the requests go out from the AngularJS application the web view is showing a new route once again providing a choppy user experience.
onLoadResource - same
JavaScriptInterface - Currently I have set up a JavaScript interface to watch for window.location changes. This seems to catch the route changes quicker than any of the above options, however, there is still a glimpse quick flicker of the web page I do not want to do go to. You can find how to do Javascript bridging on this post
Any suggestions would be greatly appreciated! Thanks.
I've been trying to get errors to display in a text field within the app for ease of error reporting from users.
I've had some success using this code I found on stackoverflow. It's used at the top level of the app but it's not working on device:
//start code
this.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, errorHandler);
function globalErrorHandler(event:UncaughtErrorEvent):void
{
var message:String;
//check for runtime error
if (event.error is Error)
message = (event.error as Error).getStackTrace();
//handle other errors
else if (event.error is ErrorEvent)
message = (event.error as ErrorEvent).text;
else
message = event.error.toString();
//do something with message (eg display it in textfield)
myTextfield.text = message;
}
//end code
At first this wouldn't work on the device and I thought it was because upon the error, when developing on the pc, flashplayer would display the actionscript popup with the error. Which you would need to click "dismiss all" or close and then the globalErrorHandler was called after and then the error written to the textfield. I thought this is what was keeping it from showing up on the device. However, by adding event.preventDefault() I was able to suppress the actionscript popup when developing on the desktop and the error was written to the textfield successfully. This was not the case however on the andriod device. It still just hangs on the error. It's as if the default error event cannot be suppressed on android.
Thanks for your time. Any help appreciated!
EDIT 22/09/2017: I was able to see the error on device finally. It had to do with while on desktop publishing the error would be shown. However, on device the behavior was different and something was covering the textfield, by bring it to the front on error I was able to see it. However, I still see that some errors deeper in the class hierarchy are not being caught.
In our project we have it simpler (and it is working):
stage.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);
private function onUncaughtError(e:UncaughtErrorEvent):void
{
// Console is basically a TextField for debug/diagnosis output.
if (e.error) Console.error(e.error.getStackTrace());
e.preventDefault();
}
The other thing you should probably check is whether your TextField actually displays any text at all for there might be text embedding issues, unrelated to the error handling routine.
UPD: Loading SWFs so it doesn't mix with the parent.
var request:URLRequest = new URLRequest(path);
var context:LoaderContext = new LoaderContext;
context.applicationDomain = ApplicationDomain.currentDomain;
var loader:Loader = new Loader;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
loader.load(request, context);
I have searched all over the web and found different ways of closing a PhoneGap App. I tested all of them and none work. At least on Android.
Question:
Is it possible (By Feb 2014) to have a close button in a PhoneGap App on Android?
Thanks
This doesn't work:
function CloseApp() {
if (confirm('Close this App?')){
if (navigator.app) {
navigator.app.exitApp();
}else if (navigator.device) {
navigator.device.exitApp();
}
}
}
Is
navigator.app.exitApp()
really killing/closing the android app with phonegap?
I use cordova and have the same issue. Above mentioned code is just putting the app into background - I checked the running tasks (android task manager) after above code got executed by the app.
I am confused on why you want a button to close the app. Android already has a back button when clicked enough times will take the user back to the phone's main screen. There is also a home button that takes the user out of an app. Once, out of the app the user can "kill" the app through a task manager.
navigator.app.exitApp()
works and I use it in all my cordova apps. Check the rest of your code.
As ejwill said, having a "close" button is a bad idea. On Android I call exitApp when the user is the home page of my app and he presses the backbutton:
function onDeviceReady() {
document.addEventListener("backbutton", onBackKey, false);
}
function onBackKey( event ) {
var l = window.location.toString();
var parts = l.split('#/'); // this works only if you are using angularjs
var page = parts[1];
if (page == 'home') {
navigator.app.exitApp();
} else {
// do something else... one option is:
navigator.app.backHistory();
}
}
My 2c.
I am building a phonegap app with jquery mobile and using build.phonegap.com
I have an event to change the page to the login screen after startup process have completed.
This works fine but it will not work on my andriod device unless a debugger is attached to it, in which case it works fine.
The code I have is
$.mobile.changePage("login.html");
I have put this in the mobileinit, pageshow, and now on document.ready function but it doesnt change the behaviour.
I've checked if $.mobile is a function and it is, Have tried everything and can not seem to figure out why this would be happening, any feedback would be much appreciated
I managed to put in a hack to work around this issue.
It was something to do with my phone being really old and slow, so something was getting a little messed up on old/slow andriod versions.
To prevent this from being an Issue I figured out this way that solves the issue and boots up my jquery mobile app on phone gap even if the phone is very slow.
$(document).bind('mobileinit', function () {
setTimeout(function () {
var html = $(".loading-status-text").html();
/* The html has Please Wait in the dom so we know it han't been touched by jQuery */
if (html == 'Please Wait') {
window.location.href = 'index.html';
}
}, 10000);
$(document).on("pageshow", function (e) {
var pageId = $.mobile.activePage.attr('id').toString();
if (pageId == 'loadingScreen') {
/* This wouldn't fire at first */
$(".loading-status-text").html("Welcome to Appname");
$.mobile.changePage("login.html");
}
});
});
i am using the Titanium studio for developing android application. a user click on item a new window is being opened which fetch data from a site and populate the tableview. so this window does take time to open.
mean while i am fetching the data and showing loading screen like:
anotherWind.addEventListener('open', function (e) {
activityIndicator.show();
setTimeout(function(){
e.source.close();
activityIndicator.hide();
}, 6000);
});
the problem is at this point i'm assuming it takes 6 second to fetch and display a tableview. but in real time it may not be the case as time may vary depending upon the data
when user click a icon it should display the loading screen only for the time data is not pulated and showed in tableview.
its a kind of notification between two tasks. one when task is complted it should notify other one.
how can i resolve that ?
You can use a custom event listener.
Example:
Ti.App.addEventListener('tableDataLoaded', function() {
activityIndicator.hide();
}
When your table data is loaded, you fire the event:
Ti.App.fireEvent('tableDataLoaded');
I hope this will help you :)
It seems multi-thread will be a good solution.Android provide some mechanisms of communication between different threads or processes.
i have implemented the same. my new window needs to load remote data and populate the tableview.
so i just show the indicator in window open
anotherWind.addEventListener('open', function (e) {
activityIndicator.show();
});
and then hide it when my remote data is loaded. inside the callback of httpclient
'APIGetRequest(this.apiURL, function(e) {
var status = this.status;
if (status == 200) {
populatetableview(this.responseText);
activityIndicator.hide();
}
});'