Existe-t-il un moyen fiable de verrouiller l'orientation de l'écran sur tous les appareils Android? Le code ci-dessous fonctionne pour mon Nexus S et d'autres téléphones, mais pour une raison quelconque, ROTATION_90 correspond à SCREEN_ORIENTATION_REVERSE_PORTRAIT sur le Xoom.
Existe-t-il un moyen de mapper de manière fiable la rotation à l'orientation?
private void lockScreenOrientation() {
if (!mScreenOrientationLocked) {
final int orientation = getResources().getConfiguration().orientation;
final int rotation = getWindowManager().getDefaultDisplay().getOrientation();
if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
else if (rotation == Surface.ROTATION_180 || rotation == Surface.ROTATION_270) {
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
}
else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
}
mScreenOrientationLocked = true;
}
}
private void unlockScreenOrientation() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
mScreenOrientationLocked = false;
}
EDIT: Ce code est destiné à obtenir l'orientation actuelle et à la verrouiller. L'orientation est verrouillée temporairement, puis communiquée à l'utilisateur.
Voici ma solution, cela fonctionne sur les téléphones et les tablettes dans n'importe quel SDK Android SDK.
switch (getResources().getConfiguration().orientation){
case Configuration.ORIENTATION_PORTRAIT:
if(Android.os.Build.VERSION.SDK_INT < Android.os.Build.VERSION_CODES.FROYO){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
int rotation = getWindowManager().getDefaultDisplay().getRotation();
if(rotation == Android.view.Surface.ROTATION_90|| rotation == Android.view.Surface.ROTATION_180){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
break;
case Configuration.ORIENTATION_LANDSCAPE:
if(Android.os.Build.VERSION.SDK_INT < Android.os.Build.VERSION_CODES.FROYO){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
int rotation = getWindowManager().getDefaultDisplay().getRotation();
if(rotation == Android.view.Surface.ROTATION_0 || rotation == Android.view.Surface.ROTATION_90){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
}
break;
}
J'ai légèrement modifié les réponses du diyisme pour compenser le fait que vous ne pouvez pas utiliser les modes reverse_landscape et reverse_portrait avant la version 2.3
private static void disableRotation(Activity activity)
{
final int orientation = activity.getResources().getConfiguration().orientation;
final int rotation = activity.getWindowManager().getDefaultDisplay().getOrientation();
// Copied from Android docs, since we don't have these values in Froyo 2.2
int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8;
int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.FROYO)
{
SCREEN_ORIENTATION_REVERSE_LANDSCAPE = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
SCREEN_ORIENTATION_REVERSE_PORTRAIT = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90)
{
if (orientation == Configuration.ORIENTATION_PORTRAIT)
{
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
else if (orientation == Configuration.ORIENTATION_LANDSCAPE)
{
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
else if (rotation == Surface.ROTATION_180 || rotation == Surface.ROTATION_270)
{
if (orientation == Configuration.ORIENTATION_PORTRAIT)
{
activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_PORTRAIT);
}
else if (orientation == Configuration.ORIENTATION_LANDSCAPE)
{
activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
}
}
private static void enableRotation(Activity activity)
{
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
pour n verrouillage d'écran temporairement vous pouvez facilement utiliser:
//developing for Android tablets **<uses-sdk Android:minSdkVersion="12" />**
//works perfectly... **WATCH OUT**: look portrait to reverse-portrait on api level 13 :)
currentActivity.setRequestedOrientation(currentActivity.getResources().getConfiguration().orientation);
//to re-enable sensor, just do:
currentActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
utilisé pour un verrouillage de l'écran temporaire lors de l'affichage de la boîte de dialogue et de l'exécution d'un travail d'arrière-plan important.
assurez-vous que currentActivity est valide au moment où vous essayez d'y accéder, sinon cela ne fonctionnera pas :)
bonne chance:)
// Works on all devices. The other solution only works on 1/2 of the devices.
// Lock orientation
int rotation = getWindowManager().getDefaultDisplay().getRotation();
lockOrientation(rotation, Surface.ROTATION_270);
// Ensure that the rotation hasn't changed
if (getWindowManager().getDefaultDisplay().getRotation() != rotation) {
lockOrientation(rotation, Surface.ROTATION_90);
}
// ...
private void lockOrientation(int originalRotation, int naturalOppositeRotation) {
int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
// Are we reverse?
if (originalRotation == Surface.ROTATION_0 || originalRotation == naturalOppositeRotation) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
setReversePortrait();
}
} else {
// Are we reverse?
if (originalRotation == Surface.ROTATION_0 || originalRotation == naturalOppositeRotation) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
setReverseLandscape();
}
}
}
@SuppressLint("InlinedApi")
private void setReversePortrait() {
if (Build.VERSION.SDK_INT >= 9) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
@SuppressLint("InlinedApi")
private void setReverseLandscape() {
if (Build.VERSION.SDK_INT >= 9) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
Cette solution ne fait que s'appuyer sur d'autres. C'est une manière différente de gérer le problème enl8enmentnow abordé: sur certains appareils, le paysage est ROTATION_90
, Mais sur (quelques-uns) d'autres, c'est ROTATION_270
. Lorsque j'ai essayé quelque chose comme la solution d'enl8enmentnow sur un Kindle Fire HD 7 ", cela a fait pivoter l'écran à l'envers, puis immédiatement en arrière. Je n'ai vu aucune autre idée que de coder en dur les appareils qui considèrent le paysage comme étant 270, alors voici solution codée en dur:
public static void unlockOrientation() {
activity.setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
public static void lockOrientation() {
if (Build.VERSION.SDK_INT < 18) {
activity.setRequestedOrientation(getOrientation());
} else {
activity.setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_LOCKED);
}
}
private static int getOrientation() {
int port = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
int revP = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
int land = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
int revL = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
if (Build.VERSION.SDK_INT < 9) {
revL = land;
revP = port;
} else if (isLandscape270()) {
land = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
revL = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
}
Display display = activity.getWindowManager().getDefaultDisplay();
boolean wide = activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
switch (display.getRotation()) {
case Surface.ROTATION_0:
return wide ? land : port;
case Surface.ROTATION_90:
return wide ? land : revP;
case Surface.ROTATION_180:
return wide ? revL : revP;
case Surface.ROTATION_270:
return wide ? revL : port;
default:
throw new AssertionError();
}
}
private static boolean isLandscape270() {
return Android.os.Build.MANUFACTURER.equals("Amazon")
&& !(Android.os.Build.MODEL.equals("KFOT") || Android.os.Build.MODEL.equals("Kindle Fire"));
}
isLandscape270()
détecte si l'appareil est un Kindle de 2e génération ou version ultérieure (voir ce lien , obtenir le MODEL
de ce lien ) . Je ne sais pas si d'autres appareils devraient également être inclus; veuillez commenter si vous en connaissez.
De plus, sur les API> = 18, cela utilise simplement setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED)
. Je n'ai testé cela que sur des émulateurs; veuillez commenter s'il a des problèmes sur de vrais appareils.
Utilisez: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR)
car l'orientation est déterminée par un capteur d'orientation physique: l'affichage pivote en fonction de la façon dont l'utilisateur déplace l'appareil. Cela permet l'une des 4 rotations possibles, indépendamment de ce que l'appareil fera normalement (par exemple, certains appareils n'utilisent normalement pas une rotation à 180 degrés). Et votre code devrait également fonctionner sur Xoom ...
Vous pouvez déclarer une activité comme étant uniquement paysage ou portrait dans votre AndroidManifest.xml. Ajoutez simplement l'attribut screenOrientation à l'élément d'activité:
http://developer.Android.com/guide/topics/manifest/activity-element.html