Android: Odd behaviour when screen is turned off? - java

I'm working on a game and use a WakeLock to keep the screen from going to sleep while the user is playing. However, I'm encountering some weird behavior when the screen is manually put to sleep..
My current approach is to store away the game info in OnPause() and load them back up when OnCreate() is called. This works fine if I hit the home button and start my app back up. However, turning the screen off seems to call OnPause() a couple times..in addition to some other funky behavior. Can anyone offer an explanation of why turning the screen off is different than hitting home?
According to Logcat, here's the sequence of events.
When Screen is turned off-OnPause is called; OnCreate is called; OnResume is called; OnPause is called again
When screen is turned back on- OnResume is called (before phone is even unlocked)

Related

Android: Killing background activities

I have an application that contains many game screens, each is its own activity. Some of these game screens will use timers to initiate some functionality. The problem I am having is when the user backs out of one of these game screens, the timers are still running in the background. I know this because when I leave to the main menu the timer loads up the losing screen because the timer and activity were still running in the background process. I simply want to kill the activity if the user hits the phone back button (Not a button I have created but the devices back button).
This is the current method I use to try and accomplish this:
#Override
public void onBackPressed() {
super.onBackPressed();
this.finish();
}
It does not kill the activity.
EDIT:
I Should mention that stopping the timers does work but for some of my screens the win or lose conditions are done when a variable hits a certain number. For example, I have one screen that when an enemy escapes the view of the player a variable goes up by 1 when this hits 5 the player loses. This is not done on a timer, so because the activity is still running, the variable hits 5 and the losing screen is loaded when I am not on that game screen anymore.
Only the visible Activity will receive that finish() command. You need to start and stop your timers onResume and onPause
First of all, remove
super.onBackPressed();
And add
yourActivity.this.finish();
Let me know if that helps :)

What is the proper method of implementing onPause, onResume, surfaceCreated and surfaceDestroyed when developing a custom camera on Android?

I'm currently developing a custom camera application which takes a video using MediaRecorder for 5 seconds. I have implemented a number countdown overlay which counts down from 5.
My problem is that I am not 100% sure how to implement surface methods and pause/resume methods. If I close my app half way through recording and then open it again, the app freezes, shows a black screen, and eventually crashes.
Should onPause and surfaceDestroyed be used in unison? (Same question applies to onResume and surfaceCreated) How does surfaceChanged fit into this?
I'm guessing I need to find a way to restart my CameraActivity every time it resumes. (As I don't want it resuming half way through a countdown).
You should look at Activity lifecycle onPause and onResume for creating and destroying camera.
http://developer.android.com/training/basics/activity-lifecycle/pausing.html#Pause

android-how to prevent screen from turning on in this case? [duplicate]

I have an activity that shows up when the phone screen goes to sleep/turns off ie turns black.
For some reason, the phone turns on when the volume buttons or the camera buttons are pressed. By turns on, I mean the screen wakes up or comes back from the black screen state.
I've tried using dispatchKeyEvent(KeyEvent event) and the buttons are disabled on the activity, but they still wake up the phone.
You could try overriding the onKeyDown(KeyEvent) method and change what happens for those keys. However, I'm not too optimistic as if you're running an activity, it will be in an inactive state when the display is off, and also it could be that the phone is hard wired to wake up on those buttons. It could be device specific. Hard to say. Try that out and let me know how it goes, I'm currious

Activity can't be resumed

Over the past months I have been developing a versatile real-time game engine, and I have learned a lot, but I still feel very naive when it comes to the application life cycle. Specifically, I am trying to implement an Activity which can be shuffled in to the background by the user, then properly resumed.
My current architecture is as such: I have a an XML menu launcher activity which can create a real-time Game activity using intent. Relevant data in this Game activity is referenced through static data structures and variables. The Game activity creates worker threads in the onSurfaceCreate() callback of my SurfaceView object.
When a user presses the back button, the activity is destroyed, and they are sent back to the XML menu in the launcher activity. Fine, good for now. When the user presses the home button, the Activity is sent to the background. OK, great. My problems arise when the user tries to find their way back in the Game activity once is has been sent to the background. When the user touches the launcher icon, the Game is destroyed and the menu is re-launched. Also, when the user resumes the game through the task manager, the onSurfaceCreate() callback fires and the worker threads are started, but the game is frozen.
So, I have two questions. First, how do I resume my activity through the launcher icon, instead of re-launching the game? Second, when I resume my activity, what actions are necessary to restart my worker threads while persisting the game data?
Thanks!
EDIT: By request, I am including some code below. My onSurfaceCreate is a little bit complicated, it sends a message to another thread, which then implements the callback. I have verified that this implementation function fires when the Game activity is resumed.
protected void surfaceCreate()
{
Log.e(TAG, "surfaceCreate");
Thread gameThread = createGameThread();
gameThread.start();
}
protected final void onResume()
{
super.onResume();
resume();
}
protected final void onPause()
{
super.onPause();
pause();
}
These cryptic pause() and resume() methods simply set a boolean variable which prevents some game logic from being executed, they do nothing to hinder the worker threads, which should continue looping.
EDIT: Thanks Mohammad, for solving my first (although smaller) problem. It turns out that the launcher icon behaves differently when not connected by USB to the IDE. The second problem remains unresolved.
EDIT: All working! The second problem turned out to be an issue unique to my code, I apologize for that. I hope that this question can still be useful for those dealing with the launcher and IDEs.
There are multiple possible problems/solutions listed in this post. This includes misunderstanding of activity lifecycle and launchMode settings.
First, how do I resume my activity through the launcher icon, instead
of re-launching the game?
You are most likely missing definition for your onResume() and onPause() methods. Examples are here:
http://developer.android.com/training/basics/activity-lifecycle/pausing.html
Straight from the API:
onPause() Called as part of the activity lifecycle when an
activity is going into the background, but has not (yet) been killed.
onResume() Called after onRestoreInstanceState(Bundle),
onRestart(), or onPause(), for your activity to start interacting with
the user.
Check the Android Activity Lifecycle out:
http://developer.android.com/reference/android/app/Activity.html
One theory on your issue may be is that you're most likely going to onStop() (by hitting the home button) and the Android OS is looking for your onRestart(), but can't find it hence freezing/restarting.
Second, when I resume my activity, what actions are necessary to
restart my worker threads while persisting the game data?
Careful how you use the word restart. You want to pause and resume the application (not restart). Save data in onPause() (use a database or any other save feature you'd like). Load data in onResume(). Although, the activity should resume as normal if you just fill up these methods.
Now, if you want to save state for when you restart the application, you should save states in onStop() and/or onDestroy(). You should load states in onStart(). In order to save states, you can check this out:
https://stackoverflow.com/a/151940/2498729
For those using Eclipse (or any other IDE to run/test your application):
From what have you described you probably have overridden
android:launchMode in AndroidManifest.xml or if you are testing by
"run as" from Eclipse try exiting the application after installing and
auto-starting. Then start again from the emulator and test the Home
button behavior. I suppose this is because Android does not put
Activities on the OS stack when started from Eclipse and then the Home
button behavior is not as usual. If this does not solve your problem,
try reading
http://developer.android.com/guide/topics/fundamentals.html#lmodes.
I had launchMode set in my StartupActivity. THen I removed that (it
was set to "singleTask", it behaves like I want it; the app is
"resumed" to the Activity I expect, ie not StartupActivity but
MainActivity.
Source:
https://stackoverflow.com/a/1619461/2498729
http://developer.android.com/guide/topics/manifest/activity-element.html
According to this:
https://stackoverflow.com/a/3002890/2498729
You should change your andoird:launchMode to "Standard" (or "default").
Standard: A > B > HOME > B (what you want)
SingleTask: A > B > HOME > A (what you don't want)

Preventing tilt from calling onCreate, and time measurement of an activity running.

Hi and thanks in advance for your time and attention.
I actually have 2 questions i'm not too sure about building an android app. Pretty basic stuff I believe:
1) My app is fully on Horizontal mode, like AngryBirds for example. When it starts the user figures out he should hold the phone like that, if he isn't already. And that is setup in the manifest for all the activities and works fine. but is there a way to prevent the physical device tilting to call onCreate again? can i override it's method or whatever? the reason i'm asking, is because i have a few ButtonViews that after you click on them, change their picture. i am using onRetainNonConfigurationInstance() to save the array of those ImageButtons, and i even mark the ones changed with the ImageButton setTag() and getTag() methods, so when onCreate is called because of the device tilt it gets the saved array from getLastNonConfigurationInstance() , but i've been trying to make it work for quite some time now and I just can't get it right. After the device tilt (I'm actually using the emulator so it's Ctrl+F11 but i believe it will happen with a device as well) all of the ImageButtons loose their pictures.. Long story short - are there better ways of doing this that you can recommend or is preventing the tilt from doing anything is possible or better?
2) What is the best way to know how many seconds the user has been on a screen? I tried to use two longs that i get via SystemClock.currentThreadTimeMillis() as follows: get the starting time onCreate, and the ending time on the method i call to move to the second intent just before i startActivity. but I think because they are called from different threads, the endingpoint - startingpoint is not correct. What is the way to insure both of the methods of SystemClock.currentThreadTimeMillis() are called from the same thread, the main thread of the activity that i'm stopwatching? Is there a better way to go around this?
Thanks again.
You are doing the right to handle orientation change. Please refer to this link http://developer.android.com/guide/topics/resources/runtime-changes.html . This will help you to get it working.
Good way would be to count the time between onResume and onPause. OnCreate is not called all the time if you are resuming activity.
1) You can try adding the property android:configChanges="orientation" to your activity in the manifest file. It worked for me when my dynamic Action Bar tabs got messed up upon rotation of the screen.
You need specify orientation in android manifest for each of your activities, it will not call onCreate then. android:screenOrientation look at http://developer.android.com/guide/topics/manifest/activity-element.html
User see and interact with your activity starting since onResume and ends on onPause. Other time it does not guarantee that user actually see and can click on something in the activity. System.getCurrentMillis() is good enough.

Categories

Resources