I have a phonegap project built for android and uses cordova. I planted a web-based app in this phonegap project. This app has one html page, index.html. In this index file, onDeviceReady() function is not called. However, this page is working perfect, only that it is called from mainactivity and for some reason it does not step into this function.
It's probably overriden by a cordova function.
Question:
How do I make this function work in index.html file?
Which function overrides/replaces this one?
function onLoad() {
document.addEventListener("deviceready", onDeviceReady, false);
}
// device APIs are available
//
function onDeviceReady() {
// Register the event listener
document.addEventListener("backbutton", onBackKeyDown, false);
}
// Handle the back button
//
function onBackKeyDown(e) {
e.preventDefault();
navigator.notification.confirm("×”×?×? ×‘×¨×¦×•× ×? ×?צ×?ת?", onConfirm, "יצי×?×”", "יצי×?×”,ביטו×?");
}
function onConfirm(button) {
if(button==2){//If User selected No, then we just do nothing
return;
}else{
navigator.app.exitApp();// Otherwise we quit the app.
}
}
What happens here is that onLoad is called, and onDeviceReady is never called.
For onDeviceReady function being called you must import Cordova.js file.
check this issue maybe can help you.
Where do I find cordova.js?
Related
I have an application where a resource is created when the user enters that page. If they do not properly save that resource an API call is called to the backend to delete it. Closing the browser before saving is one scenario.
Here I use WindowEventHandlers.onbeforeunload to listen for a close event and fire a function before the window closes.
$window.onbeforeunload = function (evt) {
if (notSavedFlag == true) {
//call an api function
$http.delete(...)
...
}
}
However, the API call does not fire when closing the browser window (and I put a breakpoint in the backend to check if it fires)
What is wrong with my code?
window.onload doesn't seem to run the specified function in the chrome console and I can't seem to find anyone with the same problem.
Code:
function preStart() {
console.log("Hello");
}
window.location = 'https://www.google.com/';
window.onload = preStart;
When ran the window.location successfully runs but "preStart" does not. Any help with this would me much appreciated.
Edit - Ben Hanna says .onload will not activate because the page is changed which is fine but is there a solution to this? (where the function runs after the page changes)
This code will never hit the onload event if you're changing the location to navigate away to another page.
Update: You could do something like this.
function preStart() {
// You can run a function like this before navigating
console.log("Hello");
window.location = 'https://www.google.com/';
// You can't run a function once you've navigated to Google
// because you can't execute arbitrary scripts on pages/domains
// that you don't own.
}
// preStart will be executed when the `onload` event fires
window.onload = preStart;
Background: I'ev succesfully integrated angular.js within phonegap 'base' application, the one created from cordova framework itself.
To detected cordova onReady event I created this
angular.module('fsCordova', []).service('CordovaService', ['$document', '$q',
function($document, $q) {
console.log ("fsCordova initialized");
var d = $q.defer(),
resolved = false;
var self = this;
this.ready = d.promise;
document.addEventListener('deviceready', function() {
console.log ("deviceready received");
resolved = true;
d.resolve(window.cordova);
});
// Check to make sure we didn't miss the
// event (just in case)
setTimeout(function() {
if (!resolved) {
console.log ("fsCordova timout, deferred resolved manually");
if (window.cordova) d.resolve(window.cordova);
}
}, 3000);
}]);
This my app main js
(function(){
var app = angular.module('myApp', ['fsCordova']);
app.controller('MyController', function($scope, CordovaService) {
$scope.ready = false;
CordovaService.ready.then(function() {
console.log ("CordovaService.ready received");
$scope.ready = true;
});
});
})();
What I'm trying to do: thanks to this service, I want to resolve manually the deferred when loading index.html from Google Chrom Browser on Windows 7, thanks to timeout waiting for an event that, on a pc, will never occours.
What is working: I can see fsCordova initialized, I see deviceready received. On a Android emulator and on Android phisical device, I see in adb console even the CordovaService ready received message. So on android all is working
Problem: on a desktop pc, I can see fsCordova initialized, I see deviceready received and I see deferred resolved manually. But I can't see the CordovaService ready received message; $scope.ready = true; was not executed, so, really, I can't test it on my pc.
So, I think that my way to manually resolve the promise on timeout has something wrong.
Please, so, note that problem is NOT cordova. Something goes wrong with q or with angularJs
Simply problem was
if (window.cordova) d.resolve(window.cordova);
I fixed changing it to
d.resolve(window.cordova);
Please note the power of my method: you can test your cordova/angularjs app on desktop pc (until you use cordova plugin for device sensors, for example...)
The best solution for this case is to manually bootstrap angular on device ready event:
bootstrapAngular = function () {
angular.bootstrap(document, ['YourAppName']);
}
document.addEventListener("deviceready", bootstrapAngular, false);
if you want to run angularjs app before device is ready and do some action when it is ready you do it like this
document.addEventListener("deviceready", function(){window.deviceIsReady = true}, false);
then where the action needs to be called:
deviceisready = $watch(function(){ return window.deviceIsReady}, function (status) {
if (status === true) {
deviceisready() //will remove the watch
//device is ready, do some crazy stuff
}
})
I am making a phonegap application with jquery. I am confused whether I should wrap my entire code inside JQuery's $(document).ready() like
$(document).ready(function(){
//mycode
});
or inside the deviceready event of phonegap like
document.addEventListener("deviceready", function(){
//mycode
});
I am currently using document.ready but I think I may encounter problems if I try to access some Phonegap API methods inside document.ready.
Which is the best event to wrap my code in, document.ready or deviceready?
A key point in the answer is this line from the documentation of the deviceready event.
This event behaves differently from others in that any event handler registered after the event has been fired will have its callback function called immediately.
What this means is that you won't 'miss' the event if you add a listener after the event has been fired.
So, first move all the initialization code to the onDeviceReady function. Then first handle the document.ready. Within the document.ready if you determine that you are running in a browser, just call the onDeviceReady function, otherwise add the deviceready listener. This way when you are in the onDeviceReady function you are sure that all the needed 'ready's have happened.
$(document).ready(function() {
// are we running in native app or in a browser?
window.isphone = false;
if(document.URL.indexOf("http://") === -1
&& document.URL.indexOf("https://") === -1) {
window.isphone = true;
}
if( window.isphone ) {
document.addEventListener("deviceready", onDeviceReady, false);
} else {
onDeviceReady();
}
});
function onDeviceReady() {
// do everything here.
}
The isphone check works because in phonegap, the index.html is loaded using a file:/// url.
You should use the deviceready event to avoid funny things happening.
The docs state:
This is a very important event that every PhoneGap application should use.
PhoneGap consists of two code bases: native and JavaScript. While the native code is loading, a custom loading image is displayed. However, JavaScript is only loaded once the DOM loads. This means your web application could, potentially, call a PhoneGap JavaScript function before it is loaded.
The PhoneGap deviceready event fires once PhoneGap has fully loaded. After the device has fired, you can safely make calls to PhoneGap function.
Typically, you will want to attach an event listener with document.addEventListener once the HTML document's DOM has loaded.
Read the documentation here:http://docs.phonegap.com/en/1.0.0/phonegap_events_events.md.html
They are not the same.
jQuery.ready() is using:
document.addEventListener("DOMContentLoaded", yourCallbackFunction, false);
Source: https://code.jquery.com/jquery-3.1.1.js
Cordova/PhoneGap instructs you to use:
document.addEventListener("deviceready", yourCallbackFunction, false);
Source: https://cordova.apache.org/docs/en/latest/cordova/events/events.html
My suggestion is, that you put all the initialization code for your Cordova/PhoneGap plugins inside the callback function which is fired when the deviceready event occurs. Example:
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
// Now safe to use device APIs
}
#Kinjal's answer really helped me get on track, but I had to fight a lot of issues with timing.
I use Cordova device ready event to read data files for my app, a few JSON packets which drive interface building and are loaded by default inside the www folder, but might eventually be downloaded from a server, to upgrade the application database.
I have found a lot of issues because the application data structures had not enough time to initialize before routing was started.
I wound up with this solution: initialize jQuery first, call the event handler of Cordova at the end of jQuery initialization, call the application startup routine at the end of the last processing in Cordova initialization.
All this nightmare started because I needed a way to read template files for Hogan.js and could not read them with the file protocol and a simple XHR.
Like this:
$(document).ready(function () {
...
// are we running in native app or in a browser?
window.isphone = false;
if (document.URL.indexOf('http://') === -1 && document.URL.indexOf('https://') === -1) {
window.isphone = true;
}
if (window.isphone) {
document.addEventListener('deviceready', onDeviceReady, false);
} else {
onDeviceReady();
}
});
function onDeviceReady() {
function readFromFile(fileName, cb) {
// see (https://www.neontribe.co.uk/cordova-file-plugin-examples/)
}
...
readFromFile(cordova.file.applicationDirectory + 'www/views/tappa.html', function (data) {
app.views.lastview = data;
app.start();
});
}
I am using PhoneGap Build cli-6.2.0 and when I test the procedure you suggested is doesn't do anything inside function onDeviceReady().
With older versions of PGB it works!
$(document).ready(function() {
window.isphone = false;
if (document.URL.indexOf("http://") === -1 && document.URL.indexOf("https://") === -1) { window.isphone = true }
if (window.isphone) { document.addEventListener("deviceready", this.onDeviceReady, false); } else { onDeviceReady(); }
});
function onDeviceReady() {
alert( window.isphone );
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
The one does not have to exclude the other. One simple example:
$(document).on('deviceready', function() {
console.log('event: device ready');
$(document).on('pause', function() {
console.log('event: pause');
});
$(document).on('resume', function() {
console.log('event: resume');
});
});
I'm a JS newb so I'm trying to figure out how to make this example from w3c to work in my WebApp that will run in a PhoneGap framework...
I'm sure this is easy, but when the event listener is triggered, it runs the attached function with the alert, problem is is it proceeds to excute everything after that again. So say I flip my iphone off, I'll get an alert then it will execute the next alert which says its online... Anywho... If any of you gys have any better ideas about executing a function like this let me know PhoneGap Cordova has two other methods as well.
<script>
<!--
window.addEventListener("offline", function(e) {alert("offline");})
window.addEventListener("online", function(e) {alert("online");})
if (navigator.onLine) {
alert('online')
//functions to run online
} else {
alert('offline');
//offline functions or through into loop
}
-->
</script>
You are missing a parameter in the addEventListener function.
For me this is working fine:
window.addEventListener("offline", function () {
console.log("Online status: " + navigator.onLine);
}, false);
window.addEventListener("online", function () {
console.log("Online status: " + navigator.onLine);
}, false);
try out this if(window.navigator.onLine) { alert('I am online');} I have just tested it in console and it works :)