Empêcher la rotation de l'écran sur Android

315

J'ai une de mes activités que j'aimerais empêcher de tourner car je démarre une tâche AsyncTask, et la rotation de l'écran la fait redémarrer.

Existe-t-il un moyen de dire à cette activité "NE PAS TOURNER l'écran même si l'utilisateur secoue son téléphone comme un fou"?

Sephy
la source
11
Vous pouvez gérer le changement d'orientation de l'écran et les tâches asynchrones. La prévention des changements d'orientation de l'écran n'est qu'une solution de contournement paresseuse. Et ce n'est pas difficile de garder une AsyncTask en vie malgré les changements d'orientation :)
Romain Guy
56
Il serait beaucoup plus utile de fournir réellement une solution ou du code, Romain, plutôt que de simplement affirmer "qu'une solution existe et qu'elle n'est pas difficile".
Peter vdL
2
vous pouvez utiliser setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
mcy

Réponses:

467

Ajouter

android:screenOrientation="portrait" 

ou

 android:screenOrientation="landscape" 

à l' <activity>élément / s dans le manifeste et vous avez terminé.

lbedogni
la source
95
Veuillez noter que cela cache simplement un bogue dans votre application, ce qui rend les utilisateurs moins susceptibles de trébucher dessus. Mais ils le feront toujours. Tout changement de configuration peut entraîner le redémarrage de votre activité. Vous avez vraiment besoin d'écrire votre activité correctement pour gérer la tâche asynchrone au redémarrage.
hackbod
1
Cela n'a pas fonctionné pour moi dans un cas. J'ai réglé l'écran sur paysage avant d'ouvrir l'application. Lorsque j'ai ouvert l'application, l'écran a tourné en mode portrait et a provoqué un deuxième appel à asynctask.
user522559
2
Vous devez définir les choses pour "ouvrir en mode portrait" ET "toujours rester en mode portrait". Faire seulement 1 est inutile.
Carol
1
@hackbod malgré tout, c'est le numéro 1 de Google pour "l'application Android empêche la rotation de l'écran", mon besoin n'a rien à voir avec les tâches asynchrones
chiliNUT
7
@hackbod Comment rédigeons-nous ensuite correctement notre activité pour résoudre ce problème?
user41805
127

Vous pouvez suivre la logique ci-dessous pour empêcher la rotation automatique de l'écran pendant que vous AsyncTaskexécutez:

  1. Stockez votre orientation d'écran actuelle dans votre activité à l'aide de getRequestedOrientation().
  2. Désactivez l'orientation automatique de l'écran à l'aide de setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR).
  3. Exécutez / exécutez votre AsyncTask.
  4. À la fin de la AsyncTaskrestauration de votre état d'orientation précédent à l'aide de setRequestedOrientation(oldOrientation).

Veuillez noter qu'il existe plusieurs façons d'accéder Activity(qui s'exécute sur le thread d'interface utilisateur) à l'intérieur d'un AsyncTask. Vous pouvez implémenter votre en AsyncTasktant que classe interne ou utiliser un message Handlerqui pique votre Activiyclasse.

Emre Yazici
la source
9
Beaucoup mieux que la réponse choisie.
Matej
3
bonne idée :) vous n'avez pas
stocké
Cela semble incroyable, @emre, merci! Il semble "Trop beau pour être vrai!" Notez l'énorme quantité de discussions sur le problème: stackoverflow.com/q/3821423/294884 ... experts Android, y a-t-il un inconvénient ici?! Merci encore .. beaucoup.
Fattie
3
Merde!! Cela NE FONCTIONNE PAS si le périphérique COMMENCE EN MODE PAYSAGE. Que se passe-t-il! Sux: O
Fattie
@Emre, ce code ne fonctionne pas dans certains cas. Par exemple, si l'utilisateur a changé son orientation entre le début de votre AsyncTask et sa fin. Vous auriez alors enregistré et restauré la mauvaise orientation.
Pacerier
27

Dans votre fichier manifeste, pour chaque activité dont vous souhaitez verrouiller la rotation d'écran, ajoutez: si vous souhaitez la verrouiller en mode horizontal:

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

ou si vous souhaitez le verrouiller en mode vertical:

<activity
            ...
            ...
            android:screenOrientation="portrait">
Sara
la source
24

La façon la plus simple que j'ai trouvée de le faire était de mettre

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

dans onCreate, juste après

setContentView(R.layout.activity_main);

alors...

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

Plutôt que d'entrer dans le AndroidManifest, vous pouvez simplement faire ceci:

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

Le seul inconvénient ici est qu'il nécessite un niveau d'API 18 ou supérieur. Donc, fondamentalement, c'est la pointe de la lance.

Antuan Develle Claude
la source
Cette partie désactive le bouton home et les applications récentes et même après avoir relâché le verrou avec SCREEN_ORIENTATION_FULL_SENSOR, son état est désactivé. Dans 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>
Li Che
la source
2

L'attribut suivant sur l'activité dans AndroidManifest.xml est tout ce dont vous avez besoin:

android:configChanges="orientation"

Ainsi, le nœud d'activité complet serait:

<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>
Ben
la source
1

Ajouter:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
        ...
        ...
        ...
}
Anas
la source
1

Ajoutez ce qui suit à votre AndroidManifest.xml

[app> src> main> AndroidManifest.xml]

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

Exemple:

<?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
la source
0

Si vous utilisez les outils de développement Android (ADT) et Eclipse, vous pouvez accéder à votre AndroidManifest.xml -> onglet Application -> descendre et sélectionner votre activité. Enfin, sélectionnez votre orientation préférée. Vous pouvez sélectionner l'une des nombreuses options.

Husam
la source
0

Vous devez ajouter le code suivant dans le fichier manifest.xml. L'activité pour laquelle il ne doit pas tourner, dans cette activité ajouter cet élément

android:screenOrientation="portrait"

Ensuite, il ne tournera pas.

Simon Chius
la source
0

Vous pouvez essayer de cette façon

<?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>

Muhaiminur Rahman
la source
0

Utilisez AsyncTaskLoader pour protéger vos données même si l'activité change, au lieu d'utiliser AsyncTask qui est un meilleur moyen de créer des applications que d'empêcher la rotation de l'écran.

Bbake Waikhom
la source
0

Empêchez la rotation de l'écran, ajoutez simplement cette ligne suivante dans vos manifestes.

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

Cela fonctionne pour moi.

DEVSHK
la source
0

L'utilisateur "portrait"dans votre fichier AndroidManifest.xml peut sembler une bonne solution. Mais cela oblige certains appareils (qui fonctionnent mieux en paysage) à passer en mode portrait, sans obtenir la bonne orientation. Sur la dernière version d'Android, vous obtiendrez une erreur. Donc, ma suggestion est préférable d'utiliser "nosensor".

<activity
        ...
        ...
        android:screenOrientation="nosensor">
Md Imran Choudhury
la source