Un certain nombre d'applications sont capables de forcer la rotation de l'écran. Ils fonctionnent même si une application souhaite explicitement être visualisée dans une autre orientation. En ce moment, je désactive le réglage du système de rotation de l’accéléromètre et mon orientation préférée. Une application peut toujours remplacer cela.
Voici l'une des applications pouvant annuler l'orientation demandée d'une application:
https://play.google.com/store/apps/details?id=nl.fameit.rotate&hl=fr
Cela peut être fait en créant un dialogue système caché. C'est une sorte de bidouille mais assez fou pour fonctionner.
wm = (WindowManager) content.getSystemService(Service.WINDOW_SERVICE);
orientationChanger = new LinearLayout(content);
orientationChanger.setClickable(false);
orientationChanger.setFocusable(false);
orientationChanger.setFocusableInTouchMode(false);
orientationChanger.setLongClickable(false);
orientationLayout = new WindowManager.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
windowType, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.RGBA_8888);
wm.addView(orientationChanger, orientationLayout);
orientationChanger.setVisibility(View.GONE);
orientationLayout.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
wm.updateViewLayout(orientationChanger, orientationLayout);
orientationChanger.setVisibility(View.VISIBLE);
J'ai essayé la réponse de kagronick mais je n'ai pas réussi à la faire fonctionner. Après avoir déconné un peu, je l'ai finalement fait fonctionner en utilisant une fenêtre de superposition système et en retirant les LayoutParams que je trouvais inutiles. Voici ma solution éventuelle:
orientationChanger = new LinearLayout(this);
// Using TYPE_SYSTEM_OVERLAY is crucial to make your window appear on top
// You'll need the permission Android.permission.SYSTEM_ALERT_WINDOW
WindowManager.LayoutParams orientationLayout = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 0, PixelFormat.RGBA_8888);
// Use whatever constant you need for your desired rotation
orientationLayout.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
WindowManager wm = (WindowManager) this.getSystemService(Service.WINDOW_SERVICE);
wm.addView(orientationChanger, orientationLayout);
orientationChanger.setVisibility(View.VISIBLE);
Vous pouvez voir mon succès dans l'application que j'ai publiée basée sur ceci: Force Dock Rotation .
Par ailleurs, vous pouvez également modifier globalement l'orientation de l'écran sans le forcer dans des applications non prises en charge. (Je sais que cette question concerne le dépassement des préférences des applications, mais cela reste utile et concerne principalement des informations pertinentes.)
Accorder l'accès à paramètres système (WRITE_SETTINGS
) dans AndroidManifest.xml
<uses-permission Android:name="Android.permission.WRITE_SETTINGS" />
Importer Settings
import Android.provider.Settings;
Assurer Rotation automatique de l'écran Android est désactivé
Settings.System.putInt(
getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION,
0
);
Réglez USER_ROTATION
sur le réglage souhaité, qui devrait être l’une des constantes ROTATION_
. Ces valeurs représentent les rotations d'écran à partir de l'orientation naturelle de l'appareil, qu'il s'agisse de paysage ou de portrait.
Settings.System.putInt(
getContentResolver(),
Settings.System.USER_ROTATION,
Surface.ROTATION_0 //Or a different ROTATION_ constant
);
Notez que les modifications apportées à USER_ROTATION
persistent même si votre application n'est pas en cours d'exécution ou est désinstallée. Si je me souviens bien, les utilisateurs peuvent réinitialiser cette valeur en désactivant et en activant manuellement la rotation automatique.
Créez une variable invisible View
qui s'affiche toujours au-dessus des autres applications. View
s peut spécifier ses propres préférences d'orientation. Ainsi, l'orientation de votre vue peut être utilisée pour remplacer les orientations des vues et des applications sous-jacentes.
Je connais quelques types de vues différents que vous pouvez utiliser pour y parvenir, chacun avec ses propres inconvénients.
Fenêtre Superposition système ( TYPE_SYSTEM_OVERLAY
)
Nécessite l'autorisation SYSTEM_ALERT_WINDOW
. (Ajoutez ce qui suit à AndroidManifest.xml .)
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW" />
Fenêtre Toast ( TYPE_TOAST
)
Aucune autorisation requise, sauf sur MIUI V8 .
N'affiche pas sur certains types de fenêtres, ainsi leurs orientations pourraient ne pas être affectées:
TYPE_PRIORITY_PHONE
)TYPE_DREAM
)TYPE_KEYGUARD_DIALOG
, TYPE_KEYGUARD_SCRIM
)View
.WindowManager.LayoutParams
. type
sur la valeur que vous avez choisie ci-dessus.width
et height
pour éviter les problèmes liés aux applications qui ne fonctionneront pas en cas de chevauchement. (Par exemple, Android ne vous laissera pas appuyer sur le bouton "OK" lorsque vous essayez d'activer un service d'accessibilité si une fenêtre se trouve en haut de celui-ci.)screenOrientation
sur n'importe laquelle valeur d'orientation vous voulez.public class ScreenOrientationEnforcer {
private final View view;
private final WindowManager windows;
public ScreenOrientationEnforcer(Context context) {
windows = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
view = new View(context);
}
public void start() {
WindowManager.LayoutParams layout = generateLayout();
windows.addView(view, layout);
view.setVisibility(View.VISIBLE);
}
public void stop() {
windows.removeView(view);
}
private WindowManager.LayoutParams generateLayout() {
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
//So we don't need a permission or activity
//Note that this won't work on some devices running MIUI
layoutParams.type = WindowManager.LayoutParams.TYPE_TOAST;
//Just in case the window type somehow doesn't enforce this
layoutParams.flags =
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
//Prevents breaking apps that detect overlying windows enabling
//(eg UBank app, or enabling an accessibility service)
layoutParams.width = 0;
layoutParams.height = 0;
//Try to make it completely invisible
layoutParams.format = PixelFormat.TRANSPARENT;
layoutParams.alpha = 0f;
//The orientation to force
layoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
return layoutParams;
}
}
ScreenOrientationEnforcer screenOrientationEnforcer
= new ScreenOrientationEnforcer(context);
//Force screen orientation
screenOrientationEnforcer.start();
//Stop forcing screen orientation
screenOrientationEnforcer.stop();
PhoneWindowManager.windowTypeToLayerLw
PhoneWindowManager.checkAddPermission