App behaves different after exit and re-enter - java

Cordova, Version 3.5.0-0.2.6
<body><script>
alert("documentready");
document.addEventListener("deviceready", function() {
alert("deviceready");
}, false);
</script></body>
I enter the app after deploying, I get 'documentready' and 'deviceready' alerted.
I leave the app with the back button.
I get 'documentready' only.
When I force-close the app with the taskmanager or re-deploy it, I get both alerts.
I want this behaviour to occur also after normal re-entering the app.
I would prefer a solution where there is no evidence left that the app has been opened before, after I leave it. Nothing restored from garbage collection etc. Ideally executing the same log as the force-close method from the task manager.
OK: I want, when I close my app via back button, that exactly the same happens, as when I open the task manager and force my app to close. Is this at least theoretically possible?
Alternatively, I would like the app, when left via back-button, to be in a 'hibernate-like' state, that if I re-enter it it behaves absolutely like it has never been left (call same logic as when the menu/home button is pressed).
QUESTION STILL OPEN - 50RS BOUNTY TO EARN

Add this to your mainActivity.java (whatever it is called in your project):
#Override
public void onBackPressed() {
finish();
}

I'm not sure why you'd want such behavior, but you can kill the app on back press (or on finish).
Calling android.os.Process.killProcess(android.os.Process.myPid()) is just like a forcing a stop from the task manager.
Add this to your CordovaActivity and it should kill everything without any remains:
#Override
public void onBackPressed() {
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}

I've implemented the same thing, I used the backbutton event from cordova. You can find more about the backbutton event here: link. I can't find documentation about the app.exitApp() function but I do know it is only available for android and amazon-fireos.
See code snippet below, you only need to know when you want to exit, but you might know that from the document.location object or something. Hope it helps.
document.addEventListener("backbutton", function (evt) {
// replace this with some logic (maybe document.location) to now if you are on the main page or not
if (true) {
// Check if methods exists
if (typeof navigator.app !== "undefined" && typeof navigator.app.exitApp !== "undefined") {
evt.preventDefault();
navigator.app.exitApp();
}
} else {
history.back();
}
}, false);

This should work:
In my_app_dir->config.xml add
<preference name="KeepRunning" value="false" />
And below
document.addEventListener("deviceready", function() {...
add
document.addEventListener('backbutton', function() {
navigator.app.exitApp();
}, false);
Afterwards open cmd, go to your project folder and run cordova build android; cordova run --device android;

What works for me, the problem might be that the DOM is not ready when you add the event listener. And may be caused by a faster load due to the app being cached. Use a self executing function to add the event listener and you will be sure the DOM is loaded.
function domIsReady() {
alert('DOM is ready')
}
function deviceIsReady() {
alert('Device is Ready')
}
( function() {
if (document.readyState === "complete") {
domIsReady();
} else {
if (window.addEventListener) {
window.addEventListener('DOMContentLoaded', domIsReady, false);
} else {
window.attachEvent('onload', domIsReady);
}
};
document.addEventListener("deviceready", deviceIsReady, true);
}());

Related

How to finish an application when it goes to the background

I need to finish an application when it goes to the background, I'm using method finishAffinity() but it seems it does not work, someone can tell me another alternative
#Override
protected void onPause() {
finishAffinity()
super.onPause();
}
Here's answer
finishAffinity() is not used to "shutdown an application". It is used to remove a number of Activitys belonging to a specific application from the current task (which may contain Activitys belonging to multiple applications).
Even if you finish all of the Activitys in your application, the OS process hosting your app does not automatically go away (as it does when you call System.exit()). Android will eventually kill your process when it gets around to it. You have no control over this (and that is intentional).
you can use this
public void endTask() {
// Is the user running Lollipop or above?
if (Build.VERSION.SDK_INT >= 21) {
// If yes, run the fancy new function to end the app and
// remove it from the task list.
finishAndRemoveTask();
} else {
// If not, then just end the app without removing it from
// the task list.
finish();
}
}
Source and read more

Add keyListener to simulate a mouse click on a link, page is made with Javax jspx servlets. getElementById returns null

I´m trying to add hotkeys to the web application we use at work. The solution was to apply a Greasemonkey script, but the web system uses Liferay Portal, which is made with JavaX and jspx server applets.
I DON´T KNOW HOW TO APPLY "WAITFORKEYELEMENTS" answer, my knowledge is not that advanced.
What is the problem? I need to search the label for a link, i.e. “case file history” , add a keylistener event and simulate a mouse click. Here´s an example link:
<a id="form1:commandLink1211" name="form1:commandLink1211"
onclick="submitForm('form1',1,{source:'form1:commandLink1211'});
return false;"
class="linkMenu" href="#">
Look case file history
</a>
I need it to simulate a mouse click into this link, but the getElementById returns null. The page loads “empty” and then loads the jspx module. I know greasemonkey puts the script first. I tried to use
window.onload=funcion
document.ready() //didn´t know how to add this to my code
Other solutions include using a timer, but I don´t know how to apply it.
Current greasemonkey script:
(function(){
document.addEventListener('keydown', function(e) {
// pressed alt+g
if (e.keyCode == 71 && !e.shiftKey && !e.ctrlKey && e.altKey && !e.metaKey)
{
console.log ("key pressed");
document.getElementById('form1:commandLink1211').click();
}
}, false);
})();
The default behaviour of GreaseMonkey and similar alternatives is to run userscripts after the DOM (document-object-model) has been loaded, i.e. as soon the HTML has been parsed but before included resources have finished to load.
Some Scripts need to do stuff before the DOM has loaded. To achieve this they use the meta block entry #run-atdocument-start. This gives you the chance to intercept anything the site is doing while loading. However, with this entry your scripts do not know anything about the document when they start running. (Note the limited support in GM 4.0)
If you do not need to do stuff before the site has been loaded, use the meta entry #run-at document-end or omit this entry at all.
The more accurate approach is to implement an event listener. Modern browsers support the DOMContentLoaded event, formerly known as "domready" event in some JS-frameworks.
document.addEventListener('DOMContentLoaded', evt =>
{
// Do DOM-based stuff here...
document.addEventListener('keydown', evt =>
{
document.getElementById('form1:commandLink1211').click();
});
});
Using JQuery the shorthand $(evt => {/* DOM ready stuff */} ); will also work.
The element was not loaded yet when the Javascript ran, so the element with the given id was not found. Try to wrap a function around your code:
function loaded(){
document.addEventListener('keydown', function(e) {
// pressed alt+g
if (e.keyCode == 71 && !e.shiftKey && !e.ctrlKey && e.altKey && !e.metaKey)
{
console.log ("key pressed");
document.getElementById('form1:commandLink1211').click();
}
}, false);
}
and make sure you have
onload="loaded()"
in the body tag.
Instead of document.getElementById('form1:commandLink1211').click(); can yo instead do submitForm('form1',1,{source:'form1:commandLink1211'});. It should do the same thing, right?

JavaFX: Stage close handler

I want to save a file before closing my JavaFX application.
This is how I'm setting up the handler in Main::start:
primaryStage.setOnCloseRequest(event -> {
System.out.println("Stage is closing");
// Save file
});
And the controller calling Stage::close when a button is pressed:
#FXML
public void exitApplication(ActionEvent event) {
((Stage)rootPane.getScene().getWindow()).close();
}
If I close the window clicking the red X on the window border (the normal way) then I get the output message "Stage is closing", which is the desired behavior.
However, when calling Controller::exitApplication the application closes without invoking the handler (there's no output).
How can I make the controller use the handler I've added to primaryStage?
If you have a look at the life-cycle of the Application class:
The JavaFX runtime does the following, in order, whenever an
application is launched:
Constructs an instance of the specified Application class
Calls the init() method
Calls the start(javafx.stage.Stage) method
Waits for the application to finish, which happens when either of the following occur:
the application calls Platform.exit()
the last window has been closed and the implicitExit attribute on Platform is true
Calls the stop() method
This means you can call Platform.exit() on your controller:
#FXML
public void exitApplication(ActionEvent event) {
Platform.exit();
}
as long as you override the stop() method on the main class to save the file.
#Override
public void stop(){
System.out.println("Stage is closing");
// Save file
}
As you can see, by using stop() you don't need to listen to close requests to save the file anymore (though you can do it if you want to prevent window closing).
Suppose you want to ask the user if he want to exit the application without saving the work. If the user choose no, you cannot avoid the application to close within the stop method. In this case you should add an EventFilter to your window for an WINDOW_CLOSE_REQUEST event.
In your start method add this code to detect the event:
(Note that calling Platform.exit(); doesn't fire the WindowEvent.WINDOW_CLOSE_REQUEST event, see below to know how to fire the event manually from a custom button)
// *** Only for Java >= 8 ****
// ==== This code detects when an user want to close the application either with
// ==== the default OS close button or with a custom close button ====
primaryStage.getScene().getWindow().addEventFilter(WindowEvent.WINDOW_CLOSE_REQUEST, this::closeWindowEvent);
Then add your custom logic. In my example i use an Alert popup to ask the user if he/she want to close the application without saving.
private void closeWindowEvent(WindowEvent event) {
System.out.println("Window close request ...");
if(storageModel.dataSetChanged()) { // if the dataset has changed, alert the user with a popup
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.getButtonTypes().remove(ButtonType.OK);
alert.getButtonTypes().add(ButtonType.CANCEL);
alert.getButtonTypes().add(ButtonType.YES);
alert.setTitle("Quit application");
alert.setContentText(String.format("Close without saving?"));
alert.initOwner(primaryStage.getOwner());
Optional<ButtonType> res = alert.showAndWait();
if(res.isPresent()) {
if(res.get().equals(ButtonType.CANCEL))
event.consume();
}
}
}
The event.consume() method prevents the application from closing. Obviously you should add at least a button that permit the user to close the application to avoid the force close application by the user, that in some cases can corrupt data.
Lastly, if you have to fire the event from a custom close button, you can use this :
Window window = Main.getPrimaryStage() // Get the primary stage from your Application class
.getScene()
.getWindow();
window.fireEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSE_REQUEST));
Ahh this is a known bug in JavaFX where the Stage will not close if a modal dialog is present at the time of closing. I will link you to the bug report which I just saw today. I think it is fixed in the latest release.
Here you go:
https://bugs.openjdk.java.net/browse/JDK-8093147?jql=text%20~%20%22javafx%20re-entrant%22
resolved in 8.4 it says. I think this what you are describing.
public Stage getParentStage() {
return (Stage) getFxmlNode().getScene().getWindow();
}
btnCancel.setOnAction(e -> {
getParentStage().close();
});

How can I detect a close in the browser tab?

Hello I am looking for information on the close tab (not browser) event if there is one in java for a applet. I am wondering if there is an event for that or a way to check a way to check for that. I would like to just capture the event and make a little popup box , stating Your session will expire or something along those lines. Is that possible at all or to a point with java or Javascript?
UPDATE: okay with the information you guys pointed me into i was able to get information on a simple enough javascript. Now it is working fine in IE , Chrome and Firefox but for some reason Safari 5.1.7 isn't liking the code. Not sure why. Here is the code if it helps.
jQuery(function() {
var hiddenBtn = document.getElementById("javaform:browserCloseSubmit");
try{
opera.setOverrideHistoryNavigationMode('compatible');
history.navigationMode = 'compatible';
}catch(e){}
//Sends the information to the javaBean.java file.
function ReturnMessage()
{
return hiddenBtn.click();
}
//UnBind Function
function UnBindWindow()
{
jQuery(window).unbind('beforeunload', ReturnMessage);
}
//Bind Exit Message Dialogue
jQuery(window).bind('beforeunload', ReturnMessage);
});
You have the onBeforeUnload event you can catch in JavaScript. See here.
Use window.onbeforeunload
window.onbeforeunload = function () {
return "Are you sure you want to exit?";
};
Note that it will also end in Are you sure you want to leave this page (or are you sure you want to reload this page if you are reloading)

How to both start a file download and close a (jQuery) dialog in Wicket?

In a Wicket app, I have a modal dialog that contains a simple form and a button. User enters values (report parameters), and then clicks the button which starts the download of a report file (typically a PDF). (All form values are required, and Wicket's validation mechanism is used to make sure user entered them before the download can start.)
Maybe this is better explained with a picture:
I'm using here a jQuery UI Dialog (instead of Wicket's ModalWindow which felt a lot clumsier and uglier from user's perspective).
Everything is pretty much working, except closing the dialog when/after clicking the download button.
Current version (irrelevant bits omitted):
public class ReportDownloadLink extends Link {
public ReportDownloadLink(String id, ReportDto report) {
super(id);
this.report = report;
}
#Override
public void onClick() {
IResourceStream resourceStream = new AbstractResourceStreamWriter() {
#Override
public void write(OutputStream output) {
try {
reportService.generateReport(output, report);
} catch (ReportGenerationException e) {
// ...
}
}
#Override
public String getContentType() {
// ...
}
};
ResourceStreamRequestTarget target =
new ResourceStreamRequestTarget(resourceStream, report.getFileName());
getRequestCycle().setRequestTarget(target);
}
The dialog is a Wicket Panel (which makes use of ReportDownloadLink above), which we put in a certain div, and then when a report is selected in a list, the dialog is opened from an AjaxLink's onClick() quite simply like this:
target.appendJavascript(String.format("showReportExportDialog('%s')", ... ));
Which calls this JS function:
function showReportExportDialog(dialogTitle) {
$("#reportExportPanelContainer").dialog(
{modal:true, draggable:true, width: 320, height: 330, title: dialogTitle}
);
}
Some options:
Make ReportDownloadLink extend something else than Link, perhaps, and/or find an appropriate method to override which would allow me to execute the tiny bit of JavaScript needed to close the jQuery Dialog.
Investigate jQuery + Wicket libraries (such as jqwicket or wiquery) that supposedly make these two work better together.
Latest thing I tried was overriding method getOnClickScript() in ReportDownloadLink which seemed promising (according to the Javadocs, it returns "Any onClick JavaScript that should be used"):
#Override
protected CharSequence getOnClickScript(CharSequence url) {
return "closeDownloadDialog()";
}
Thing is, this causes onClick() not to be called at all, i.e., the download doesn't start.
Could I perhaps override some more "ajaxy" class from Wicket (than Link) to combine these things: first init the download, then call the JS for closing the dialog?
Any recommendations or experiences from similar cases? Note that I want to keep using the jQuery dialog here, even though it makes things like these more complicated. Using a DownloadLink (see related question) is fine too in case that makes things easier.
NB: if you recommend JQWicket or wiQuery, please provide an example of how to do this.
Maybe you can try to bind the close modal code to the button "click" event using only JQuery, in your modal panel page, add something similar to ${"#mySubmit").click(myCloseModalFunction). It should keep Wicket default's behavior and add modal closing in the mix.
The other way is to override the getOnClickScript(...) method but the javascript has to return true in order for the browser to call the continue link evaluation and load the corresponding href. If you return false, the evaluation stops. I would suggest something like
#Override
protected CharSequence getOnClickScript(CharSequence url) {
return "closeDownloadDialog();return true;";
}
Hope it helps...
See https://cwiki.apache.org/WICKET/ajax-update-and-file-download-in-one-blow.html for inspiration.

Categories