1.Activity.setRequestedOrientation (int requestedOrientation)。
2.getResources().getConfiguration().orientation;
![]()
int getCurentOrientation() {
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int rotation =
display.getRotation();
boolean isWide = display.getWidth() >= display.getHeight();
switch (rotation) {
case Surface.ROTATION_0:
return isWide ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
case Surface.ROTATION_90:
return isWide ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
: ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
case Surface.ROTATION_180:
return isWide ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
: ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
case Surface.ROTATION_270:
return isWide ? ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
return -1;
}
3.Settings.java
![]()
class Settings {
...
/**
* Control whether the accelerometer will be used to change screen
* orientation. If 0, it will not be used unless explicitly requested
* by the application; if 1, it will be used by default unless explicitly
* disabled by the application.
*/
public static final String ACCELEROMETER_ROTATION = "
accelerometer_rotation";
DisplaySettings.java
![]()
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (preference == mAccelerometer) {
RotationPolicy.setRotationLockForAccessibility(
getActivity(), !mAccelerometer.isChecked());
...
RotationPolicy.java
![]()
/**
* Enables or disables rotation lock.
*
* Should be used by the rotation lock toggle.
*/
public static void setRotationLock(Context context,
final boolean enabled) {
Settings.System.putIntForUser(context.getContentResolver(),
Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0,
UserHandle.USER_CURRENT);
AsyncTask.execute(
new Runnable() {
@Override
public void run() {
try {
IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
if (enabled) {
wm.freezeRotation(-1);
}
else {
wm.thawRotation();
}
}
catch (RemoteException exc) {
Log.w(TAG, "
Unable to save auto-rotate setting");
}
}
});
}
/**
* Enables or disables rotation lock and adjusts whether the rotation lock toggle
* should be hidden for accessibility purposes.
*
* Should be used by Display settings and Accessibility settings.
*/
public static void setRotationLockForAccessibility(Context context,
final boolean enabled) {
Settings.System.putIntForUser(context.getContentResolver(),
Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, enabled ? 1 : 0,
UserHandle.USER_CURRENT);
AsyncTask.execute(
new Runnable() {
@Override
public void run() {
try {
IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
if (enabled) {
wm.freezeRotation(Surface.ROTATION_0);
}
else {
wm.thawRotation();
}
}
catch (RemoteException exc) {
Log.w(TAG, "
Unable to save auto-rotate setting");
}
}
});
}
WindowManagerService.java
![]()
/**
* Freeze rotation changes. (Enable "rotation lock".)
* Persists across reboots.
* @param rotation The desired rotation to freeze to, or -1 to use the
* current rotation.
*/
@Override
public void freezeRotation(
int rotation) {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
"
freezeRotation()")) {
throw new SecurityException("
Requires SET_ORIENTATION permission");
}
if (rotation < -1 || rotation > Surface.ROTATION_270) {
throw new IllegalArgumentException("
Rotation argument must be -1 or a valid "
+ "
rotation constant.");
}
if (DEBUG_ORIENTATION) Slog.v(TAG, "
freezeRotation: mRotation=" + mRotation);
long origId = Binder.clearCallingIdentity();
try {
mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
rotation == -1 ? mRotation : rotation);
}
finally {
Binder.restoreCallingIdentity(origId);
}
updateRotationUnchecked(
false,
false);
}
/**
* Thaw rotation changes. (Disable "rotation lock".)
* Persists across reboots.
*/
@Override
public void thawRotation() {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
"
thawRotation()")) {
throw new SecurityException("
Requires SET_ORIENTATION permission");
}
if (DEBUG_ORIENTATION) Slog.v(TAG, "
thawRotation: mRotation=" + mRotation);
long origId = Binder.clearCallingIdentity();
try {
mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE,
777);
// rot not used
}
finally {
Binder.restoreCallingIdentity(origId);
}
updateRotationUnchecked(
false,
false);
}
WindowManagerGlobal.java
![]()
class WindowManagerGlobal {
...
public static IWindowManager getWindowManagerService() {
synchronized (WindowManagerGlobal.
class) {
if (sWindowManagerService ==
null) {
sWindowManagerService = IWindowManager.Stub.asInterface(
ServiceManager.getService("
window"));
}
return sWindowManagerService;
}
}
老的Android系统过程间的转换可参考Android4.0 状态栏添加屏幕锁定按钮和Android4.1 关于Rotation相关的Configuration整体分析。
![]()
try {
IWindowManager mWindowManagerService = IWindowManager.Stub.asInterface(ServiceManager.getService("
window"));
classType = Class.forName("
android.view.IWindowManager");
Method freezeRotation = classType.getDeclaredMethod("
freezeRotation",
new Class[]{Integer.TYPE});
freezeRotation,setAccessible(
true);
freezeRotation.invoke(mWindowManagerService,
new Object[]{
Surface.ROTATION_0 });
Method thawRotation = classType.getDeclaredMethod("
thawRotation",
null);
thawRotation,setAccessible(
true);
freezeRotation.invoke(mWindowManagerService,
null);
}
catch (NoSuchMethodException x) {
}
catch (IllegalAccessException x) {
}
catch (InvocationTargetException x) {
}
catch (IllegalArgumentException x) {
}
catch (NoSuchFieldException x) {
}
【注】Java反射请参考The Reflection API
其它:Android模拟器横竖屏切换快捷键:
KEYPAD_7, Ctrl-F11 --- 切换到上个布局方向
KEYPAD_9, Ctrl-F12 --- 切换到下个布局方向