I currently have the $ionicPlatform event listener in my app.js. I know it's working in the test environment on the pc browser, but when I build the app and run it on my android device, the ionicPlatform.ready never actually runs/fires. Any ideas?
Here are some threads/questions posted, with some solutions that haven't worked for me.
https://github.com/driftyco/ionic/issues/1751
https://stackoverflow.com/questions/32421291/code-inside-ionic-platform-ready-not-getting-fired-up
app.js
var app = angular.module('who', ['ionic', 'ngCordova'])
.run(function($ionicPlatform, $rootScope, $cordovaDevice) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
// Don't remove this line unless you know what you are doing. It stops the viewport
// from snapping when text inputs are focused. Ionic handles this internally for
// a much nicer keyboard experience.
cordova.plugins.Keyboard.disableScroll(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
var push = new Ionic.Push({
"debug": true
});
push.register(function(token) {
console.log("Device token:",token.token);
});
console.log('reached end of ionic platform ready');
});
})
UPDATE 12/14/2015 # 5:24 AM - I have a view/activity that loads first, it renders the results from the $ionic.platform.ready listener. Upon loading the app, it renders nothing. What's interesting is this, after going to another view/activity, and then going back to the first view/activity, the result is then loaded/rendered. Any ideas?
UPDATE 12/14/2015 # 5:30 AM - I have tried ionic.Platform.ready, I have tried the document.addEventlistener 'deviceready'. None of them are working, and $ionicPlatform.ready gives me the least amount of problems, so I have defaulted to that.
I've decided to go with this workaround for now, unless someone can refactor this better for me.
The data retrieved in the $ionicPlatform.ready would not be rendered in the first activity loaded. I would usually have to navigate to at least 1 more activity and then go back to see the results. Now I know ionicFramework has it's own default splash activity that I don't want to override for this purpose (for now), so I added another view/state/activity that just serves as a buffer and immediately navigates to the results activity.
app loaded <- the ionic platform ready should be fired here, but it doesn't
ionic splash activity
buffer activity
result activity <- ionic platform ready finally fires up, weird.
Could just be my misunderstanding of Ionic's data synchronization, but this dirty fix seems to have solved it.
Related
Working on a Project and stuck in an Issue:
Hardware Back Button Reloading Application (I am using Angular Router in this application).
My Code to Exit Application:
ionViewDidEnter(){
this.subscription = this.platform.backButton.subscribe(()=>{
navigator['app'].exitApp();
});
}
ionViewWillLeave(){
this.subscription.unsubscribe();
}
While same logic Working in other applications. but in this application its reloading the application not exiting it.
P.S: i have also tried it to put in platform.ready() but no luck.
With IONIC 4, there is new method subscribeWithPriority developed to handle race between soft & hard back button. Try modifying your code like below:
this.platform.backButton.subscribeWithPriority(1, () => {
navigator['app'].exitApp();
});
subscribeWithPriority() stops the propagation of the event after its execution and if we subscribe with high priority and execute our prefered navigation instead of default one then it is going to work as you want.
More reference docs for details:
https://github.com/ionic-team/ionic/commit/6a5aec8b5d76280ced5e8bb8fd9ea6fe75fe6795
https://medium.com/#aleksandarmitrev/ionic-hardware-back-button-nightmare-9f4af35cbfb0
UPDATES:
Try using this new version of exitApp cordova plugin. I haven't
tried myself but looks promising from popularity.
Also try to empty the page stack from Navcontroller or go to your home screen, seems like that's causing the reload for app with sidemenu's & tab pages... this.navCtrl.pop() / this._navCtrl.navigateBack('HomeScreen'), and then call exitApp.
NOTE: Tabs & SideMenu as those have its own routing module does create lot of complexity with app navigation.
Solved:
As Mention by #rtpHarry template of SideMenu / Tabs have History which leads application to Reload it self on root page. i was able to solve this by clearing History.
ionViewDidEnter(){
navigator['app'].clearHistory();
}
on Your Root Page just Clear your history and your Hardware Back Button will close the Application instead of Reloading it.
Do you have a sidemenu in your app? I'm just curious because this seems to be when I get this problem as well.
If you look in your inspector, you will see that window.history has a length of 1.
I don't see it in some of my apps, but the app that I have a side menu setup acts this way - on the homepage if you press back the screen goes white then it reloads the app.
Like I say, looking in the inspector shows that there is a history to step back to, which it is trying to do, and whatever that history step is, it just pushes it forward back to the homepage, which made me wonder if it was the sidemenu setting up its own control of the navigation system.
I've probably said some poorly worded terminology but as I haven't solved this myself I thought I would just let you know what I had found... hopefully it helps you move forward.
In my scenario, I wasn't even trying to do the exit on back code - I just noticed that the app would appear to "reboot" if I kept pressing back.
This explain the solution on Ionic 5 (and 4.6+ too I think).
private backButtonSub: Subscription;
ionViewDidEnter() {
this.backButtonSub = this.platform.backButton.subscribeWithPriority(
10000,
() => {
// do your stuff
}
);
}
ionViewWillLeave() {
this.backButtonSub.unsubscribe();
}
also keep
IonicModule.forRoot({
hardwareBackButton: true
}),
to true (default) in your app.module.ts
Sources:
https://www.damirscorner.com/blog/posts/20191122-CustomizingAndroidBackButtonInIonic4.html
The Doc
I'm trying to control how the android hardware back button behaves in my app. I had it all working but now I can't reproduce it. The code I'm using is in app.js. I'm expecting the back button to do nothing but write to the console.
.run(function($ionicPlatform) {
$ionicPlatform.onHardwareBackButton(function() {
console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!")
});
Can any one see what the problem is? I'm running ionic CLI v1.7.11. I'm running the code with ionic view on android
You can find full details, including a full working solution for both hard & soft back buttons at my related post:
Ionic override all BACK button behaviour for specific controller
To summarise how I handled the hardware back button, the trick is to register an action for the Back button, using code like this:
var doCustomBack= function() {
// do something interesting here
};
// registerBackButtonAction() returns a function which can be used to deregister it
var deregisterHardBack= $ionicPlatform.registerBackButtonAction(
doCustomBack, 101
);
$scope.$on('$destroy', function() {
deregisterHardBack();
});
The actual setting is done in that second block calling $ionicPlatform.registerBackButtonAction().
This returns a method that can be called to deregister the action later on if you want to.
It was a ionic view problem. Seems it does not support this.
I've built and app for android with meteor and phonegap/cordova:
https://play.google.com/store/apps/details?id=com.idqkd3gsl4qt51152xgy
It works decently OK (especially given that I'm not really a programmer), but one UX issue I've been struggling with is that the app will not consistently close when pressing the back button on my phone. Every once in a while it works on the first press, but most of the time I have to jam it 5-6 times in a row to get the app to close.
I'm using the latest iron-router. The rest of the packages I'm using don't seem particularly relevant to this issue but they are as follows just in case:
standard-app-packages
coffeescript
natestrauser:font-awesome#4.1.0
accounts-password
aldeed:autoform
aldeed:collection2
nemo64:bootstrap
less
alanning:roles
joshowens:accounts-entry
mrt:accounts-admin-ui-bootstrap-3
mizzao:jquery-ui
iron:router
sacha:spin
raix:push
mizzao:bootboxjs
meteorhacks:kadira
bootstrap3-media-query
the repo can be seen here: https://github.com/The3vilMonkey/BrewsOnTap
I can't specify the exact reason for this issue other than it seems like at startup there is a sort of redirect happening with cordova apps. Best solution I've found is to catch the popstate event and when you get back to the beginning exit or suspend the application.. I prefer suspend that way when the user comes back to the app it doesn't start it's lifecycle from the beginning.
if(Meteor.isCordova){
Meteor.startup(function(){
window.onpopstate = function () {
if (history.state && history.state.initial === true){
navigator.app.exitApp();
//or to suspend meteor add cordova:org.android.tools.suspend#0.1.2
//window.plugins.Suspend.suspendApp();
}
};
});
}
One caveat that got me when I first used this was redirecting to a login page if the user wasn't logged in.. If you're using this method in an app that does this, you'll want to switch to rendering the login page in place rather than redirecting otherwise your app will exit/suspend immediately.
In my case, I made a mix of the two previous answers so that it works well.
document.addEventListener("backbutton", function(){
if (history.state && history.state.initial === true) {
navigator.app.exitApp();
} else {
history.go(-1);
}
});
While Kelly's answer does work, it did not end up being functionally correct for my particular situation. An important point to note about that solution is that it will exit as soon as the back button causes you to return to the initial page and not when you press the back button while on the initial page.
Ultimately I used cordova's backbutton listener to see if the backbutton was pressed:
if Meteor.isCordova
Meteor.startup ->
document.addEventListener("backbutton", ->
if document.location.pathname is "/"
navigator.app.exitApp()
else
history.go(-1)
and then if I am at the root of my application I exit/suspend, otherwise I simply go back in the history.
Using the backbutton event listener does seem to override it's default functionality so calling history.go(-1) was necessary in my case.
Also note that this solution would break if you want a true history that could go back through the history (potentially hitting the root of your application multiple times) before existing on the initial entry point. A combination of my answer and Kelly's might work for that. I find that while that might be the expected behavior for websites, it isn't really for mobile apps.
Here's a meteor package available to do this for you as well:
https://github.com/remcoder/fix-back-button-android
EDIT:
I actually went ahead and forked that repo, fixed the cordova plugin dependency issues, and used Kelly's code instead of the code from the original repo, find my fork here:
https://github.com/tripflex/fix-back-button-android
Or install in Meteor using:
meteor add tripflex:fix-back-button-android
I can confirm it works correctly, when adding via GitHub method described below, and using Kelly's answer for detecting the root page (do not use the example on the GitHub repo).
I'm no meteor expert as well (but am a full time dev), but going off of Kelly's answer, I would move the check for isCordova inside the Meteor Startup (as i'm sure you will have more startup code as your app progresses)
Meteor.startup(function(){
// Mobile specific code
if(Meteor.isCordova) {
window.onpopstate = function () {
if (history.state && history.state.initial === true) {
navigator.app.exitApp();
//or to suspend meteor add cordova:org.android.tools.suspend#0.1.2
//window.plugins.Suspend.suspendApp();
}
};
}
// Any other startup code below here
});
EDIT: If you decide you want to use the cordova suspend package, it will not work like most cordova plugins in Meteor due to the plugin not existing in npm, so this will NOT work:
meteor add cordova:org.android.tools.suspend#0.1.2
You MUST add it like this using the GitHub repo:
meteor add cordova:org.android.tools.suspend#https://github.com/Lamerchun/org.android.tools.suspend.git#0dbb52cca0244ba22a8c7975895f0f45d2e9a4a9
In a Kendo UI Mobile ListView, a script to open an external link by native browser is called when a link is clicked.
The PhoneGap script is as follow:
On Android:
navigator.app.loadUrl(link, { openExternal:true } );
On iOS:
window.open(link, '_system');
The link can be opened on the corresponding native browser.
However, when the user switch back to the app from the native browser, some problems happen.
On Android, the screen hung on the original view, when the back button is pressed again, the screen is un-freezed and can be refreshed.
On iOS, however, the screen is also hung on the original view. When tapped on the screen, the complete view (with the layout) is moved. There is no way to un-freeze this screen.
How to fix this so that the screen can be un-frezzed after switching back from the native browser to the app?
Thank you very much for your help.
Updated 1:
I changed the original tag to a tag, everythings work now. But I am still curious to see if it is certain kind of bugs for Kendo UI Mobile.
There is a serious problem with Kendo Mobile hanging the page completely, making the app totally unresponsive to touch/mouse. The offending CSS is in Loader.transition() which does this.container.css("pointer-events", "none") which is equivalent to:
document.body.style.pointerEvents = "none";
Ouch - that is ugly. Plus in _attachCapture there is offensive JavaScript for all mouse and touch events that does:
event.preventDefault();
Fatal if using an app with an embedded full page WebView/UIWebView (requiring app to be closed and restarted).
Hangs can happen if:
You have an exception in your code (even in unobvious places),
You mistype a transition (no exception, just hangs),
A user's browser doesn't fire the transitionEnd event properly for some reason (This was repeatable for one user's up-to-date Chrome browser.
There is a failure mode in the Interaction between page transitions and Loader (depending on timing, couldn't repeat),
Multiple other causes
Note that there is a comment in Kendo that says: "This should be cleaned up at some point (widget by widget), and refactored to widgets not relying on the complete callback if no transition occurs.", so clearly Telerik know there is a problem.
You can use the following code during development to at least warn when Kendo Mobile has crapped itself:
var transitionTimer;
kendo.mobile.ui.Loader.prototype.wasTransition = kendo.mobile.ui.Loader.prototype.transition;
kendo.mobile.ui.Loader.prototype.transition = function() {
transitionTimer = setTimeout(function() {
alert('Kendo has hung the page');
}, 10000);
this.wasTransition.apply(this, arguments);
}
kendo.mobile.ui.Loader.prototype.wasTransitionDone = kendo.mobile.ui.Loader.prototype.transitionDone;
kendo.mobile.ui.Loader.prototype.transitionDone = function() {
clearTimeout(transitionTimer);
this.wasTransitionDone.apply(this, arguments);
}
I have run into this issue where asynchronous functions do not execute when the soft keyboard is open in the android browser.
For example:
<input type='text' id='foo'/>
....
document.getElementById("foo").addEventListener("keyup", function() {
window.setTimeout(function() { alert("1"); }, 20);
}, false);
You will never see the alert as long as you remain focused on the text input. This is true for xhr callbacks as well. If you attempt to make an ajax request, the request is sent, but the oncomplete callback is never fired until after you type another character in the textbox.
Does anyone know a workaround? You can see that Google obviously has a working example with their search suggestions, though I've not yet been able to figure out what exactly their solution is yet by looking at the minified/obfuscated source.
Any insight appreciated, Thanks
Using the newest jquery lib in the style of
$("#inputnum").keyup(function(e){
if (e.keyCode != '13') {
$("#outputarea").slideUp('slow');
};
});
causes the item selected with "#outputarea" to be slid up every time - as soon as I type any letter on the software keyboard or a hardware keyboard. Might want to give the jquery lib a shot? Cross-browser compatibility is the main reason I keep going back to it.