Запобігати повороту екрана на Android


315

У мене є одна з моїх дій, яку я хотів би запобігти обертанню, тому що я запускаю AsyncTask, а обертання екрана змушує його перезапустити.

Чи є спосіб сказати цю діяльність "НЕ ВРЕМИТИ екран, навіть якщо користувач трясе телефон, як божевільний"?



11
Ви можете мати справу зі зміною орієнтації екрана та AsyncTasks. Запобігання змінам орієнтації екрану - це лише ледачий спосіб вирішення. І не важко підтримувати AsyncTask в живих через зміни орієнтації :)
Romain Guy


56
Було б набагато корисніше фактично запропонувати рішення або якийсь код, Ромен, а не просто стверджувати, що "рішення існує, і це не важко".
Пітер vdL

2
ви можете скористатися setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
mcy

Відповіді:


467

Додайте

android:screenOrientation="portrait" 

або

 android:screenOrientation="landscape" 

до <activity>елемента / s в маніфесті, і ви закінчили.


95
Зауважте, що це просто приховує помилку у вашій програмі, що робить її меншою ймовірність, що користувачі можуть подолати її. Але вони все одно будуть. Будь-яка зміна конфігурації може призвести до перезапуску вашої діяльності. Вам дійсно потрібно правильно записати свою діяльність, щоб вирішити завдання async під час її перезавантаження.
hackbod

1
Це не спрацювало для мене в одному випадку. Перед тим, як відкрити додаток, у мене був пейзаж на екрані. Коли я відкрив додаток, екран повернувся до портретного і викликав другий дзвінок в асинтакт.
користувач522559

2
Потрібно встановити параметри "відкриватись у портретному режимі" І "завжди залишатися в портретному режимі". Робити лише 1 - безглуздо.
Керрол

1
@hackbod незалежно, це номер 1 для Google для "програми для Android запобігають обертанню екрана", моя потреба не має нічого спільного з завданнями асинхронізації
chiliNUT

7
@hackbod Як ми можемо правильно записати свою діяльність для вирішення цієї проблеми?
користувач41805

127

Ви можете слідувати логіці нижче , щоб запобігти автоматичний поворот екрану в той час як ваш AsyncTaskпрацює:

  1. Зберігайте поточну орієнтацію екрана всередині своєї діяльності, використовуючи getRequestedOrientation().
  2. Вимкнути автоматичну орієнтацію екрана за допомогою setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR).
  3. Запустити / виконати своє AsyncTask.
  4. В кінці AsyncTaskвідновлення попереднього стану орієнтації використовуючи setRequestedOrientation(oldOrientation).

Зауважте, що існує декілька способів доступу до Activityвластивостей (який працює на потоці інтерфейсу користувача) всередині AsyncTask. Ви можете реалізовувати свій AsyncTaskяк внутрішній клас, або ви можете використовувати повідомлення, Handlerяке клацає ваш Activiyклас.


9
Набагато краще, ніж обрана відповідь.
Матей

3
відмінна ідея :) у вас немає збереження поточної орієнтації на екран, ви можете використовувати ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
fligant

Це здається неймовірним, @emre, дякую! Здається "Занадто добре, щоб бути правдою!" Зверніть увагу на величезну кількість дискусій з цього питання: stackoverflow.com/q/3821423/294884 ... андроїдні експерти, чи є тут недоліки ?! Ще раз дякую .. стільки.
Fattie

3
Лайно !! Це НЕ ПРАЦЮЄ, якщо пристрій ЗАПОВІДАЄТЬСЯ В РЕЖИМЕ ПІДПРИЄМСТВА. Якого біса! Sux: O
Fattie

@Emre, Цей код не працює в певних випадках. Наприклад, якщо користувач змінив свою орієнтацію між початком роботи AsyncTask та його закінченням. Ви б тоді зберегли та відновили неправильну орієнтацію.
Pacerier

27

У файлі Manifest для кожної діяльності, яку ви хочете заблокувати обертання екрана, додайте: якщо ви хочете заблокувати його в горизонтальному режимі:

<activity
        ...
        ...
        android:screenOrientation="landscape">

або якщо ви хочете заблокувати його у вертикальному режимі:

<activity
            ...
            ...
            android:screenOrientation="portrait">

24

Найпростіший спосіб, який я знайшов це зробити, - це поставити

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

всередині onCreate, відразу після

setContentView(R.layout.activity_main);

тому...

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

7

Замість того, щоб заходити в AndroidManifest, ви можете просто зробити це:

screenOrientation = getResources().getConfiguration().orientation;
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
... AsyncTask

screenOrientation = getResources().getConfiguration().orientation;


@Override
protected void onPostExecute(String things) {
    context.setRequestedOrientation(PlayListFragment.screenOrientation);
    or 
    context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
}

Єдиним недоліком тут є те, що для нього потрібен рівень API 18 або вище. Так що в основному це кінчик списа.


Ця частина вимикає кнопку домашніх та останніх додатків, навіть після вимкнення блокування за допомогою SCREEN_ORIENTATION_FULL_SENSOR, її в відключеному стані. В Android N.
kAmol

6

Activity.java

@Override     
 public void onConfigurationChanged(Configuration newConfig) {       
        try {     
            super.onConfigurationChanged(newConfig);      
            if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {      
                // land      
            } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {      
               // port       
            }    
        } catch (Exception ex) {       
     }   

AndroidManifest.xml

 <application android:icon="@drawable/icon" android:label="@string/app_name">
  <activity android:name="QRCodeActivity" android:label="@string/app_name"
  android:screenOrientation="landscape" >
   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  </activity>

 </application>

2

Наступний атрибут ACTIVITY в AndroidManifest.xml - це все, що вам потрібно:

android:configChanges="orientation"

Отже, повним вузлом активності буде:

<activity android:name="Activity1"
          android:icon="@drawable/icon"
          android:label="App Name"
          android:excludeFromRecents="true"
          android:configChanges="orientation">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>

1

Додати:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
        ...
        ...
        ...
}

1

Додайте наступне до свого AndroidManifest.xml

[app> src> main> AndroidManifest.xml]

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

Приклад:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xxx.zzzzzz.yyyyy">

   <uses-permission android:name="A-PERMISSION" />

   <application>
      <activity android:name=".MainActivity"
                android:screenOrientation="portrait"
                android:configChanges="orientation">
      </activity>
   </application>

</manifest>

0

Якщо ви використовуєте Інструменти для розробників Android (ADT) та Eclipse, ви можете перейти на AndroidManifest.xml -> вкладка програми -> спуститися вниз і вибрати свою діяльність. Нарешті, виберіть бажану орієнтацію. Ви можете вибрати один із багатьох варіантів.


0

Ви повинні додати наступний код у файл manifest.xml. Діяльність, для якої вона не повинна обертатися, в цій діяльності додайте цей елемент

android:screenOrientation="portrait"

Тоді він не буде обертатися.


0

Ви можете спробувати таким чином

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itclanbd.spaceusers">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<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=".Login_Activity"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>


0

Використовуйте AsyncTaskLoader, щоб захистити ваші дані, навіть якщо активність зміниться, замість того, щоб використовувати AsyncTask, що є кращим способом створення додатків, ніж запобігання обертання екрана.


0

Запобігання повороту екрана просто додайте цей наступний рядок у ваші Маніфести.

<activity
        android:name=".YourActivity"
        android:screenOrientation="portrait" />

Це працює для мене.


0

Користувач "portrait"у вашому файлі AndroidManifest.xml може здатися хорошим рішенням. Але це змушує певні пристрої (які найкраще працюють у ландшафті) переходити до портрету, не отримуючи належної орієнтації. В останній версії Android ви отримаєте помилку. Тож мою пропозицію краще використовувати "nosensor".

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