Comment désactiver le changement d'orientation sur Android?


287

J'ai une application que je voudrais simplement utiliser en mode portrait, j'ai donc défini android: screenOrientation = "portrait" dans le manifeste XML. Cela fonctionne bien pour le téléphone HTC Magic (et empêche également les changements d'orientation sur d'autres téléphones).

Mais j'ai un problème avec le téléphone HTC G1 car j'ouvre le clavier QWERTY matériel (pas le clavier virtuel). Mon activité reste en mode portrait, mais elle semble redémarrer et perd tous ses états. Cela ne se produit pas avec la version HTC Hero .

Mon application est assez grande, donc je ne veux pas qu'elle redémarre et perde tous ses états à l'ouverture du clavier. Comment puis-je empêcher cela?


2
Essayez de regarder ici aussi: stackoverflow.com/questions/2366706/…
Andy Weinstein

Réponses:


317

Mise à jour d'avril 2013: ne faites pas ça. Ce n'était pas une bonne idée en 2009 lorsque j'ai répondu pour la première fois à la question et ce n'est vraiment pas une bonne idée maintenant. Voir cette réponse par hackbod pour des raisons:

Évitez de recharger l'activité avec asynctask sur le changement d'orientation dans Android

Ajoutez android:configChanges="keyboardHidden|orientation"à votre AndroidManifest.xml. Cela indique au système les modifications de configuration que vous allez gérer vous-même - dans ce cas, en ne faisant rien.

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

Voir ConfigChanges de référence pour les développeurs pour plus de détails.

Cependant, votre application peut être interrompue à tout moment, par exemple par un appel téléphonique, vous devez donc vraiment ajouter du code pour enregistrer l'état de votre application lorsqu'elle est en pause.

Mise à jour: à partir d'Android 3.2, vous devez également ajouter "screenSize":

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

À partir du guide du développeur Gérer vous-même la configuration

Attention: à partir d'Android 3.2 (API niveau 13), la "taille d'écran" change également lorsque l'appareil bascule entre l'orientation portrait et paysage. Ainsi, si vous souhaitez empêcher les redémarrages de l'exécution en raison d'un changement d'orientation lors du développement pour l'API de niveau 13 ou supérieur (comme déclaré par les attributs minSdkVersion et targetSdkVersion), vous devez inclure la valeur "screenSize" en plus de la valeur "orientation". Autrement dit, vous devez déclarer android:configChanges="orientation|screenSize". Cependant, si votre application cible l'API de niveau 12 ou inférieur, votre activité gère toujours cette modification de configuration elle-même (cette modification de configuration ne redémarre pas votre activité, même lorsqu'elle s'exécute sur un appareil Android 3.2 ou supérieur).


36
Juste pour ajouter à cela et être vraiment explicite, Android peut tuer sans pitié votre application à tout moment, indépendamment des changements d'orientation, vous devez donc utiliser onPause () et onSaveInstanceState () pour enregistrer l'état, quoi qu'il arrive.
Eric Mill

La mise à jour 3.2 était très utile et était ce qui me bloquait. Je ne savais pas pourquoi mon gestionnaire onConfigurationChanged ne se déclenchait pas et c'était tout. Merci!
sweetlilmre

le troisième paramètre - screenSize est introuvable dans 2.3.x, dois-je passer à screenLayout?
deadfish

2
@Lumma Non, "screenSize" n'est nécessaire que pour Android 3.2 et plus récent. Quel niveau d'API visez-vous? Je pense que vous ne devez l'ajouter que si vous visez le niveau 13 ou supérieur. Je mettrai à jour la réponse pour clarifier.
Intrications

1
Juste au cas où cela serait utile à d'autres personnes, je vous ai trouvé <... android: configChanges = "orientation" ...> pour remplacer les modifications et <... android: screenOrientation = "portrait" ...> pour définir la valeur par défaut.
Sogger

97

Vous devez modifier AndroidManifest.xml comme Intrications (précédemment Ashton) mentionné et assurez-vous que l'activité gère l'événement onConfigurationChanged comme vous le souhaitez. Voici à quoi cela devrait ressembler:

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

Comme l'a souligné Dmitry Zaitsev, il est préférable de mettre l' setRequestedOrientation()en onCreate().
Timmmm

3
N'obtient pas onConfigurationChanged()appelé avant onCreate()si la définition de l'orientation avant la définition de contentViews dans oncreate est une meilleure approche, définir la configuration à laquelle il appartient est également plus propre, donc cette réponse est toujours valable.
Samuel

39

J'ai toujours trouvé que tu avais besoin des deux

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

22

Comme indiqué, définissez android:configChangesvotre activité (dans le fichier manifeste) sur keyboardHidden|orientation, puis:

1) Remplacer onConfigurationChanged()

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

2) Ajoutez cette ligne à votre activité onCreate()

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

C'est mieux que d'ajouter la même ligne à onConfigurationChanged, car votre application passera en mode portrait, puis reviendra au paysage (cela ne se produira qu'une seule fois, mais c'est ennuyeux).

Vous pouvez également définir android:screenOrientation="nosensor"votre activité (en manifeste). Mais de cette façon, vous n'êtes pas du tout en mesure de gérer les changements d'orientation.


Que dois-je faire si je veux éviter de recréer l'activité lors de la rotation, mais je souhaite autoriser l'utilisateur à verrouiller l'orientation via les paramètres du système d'exploitation?
développeur Android

@androiddeveloper qu'une question distincte, qui a déjà une réponse: stackoverflow.com/a/14771495/926907
Dmitry Zaytsev

Votre lien consiste à modifier le contenu par moi-même lorsque la configuration change, mais je souhaite éviter la rotation de l'activité (afin qu'elle reste exactement à quoi elle ressemble) au cas où l'utilisateur aurait choisi de verrouiller l'orientation via le système d'exploitation. paramètres (disponibles sur certains appareils via les réglages rapides, dans le tiroir de notification).
développeur Android

@androiddeveloper ah, je pense avoir compris. Ensuite, jetez un œil à ce lien: developer.android.com/reference/android/… Selon les documents, l'orientation par défaut devrait déjà tenir compte des préférences de l'utilisateur. Si ce n'est pas le cas, je soupçonne que c'est un comportement spécifique au système d'exploitation. Je serais heureux d'entendre vos résultats - maintenant je suis aussi intéressé par ça :)
Dmitry Zaytsev

Je sais que la valeur par défaut gérera les préférences de l'utilisateur, mais elle recrée également l'activité lorsque vous faites pivoter l'écran, ce que je ne veux pas avoir.
développeur Android


13

Dans la méthode OnCreate de votre activité, utilisez ce code:

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

Maintenant, votre orientation sera définie sur portrait et ne changera jamais.


4
Avec cela, vous n'empêchez pas de redémarrer l'activité chaque fois que la configuration d'orientation change.
AxeEffect

En outre, cela ne fonctionne pas si vous entrez l'activité d'une activité précédente en orientation paysage.
w3bshark

10

Dans le fichier AndroidManifest.xml, pour chaque activité que vous souhaitez verrouiller, ajoutez la dernière screenOrientationligne:

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

Ou android: screenOrientation = "paysage" .


8

Dans votre fichier androidmanifest.xml :

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

ou

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

6

Pour verrouiller l'écran par code, vous devez utiliser la rotation réelle de l'écran (0, 90, 180, 270) et vous devez connaître sa position naturelle, dans un smartphone la position naturelle sera portrait et dans une tablette, ce sera le paysage.

Voici le code (méthodes de verrouillage et de déverrouillage), il a été testé sur certains appareils (smartphones et tablettes) et il fonctionne très bien.

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

quel paramètre doit être adopté comme activité?
WISHY

Activité qui appelle la méthode pour verrouiller / déverrouiller son orientation. C'est une méthode d'utilité statique publique à appeler à partir de différentes activités.
PoOk

1
Fonctionne très bien, mais, sérieusement, Android, pourquoi devons-nous faire tout ce qui est juste pour l'orientation de l'écran de verrouillage? !!!
Cocorico

Oui. Celui-ci verrouille l'orientation comme nous le faisons dans le manifeste. Cela empêchera l'invocation de onConfigurationChanged. Existe-t-il une méthode qui verrouille l'interface utilisateur sur Paysage et invoque toujours onConfigurationChanged. Tout comme l'application appareil photo dans Android
Ajith Memana

Il existe un indicateur SCREEN_ORIENTATION_LOCKED sur le SDK 18+ qui semble fonctionner, mais vous voudrez toujours utiliser le code ci-dessus pour prendre en charge tous les appareils
DominicM

2

Dans Visual Studio Xamarin:

  1. Ajouter:

using Android.Content.PM; à votre liste d'espace de noms d'activité.

  1. Ajouter:

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

comme attribut à votre classe, comme ça:

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

Cette question concerne Android, pas Xamarin.Android
Trevor Hart

1

Ajouter

android:configChanges="keyboardHidden|orientation|screenSize" 

à votre manifeste.


à l'intérieur de votre balise <activité>
Ege Kuzubasioglu

0

Veuillez noter qu'aucune des méthodes ne semble fonctionner maintenant!

Dans Android Studio 1, une méthode simple consiste à ajouter android:screenOrientation="nosensor".

Cela verrouille efficacement l'orientation de l'écran.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.