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?

Vidar Vestnes
la source

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).

Intrications
la source
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);
}
ubershmekel
la source
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"
m00sey
la source
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.

Dmitry Zaytsev
la source
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
20

Utilisez ceci..

    android:screenOrientation="portrait"
Muhammad Aamir Ali
la source
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.

Numenor
la source
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" .

Gil Allen
la source
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);
}
Jorgesys
la source
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);
}
PoOk
la source
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
{...}
Roy Doron
la source
Cette question concerne Android, pas Xamarin.Android
Trevor Hart
1

Ajouter

android:configChanges="keyboardHidden|orientation|screenSize" 

à votre manifeste.

saurabh
la source
à 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.

képhalien
la source