Android 8.1 screen orientation issue: flipping to

2020-01-29 03:43发布

I have all activities in portrait mode except the one that I use to play a video that is always landscape. I found that on Android 8.1 every time I open the video activity and close it the previous activity go to landscape even it's set to "portrait" on the manifest.

  1. Sometimes goes to portrait then to landscape and stay on landscape.
  2. Sometimes goes to portrait then to landscape and finally portrait again.

This is only happening when a go back from a activity that it's landscape.

There is anyone who is experiencing this?

Thanks.

EDIT

I report the bug on Google: https://issuetracker.google.com/issues/69168442

EDIT 2

It seems fixed on Android 9

10条回答
来,给爷笑一个
2楼-- · 2020-01-29 04:22

I had such problem and been trying all of above use cases. Most of them work, but there is one case you should know:

The final reason was the using of fragments inside an activity content layout in case of Android 8. For example: The activity launches in Landscape mode, but the fragment shows you the Portrait layout.

Try to avoid fragments.

查看更多
家丑人穷心不美
3楼-- · 2020-01-29 04:26

To fix this issue:

When you will back to Activity A from Activity B and if you know the screen's orientation of the Activity A, so set the screen orientation into the ondestroy of Activity B.

@Override
protected void onDestroy() {
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    super.onDestroy();
}
查看更多
做个烂人
4楼-- · 2020-01-29 04:27

The next workaround may help you to solve the issue.

You must extend all your activities using the one in the code. It takes care of setting and restoring the correct orientations whenever the onPause / onResume methods are called.

The workaround will work for any type of orientation defined in the manifest activity tags.

For my own purposes I extend this class from ComponentActivity, so you may want to change this to extend from Activity, ActivityCompat, or whatever type of activity you are using in your code.

public abstract class AbsBaseActivity extends ComponentActivity
{
    private int currentActivityOrientation   = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    private int parentActivityOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;

    @CallSuper
    @Override
    protected void onCreate(@Nullable final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        this.cacheOrientations();
    }

    private void cacheOrientations()
    {
        if (this.currentActivityOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
        {
            final Intent parentIntent = this.getParentActivityIntent();

            if (parentIntent != null)
            {
                final ComponentName parentComponentName = parentIntent.getComponent();

                if (parentComponentName != null)
                {
                    this.currentActivityOrientation = this.getConfiguredOrientation(this.getComponentName());
                    this.parentActivityOrientation = this.getConfiguredOrientation(parentComponentName);
                }
            }
        }
    }

    private int getConfiguredOrientation(@NonNull final ComponentName source)
    {
        try
        {
            final PackageManager packageManager = this.getPackageManager();
            final ActivityInfo   activityInfo   = packageManager.getActivityInfo(source, 0);
            return activityInfo.screenOrientation;
        }
        catch (PackageManager.NameNotFoundException e)
        {
            e.printStackTrace();
        }

        return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
    }

    @CallSuper
    @Override
    protected void onPause()
    {
        if (this.parentActivityOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
        {
            this.setRequestedOrientation(this.parentActivityOrientation);
        }

        super.onPause();
    }

    @CallSuper
    @Override
    protected void onResume()
    {
        super.onResume();

        if (this.currentActivityOrientation != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
        {
            this.setRequestedOrientation(this.currentActivityOrientation);
        }
    }
}
查看更多
等我变得足够好
5楼-- · 2020-01-29 04:37

Using intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK) in previous Activity resolved my issue.

查看更多
何必那么认真
6楼-- · 2020-01-29 04:37

from Narmi's answer:

When you will back to Activity A from Activity B and if you know the screen's orientation of the Activity A, so set the screen orientation into the ondestroy of Activity B.

you have to detect if activity is destroying from configuration change, so add field isConfigurationChanged = false, then on onSaveInstanceState method turn it to true and on onDestroy method add this:

@Override
protected void onDestroy() {
    if(!isConfigurationChanged)
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    super.onDestroy();
}
查看更多
爷、活的狠高调
7楼-- · 2020-01-29 04:42

If u have DialogTheme like theme=Theme.AppCompat.Light.Dialog in your manifesto, remove the set orientation tag for that Dialog activity from manifesto , It will take the Orientation from the previous activity and put setorientation tag for remaing activites

and for below Versions place this on oncreate

if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  }

and set theme for application Theme.AppCompat.Light.DarkActionBar no need to add theme to activities

查看更多
登录 后发表回答