This is probably a beginner question, but I've already tried looking for an answer and couldn't find one. I was testing an Android app I made on my phone and it was working fine until I switched from portrait to landscape, just to see what would happen. It pretty much made the app go back to the home page, so I'm guessing it calls onCreate() every time the orientation changes. Is it possible to prevent an orientation change from restarting everything, and just have it switch all the views to fit landscape or portrait mode?
This question has been answered thousand times, but ...
You should add in you Manifest.xml for your activity android:configChange="orientation"
and then override onConfigurationChanged(newConfig) method and do not add anything inside, since you are telling you app to do nothing when config changes occur.
Whenever the orientation changes onCreate() method gets called again and again.
Inorder to prevent that add android:configChanges="orientation|keyboardHidden|screenSize"
to the Manifest file, and then override onConfigurationChanged() method.
Related
I'm playing around with SDL2 on Android and I have a problem when setting the orientation to stay in landscape.
I have the following lines in my AndroidManifest.xml:
android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation"
Without the orientation|screenSize and landscape line, everything is fine. When these lines are added and I tap the back button (to close that app), I get the following log line printed over and over:
E libEGL : eglSwapBuffersWithDamageKHR:1089 error 300d (EGL_BAD_SURFACE)
I am only using SDL functions for rendering with no OpenGL code.
Any ideas why setting the orientation in the manifest would cause this? Is this not the correct way to lock orientation?
Update:
Setting the orientation in the onCreate method is good workaround and seems to do the job. Here's the line of code for that:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
It would still be good to know why setting the orientation in the manifest breaks everything. Setting it to portrait is fine, it's just setting it to landscape that gives the issue.
Update 2:
Setting the orientation in the onCreate method is mostly fine. Closing the app doesn't cause problems, switching to the home screen is fine and so is switching to another application. I found the app would open back up again with no problems. I did find that the app would crash when the screen turns off. Again, this issue only occurs when the app is locked in landscape mode, in portrait it works fine. In the logging I noticed that the onDestroy method is being called when the power button is press in landscape mode, but it's not being called in portrait. When turning the screen on again to resume, the onCreate method isn't even called. It just stops.
I may end up locking the screen in portrait and just rendering everything sideways.
I found the answer.
The errors I was getting when closing the app no longer occur in the latest development version of the SDL2 (as suggested by Treble on the SDL forums). That can be found here.
The problem with the app crashing when resuming from the screen being off was due to the onDestroy method being called. When the screen goes off, Android calls the activity's onDestroy method, the orientation is set to portrait, the activity is re-initialised, and then the screen goes off.
The fact that this crashes my app probably means that I'm not destroying everything correctly (which I will be looking in to).
I found this post which details a good way to get around this issue. All you need to do is make sure you have these lines in your manifest:
android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation|screenSize"
... and this in the activity:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
This means that change in configuration (like orientation) is not handled by destroying and recreating the activity.
Adding this, along with updating to the latest dev build of SDL2 seems to have fixed my problems.
I got an app that is locked in landscape orientation. Now, when I change the devices settings to set its orientation locked to portrait, some problems occur.
After a bit of testing, it seems that for each Activity that is started, the onCreate is called twice.
First time for portrait orientation, second time as an orientationChange with orientation set to landscape. The first orientation is wrong, and probably has something to do with the device being locked to portrait.
In the app, the orientation is forced to landscape programmatically (using setRequestedOrientation), and I prefer to keep it that way, if possible, for various reasons.
Any ideas about how to avoid this behavior?
Thanks in advance!
Ok, I found a solution myself.
After a lot of searching and digging in the code, the solution was fairly simple.
All I had to do was add:
android:configChanges="orientation|screenSize"
... to all my Activities in the manifest file.
This tells the app that I will handle configuration changes myself in the code. Instead of doing this, I didn't add any handlers for these config changes. This way, my Activities aren't recreated when the orientation change happens at the creation of those Activities. I can do it this way, because my app is locked in a certain orientation.
This post came closest to my problem, but it's solution didn't work for me:
Android: set activity orientation BEFORE onCreate, but not in manifest (HDMI plugged in issue)
This post gave me the answer:
http://www.acnenomor.com/1053172p1/oncreate-were-called-twice-after-implementing-setrequestedorientation
Try setting up the orientation directly in the manifest instead of programmatically. Under your activity tag in AndroidManifest.xml add android:screenOrientation="landscape".
This should force the activity to be directly created in the correct orientation.
I have stumbled on a problem, that, when the screen turns off while being in LANDSCAPE orientation, certain devices "rotate" the app back to PORTRAIT position (because the lockscreen is PORTRAIT only or something like that). I did a little research before posting this, and most popular work-around is to modify app's configuration change process to prevent activity being recreated after the configuration has changed.
But disabling activity recreation is not a solution for me, because my app supports both orientations with sepparate layout's etc.
So i would like to find out, is it possible to disable the configuration change only in special cases (Screen turned off and orientation is landscape)? Or is the right way to override onConfigurationChanged() then manually manage activity recreation inside that function (i guess simply setting different layout resources when orientation is changed simply wont cut it)?
Or is the right way to override onConfigurationChanged() then manually manage activity recreation inside that function?
Yes to an extent.
You cannot set the configChanges attribute programmatically. I guess it's to do with the way an Activity is created. They're created from the XML first and then the overridden methods in your activity implementation are invoked. There's nothing in the API that lets you change the configChanges attribute.
Now in your case it doesn't sound like you need to. If you support both orientations, then if the user locks the device and it rotates back why does it matter? From a UX perspective we know it's in portrait mode again. So should your app when it opens back up.
I am developing an android application I am facing below two problems,
data lose : login screen when I change the landscape to portrait mode the entered text will be lost.
force close: Inside the application when I captured the image form camera then I change the portrait to landscape mode some time getting force close and image not showing in ImageView.
How to solve this problem? I should not lock the application in portrait mode and I have no idea to solve this please suggest me any useful links and sample code it might be useful for me.
add below property in your mainifest file inside the activity.you can change as per your requirement
android:configChanges="orientation|screenSize|keyboard|screenLayout"
In order to prevent data loss, add configChanges to the manifest, and to it set the values: screenOrientation, screenSize, layoutDirections.
and if that too does not work,
override the onConfigurationChanged method, and handle what you have to do with the data in that method.
1)
android:configChanges="orientation|screenSize|keyboard|screenLayout"
add this to you AndroidManifest.xml file for which makes sure onCreate() is not called again when orientation change happens, but only the ui rendered will change maintaining the user entered data on UI.
<activity
android:name="LoginActivity"
android:configChanges="orientation|screenSize"
android:label="#string/app_name"
android:logo="#drawable/menu_button"
android:windowSoftInputMode="adjustPan|stateHidden" >
2)
need more info, however this might be case of when orientation gets changed ui views will be recreated hence will be null for some very small fraction of time and your code might be trying to access the same view in this time.
I feel 1) and 2) are related, solve 1) using above and try to reproduce 2) again.
I want to make my application displayed only in portrait orientation, so I have put android:screenOrientation="portrait" in the Activity tag in AndroidManifest.xml, and have put setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); in the Activity's onCreate method.
This works to lock the orientation to portrait, however, when the Activity starts, it shows itself once, then shows itself again, so you see a sort of flash. I can confirm that onCreate is being called twice as well.
This flash is causing further force closes later in my application.
How can I eliminate this flash?
Edit
I had a splash screen displaying before the activity I had described. It was being run twice, and therefore ran this activity twice (via an Intent) twice. I fixed this issue by checking if this activity had already been stared using an intent in the splash screen class, and it had, not to run it again. The fix was more of a workaround than a fix, but I hope it helps people.
I believe that using the Activity's configChanges attribute (in the manifest) should solve your problem. ConfigChanges attribute documentation
However, you are just going around another problem. What you really should address is why is that provoking FC? There is absolutely no reason for that to happen so you also should solve that problem. More info in handling runtime changes.
Please note: using the first approach is acceptable to address the performance/UX issues though.
Just in case you wonder why onCreate is called twice, once I got into this problem and I think that it was related to having the orientation fixed and then having another activity being created but in a different orientation. Before the second activity was started, the former activity changed into the orientation of the latter. And remember that keyguard is also an Activity! I'm not sure if this happens for this reason though.
don't put : "setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);".
Just let the AndroidManifest do his job. I thing what you did is :
Tell your App to go only in Portrait mode
Tell your Activity to be in Portrait mode, wherever it was already like this or not (The flash have to come from this).
I could be wrong.