I am a developing game using andengine. When I press the power button, the onPause() method is not being called. How do I fix the issue?
#Override
protected void onPause() {
//this method is not calling when press power button
super.onPause();
this.mEngine.onPause() ;
}
Weird, haven't heard of it not being called. Let me research a bit.
Okay, pressing power should always call onPause(), there seem to be some kind of bug in your code. Could you add some log calls to follow every step. and print the DDMS log.
Other possible problems:
It seems some devices misbehave and call onPause() twice when pressing the power button.
In this case try using the powerManager to see if the screen is actually turned of.
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (pm.isScreenOn()) {
//now do stuff
}
Maybe onPause() is called but onCreate() is called right after ?
When you turn off the device, the lock screen is displayed. This typically forces the display to a particular orientation. If the screen is not currently in that orientation, it will need to be changed, and the top activity's configuration appropriately changed to match.
You can add config changes like this:
android:configChanges="keyboardHidden|orientation" android:configChanges="keyboardHidden|screensize"
To make sure this doesn't happen.
Related
I have just started insuring my apps work with Android 12. What I notice is that for (I believe) all of them when the back button is pressed, then onPause() is called, but not onDestroy(). This means the app is still running.
Previously, onDestroy() was called after onPause() when the back button was pressed.
It is a definite problem for ones running a background service that has (actually, must have) a notification. Stopping the service is typically done in onDestroy() and certainly not in onPause(). Since onDestroy() is not called, the service continues running and the notification remains up. If you select the notification, it brings up the [running] app again. There is no way to stop the service and hence the notification, except by killing the process via the overview (left) button.
I also notice that if an app with a service crashes, then the notification stays up. This is surely not desired behavior.
You can, and apparently have to, kill the process with the overiew (left) soft button).
I can get around this by implementing onBackPressed:
#Override
public void onBackPressed() {
// This seems to be necessary with Android 12
// Otherwise onDestroy is not called
Log.d(TAG, this.getClass().getSimpleName() + ": onBackPressed");
finish();
super.onBackPressed();
}
but that seems like a kludge.
For other apps maybe it doesn't matter they are still running or not. However, it is unexpected behavior.
Added later: This is apparently intentional and is a change from previous behavior. It is mentioned in this article (curtesy of #ianhanniballake):
https://developer.android.com/about/versions/12/behavior-changes-all#back-press
I have several apps, and I have verified it is happening with all of them on Android 12. It is causing problems with those that have services.
The implied question for this issue is what to do about it. I personally am implementing onBackPressed for those and leaving the others be.
I am not sure if this should be an answer or a comment, so, given the size of the text, I decided to go with answer.
The solution I came up with was forcing onDestroy() to be called, by finishing the activity from within onStop() in some circumstances.
In my case, I use onDestroy() to persist a few things. I know there are better ways of doing this, but that is how the code was, and this quick workaround fixed the issue, at least temporarily:
#Override
protected void onStop() {
// Try to differentiate a home button press from the screen being turned off
final PowerManager powerManager = (PowerManager)getSystemService(POWER_SERVICE);
if (powerManager != null && powerManager.isInteractive()) {
if (webViewHost != null && !webViewHost.isPaused()) {
// My old/existing logic (for Android < 12)
finish();
} else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
// New workaround for Android 12 onwards
finish();
}
}
super.onStop();
}
This is the project's repo, already pointing at the line where the workaround has been created.
As per the new changes in Android 12, back button on root/home activity is now minimize the app instead of close entirely. Hence it calls only onPause() and onStop() functions not onDestroy(). So I called finish() function from inside onBackPressed() function like this.
override fun onBackPressed() {
super.onBackPressed()
finish()
}
This could be a simple and quick workaround to match the behaviour with below Android 12. However the good practice is to optimise the app as per the Android 12 guidelines mentioned here
Which Method is called when Android screen is became off and on.
When Android screen is became off onPause and etc and when Andriod screen is became on onResume and etc is called I want to know isn't any special method just for screen on and off purpose in Activity or particular in Fragment.
As screen turns off your activity becomes invisible which triggers onPause followed by onStop
Screen on, on the other hand, triggers onStart followed by onResume.
Having said that, you best way for detecting screen events will be to register a broadcast receiver for
"android.intent.action.ACTION_SCREEN_ON"
"android.intent.action.ACTION_SCREEN_OFF"
See code example here.
If you are talking about your activity getting visible/invisible check onResume and onPause of the activity life cycle in the Android documentation.
If you are talking about screen on and off, check BroadcastReceivers for the Intent.ACTION_SCREEN_ON and Intent.ACTION_SCREEN_OFF events.
Have a look at this example as well.
screen off onPause > onStop (1st onPause get called then onStop)
screen on-> onStart > onResume (1st onStart get called then onResume)
please see activityLifecycle diagram
Diagram of activity life cycle
I'm not sure if you want is this, but this will able to turn the screen on and off.
PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);
// Choice 1
manager.goToSleep(int amountOfTime);
// Choice 2
PowerManager.WakeLock wl = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Your Tag");
wl.acquire();
wl.release();
Also you will need this premission:
<uses-permission android:name="android.permission.WAKE_LOCK" />
If want you want to know what method is called when the App becomes active again is the
onResume()
You should #Override it if you want to make any changes.
I am logging each onCreate() and onDestroy() calls. I found out that once I click power button on my Android (and on the emulator too!) the phone calls in my activity
> onDestroy();
> onCreate();
Which kills my game and then immediately reopen it from the beginning. Of course once user unlock the screen the game is presented in main menu with all progress killed.
Is it possible to override or disable this behavior?
When you press the power button, the screen lock usually kicks in. This may trigger a configuration change on the activity currently in the foreground (the screen lock is usually in portrait mode), causing it to be destroyed and recreated.
Declaring android:configChanges="keyboardHidden|orientation" for such activities in AndroidManifest.xml prevents them to be destroyed and recreated but also implies that you will handle the configuration changes by yourself (if necessary) by overriding onConfigurationChanged
You can't override when the onCreate() and onDestroy() methods get called (at least not without experiencing extraordinary amounts of pain). The best thing for you to do is to figure out how to work within the confines of when they get called. Save your state in onDestroy(). Make it so that your app can tolerate this call sequence because quite frankly, it supposed/has to. That's just how android works.
I just developed a screen saver app and I found a strange behavior in its lifecycle.
My work flow is like this:
start my RegisterService, where I call registerReceiver method to register a BroadcastReceiver, which can receive ACTION_SCREEN_OFF.
2.In the onReceive method of this BroadcastReceiver, I start an activity as the screensaver.
3.In the activity, I write Log.i() statement to track its running.
My question is:
When the screen times out, or when I press the POWER key, the screen turns off, and the system will send ACTION_SCREEN_OFF message. As I expect, my receiver starts the screen saver activity. However, I find this Activity calls onCreate(), onResume(), onPause(), onResume() sequentially according to the output in logcat.
It seems as if some a activity comes at front of my screensaver and finishes immediately, so my screensaver calls onPause() and then onResume().
Any idea? This problem handicaps me in programming, please help. Thanks!
Well based on a brief study of the PowerManagerService.java source code, when it's time to turn the screen off, the system initiates an animation (look at line 2183 for the class source) to do that. That means that your activity will pause and then will resume after the animation has ended.
I cannot be 100% sure for this, since I haven't tested it in my environment but this is the only logical explanation I found for your situation.
Hope this helps...
I can recommend you something very easy that might work for you, if you do not want the pause behavior why don't you try to Override the method onPause() and just do nothing :P don't call super.onPause() and that will terminate the behavior of it.
Other thing that might work for you, declare a static variable, add 1 on the "onResume()" method and return to "0" when "onStop()" is called. now just evaluate when the "onResume()" is called and if the variable is "0" then is the first time, anything else do nothing.
I hope this helps cause there is no much information on your question to be more specific.
I have an app that starts playing sounds and begins/resumes gameplay in the onResume() method, but what I'm noticing is that if my app was the last run application when I put the phone into standby (screen off), and I just press the Menu button to check the time, then the phone starts playing the game and sounds in the background (the app isn't actually visible, only the screen with the date/time is, yet onResume must have been called in my app). What am I to do here? Is there a way to discern what is reactivating the app, and then add a conditional statement that only starts the game when the app is actually visible?
Here is a snippet from my onResume:
#Override
protected void onResume()
{
mySaveGame = Utilities.loadSavegame(this);
//check the savegame
if(mySaveGame!=null)
{
//start game using savegame values
this.startFromSavedGame(mySaveGame.getIsLevelComplete());
}
else
{
//run the 1st-run components
this.startFirstRun();
}
super.onResume();
}
The only thing I can think of doing to prevent the game from starting whenever the screen gets turned on (even when the app isn't visible) is to put this.finish() as the last line in onPause()... but that forces you to restart the app every time you want to go back to it because the precess itself was killed (which is fine because my onPause saves persistent data, but it's not an elegant solution).
Please help.
Have you considered switching to onStart() and onStop(), rather than onResume() and onPause()?
I was having the same problem (I had my music player resume/pause at onResume()/onPause()) and the best solution I found is to pause and resume my activity when it is on the foreground which you can get with public void onWindowFocusChanged (boolean hasFocus) callback.
Edit: This in an old and slightly incorrect answer - correct response is described in the Android Developers Blog: making android games that play nice