Проблема с ориентацией экрана Android 8.1: переключение на альбомный портрет

У меня есть все действия в портретном режиме, кроме той, которую я использую для воспроизведения видео, которое всегда в альбомной ориентации. Я обнаружил, что в Android 8.1 каждый раз, когда я открываю видеоактив и закрываю его, предыдущее действие переходит в альбомную ориентацию, даже если в манифесте установлено "портрет".

  1. Иногда идет в портрет, затем в пейзаж и остается на ландшафте.
  2. Иногда переходит в портрет, затем в пейзаж и, наконец, снова в портрет.

Это происходит только тогда, когда вы возвращаетесь из вида деятельности, к которому он относится.

Есть кто-нибудь, кто испытывает это?

Благодарю.

РЕДАКТИРОВАТЬ

Я сообщаю об ошибке в Google: https://issuetracker.google.com/issues/69168442

РЕДАКТИРОВАТЬ 2

Кажется исправлено на Android 9

Ответы

Ответ 1

Просто наткнулся на эту проблему в моем собственном приложении.

Решение, которое работает для меня, выглядит следующим образом:

onCreate(){
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}

onPause(){ 
  if (android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
  }
}

onResume(){
  if (android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
  }
}

Вышеприведенный код должен находиться в режиме, который находится в ландшафтном режиме (т.е. Втором действии, и том, на который вы нажимаете кнопку "Назад")

Я хотел бы отметить, что это решение не было моим собственным, и я взял его из сообщения № 20 по следующей ссылке (что также отмечено в OP):

https://issuetracker.google.com/issues/69168442

Я просто подумал, что людям может быть проще получить доступ, если им не нужно искать другую страницу.

Ответ 2

Это устранило проблему.

Переопределите метод onBackPressed() для ландшафтной активности и настройте ориентацию на портрет.

@Override
public void onBackPressed() {
    super.onBackPressed();
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

Ответ 3

Использование intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK) в предыдущей работе разрешило мою проблему.

Ответ 4

Если у вас есть DialogTheme, например theme = Theme.AppCompat.Light.Dialog в манифесте, удалите установочный тег ориентации для этой операции Dialog из манифеста, он примет ориентацию от предыдущей активности и поместит тег setorientation для повторной активации

и ниже Версии помещают это в oncreate

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

и задать тему для приложения Theme.AppCompat.Light.DarkActionBar не нужно добавлять тему в действия

Ответ 5

в методе onCreate каждого вида деятельности вставьте эту строку

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

для пейзажа и

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

для портретных

Ответ 6

У меня была такая проблема, и я пытался использовать все вышеприведенные варианты использования. Большинство из них работают, но есть один случай, который вы должны знать:

Последняя причина заключалась в использовании фрагментов внутри макета контента активности в случае Android 8. Например: Действие запускается в альбомном режиме, но фрагмент показывает макет Portrait.

Старайтесь избегать фрагментов.

Ответ 7

Чтобы устранить эту проблему:

Когда вы вернетесь в Activity A из Activity B, и если вы знаете ориентацию экрана Activity A, установите ориентацию экрана в ondestroy Activity B.

@Override
protected void onDestroy() {
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    super.onDestroy();
}

Ответ 8

Я добавил все комментарии выше, и никто не помогает мне http://prntscr.com/m9zbw3

Ответ 9

Следующий обходной путь может помочь вам решить проблему.

Вы должны расширить все свои действия, используя тот, который в коде. Он заботится об установке и восстановлении правильных ориентаций при каждом вызове методов onPause/onResume.

Обходной путь будет работать для любого типа ориентации, определенного в тегах активности манифеста.

Для своих собственных целей я расширяю этот класс от ComponentActivity, так что вы можете изменить его на расширение Activity, ActivityCompat или любого другого вида деятельности, который вы используете в своем коде.

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);
        }
    }
}

Ответ 10

Если вам нужно поддерживать изменения ориентации родительской активности, рассмотрите возможность использования текущей ориентации в onPause() вашей ландшафтной активности.

onCreate(){
   super.onCreate();
   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
}

onPause(){ 
  super.onPause();
  if (android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(getResources().getConfiguration().orientation);
  }
}

onResume(){
  super.onResume();
  if (android.os.Build.VERSION.SDK_INT >= 27) {
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
  }
}

Этот ответ основан на ответе TheTestSpecimen.