Как предотвратить изменение ориентации экрана при завершении Activity на устройствах версии 8.1 Android?

Я работаю над приложением и столкнулся с необычным поведением на 8.1 Devices (Pixel2, Nexus5x), поэтому я написал небольшое приложение, чтобы проверить это поведение.

MainActivity заблокирован в режиме portrait, а LandscapeActivity заблокирован до landscape. MainActivity запускает LandscapeActivity для результата. Экран переключается с portrait на landscape, как ожидалось. Когда LandscapeActivity закончен, он передает результат на MainActivity, возвращаясь к portrait (как и ожидалось).

Но иногда я встречаю здесь какую-то ошибку. После onActivityResult в MainActivity он переключается с portrait на landscape, чтобы немедленно вернуться к portrait. Пока я могу справиться с состоянием, он все еще выглядит противно.

Для отслеживания я опубликую все, чтобы перестроить его.

Что я могу сделать, чтобы предотвратить это? Также обратите внимание, что это происходит не каждый раз, и насколько я могу тестировать только на 8.1 устройствах. Кажется, это нормально на устройствах Android ниже 8.1

EDIT: Добавлен android:configChanges="orientation|screenSize" к моему манифесту как @Floern, предложенный в его ответе без успеха. Подтверждение ошибки на платформе также будет приемлемым ответом

манифеста

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:screenOrientation="portrait"
            android:configChanges="orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".LandscapeActivity"
            android:screenOrientation="landscape"/>

    </application>

MainActivity

public class MainActivity extends AppCompatActivity {

    public static final String TAG = MainActivity.class.getSimpleName();

    private static final int REQ_CODE = 878;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate: savedInstanceState=" + savedInstanceState + ", orientation=" + orientation());
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity.this, LandscapeActivity.class);
                startActivityForResult(intent, REQ_CODE);

            }
        });
    }

    @Override
    protected void onResume() {
        Log.d(TAG, "onResume: orientation=" + orientation());
        super.onResume();
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "onPause: orientation=" + orientation());
        super.onPause();
    }

    @Override
    protected void onStart() {
        Log.d(TAG, "onStart: orientation=" + orientation());
        super.onStart();
    }

    @Override
    protected void onStop() {
        Log.d(TAG, "onStop: orientation=" + orientation());
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG, "onDestroy: orientation=" + orientation());
        super.onDestroy();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d(TAG, "onActivityResult: orientation=" + orientation());
        if (requestCode == REQ_CODE){
            Toast.makeText(this, "Result=" + data.getStringExtra(LandscapeActivity.KEY_DATA), Toast.LENGTH_LONG).show();
        }
    }

    String orientation(){
        return getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ?  "Landscape" : "Portrait";
    }
}

LandscapeActivity

public class LandscapeActivity extends AppCompatActivity{

    public static final String TAG = LandscapeActivity.class.getSimpleName();

    public static final String KEY_DATA = "DATA";
    static int COUNTER = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate: savedInstanceState=" + savedInstanceState + "orientation=" + (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ?  "Landscape" : "Portrait"));
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent data = new Intent();
                COUNTER++;
                data.putExtra(KEY_DATA, "Runned " + COUNTER + " times");
                setResult(RESULT_OK, data);
                finish();
            }
        });
    }

    @Override
    protected void onResume() {
        Log.d(TAG, "onResume: orientation=" + orientation());
        super.onResume();
    }

    @Override
    protected void onPause() {
        Log.d(TAG, "onPause: orientation=" + orientation());
        super.onPause();
    }

    @Override
    protected void onStart() {
        Log.d(TAG, "onStart: orientation=" + orientation());
        super.onStart();
    }

    @Override
    protected void onStop() {
        Log.d(TAG, "onStop: orientation=" + orientation());
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        Log.d(TAG, "onDestroy: orientation=" + orientation());
        super.onDestroy();
    }

    String orientation(){
        return getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ?  "Landscape" : "Portrait";
    }
}

build.gradle

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "android.example.com.orientationtest8_1"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

layout activity_main Файл:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="android.dermalog.com.orientationtest8_1.MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

И последний журнал из щелчка на кнопках повторяется:

01-04 15:18:06.744  D/MainActivity: onCreate: savedInstanceState=null
01-04 15:18:06.847  D/MainActivity: onStart: orientation=Portrait
01-04 15:18:06.850  D/MainActivity: onResume: orientation=Portrait
01-04 15:18:14.036  D/MainActivity: onPause: orientation=Portrait
01-04 15:18:14.108  D/LandscapeActivity: onCreate: savedInstanceState=nullorientation=Landscape
01-04 15:18:14.139  D/LandscapeActivity: onStart: orientation=Landscape
01-04 15:18:14.141  D/LandscapeActivity: onResume: orientation=Landscape
01-04 15:18:14.217  D/MainActivity: onStop: orientation=Portrait
01-04 15:18:15.643  D/LandscapeActivity: onPause: orientation=Landscape
01-04 15:18:15.711  D/MainActivity: onActivityResult: orientation=Portrait
01-04 15:18:15.719  D/MainActivity: onStart: orientation=Portrait
01-04 15:18:15.720  D/MainActivity: onResume: orientation=Portrait
01-04 15:18:15.786  D/LandscapeActivity: onStop: orientation=Landscape
01-04 15:18:15.786  D/LandscapeActivity: onDestroy: orientation=Landscape
01-04 15:18:18.036  D/MainActivity: onPause: orientation=Portrait
01-04 15:18:18.097  D/LandscapeActivity: onCreate: savedInstanceState=nullorientation=Landscape
01-04 15:18:18.121  D/LandscapeActivity: onStart: orientation=Landscape
01-04 15:18:18.123  D/LandscapeActivity: onResume: orientation=Landscape
01-04 15:18:18.213  D/MainActivity: onStop: orientation=Portrait
01-04 15:18:19.505  D/LandscapeActivity: onPause: orientation=Landscape
01-04 15:18:19.564  D/MainActivity: onActivityResult: orientation=Portrait
01-04 15:18:19.569  D/MainActivity: onStart: orientation=Portrait
01-04 15:18:19.569  D/MainActivity: onResume: orientation=Portrait
01-04 15:18:19.639  D/LandscapeActivity: onStop: orientation=Landscape
01-04 15:18:19.640  D/LandscapeActivity: onDestroy: orientation=Landscape
01-04 15:18:20.102  D/MainActivity: onPause: orientation=Portrait
01-04 15:18:20.103  D/MainActivity: onStop: orientation=Portrait
01-04 15:18:20.104  D/MainActivity: onDestroy: orientation=Portrait
01-04 15:18:20.123  D/MainActivity: onCreate: savedInstanceState=Bundle[{android:viewHierarchyState=Bundle[{android:views={[email protected], [email protected], [email protected], [email protected], [email protected], [email protected]}}], android:lastAutofillId=1073741823, android:[email protected]}]
01-04 15:18:20.149  D/MainActivity: onStart: orientation=Landscape
01-04 15:18:20.152  D/MainActivity: onResume: orientation=Landscape
01-04 15:18:20.699  D/MainActivity: onPause: orientation=Landscape
01-04 15:18:20.701  D/MainActivity: onStop: orientation=Landscape
01-04 15:18:20.702  D/MainActivity: onDestroy: orientation=Landscape
01-04 15:18:20.718  D/MainActivity: onCreate: savedInstanceState=Bundle[{android:viewHierarchyState=Bundle[{android:views={[email protected], [email protected], [email protected], [email protected], [email protected], [email protected]}}], android:lastAutofillId=1073741823, android:[email protected]}]
01-04 15:18:20.748  D/MainActivity: onStart: orientation=Portrait
01-04 15:18:20.751  D/MainActivity: onResume: orientation=Portrait

Ответ 2

Это может быть ошибка структуры. Я заметил подобное поведение на устройствах Samsung, используя приложение камеры (через Intent) в пейзаже из приложения, предназначенного только для портрета. Я не мог понять, в чем причина, но я нашел работу, которая минимизирует эффект.

Если вы сообщите системе, что хотите сами изменить ориентацию, добавив android:configChanges="orientation|screenSize" в свою активность, она не будет воссоздана при изменении ориентации. Таким образом, вы можете избежать накладных расходов на воссоздание Activity (дважды), что может повысить производительность до такой степени, что вы вообще не заметили изменения ориентации.

<activity android:name=".MainActivity"
    android:screenOrientation="portrait"
    android:configChanges="orientation|screenSize">

Ответ 3

Да, это проблема в версии ОС Android 8.1. Как это было сделано устаревшим. мы можем обойти эти проблемы. На этом конкретном уровне API ОС Android может сохранять последнее значение ориентации и применяется ко всем экранам до тех пор, пока предыдущий экран или этот конкретный экран не будет уничтожен. Таким образом, решение этой проблемы заключается в изменении ориентации, прежде чем вернуться к экрану.
Например:
Если ScreenA находится в портретном режиме, а screenB находится в альбомном режиме, и если экран перемещен в ScreenB, который является альбомным, и если вы вернетесь к ScreenA без уничтожения ScreenB (восстановление ScreenA), экран A также будет виден в альбомном режиме.
Чтобы устранить эту проблему, принудительно измените ориентацию ScreenA на Portrait в onPause() или OnStop() ScreenB (чтобы восстановить ScreenA).

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

после этого звонка ScreenA будет в портрете. Кроме того, в onResume() ScreenB,

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

Ответ 4

Android Oreo в основном разрушил нашу жизнь... Моя жена отключена и лежит на боку едва ли как-либо иначе, чтобы использовать свои творческие способности, кроме как держать легкий планшетный компьютер (сбоку), а в ландшафтном режиме иметь достаточно большую клавиатуру, чтобы быть функциональным для нее... так как обновление Oreo ландшафтный режим исчез и существует только в режиме "автоповорота"... который бесполезен, когда вам приходится лежать в стороны.

Почему планшетный компьютер вообще существует, если вы не можете использовать альбомный режим?