Як відключити зміну орієнтації на Android?


287

У мене є додаток, який я просто хотів би використовувати в портретному режимі, тому в маніфесті XML я визначив андроїд: screenOrientation = "портрет". Це добре для телефону HTC Magic (і запобігає зміні орієнтації також на інших телефонах).

Але у мене є проблема з телефоном HTC G1, коли я відкриваю апаратну QWERTY клавіатуру (не віртуальну клавіатуру). Моя активність залишається в портретному режимі, але вона, здається, перезавантажується і втрачає всі стани. Це не відбувається з версією HTC Hero .

Моя програма досить велика, тому я не хочу, щоб вона перезапускалася і втрачала всі її стани при відкритті клавіатури. Як я можу запобігти цьому?



Відповіді:


317

Оновлення квітня 2013 року: Не робіть цього. У 2009 році я не була гарною ідеєю, коли я вперше відповіла на це питання, і тепер це не дуже гарна ідея. Дивіться цю відповідь від hackbod з причин:

Уникайте перезавантажувальної діяльності за допомогою асинтакта на зміну орієнтації на андроїд

Додайте android:configChanges="keyboardHidden|orientation"до свого AndroidManifest.xml. Це повідомляє системі, які зміни конфігурації ви збираєтеся впоратися самостійно - у цьому випадку нічого не роблячи.

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

Докладнішу інформацію див. У довідковій програмі configChanges .

Однак ваш додаток може бути перервано в будь-який час, наприклад, телефонним дзвінком, тому вам дійсно слід додати код, щоб зберегти стан вашої програми, коли вона призупинена.

Оновлення: На Android 3.2 вам також потрібно додати "screenSize":

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

З посібника для розробників Поводження з конфігурацією Змініть себе

Застереження: Починаючи з Android 3.2 (рівень API 13), "розмір екрана" також змінюється, коли пристрій перемикається між портретною та пейзажною орієнтацією. Таким чином, якщо ви хочете запобігти перезапуску часу виконання через зміну орієнтації при розробці для API рівня 13 або вище (як заявлено атрибутами minSdkVersion та targetSdkVersion), вам слід додати значення "screenSize" на додаток до значення "орієнтація". Тобто ви повинні заявити android:configChanges="orientation|screenSize". Однак якщо ваша програма орієнтована на рівень API 12 або нижчий, ваша діяльність завжди обробляє цю зміну конфігурації (ця зміна конфігурації не перезапускає вашу активність, навіть коли ви працюєте на пристрої Android 3.2 або новішої версії).


36
Просто для того, щоб додати це і бути по-справжньому явним, Android може безжально вбивати вашу програму в будь-який час, незалежно від змін орієнтації, тому вам слід використовувати OnPause () і onSaveInstanceState () для збереження стану, незалежно від того.
Ерік Мілл

Оновлення 3.2 було дуже корисним і саме мене блокувало. Я поняття не мав, чому мій обробник onConfigurationChanged не стріляв, і це було все. Дякую!
sweetlilmre

третій парам - screenSize не можна знайти в 2.3.x, я повинен змінити на screenLayout?
мертвий риб

2
@Lumma Ні, "screenSize" потрібен лише для Android 3.2 та новіших версій. На який рівень API ви орієнтовані? Я думаю, вам потрібно додати його лише в тому випадку, якщо ви орієнтуєтесь на рівень 13 або вище. Я уточну відповідь, щоб уточнити.
інтригації

1
На всякий випадок, якщо це корисно іншим людям, я знайшов, що ви обидва <... android: configChanges = "орієнтація" ...> змінити зміни та <... android: screenOrientation = "portrait" ...> to визначити за замовчуванням.
Sogger

97

Вам потрібно змінити AndroidManifest.xml , як Intrications згадувалося (раніше Ashton) і переконайтеся , що ручки діяльності по onConfigurationChanged подій , як ви хочете , це обробляється. Ось як це має виглядати:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

Як зазначив Дмитро Зайцев, то краще поставити setRequestedOrientation()в систему onCreate().
Timmmm

3
Чи не onConfigurationChanged()додзвонилися до того, onCreate()якщо так установки орієнтації перед установкою contentViews в OnCreate є краще підходом, настройка конфігурації , де вона належить також чистіше , так що ця відповідь до сих пір стоїть добре.
Самуїл

39

Я завжди вважав, що потрібно обоє

android:screenOrientation="nosensor" android:configChanges="keyboardHidden|orientation"

22

Як було сказано, встановіть android:configChangesсвою активність (у файлі маніфесту) на, keyboardHidden|orientationа потім:

1) Переосмислення onConfigurationChanged()

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //here you can handle orientation change
}

2) Додайте цей рядок до активності onCreate()

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

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

Також ви можете встановити android:screenOrientation="nosensor"свою діяльність (у маніфесті). Але використовуючи цей спосіб, ви взагалі не можете впоратися зі змінами орієнтації.


Що робити, якщо я хочу уникнути відновлення діяльності після обертання, але все ж хочу дозволити користувачеві блокувати орієнтацію через налаштування ОС?
андроїд розробник

@androiddeveloper, що окреме питання, на яке вже є відповідь: stackoverflow.com/a/14771495/926907
Дмитро Зайцев

Ваше посилання стосується самої зміни вмісту, коли змінюється конфігурація, але я хочу уникати повороту діяльності (щоб він залишався саме таким, як він виглядає), якщо користувач вирішив заблокувати орієнтацію через ОС налаштування (доступні на деяких пристроях через швидкі налаштування, в ящику сповіщень).
андроїд розробник

@androiddeveloper ах, я думаю, я зрозумів. Потім перегляньте це посилання: developer.android.com/reference/android/… Відповідно до документів, орієнтація за замовчуванням вже повинна враховувати переваги користувачів. Якщо це не так, то я підозрюю, що це специфічна поведінка ОС. Я був би радий дізнатися про ваші результати - зараз мене теж цікавить :)
Дмитро Зайцев

Я знаю, що за замовчуванням буде працювати вподобання користувача, але він також відновлює активність під час обертання екрана, чого я не хочу мати.
андроїд розробник


13

У методі OnCreate своєї діяльності використовуйте цей код:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

Тепер ваша орієнтація буде встановлена ​​на портрет і ніколи не зміниться.


4
З цим ви не перешкоджаєте перезавантажувати діяльність щоразу, коли зміна конфігурації орієнтації.
AxeEffect

Крім того, це не працює, якщо ви ввели активність із попередньої діяльності в альбомній орієнтації.
w3bshark

10

У файлі AndroidManifest.xml для кожної дії, яку ви хочете заблокувати, додайте останній screenOrientationрядок:

android:label="@string/app_name"
android:name=".Login"
android:screenOrientation="portrait" >

Або android: screenOrientation = "пейзаж" .


8

У вашому файлі androidmanifest.xml :

   <activity android:name="MainActivity" android:configChanges="keyboardHidden|orientation">

або

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

6

Щоб заблокувати екран за кодом, ви повинні використовувати власне обертання екрана (0, 90, 180, 270), і ви повинні знати його природне положення, в смартфоні природне положення буде портретним і в планшеті, це буде пейзаж.

Ось код (методи блокування та розблокування), він протестований на деяких пристроях (смартфонах і планшетах) і він чудово працює.

public static void lockScreenOrientation(Activity activity)
{   
    WindowManager windowManager =  (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);   
    Configuration configuration = activity.getResources().getConfiguration();   
    int rotation = windowManager.getDefaultDisplay().getRotation(); 

    // Search for the natural position of the device    
    if(configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&  
       (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) ||  
       configuration.orientation == Configuration.ORIENTATION_PORTRAIT &&   
       (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270))   
    {   
        // Natural position is Landscape    
        switch (rotation)   
        {   
            case Surface.ROTATION_0:    
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);    
                break;      
            case Surface.ROTATION_90:   
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
            break;      
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
                break;
        }
    }
    else
    {
        // Natural position is Portrait
        switch (rotation) 
        {
            case Surface.ROTATION_0: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
            break;   
            case Surface.ROTATION_90: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
            break;   
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;
        }
    }
}

public static void unlockScreenOrientation(Activity activity)
{
    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}

який параметр слід передавати як діяльність?
ПОЖИВАТИ

Діяльність, яка викликає метод блокування / розблокування його орієнтації. Це загальнодоступний метод статичної корисності, який потрібно викликати з різних видів діяльності.
PoOk

1
Відмінно працює, але, серйозно, Android, чому ми повинні робити все це саме для орієнтації на заблокований екран? !!!
Cocorico

так. Цей фіксує орієнтацію, як ми робимо в маніфесті. Це не дозволить більше запускати onConfigurationChanged. Чи існує метод, який блокує інтерфейс користувача на Landscape і все ще викликає onConfigurationChanged. Так само, як це робить додаток для камери в андроїді
Айфіт Мемана

На SDK 18+ є прапор SCREEN_ORIENTATION_LOCKED, який, здається, працює, але ви все одно хочете використовувати код вище для підтримки кожного пристрою
DominicM

2

У Visual Studio Xamarin:

  1. Додати:

using Android.Content.PM; до списку простору імен діяльності

  1. Додати:

[Activity(ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait)]

як атрибут класу, як:

[Activity(ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : Activity
{...}

Це питання задають про Android, а не про Xamarin.Android
Тревор Харт


0

Зверніть увагу, жоден із методів, здається, не працює зараз!

В Android Studio 1 один простий спосіб - додати android:screenOrientation="nosensor".

Це ефективно блокує орієнтацію екрана.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.