Запретить поворот экрана на Android

315

У меня есть одно из моих действий, которое я хотел бы предотвратить вращением, потому что я запускаю AsyncTask, и поворот экрана заставляет его перезапускаться.

Есть ли способ сказать это действие "НЕ ВРАЩАТЬ экран, даже если пользователь трясет свой телефон, как сумасшедший"?

Sephy
источник
11
Вы можете иметь дело с изменением ориентации экрана и AsyncTasks. Предотвращение изменения ориентации экрана - просто ленивый обходной путь. И нетрудно поддерживать AsyncTask при изменениях ориентации :)
Romain Guy
56
Было бы гораздо полезнее на самом деле предоставить решение или некоторый код Romain, чем просто утверждать, что «решение существует, и оно не сложное».
Питер vdL
2
Вы можете использовать setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
mcy

Ответы:

467

Добавить

android:screenOrientation="portrait" 

или

 android:screenOrientation="landscape" 

к <activity>элементу / с в манифесте , и вы сделали.

lbedogni
источник
95
Пожалуйста, обратите внимание, что это просто скрывает ошибку в вашем приложении, уменьшая вероятность того, что пользователи пройдут через нее. Но они все еще будут. Любое изменение конфигурации может привести к перезапуску вашей активности. Вам действительно нужно правильно написать свою деятельность, чтобы справиться с асинхронной задачей при ее перезапуске.
hackbod
1
Это не сработало для меня в одном случае. У меня был экран в горизонтальной ориентации перед открытием приложения. Когда я открыл приложение, экран повернулся в портретный режим и вызвал второй вызов asynctask.
user522559
2
Вам необходимо установить «открыть в портретном режиме» И «всегда оставаться в портретном режиме». Делать только 1 бессмысленно.
Кэрол
1
@hackbod, независимо от того, что это номер №1 в Google по запросу "Android-приложение предотвращает поворот экрана", моя потребность не имеет ничего общего с асинхронными задачами
chiliNUT
7
@hackbod Как правильно написать свою деятельность, чтобы справиться с этой проблемой?
user41805
127

Вы можете следовать логике ниже , чтобы предотвратить автоматический поворот экрана в то время как ваш AsyncTaskработающий:

  1. Сохраните текущую ориентацию экрана в вашей деятельности, используя getRequestedOrientation().
  2. Отключите автоматическую ориентацию экрана, используя setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR).
  3. Запустите / выполните ваш AsyncTask.
  4. В конце вашего AsyncTaskвосстановления ваш предыдущий статус ориентации с помощью setRequestedOrientation(oldOrientation).

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

Эмре Язычи
источник
9
Гораздо лучше, чем выбранный ответ.
Matej
3
отличная идея :) у вас нет сохранения текущей ориентации экрана, вы можете использовать ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
fligant
Это кажется невероятным, @emre, спасибо! Кажется, "слишком хорошо, чтобы быть правдой!" Обратите внимание на огромное количество дискуссий по этому вопросу: stackoverflow.com/q/3821423/294884 ... эксперты по Android, есть ли здесь недостаток ?! Еще раз спасибо .. так много.
Толстяк
3
Дерьмо!! Это НЕ РАБОТАЕТ, если устройство НАЧИНАЕТСЯ В ЛАНДШАФТНОМ РЕЖИМЕ. Какого черта! Sux: O
Толстяк
@ Emre, этот код не работает в некоторых случаях. Например, если пользователь изменил свою ориентацию между началом вашей AsyncTask и его концом. Тогда вы бы сохранили и восстановили неправильную ориентацию.
Pacerier
27

В своем файле манифеста для каждого действия, которое вы хотите заблокировать поворотом экрана, добавьте: если вы хотите заблокировать его в горизонтальном режиме:

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

или если вы хотите заблокировать его в вертикальном режиме:

<activity
            ...
            ...
            android:screenOrientation="portrait">
Сара
источник
25

Самый простой способ сделать это -

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.
Камоль
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>
andrewoodleyjr
источник
0

Если вы используете Android Developer Tools (ADT) и Eclipse, вы можете перейти на свой AndroidManifest.xml -> вкладка « Приложение » -> перейти вниз и выбрать свою деятельность. Наконец, выберите предпочитаемую ориентацию. Вы можете выбрать один из множества вариантов.

Husam
источник
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, который является лучшим способом создания приложений, чем предотвращение поворота экрана.

Bbake Waikhom
источник
0

Предотвратить поворот экрана просто добавьте следующую строку в свои манифесты.

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

Это работает для меня.

DEVSHK
источник
0

Пользователь "portrait"в вашем файле AndroidManifest.xml может показаться хорошим решением. Но это заставляет определенные устройства (которые лучше всего работают в ландшафте) переходить в портрет, не получая правильной ориентации. В последней версии Android вы получите ошибку. Так что мое предложение лучше использовать "nosensor".

<activity
        ...
        ...
        android:screenOrientation="nosensor">
Имран Чоудхури
источник