I declare my variable 'shake' as a global variable, then I created new object inside the oncreate, then I call this :
#Override
public void onPause() {
super.onPause();
shake.cancel();
}
my phone can still vibrate although home button is pressed! I tried onStop(), same doesn't work..
my app is like this : countdown 10 sec, after that vibrate.. but the problem is onPause cannot be call so the user may feel where's the vibrate come from if it's set 2 minutes on the countdown ticker.. help!
Since I can't see the rest of your code, I'm gonna assume a few things.
Assumption #1
If you have your activity open, and the countdown starts and expires after 10 seconds, your phone vibrates (with your activity still open). If you go to home screen, the vibration stops.
Assumption #2
You have your activity open, and the countdown starts. Before the 10 second expires, you go to home screen. Your activity is not visible, but the phone starts vibrating soon.
If this is what you are seeing, it's the correct behavior. The problem is that in the 2nd case, your shake.cancel() from onPause() is called when you go to the home screen, before it actually starts vibrating. shake.cancel() can only cancel if it's already vibrating.
If that's what you are trying to fix (I can only assume since I can't see the rest of your code), you can try this:
private boolean mAllowShake = false;
#Override
public void onResume() {
super.onResume();
mAllowShake = true;
}
#Override
pulic void onPause() {
super.onPause();
mAllowShake = false;
shake.cancel();
}
// wherever you are calling the shake.vibrate()
if (mAllowShake)
shake.vibrate();
This way, when your activity is not visible and your timer goes off, since mAllowShake is false, it won't actually vibrate.
If that's not what you are trying to fix, please update your question with more code and description of your exact use case. Hope it helps!
Related
Original question:
A button in my app starts an activity, which needs some time to prepare classes.
To let a user know this, I start a new loading activity that starts the actual activity.
This activity needs to be shown before the actual is started.
But all methods of the Android lifecycle seem to be called before the activity is shown to the user and if I start a new activity before the activity I'm currently in is shown, it won't be shown anymore.
I tried:
Starting the activity in another thread, but this does not work because the startActivity(...) seems to block the UI reload
Waiting a few milliseconds before starting the activity, but this seems dirty
Any help is appreciated! Please tell me if using a forward activity is not the right solution!
Answer for people who are searching:
Use this code to do something when the activity is already visible:
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
// do something
}
}
If the activity can also turn visible shortly after your code, use Androids lifecycle methods (here probably onResume()):
#Override
protected void onResume() {
super.onResume();
// do something
}
Is there any way to prevent executing code within onResume when returning to an application after the home button has been pressed?
What method is called when the home button is pressed? I could possibly flag something up when home button is pressed?
Thanks
After overriding above method, now you can easily listen HOME Key press in your activity using onKeyDown() method.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_HOME)
{
//The Code Want to Perform.
}
});
Hope this will help
Thanks for the help everyone I managed to solve this by creating a boolean, executeOnResume, which I make false everytime onStop() is called and the app is closed. I then check the state of this boolean in onResume() when the app is opened again to choose whether some code should be executed or not.
onStop()
//-----application stopped
#Override
protected void onStop() {
super.onStop();
//do not execute onResume code when app opened again
executeOnResume = false;
}
onResume()
//-----application resumed
#Override
protected void onResume() {
super.onResume();
//if true
if (executeOnResume) {
//do something
}
else {
//execute onResume true code the next time onResume is called. For example, returning from another activity
}
}
tapping the Home button creates an intent to launch the Home screen and then starts that inten
Correct.
If this is the case, I'd expect the onCreate() method to be run whenever the Home screen is created
Not necessarily. If it is already running, it would be called with onNewIntent().
If someone could just offer some enlightenment into this matter, the basic question is whether onResume() or onCreate() gets called when I tap the Home button
Any time any activity returns to the foreground from a user input standpoint, onResume() is called. Home screens should be no different in this regard.
onCreate() is called when the activity is created. Existing activities are not created, but are merely brought back to the foreground. If what triggered the activity to return to the foreground was a startActivity() call, the activity will be called with onNewIntent() and onResume() (and usually onStart(), for that matter).
Reference : Which method is run when Home button pressed?
Users can leave your app in all kinds of different ways. Pressing HOME is only one of them. An incoming phone call will leave your app, pulling down the list of notifications and pressing one will leave your app, etc. In all of these cases, when the user returns to your app, onResume() will be called. This is standard Android behaviour and tells your app that it is now in the foreground and visible to the user.
Your architecture is flawed if you need to know how the user is returning to your app. You probably need to move some code that you have in onResume() back to onCreate() or onNewIntent().
My client wants their app to always show a "WARNING" screen when the application starts or when it awakens from sleep. I've tried creating an onResume() event in my master activity (which every other activity inherits from), but this causes an endless loop:
Activity is called, onResume() is fired
Warning screen fires, causing the calling activity to be paused
User clicks OK to accept the message, returning the user to the prior screen
Activity is woken up
Go to 1
Even if I could get around the endless loop, the Warning screen would fire whenever a new activity loads. This is what I like to call a Bad Thing.
Is there a way to mimic the onResume() event but at the application level rather than at the activity level, so that I can avoid these scenarios but still have the warning pop up on application wake?
Why not just use SharedPreferences.
http://android-er.blogspot.com/2011/01/example-of-using-sharedpreferencesedito.html
Store the time the popup is brought up, and if it was within 5 mins, or something, then don't pop it up.
This will break your loop and not completely annoy the user.
I would write a method to pop the warning and, in onPause, set a global flag. Check that global flag in the onResume, then reset it in your popup method. Simplified pseudo code...
class myApplication Extends Application{
boolean appIsPaused = false;
}
class myActivity Extends Activity{
#Override
protected void onPause(){
appIsPaused = true;
}
#Override
protected void onPause(){
if (appIsPaused){
showPopup();
}
}
public void showPopUp{
if (!appIsPaused){
return;
}
appIsPaused = false;
}
}
You could use an AlertDialog to show the warning message, it would solve your problem.
Else, try to start the warning screen from the onStart or onRestart of your application ?
Here's the android lifecycle if it can help : http://developer.android.com/reference/android/app/Activity.html
I want to launch a Notification in my app in a specific situation only when a certain Activity is not visible.
I managed to do it doing the bind/unbind of the Service when I create and destroy the Activity (using onCreate/onDestroy) e saving in a boolean if this Activity is visible through onPause/onResume methods, as the following code bellow shows:
public void onCreate(Bundle savedInstanceState) {
// ...
bindService(...);
}
public void onDestroy() {
// ...
unbindService(mConnection);
}
public void onResume() {
// ...
// this method sets to true the Service's boolean which retain Activity's visibility.
mService.registerActivity(true);
}
public void onPause() {
mService.registerActivity(false);
}
And on the Service, I check this boolean to launch the Notification.
It works for all the cases except in a specific one: when the app is opened in this Activity but the lock screen is enabled.
By some tests I've made, when the lock screen appears, the Activity.onPause method is called. I was hoping that the Activity.onResume method was just called when the lock screen was unlocked, but that's not what happens. When I press the power button to summon the lock screen, the Activity.onResume method is called already. In this sense, what I am doing is not right.
How can I make the Activity.onResume method to be called only when the user unlock the lock screen? Or... how can I identify that the lock screen was unlocked and the user is REALLY looking at the Activity?
Activity.onWindowFocusChanged(boolean hasFocus) should return true every time your Activity regains focus after the screen is unlocked.
2 thoughts, untested and i'm still kind of an android noob :
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> list2 = am.getRunningAppProcesses();
Then, filter your Activity from this list and check the importance property of it. Front running apps it's 100, don't know if it's still 100 when a lock screen is in front of it.
Or, you could create a running process what checks ever x seconds if the screen was locked, and, does something when it's unlocked again.
It was my understanding, obviously wrong, that onPause() is called whenever the back button is pressed? Now in my code I've put this onPause() event:
#Override
protected void onPause(){
super.onPause();
if(!_END_GAME){
Builder _alert = new AlertDialog.Builder(this)
.setMessage("onPause, with game NOT over!");
_alert.setNeutralButton("OK.",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
arg0.dismiss(); // Kills the interface
System.runFinalizersOnExit(true);
finish();
}
});
_alert.setTitle("Your Score!");
_alert.show();
}
}
Now the problem is, the dialog does not launch what-so-ever, and then the code errors out. I put the dialog there to try to visualize where the onPause() was called and help me debug some other variables and such. Yet like I said it never even gets shown. Any ideas why this would be? Is there a function that is launched prior to onPause() when the back button is pressed? Thank you in advance for any info.
onPause will always be called when your activity is no longer in the foreground, that's guaranteed. Maybe your _END_GAME is not false? Add a debug log output to your onPause method, you'll see that it always gets called.
I should note though that displaying a dialog during onPause is extremely bad form - the user is trying to get rid of your app (could even be because of an incoming phone call). You DO NOT want a dialog then. That goes against the Android design.
In fact, the Android OS will simply short-circuit your app if you try to do lengthy shenanigans in onDestroy or onPause. Basically, if those get called, you're supposed to disappear quietly.
If you really want to intercept the back button, you can check for the button like Ted suggested, but keep in mind that your app can go to the background in many other ways - home button, selected notification, incoming phone call, etc.
You should check for the back button by overriding onKeyDown, not testing in onPause. onPause gets called whenever your activity is no longer in the background leaves the foreground; it is not necessarily finishing. (You can check isFinishing() for that.) See here for more info on handling the back key.
onPause is getting called, and your dialog is showing, just for a tiny split-second before Android finishes your app. Put log statements in there if you want to watch what is going on.
If you want to show a dialog when the back button is pressed then the easiest way (works on Android 2.1+) is to override the onBackPressed method in your activity
#Override
public void onBackPressed() {
if (gameRunning) {
// show dialog
} else {
// exit
super.onBackPressed();
}
}