I have the following logic for my mobile app using cordova and angular.js
Process my logic in mobile.js included in index.html like saving the files on sdcard then redirect the user to the second html page using
window.location.href="main.html";
which will use the files put in sdcard by mobile.js
The issue I'm facing is that when I am on the homepage on main.html and the user presses the back button it comes back to the index.html file and then, after processing goes back to main.html instead of App closing.
I tried using the history.length object with the "backbutton" eventListener
document.addEventListener('deviceready',function(){
document.addEventListener('backbutton',function(e){
console.log("history is "+history.length);
if(history.length==1){
e.preventDefault();
navigator.app.exitApp();
}
else{
navigator.app.backHistory();
}
},false);
},false);
but it doesn't decrease the length when going back, only increases it, so the app goes back to index.html.(history.length is always greater than 1)
I have looked the solution available, like
document.addEventListener("backbutton", function(e){
if($.mobile.activePage.is('#homepage')){
/*
Event preventDefault/stopPropagation not required as adding backbutton
listener itself override the default behaviour. Refer below PhoneGap link.
*/
//e.preventDefault();
navigator.app.exitApp();
}
else {
navigator.app.backHistory()
}
}, false);
but the issue in using it is, if the user goes to
second-page->homepage->third-page->homepage
the app will exit, but instead should go to the third-page.
You could use the jQuery mobile pageload event to keep your own history list, whose length does decrease when you go back. Something like this (untested off the top of my head, so might not be exactly correct):
var pageHistory = [];
$(document).on("deviceready", onDeviceReady);
function onDeviceReady(){
$(document).on("pagecontainerload", onPageLoad);
$(document).on("backbutton", onBackButton);
}
function onBackButton(e){
e.preventDefault();
pageHistory.pop();
if(pageHistory.length==0){
navigator.app.exitApp();
}
else{
navigator.app.backHistory();
}
}
function onPageLoad(e, ui){
var pageId = ui.toPage.attr('id');
if(pageId !== pageHistory[pageHistory.length]){
pageHistory.push(pageId);
}
}
Related
In my (android) phonegap app, I've added the code below to show a loading-spinner while logging in on facebook.
At first start-up, it works beautifuly. However, when I press the back-button and launch the app again, the spinner is out of control: it spins way too fast and with short pauzes. Also, the spinner appears not in the center of the screen, but slightly higher (it looks like it's centered with my text that follows afterwards).
Anyone familiar with this issue and knows how to fix it?
function DeviceReadyListener() {
$.mobile.loading( 'show' );
console.log("Device ready");
try {
FB.init({ appId:"xxx", nativeInterface:CDV.FB, useCachedDialogs:false });
navigator.splashscreen.hide();
getLoginStatus();
document.addEventListener("offline", onOffline, false);
} catch (e) {
alert(e);
}
}
I would like to disable or override the Android Back button while I am navigating pages on the InAppBrowser. Can I add an event listener that can handle that?
EDIT:
Looking at the answer by #T_D below the solutions provided are the closest I could get to. It does not seem to be possible to override the button in InAppBrowser as all the PhoneGap tweaks stop working while navigating pages on this plugin. I was not able to find any other solution rather than modifying the API library. If there are any PhoneGap guys here and know something more, I 'll be glad to get some comment. Thanks.
The closest I got:
var ref = window.open('http://apache.org', '_blank', 'location=yes');
ref.addEventListener("backbutton", function () { })
According to the documentation the behaviour of the hardware back button can be configured now for the InAppBrowser:
hardwareback: set to yes to use the hardware back button to navigate backwards through the InAppBrowser's history. If there is no previous page, the InAppBrowser will close. The default value is yes, so you must set it to no if you want the back button to simply close the InAppBrowser.
Thanks to Kris Erickson.
So just update your InAppBrowser plugin if the backward navigation is the desired behaviour.
For more details see: https://github.com/apache/cordova-plugin-inappbrowser/pull/86
You can do it quite easily now (as of InAppBrowser version 0.3.3), but you will have to edit the Java files. Go to src/com/org/apache/corodova/inappbrowser directory and edit the InAppBrowserDialog.java:
Change
public void onBackPressed () {
if (this.inAppBrowser == null) {
this.dismiss();
} else {
// better to go through the in inAppBrowser
// because it does a clean up
this.inAppBrowser.closeDialog();
}
}
to
public void onBackPressed () {
if (this.inAppBrowser == null) {
this.dismiss();
} else {
if (this.inAppBrowser.canGoBack()) {
this.inAppBrowser.goBack();
} else {
this.inAppBrowser.closeDialog();
}
}
}
Then go to InAppBrowser and find the goBack function, change:
/**
* Checks to see if it is possible to go back one page in history, then does so.
*/
private void goBack() {
if (this.inAppWebView.canGoBack()) {
this.inAppWebView.goBack();
}
}
to
/**
* Checks to see if it is possible to go back one page in history, then does so.
*/
public void goBack() {
if (this.inAppWebView.canGoBack()) {
this.inAppWebView.goBack();
}
}
public boolean canGoBack() {
return this.inAppWebView.canGoBack();
}
And now the hardware back button will go back until there are no more backs to do. I really think this should be the default behavior in android since the Done button already closes the InAppBrowser window.
This worked for me in PhoneGap 2.7, help came from here, How do I disable Android Back button on one page and change to exit button on every other page
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
document.addEventListener("backbutton", function (e) {
e.preventDefault();
}, false );
}
I was having this same issue and finally got it to work, I'll post the answer here in case it helps someone.
This is the code I use:
window.new_window = window.open(url, '_blank', 'location=no');
window.new_window.addEventListener("exit", function () {
window.new_window.close();
});
So the key basically is to attach the exit event, which gets called when the back button of the device is tapped.
BTW, I used cordova.js, and build my apps locally using the Cordova CLI, I don't know if that makes any difference, I mention it just in case.
EDIT NOTE: As far as I know, it's not possible to override the back-button for the InAppBrowser in PhoneGap. But I did my best searching for possible solutions...
There's an eventListener to override back-button in PhoneGap -doesn't work for InAppBrowser-
function onDeviceReady(){
document.addEventListener("backbutton", onBackKeyDown, false);
}
Alternative eventListener to override back-button -the OP said this didn't work either-
var ref = window.open('http://www.stackoverflow.com', '_blank', 'location=yes');
ref.addEventListener("backbutton", function () {
//logic here
})
Overriding the Back-button in an Activity -this is plain java, obviously didn't work in PhoneGap-
#Override
public void onBackPressed()
{
//logic here
}
Conclusion:
Above solutions didn't work, following links (this answer, this one and a third one) didn't help either. So it's highly possible that overriding the back-button for the InAppBrowser in PhoneGap is not possible. If someone does come up with a solution or if things changed for a new PhoneGap version feel free to let us know...
EDIT:
Installing this plugin may take you to closest solution:
cordova plugin add org.apache.cordova.inappbrowse
What this plugin will do, in WP8, it will overlay back/forward/close button on InAppBrowser whenever you open any link/page in it.
See this image:
Use jQuery mobile:
$(document).on('backbutton',
function(e){
e.preventDefault();
// YOUR CODE GOES HERE
});
Running Cordova 5.1.1 and when i load pages in the inappbroswer i like having the back button work until the inappbrowser exits back to my index.html page because it's blank and just sits there. So i used the following code to fix this. It exits the app when it exits the inappbrowser.
window.open = cordova.InAppBrowser.open;
var ref = window.open(url, '_blank', 'location=no');
ref.addEventListener('exit', function () {
navigator.app.exitApp();
});
As far as I know it's not possible to override or detect the back button from inAppBrowser. When you press the back button, inAppBrowser will hide and return control to the Phonegap page. You can catch this with the focus event on the window, (using jQuery) like
var browser = window.open('http://example.com', '_blank', 'location=no');
$(window).on('focus', function() {
browser.show();
});
to reopen the browser. You could then use browser.executeScript() to signal the webapp loaded in the browser, if you like.
Inspired by this forum post.
I know this question has an answer already but I post my answer for those who any of these answers didn't work for them(such as myself):
so I have a multi page app for android and IOS and I am using cordova 5.x and I added the code below in every page except the page I needed InAppBrowser:
delete window.open;
and then for the rest of the pages I used:
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown(event) {
// your code for handling back button comes here
}
for handling back button
note that: delete window.open; base on the documentation
manually restore the default behaviour of 'window.open'
after that InAppBrowser plugin worked great and I handled back button in all pages correctly.
one last thing don't forget to add:<script type="text/javascript" charset="utf-8" src="cordova.js"></script> in pages you need to have InAppBrowser.
hope this help.
In my app i am using phonegap 2.6.For back button, I am using the following function
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
alert("hello");
navigator.app.backHistory();
}
document.addEventListener('deviceready', onDeviceReady, true);
The above function works fine when I click on the device's hardware back button. But when I click on the back button it is not working.
I have designed my back button as below:
<a class="ui-link" href="#" rel="external" onclick="onBackKeyDown()">
<img src="images/icon-back.png" alt="Phone" border="0">
</a>
But this button is working fine for this navigator.app.exitApp(); (application exit).
//Working Fine
function onBackKeyDown() {
navigator.app.exitApp();
}
//Not Working
function onBackKeyDown() {
navigator.app.backHistory();
}
but not working for navigator.app.backHistory();.
I have tried 3 separate things when I faced the same situation:
window.history.back()
navigator.app.backHistory();
History.go(-1);
Individually, none of these solve the problem. I put all 3 things together and much to my surprise it worked. I really don't know what is behind it.
Then I decreased to two functions and removed:
window.history.back()
Now I am using this function and it is working fine.
//Works Fine
function onBackKeyDown() {
history.go(-1);
navigator.app.backHistory();
}
If you use the attribute data-rel="back" on an anchor, any clicks on that anchor will mimic the back button, going back one history entry and ignoring the anchor's default href.
it depends where you are:
on my windowsphone 8.1 lumia 925, it works history.go(-1);,
while navigator.app.backHistory(); causes an exception before crashing.
On my Android (I believe the majority), navigator.app.backHistory(); works properly.
This might help some people, as it helped me fix the history.go(-1) not working in google chrome browser.
// Doesn't work in Chrome browser
function onBackKeyDown() {
history.go(-1);
navigator.app.backHistory();
}
// Does work in Chrome browser
function onBackKeyDown() {
history.go(-1);
return false; //needed in chrome to prevent about:blank page.
navigator.app.backHistory();
return false; //needed in chrome to prevent about:blank page.
}
Im no expert at all in jQuery, but thought it might help someone, as I was looking for this answer but couldn't find it at first.
Solved! Stop getting "TypeError: navigator.app is undefined"
A function I created that will first check what device you're on and then apply the relevant script:
function onBackKeyDown() {
var userAgent = navigator.userAgent || navigator.vendor || window.opera;
if (userAgent.match(/iPad/i) || userAgent.match(/iPhone/i) || userAgent.match(/iPod/i)) {
// IOS DEVICE
history.go(-1);
} else if (userAgent.match(/Android/i)) {
// ANDROID DEVICE
navigator.app.backHistory();
} else {
// EVERY OTHER DEVICE
history.go(-1);
}
}
Call function by adding this to your back link/button:
onclick="onBackKeyDown()"
I am trying to use the back button in android to go to the main page every time the user press the back button and when the user is not logged in, the application should exit. I have tried this coded but it only works in index page and in the other pages, back button acts as it has been disabled. i am using phonegap for this application.
$(document).ready(function(){
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
document.addEventListener("backbutton", onBackKeyDown, false);
}
}
I kept the following function on .js file.
function onBackKeyDown() {
alert('Back Button!');
if (window.localStorage.getItem("loggedInData") == "undefined"
&& window.localStorage.getItem("loggedInData") == "") {
//location.href = 'main.html';
alert('LoggedIn');
} else {
alert('not logged in');
navigator.app.exitApp();
}
}
In my brief experience with Phonegap to get this to work i had to call the onDeviceReady before document.ready (i know this doesnt make sense but it worked for me on a small project).
Also if i am assigning different functions to the back button based on a page, i like to clear them first before rebinding them each time by chaining off().on() as below:
$(document).off("deviceready").on("deviceready", PhoneGapReady);
function PhoneGapReady(e) {
$(document).off("backbutton").on("backbutton", backHandler);
}
function backHandler(e) {
//back button pressed do something if you like
}
Also in the if statement for localstorage, should that be 'or' instead of 'and'?
To make the back button work for every pages of your app add the following code to every html pages.
$(document).ready(function() {
$(document).on("deviceready", PhoneGapReady);
function PhoneGapReady(e) {
document.addEventListener("backbutton", onBackKeyDown, false);
}
}
function onBackKeyDown(){
//your codes for back button
}
and add
<script>type="text/javascript" charset="utf-8" src="cordova-2.0.0.js"</script>
to the every page...
As i am using cordova-2.0.0,i have used that.
I am developing an app using phonegap-1.3.0 and android-4.0.3.Below is my code :
function home() {
document.removeEventListener("backbutton", handleBackButton, false);
document.addEventListener("backbutton", handleBackButtonOnHome, false);
}
function edit() {
document.removeEventListener("backbutton", handleBackButtonOnHome, false); document.addEventListener("backbutton", handleBackButton, false);
}
function handleBackButton() {
console.log("Back Button Pressed!");
home();
}
function handleBackButtonOnHome() {
console.log("Back Button Pressed in home!");
navigator.app.exitApp();
}
On click of hardware back button on edit page takes the user to the home page and when on home page the app exits as specified by the event handlers. The app is working fine on the specified setup (configuration).
Recently I upgraded to cordova-2.1.0, on click of back button on edit page exits the app instead of taking the user to the home page.
Please note : I have tried my thing but nothing seems to work,
navigator.app.backHistory()
history.back()
Any help welcome..
When looking for a solution to this problem in my environment (Sencha Touch 2 inside PhoneGap, see Andreas Sommer's instructions here) I fixed by adding the following code to my index.html HEAD secion:
<!-- handle android hardware back button -->
<script type="text/javascript" charset="utf-8">
document.addEventListener("deviceready", function() {
document.addEventListener("backbutton", function() {
if (Ext.getCmp('mainview').pop(1) == null) {
Ext.Msg.confirm("Exit", "Do you want to Exit?", function(e) {
if (e == 'yes') {
navigator.app.exitApp();
}
});
}
else {
return false;
}
}, false);
}, false);
</script>
FYI, the "mainview" component is an Ext.navigation.View where I'm popping off the current view from the stack. If pop() returns null then we are at the home view.
This worked fine for Gingerbread and ICS but did not work with Jelly Bean. To get it to work with Jelly Bean I needed to remove the android:targetSdkVersion="17" attribute from the tag in the AndroidManifest.xml file under PhoneGap.
All of this only worked with PhoneGap. When I generate the .apk under Sencha Touch instead of PhoneGap then the hardware back button didn't get captured.
Thanks for having a look into the problem.
I resolved the issue by adding the below line
document.addEventListener("backButton", backPressed, false);
in onDeviceReady() function. And used a flag variable to navigate between pages like this,
function backPressed() {
alert('backPressed');
if(gAppControl.pageFlag == true)
home();
else
navigator.app.exitApp();
}
Regards,
Nanashi