I am developing an ionic app. I am wondering if there is any event handler for this condition when the app is being stop/close in follow ways:
1) Settings -> Application -> Application Name -> Force stop
2) Swipe to close app.
I would expect something like this. But the best i could found is to cater for app exiting via $ionicPlatform.registerBackButtonAction which does not include the above two scenario.
Also, I am not sure whether this can be done in native platform as well. Please advise on this.
angular.module('app').run(function($ionicPlatform) {
$ionicPlatform.onAppStopOrForceClose(function() {
// Any function here
});
});
ionic.Platform.exitApp(); // stops the app
window.close();
see: http://ionicframework.com/docs/api/utility/ionic.Platform/
if you try in ios: you can't exit an IOS App, Apple do not allow apps to exit programmatically
Related
My app performs some checks inside main() function, before runApp( MyApp());, most important is load app configuration from Firebase. If failed, there's no any way to run not configured app. So I want to show message box saying "app configuration load failed", then after user press OK, exit app.
What is preferred way to exit app in that case? I need it working on iOS and Android.
If you need UI, I would suggest still calling runApp but on a different widget:
if(success){
runApp(MyApp());
} else {
runApp(ErrorApp());
}
For closing a flutter app programmatically, the best way is using SystemNavigator.pop() but if that didn't work, you can try exit(0).
I like to know how to exit an app in a good way in Android and Ios?
In the helloworld app of cocos2d-js this code is unfortunately omitted:
var closeItem = cc.MenuItemImage.create(
res.CloseNormal_png,
res.CloseSelected_png,
function () {
cc.log("Menu is clicked!");
}, this);
What can be there instead of
cc.log("Menu is clicked!");
?
For Android, you should call CCDirector::sharedDirector()->end(); to end the app. For Apple though, you could call exit(0) but its not really recommended to exit apps and will appear sort of like a crash. Do you need a close button? Most apps don't tend to have them and just keep running until the system or the user kills them.
This is a bit of a long shot but I'm going to ask to see if others have experienced anything similar.
We are creating a cordova ( 3.3.0 ) iOS / Android app. On iOS all is well.
On Android ( testing with Android emulators or a Samsung 8 Tab 4.2.2 ) when navigator.notification.confirm is called we quite often see the callback not fired back in JS after one of the confirm dialog buttons has been pressed.
Debugging Cordova ( native side ) we see the button pressed, the native dialog dismissed and the callback message added to the JsMessageQueue. But the queue doesn't seem to be serviced until something else forces it to be. For example, another call to navigator.notification.confirm would then causes the queued message to run.
We've put extra logging into the NativeToJSMessageQueue on setPaused to see if something was not restoring the pause but it looks ok.
I'm sure we've done something to upset it. Is there anything fundamental that basically stops the message queue from being processed that we should be aware of ? Something that on the javaside would cause cordova on Android not to check the queue ?
We don't see the problem on iOS but I'm sure this is because it doesn't use the same message despatch system as Android.
Sorry for the lack of code or any more info. I was hoping this may ring a few bells.
Update :
We've done a little more debugging and it appears to have something to do with fullscreen mode. If set in fullscreen mode ( via the config ) or native code the events do fire.
If fullscreen mode is set to false the callback event is left in the queue, and fired as soon as the button is pressed a second time.
function onConfirm(buttonIndex) {
alert('You selected button ' + buttonIndex);
}
function testButton()
{
navigator.notification.confirm('You are the winner!',onConfirm, 'Game Over', ["Butt1","Butt2"]);
}
This has been fixed in Cordova 3.6.0.
Anyone can explain me how keepRunning works in the config.xml for Android.
I mean, I don't want to know how to write the instruction but how does it work, how does it affect the execution of the Android app ? Does it create an Service in background ?
If anyone can find the source where we can see how does it work, that will be great
Thanks.
Edit : I try to analyze the generated code, analyze the RAM, services and processus in the setting of Android. And my conclusion is..... that do nothing.
If you try to make a app which track the user with GPS, dont use Cordova. To track the user correctly, you need to make a Service with the START_STICKY option. So, it's in native code. you lost the interest of the CrossPlatform because you have to recode the service for all platforms and in my opinion, the communication between Native Service and Cordova App is not easy.
In conlusion, if you use Cordova, you have to know you can't use the power of all native, you have to make choise :
- easy dev (subjective) and crossplaform (really crossplatform ?)
and
- Native dev with its power and no compatibility problems but you have to make one app for one platform
I'm not a JS/Cordova developer, I'm an Android developer. Once I worked on a Cordova plugin, faced some issues and did some investigations on the subject.
General purpose of keepRunning flag is to indicate if JS timers should be stopped when the app is paused (goes to background). Answering your question: no, it doesn't create any new Service. Existing design is quite plain in this regard.
The keepRunning flag is defined in CordovaActivity.java as follows:
// Keep app running when pause is received. (default = true)
// If true, then the JavaScript and native code continue to run in the background
// when another application (activity) is started.
protected boolean keepRunning = true;
Its main purpose is to disable JS timers when Cordova app is paused, in CordovaWebView.java:
public void handlePause(boolean keepRunning)
{
LOG.d(TAG, "Handle the pause");
// Send pause event to JavaScript
this.loadUrl("javascript:try{cordova.fireDocumentEvent('pause');}catch(e){console.log('exception firing pause event from native');};");
// Forward to plugins
if (this.pluginManager != null) {
this.pluginManager.onPause(keepRunning);
}
// If app doesn't want to run in background
if (!keepRunning) {
// Pause JavaScript timers (including setInterval)
this.pauseTimers();
}
paused = true;
}
Note that plugins are also notified via PluginManager, so in theory they can handle app paused events, to stop (or not) their activity in background, depending on keepRunning flag.
In my case I had an issue/bug when keepRunning was true, but JS timers were stopped anyway. It happened because there is additional functionality related to that flag, in CordovaActivity.java:
/**
* Launch an activity for which you would like a result when it finished. When this activity exits,
* your onActivityResult() method will be called.
*
* #param command The command object
* #param intent The intent to start
* #param requestCode The request code that is passed to callback to identify the activity
*/
public void startActivityForResult(CordovaPlugin command, Intent intent, int requestCode) {
this.activityResultCallback = command;
this.activityResultKeepRunning = this.keepRunning;
// If multitasking turned on, then disable it for activities that return results
if (command != null) {
this.keepRunning = false;
}
// Start activity
super.startActivityForResult(intent, requestCode);
}
When Cordova app launches another Android activity, main Cordova activity (screen with WebView) goes to background and is therefore paused. In my case it was made via Google Maps plugin which started GM screen over Cordova app.
The code above turns off keepRunning flag, and it means that JS timers are stopped anyway when the called activity appears (in CordovaActivity.onPause method) regardless keepRunning is true or false!
It looks like a kind of trick implemented for some unclear (and not documented) purpose, I do not know its context. In my case it caused a bug, and I just removed keepRunning handling in startActivityForResult, recompiled Cordova and it worked OK.
ADDED: About using a Service for GPS - you are quite right, I agree. As an Android developer with relevant (GPS) experience I can say that a right approach (and possible the only acceptable) is to use a service for that. As far as I know Cordova doesn't provide any functionality for it, so I think it should be made via a plugin. I mean you can write native Android code for GPS functionality (implemented as a Service) and access it from JS code. I believe it is a common solution in Cordova for such cases.
Perfect answer, helped me a lot! I was searching for the solution to the problem for 2 days now.
In my case I'm currently developing a cordova plugin for login purposes. For the login I use an external form which I load in a webview. For two days now I was struggling with the fact that the "Password forgotten" link and every other link on the page I loaded was working, but I wasn't able to submit my form. Only when I hit the back button and through this finished the intent holding the webview, it did submit and proceed.
Turns out that the keepRunning handling was the only problem here. In the end I replaced: `
cordova.startActivityForResult(this, intent, 0);
by:
cordova.setActivityResultCallback(this);
cordova.getActivity().startActivityForResult(intent, 0);
which basically fulfills the whole job Cordova's startActivityForResult would do The only thing that's left out is the whole keepRunninghandling which messed up my plugin in the first place.
Thanks again, Mixaz!
I am writing a simple Phonegap application for Android. This program will send notification to notification bar and make the phone vibrate periodically.
I use navigator.notification.vibrate(time_period) to achieve the target. According to this article, both beep and vibration are not supported by android emulator. Hence, I was expecting that there could be entry indicating failure of it in the Catlog, but there is no such entry. The question is how to make sure that a vibration event has happened or failed (without deploying to a device).
AppHarbor looks like one of the ways to debug Phonegap application remotely. I wonder if there is other local ways to test Phonegap application as an HTML5 website in a Chrome browser (navigator.notification call is a standard call)? If yes, then it is probably possible to somehow parse the browser's console automatically to find out if the vibration event has happened.
Can you hide the vibrate() call behind an abstraction which you can replace depending on which platform you are using?
For example
var vibrateFunc = function(time_period) {
if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
console.log('vibrating for ' + time_period)
} else {
navigator.notification.vibrate(time_period)
}
}
and then have your app code call vibrateFunc() whenever it wants to vibrate.