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.
Related
When I change the screen size in the multiview / split screen mode, the onCreate function in MainActivity is called again.
Because in onCreate I have a ProcessLifecycleOwner observer:
ProcessLifecycleOwner.get().GetLifecycle().AddObserver(this);
I don't want it to be restarted ... How do I know that onCreate has been called before?
I know you can add:
android:configChanges="screenSize"
in the manifest, but unfortunately needs to "refresh the layout" when resizing.
Android is going to manage the life cycle, and the programmer needs to deal with all eventualities. On this page, there's an abbreviated diagram:
That would indicate that you would need to manage the observer in the onStop().
I have an Activity which can open 2 different Fragments by 2 different Buttons. By the default that Activity when it creates, it is opening a Fragment, we call it "The Main Fragment".
The first Fragment to which we are going over by the first Button we meet zero problems with the Rotation, but the second one after the rotation disappears and the screen shows the Main Fragment's content. When I tried to rotate the screen back, I see the Main Fragment's content again. But why it is so, if I didn't write any code, which must return me to the Main Fragment without clicking a button.
What assumptions do you have?
Why this is happening ?
Default Behavior, Actiivty is getting recreated on orientation change so your fragment are.
Explanation
You need to understand Activity Life Cycle to understand why this is happening.
First, “rotating the screen” is not the actual scenario we are talking about today. Because any configuration change will cause Android to restart your Activity. A configuration change might be the device rotating (because now we have a different screen layout to draw upon), or it could be a language switch (because we need to re-write all those strings, which may need more room now OR it could be the scary RTL switch!), or even keyboard availability.
By reloading your app, what the system is actually doing is calling onDestroy() and then immediately calling onCreate(). This way, your Activity is as fresh as possible, with all of the right creation data (even though the user has been with you the entire time).
Now you have following option -
Either Fix Orientation for your app from AndroidManifest.xml
But oviously that is not a very good experience for user.
Save activityState with onSaveInstanceState()
This method will be called before onDestroy(). And, when your Activity is created, there’s a matching step onRestoreInstanceState(), which will also be called automatically. All of these automatic steps mean that you can let the system worry about saving and loading your data, because you planned ahead and mapped out what was important. (Or, you can skip onRestoreInstanceState() and load your saved state from the Bundle that comes with onCreate().
In you integrate Fragment in activity, because activity is getting destroy() so your fragment will also destroy() and will be recreated.
Please take a good read on Handling Configuration Change and this.
Once you understood the concepts things will start falling into your but it will only happen if you will complete your learning curve.
Happy Coding !
That is because onCreate is being called every time the screen is rotated. Probably you are displaying The Main Fragment from your onCreate method. You will face the same issue if you put your fragment display logic in onResume because just after onCreate, onResume is called.
Solution: store the fragment on top in shared preferences that way you know what to display every time onCreate is being called.
I've spent a few hours looking for this. My test device is a nexus 6, though it has been tried on android 4.4 and 5.0+ as well.
Basically I want to catch a user's click of the onBackPress, but I want to do this outside of the activity. Say I've got an object that is initialized and while its running, It is to handle onBackPress, until the its killed.
I've looked into setting an onKeyListener to the contentView but that does not work at all (I figured as much, but its worth a shot).
Any idea how to do this (again, outside the scope of overriding in the activity)?
I cannot imagine something like that being possible since it would be a rather large security risk if a regular application could just catch user input outside of its scope.
The only hardware button I know of that you can detect being pressed even when your activity is not running in the foreground is the camera button, since pressing that generates an Intent. http://developer.android.com/reference/android/content/Intent.html#ACTION_CAMERA_BUTTON
I have an app that has a few screens.
The Main screen automatically opens a "new" screen if it's the first time the user opens the app.
I then set a boolean variable (on the Main screen) keeping track of this.
The intention is if the user goes back to the Main screen, the code that opens the "new" screen can be skipped.
The problem is that the variable keeps getting reset on OnCreate.
So, I added some code to use SharedPreferences.
This works; however, I want to clear the variable when the app exits.
(I want the "new" screen to open every time the app opens the first time).
So, looking at the lifecycle I tried both onStop and onDestory.
The SharedPreferences are cleared but... not when the app is exited; but when the "new" screen appears.
Am I looking at the lifecycle wrong?
Is there some sort of global variable I can declare that only lives while the app is open?
This functionality is the requirement, so I cannot change it.
You should use onSaveInstanceState and onRestoreInstanceState, they will keep the boolean alive if your activity calls onCreate but not if you exit and come back later.
See this answer for implementation:
Saving Android Activity state using Save Instance State
You can define the variable in the line one of ur whole code, that way it will only reset when the app is opened again.
When my program start I would like to do some settings before is really starting. Forexample choose the user, check the updates and so on. After these settings I would like to start the main program with the appropriate.
Which is the best way to do this?
You can run an AyncTask, or multiple if you need one for each check, in your onCreate() and show a ProgressDialog while the data is being fetched then cancel it in onPostExecute() and move on to the rest of the MainActivity depending on the data that is downloaded. If you need help getting started with AsyncTask you can see this SO answer on the basic structure.
If you use a ProgressDialog then the app will still start but the users will see something and know that data is loading so they won't feel like it is freezing or taking too long to load (or at least they will know why it isn't loaded right away).
AsyncTask Docs
Edit after comment
For what you said you want in your comment you can do this easily with an Activity that has a Dialog Theme. This will give you the functionality you need (a couple Buttons and store the values) but it will look like a little popup. You can't use an actual Dialog as they need an Activity, the same with any menus, AFAIK. Just create your Activity and make it the launcher and main using the Intent-filters then also add the following line to that Activity's tag in the manifest
android:theme="#android:style/Theme.Dialog"
This approach should give you what you need
There are numerous ways to do that.
First - your app is doing some heavy stuff and this may be freezing user interface. In that version do:
1. Create and activity on what you will override onCreate method and set some content with a spinner - so something will be alive and user will see that something is being done.
2. after you will compute all the things that your app need and may I suggest write it to some global variables override onStart method in what change layout to what suit you and give a user a great UI!
Second - you app is not heavy lifting here just throw everything into override of onStart method.
Handy material here for educating: