activity orientation change bug - java

I'm experiencing a weird bug that I haven't seen in an Android application before. When navigating from an activity locked in portrait mode to an activity locked in landscape mode and back, the activity that's supposed to be in portrait appears in portrait mode, goes to landscape and then back to portrait.
This happens while the device is flat on the table with no actual orientation changes. I'm using two separate activities, and that's the only code that I have in the project.
Here is a video of the bug, and here's a link to the exact project that reproduces this bug. It happens on more than one device so it's not isolated to my device.
Questions:
Do you know what could be causing this?
Is there anything that you can recommend for fixing this?
Things I've tried:
Setting the orientation programatically
Googling and not finding anything
Update 1
More things I've tried:
Setting the portrait activity to "nosensor" and the landscape one to "landscape"
Setting the portrait activity to "nosensor" and programatically setting the landscape activity in onCreate
Update 2
I've been working with the project linked above and just did some overrides to log out everything that's happening. I found that when the onConfigurationChanged is called it does the little shimmy between the landscape and the portrait orientations. The output for a back navigation that doesn't do the shimmy is:
D/class com.mdk_studio.orientationbugtests.MainActivity: onStateNotSaved
D/class com.mdk_studio.orientationbugtests.MainActivity: onRestart
D/class com.mdk_studio.orientationbugtests.MainActivity: onWindowFocusChanged
The output for the shimmy bug is:
D/class com.mdk_studio.orientationbugtests.MainActivity: onStateNotSaved
D/class com.mdk_studio.orientationbugtests.MainActivity: onRestart
D/class com.mdk_studio.orientationbugtests.MainActivity: onWindowFocusChanged
D/class com.mdk_studio.orientationbugtests.MainActivity: onConfigurationChanged
D/class com.mdk_studio.orientationbugtests.MainActivity: onConfigurationChanged
I guess the question now becomes, how do I make sure the orientation change does not get called?

After testing out all the different combinations of manifest level orientation setting and programmatic orientation setting. I have figured out that for the orientation to not be wrong in the onConfigurationChanged function you have to set the orientation before the navigation is actually started.
The combination that worked for me and took the behaviour away completely was to set the activity in the manifest that I want in portrait to "nosensor". Then set the activity that I want in landscape to landscape using
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
and set the orientation back to portrait in the onBackPressed before the navigation occures. That part is important, once the navigation has been triggered and then you set the orientation, in some cases when the newConfiguration comes through in the onConfigurationChanged call it has the wrong orientation, and then it somehow issues another call to it to correct it after it's been updated on the first call.
tl;dr
Set the orientation for the activity you want in portrait to "nosensor". Programatically set the orientation to landscape in onCreate. Set the orientation back to portrait in onBackPressed, before the super call.

Related

can we change status bar or notification bar position programmatically

I had locked my app to portrait only mode and I handled orientation changes myself, but I realized that in landscape mode the status bar stays the same, and the UI experience would be bad.
Now, that I have developed everything accordingly, the only workaround seems to be for me is to change the status bar position programmatically, since I don't(or actually can't at this point) respect system orientation changes.
Is this possible? To change the status bar position programmatically? Only inside my app and restore once I exit?
Below I have illustrated the desired effect:
first, the app is locked to portrait mode and when I rotate the device the app's views rotate since I parse the raw sensor data and apply the rotation, but in this case the status bar doesn't rotate(since the app is locked to portrait mode, and I only have access to app's views for rotation):
A pseudocode of how I've done the above is:
View views[] = new View[]{view1, view2, view3, view4 ....};
float rotationAngle = parseRawSensorData();//typically accelerometer input
for(View view: views){
rotateWithAngle(rotationAngle);
}
Therefore the views rotate but the status bar is affixed.
what I'd like to do is to be able to rotate the status bar using some code like this:
i.e. rotate the statusbar according to the sensordata I fetch.
The statusbar is part of the Android system, not part of your application. So there is no way you could control that from your application.
Instead of rotating a status bar, you can just hide it when using your app.
Import:
import android.view.WindowManager
And write this:
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)

Changing orientation of the device refreshes the fragments activities

I realized a problem in my app, I use BottomNavigation with FragmentActivities, the problem was that when clicking one of the 5 FragmentActivities. 5 activities are [Home, Search, Post, Notifications & Profile] if I click any of them being in portrait state and change the device orientation to landscape the activities refreshes and start to [Home] screen always.
How do I fix this?
maybe you can try add configuration in your main_activity in manifest
<activity
android:name=".your.main_activity"
android:configChanges="keyboardHidden|orientation|screenSize"/>

Android - FlipView reset by itself

I'm pretty new in Android development, so i'm not sure what is happening.
I have made an app with a fixed part outside and a part inside that switch a FlipView during onCreate event and onNavigationItemSelected. All work fine, exept when i flip my phone to landscape and back, the flipview automaticaly return on it's original page.
Your Activity recreated, when you turn device. Read THIS to solve this problem. You need to implement onSaveInstanceState function.

On change screen orientation, new activity created

I'm relatively new to Android but have made quite a few apps over the past year so forgive me.
I know that when you are running an app on a device and change the screen orientation by turning the device the activity that is showing is completely recreated. I go to the youtube app (I am using Nexus 7 w/ Android 4.2.2) and play some video and then flip the screen to change orientation. The video keeps playing and everything is re-sized accordingly... How is this possible if the activity is completely recreated?
Thank you.
In your AndroidManifest.xml add, android:configChanges and this would avoid the activity being re-created on orientation change. I hope your landscape and portrait mode has the same layout.
<activity android:label="Your Activity Name"
android:configChanges="keyboardHidden|orientation|screenSize"
android:name="com.yourpackage">
To add more to this, i would suggest you to look at the onPause() and onResume() methods and if you are playing with Fragments then have a watch on onSaveInstanceState and onRetainInstanceState rather than applying the xml changes as "Activity is destroyed by design."
http://developer.android.com/training/basics/activity-lifecycle/index.html
If you are worried about losing the value of local variables within your activity... You could use Singleton Pattern for some of those variables. This not a beautiful solution, but could work.

Why is it that when I swap to landscape, my changes to the User Interface are undone?

I have another question!
I have a configure Activity in my app. On it, I have a ListView. Now adding & removing items to & from it works, but when I rotate the screen to landscape or back, all added & non-saved items in the ListView get removed... I wonder why this is... Why is this?
When screen orientation changes, by default, the activity will be destroyed and create again. That means, the onCreate will be called again once the orientation changed. There are basically two way to solve your problem:
Save your activity state before destory and load it back when create
Set the Activity in AndroidManifest that not to handle screen orientation change.
E.g.
<activity name="..."
android:configChanges="orientation" .../>
When you rotate the handset, the onStart method of you Activity is invoked. Check maybe you do some sort of initialization there.
I've solved it partially. Now it is able to hold on to the changes when changing to landscape view, but not the other way back to the normal view. I did it through the use of protected void onSaveInstanceState(Bundle saveState). But as I said, this doesn't work when it changes back from Landscape... Anybody got any ideas about this?

Categories