Android Phonegap - detect home button? - android

I have the following script that monitors the android back button actions -
document.addEventListener("backbutton", backKeyDown, true);
function backKeyDown() {
if($.mobile.activePage.is('#homepage')){
setTimeout( function() {navigator.app.exitApp();}, 100 );
}
else {
setTimeout( function() {$.mobile.changePage("#homepage");}, 100 );
}
}
I would like to also close the app when the physical home button is pressed - does anyone know how to detect this?
Cheers
Paul

You can't do that but you can kill your app in onPause() method instead see more here
EDIT:
Doing that in onPause will get your app killed whenever the user leaves the activity, I am not sure if there is a way to do what you want in android though, also is not recommended!
You can create some complex broadcast messaging system that sends messages from your activities to the application instance at a given interval of time and if you don't get any message in the application instance for x seconds then you know that the app is in background..
You can do that using a base activity class that sends messages at x seconds until onPause is called and extend that activity in all the other activities that you use so you can have this behaviour.
This is for sure not the best option that is out there and will consume battery life depending on the implementation so you have to be really sure that you need this before implementing such thing.

Capturing the Hardware's Home key event is bad approach and Android will never allow you to do that. and for closing the app, android framework will automatically send your app to background so you don't need to care about closing your app on Home button pressed event.

I agree with Adil.. but if you really want to or need to exit your app, adding the same listener/function for PhoneGap's "pause" event would probably do the trick.

Related

How to dispose of resources safely in android studio?

Just like in visual studio WinForms. I first close any connections before exiting the application. Otherwise, the application will still run in the background. I do this by clicking on the form itself and then click on the closeBeforeexiting property.
I then close all of my connection just before the application exits.
My question is then, how do I do this in an android studio? I want to close of a RFID class first before exiting the app. The reason for this is another app on the device that uses the same RFID class. But since the RFID class did not close safely and is still running in the background, the other application crashes because it cannot access this class.
Is there a closeBeforeexit property in android studio, perhaps in the res->layout->content_main.xml that provides me with the same functionality as in visual studio
I could do this using an exit button on the application but I see people generally use the back button that is already on the screen to exit the application. Is there any way I can access this back button and put my close connection function in there?
Answer:
#Override
public void onBackPressed()
{
try {
RFIDReader reader = RFID.open();
reader.stop();
reader.close();
super.onBackPressed();
return;
}
catch (ReaderException e) {
Toast.makeText(this, "Error: " + e, Toast.LENGTH_LONG).show();
}
}
Yes, you can intercept the back button and do anything you want there (even cancel the back navigation), but then you'll miss the cases where the user leaves by the Home button, or an incoming call, or through a notification...
What you should do instead is to override the onPause, onStop, and/or, onDestroy methods for your activity. They are all callbacks related to the activity life cycle, which you will soon need to learn about.
In short: onPause happens when you lose focus, onStop when you're no longer visible, and onDestroy when the activity is fully deleted (e.g. the user pressed "back", but usually not when they pressed "home").
In your case, onStop is probably the most suitable one.
My question is then, how do I do this in an android studio? I want to
close of a RFID class first before exiting the app. The reason for
this is another app on the device that uses the same RFID class. But
since the RFID class did not close safely and is still running in the
background, the other application crashes because it cannot access
this class.
You better read -> Understand the Activity Lifecycle to see how Android works with Activities and background tasks. If you're running the task in a background task, you should be able to close the RFID using close() method.
I could do this using an exit button on the application but I see
people generally use the back button that is already on the screen to
exit the application. Is there any way I can access this back button
and put my close conection funstion in there?
Using onBackPressed() method should help in your case. Keep in mind that finish() method is not a good approach to close the Activity.
Is there a closeBeforeexit property in android studio, perhaps in the
res->layout->content_main.xml that provides me with the same
functionality as in visual studio
layout->content_main.xml is the UI layout in Android and to be able to handle such things, you'll need to go with java or Kotlin.

How to hide current screen when app goes background in React Native Android

I have a react-native-init App which uses appState to detect when an app goes background in order to hide the screen that the user was using (for example a list of emails), and put an image in front of it until the user calls the app foreground again and is authenticated.
This is to prevent any person, checking which are the current opened apps, from seeing what the last screen that the user was checking in my app looks like, and see the image instead (like a splash screen).
This can be easily achieved in iOS because iOS has three stages:
active: when the app is in foreground being used.
inactive: When the app is in transition about to go background.
background: When the app is already in background.
So when the app goes inactive, a flag in the component state is changed and a component with an image is shown instead of the current screen.
handleAppStateChange = (nextAppState) => {
if (nextAppState.match(/inactive|background/)) {
this.setState({ showSplashScreen: true })
}
if (this.state.appState.match(/background/) && nextAppState === 'active') {
this.setState({ showSplashScreen: false })
}
}
However, android uses only active and background appStates, so when it goes background the function is called with background as nextAppState and the flag showSplashScreen in the state is changed to true, but seems like since the app is already background the component does not react to the state change and when you check the list of opened apps you still see the last screen been used, a screen that can contain sensitive data.
Is there any way to detect in react-native Android when the app is going to go background so that the current screen can be replaced with an image before going background?
THere's mechanisms built into Android to prevent the leak of sensitive data. Use them, do NOT attempt to overwrite with an image- or at least don't rely on that alone.
The correct way to do this is to set the SECURE flag on the window, so that the Android OS will take care of this and other possible issues for you, such as screen shots. The code to do that is
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
This can be placed in your activity's onCreate, before setContentView is called.
Take a look on the Activity Life Cycle of android apps, you can check the following link
there are three stages that can help you
onPause: called when activity is not visible to the user.
onStop: called when activity is no longer visible to the user.
onResume: called when activity will start interacting with the user again.

How to Save State on Cordova App Exit?

I have a cordova (ionic) app that facilitates entering a lot of form data. This form data is saved to localStorage until it is ready to be published.
So keep the app quick I am not saving to the disk everytime and input changes. I am saving when the user navigates away from the page.
The problem I'm having is that the user may enter a lot of data on one page, and close the app without navigating. This is an obvious use case but I'm not sure how to get in front of it without frequently going back to the disk.
Is there a way I can quickly save when the app is exited? I know I can listen to the "pause" event in cordova apps but is that the same when the app is exited? Does an exit emit "pause" ?
If not, what are some strategies for handling this?
TLDR: Listening to the pause event is the right strategy.
The pause event fires when the native platform puts the application
into the background, typically when the user switches to a different
application.
Source
The pause event is the only way to let you know your app is being put in the background. On some mobile platforms you don't even have the possibility to exit your app (in iOS for example), as the platform is managing this for you. So listening to the pause event is your only choice as you loose control once the app is paused. Therefore listening to the pause event is the right strategy.
See following code snippet:
document.addEventListener("pause", onPause, false);
function onPause() {
// Save the application state here
}
In detail I have implemented a storage service with a save-method, which is called in the OnPause-handler.
Pause only fires when going to background. Why you say "to keep the app quick"? it's javascript, you can save to disk every field when is filled and it can be asynchronous.
function onLoad() {
document.addEventListener("deviceready", onDeviceReady, false);
document.addEventListener("pause", onPause, false);
function onDeviceReady() {
var pageNow = document.getElementsByTagName(body);
var currentPage = JSON.stringify(pageNow);
localStorage.setItem("uiState", currentPage);
}
function onPause() {
//retrieve info here
var pageShow = document.getElementsByTagName(body);
let techStack = localStorage.getItem("uiState");
// JSON.parse(techStack); //unnecessary because the parser will detect HTML
pageShow.innerHTML(techStack);
}
}
you can get the current state of the UI in any element, just use a different selector.

Android - Detect 'app became active' from multi-tasking

I am trying to detect if my app became active from multi-tasking and display a dialog.
The use-case is something like this: User is using the app -> Hits the home button -> Does something -> User taps on the app again
As expected, the last activity the user was on is being shown.
I want to display a dialog when this happens. I used onRestart() for the same and it works. Only problem is, even when the user goes to some activity in the app and then hits back, the dialog is being displayed.
I went through the activity lifecycle several times, but couldn't figure out the solution. Any ideas?
Well, you can tell the foreground application using the technique outlined in Determining the current foreground application from a background task or service: look for getForegroundApp. You could run a timer that checks periodically to see if the app is foreground, and if its not then set a variable after a suitable delay (to make sure you don't happen to hit it in the wrong order when switching Activities). Clear the variable in onStart, and if onCreate of the rooth Activity is ever called you know that the app just became Active.
I achieved this by setting a flag in Shared Preferences in onStop() and cleared it in onDestroy().
Then I overrided the Back button to clear the flag whenever it is pressed. This solves the problem I had stated.
Now in onRestart(), if the flag is true.... I display the dialog.
I know it is not the most elegant solution but does the job! Hope this helps somebody.

Android - handle onPause, onStop in specific way

I need to log action in my app. Action is startApp, stopApp, pauseApp and resumeApp. Tricky part is that my approach is diffrent than standard Android way. When I say startApp I need start aplicaton, stopApp is when all Application goes background(ex. hit home button). Pause is when something force to pause App ( but don't want log when I lunch another activity from my app ). So startApp != onStart() , rather Application.onCreate(), stopApp != onStop() , pause != onPause() etc....
Has anybody idea how to handle this ?
I think about put KeyEvent on "Back Button" in first activity to determine if app is stop. But how about Home Button ? I can't use it the way I use "Back Button". How about pause ? I think about use standard onPause() and inside this method try to recognize if onPause() is invoke by my another Activity or by for example phone call. But how to recognize what invoke onPause ?
Thanks for any suggestions.
It's probably not a good idea to override what the home button does. Users will always expect it to do the same thing, so you want to keep that experience consistent.
I would recommend finding a way to do what you want to do within Android's given life cycle methods. So, in onPause you could use a flag of some sort to denote whether to do your own stuff or to handle the regular Android way. Does that make sense?

Categories

Resources