通过adb shell 查看加速度计开启情况
//0:不支持旋转 1:支持旋转
adb shell settings get system accelerometer_rotation
通过adb shell 设定加速度计关闭与开启
//0:不支持旋转 1:支持旋转
adb shell settings put system accelerometer_rotation 0
通过adb shell 查看指定的屏幕旋转方向
//0:0度 1:90度 2:180度 3:270度
adb shell settings get system user_rotation
通过adb shell 更改指定的屏幕旋转方向
//0:0度 1:90度 2:180度 3:270度
adb shell settings put system user_rotation 0
屏幕属性:
路径:frameworks\base\core\java\android\content\pm\ActivityInfo.java
/** @hide */
@IntDef({
SCREEN_ORIENTATION_UNSPECIFIED,//系统自动选择合适方向
SCREEN_ORIENTATION_LANDSCAPE,//正向横屏,显示的宽比高长(锁死为横屏方向,不再让方向感应起作用)
SCREEN_ORIENTATION_PORTRAIT,//正向竖屏,显示的高比宽长(锁死为竖屏方向,不再让方向感应起作用)
SCREEN_ORIENTATION_USER,//用户当前首选的方向
SCREEN_ORIENTATION_BEHIND,//Activity堆栈中的下面一个Activity的方向一致
SCREEN_ORIENTATION_SENSOR,//开启方向传感器计算方向,忽略用户强制设定
SCREEN_ORIENTATION_NOSENSOR,//关闭方向传感器
SCREEN_ORIENTATION_SENSOR_LANDSCAPE,//开启方向传感器计算方向,只切换正反横向,忽略用户强制设定
SCREEN_ORIENTATION_SENSOR_PORTRAIT,//开启方向传感器计算方向,只切换正反竖向,忽略用户强制设定
SCREEN_ORIENTATION_REVERSE_LANDSCAPE,//反向横屏
SCREEN_ORIENTATION_REVERSE_PORTRAIT,//反向竖屏
SCREEN_ORIENTATION_FULL_SENSOR,//支持在四个方向旋转,即使设备在某个方向上不适用旋转
SCREEN_ORIENTATION_USER_LANDSCAPE,
SCREEN_ORIENTATION_USER_PORTRAIT,
SCREEN_ORIENTATION_FULL_USER,
SCREEN_ORIENTATION_LOCKED
})
@Retention(RetentionPolicy.SOURCE)
public @interface ScreenOrientation {}
/**
* Constant corresponding to <code>unspecified</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_UNSPECIFIED = -1;
/**
* Constant corresponding to <code>landscape</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_LANDSCAPE = 0;
/**
* Constant corresponding to <code>portrait</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_PORTRAIT = 1;
/**
* Constant corresponding to <code>user</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_USER = 2;
/**
* Constant corresponding to <code>behind</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_BEHIND = 3;
/**
* Constant corresponding to <code>sensor</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_SENSOR = 4;
/**
* Constant corresponding to <code>nosensor</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_NOSENSOR = 5;
/**
* Constant corresponding to <code>sensorLandscape</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_SENSOR_LANDSCAPE = 6;
/**
* Constant corresponding to <code>sensorPortrait</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_SENSOR_PORTRAIT = 7;
/**
* Constant corresponding to <code>reverseLandscape</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8;
/**
* Constant corresponding to <code>reversePortrait</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9;
/**
* Constant corresponding to <code>fullSensor</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_FULL_SENSOR = 10;
/**
* Constant corresponding to <code>userLandscape</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_USER_LANDSCAPE = 11;
/**
* Constant corresponding to <code>userPortrait</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_USER_PORTRAIT = 12;
/**
* Constant corresponding to <code>fullUser</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_FULL_USER = 13;
/**
* Constant corresponding to <code>locked</code> in
* the {@link android.R.attr#screenOrientation} attribute.
*/
public static final int SCREEN_ORIENTATION_LOCKED = 14;
/**
* The preferred screen orientation this activity would like to run in.
* From the {@link android.R.attr#screenOrientation} attribute, one of
* {@link #SCREEN_ORIENTATION_UNSPECIFIED},
* {@link #SCREEN_ORIENTATION_LANDSCAPE},
* {@link #SCREEN_ORIENTATION_PORTRAIT},
* {@link #SCREEN_ORIENTATION_USER},
* {@link #SCREEN_ORIENTATION_BEHIND},
* {@link #SCREEN_ORIENTATION_SENSOR},
* {@link #SCREEN_ORIENTATION_NOSENSOR},
* {@link #SCREEN_ORIENTATION_SENSOR_LANDSCAPE},
* {@link #SCREEN_ORIENTATION_SENSOR_PORTRAIT},
* {@link #SCREEN_ORIENTATION_REVERSE_LANDSCAPE},
* {@link #SCREEN_ORIENTATION_REVERSE_PORTRAIT},
* {@link #SCREEN_ORIENTATION_FULL_SENSOR},
* {@link #SCREEN_ORIENTATION_USER_LANDSCAPE},
* {@link #SCREEN_ORIENTATION_USER_PORTRAIT},
* {@link #SCREEN_ORIENTATION_FULL_USER},
* {@link #SCREEN_ORIENTATION_LOCKED},
*/
@ScreenOrientation
public int screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
双屏属性:
ro.same.orientation=false 主屏与副屏方向是否相同
ro.rotation.external=false 副屏是否随主屏旋转
ro.sf.hwrotation=0 主屏初始方向
ro.orientation.einit=90 副屏初始方向
一. 固定横屏或者竖屏
1.通过system.prop 系统属性进行修改
路径:device\rockchip\rk3288\system.prop
//控制开机动画是否旋转true:旋转 false:不旋转
ro.sf.fakerotation=false
//0:横屏 90:竖屏
ro.sf.hwrotation=90
二. Sensor如何控制屏幕自动旋转
1.Settings -> Display 中有When device is rotated 选项用来控制是否开启自动旋转
路径:packages\apps\Settings\res\values\strings.xml
<string name="display_auto_rotate_title">When device is rotated</string>
<!-- [CHAR LIMIT=70] Rotate when screen is turned option -->
<string name="display_auto_rotate_rotate">Rotate the contents of the screen</string>
2.对应布局在Display_settings.xml 中(其实rk3288 android7.1.2并没有添加自动旋转开关布局)
<com.android.settings.DropDownPreference
android:key="auto_rotate"
android:title="@string/display_auto_rotate_title" />
3.java层调用
路径:packages\apps\Settings\src\com\android\settings\DisplaySettings.java
private static final String KEY_AUTO_ROTATE = "auto_rotate";
if (RotationPolicy.isRotationLockToggleVisible(activity)) {
DropDownPreference rotatePreference =
(DropDownPreference) findPreference(KEY_AUTO_ROTATE);
int rotateLockedResourceId;
// The following block sets the string used when rotation is locked.
// If the device locks specifically to portrait or landscape (rather than current
// rotation), then we use a different string to include this information.
if (allowAllRotations(activity)) {
rotateLockedResourceId = R.string.display_auto_rotate_stay_in_current;
} else {
if (RotationPolicy.getRotationLockOrientation(activity)
== Configuration.ORIENTATION_PORTRAIT) {
rotateLockedResourceId =
R.string.display_auto_rotate_stay_in_portrait;
} else {
rotateLockedResourceId =
R.string.display_auto_rotate_stay_in_landscape;
}
}
rotatePreference.setEntries(new CharSequence[] {
activity.getString(R.string.display_auto_rotate_rotate),
activity.getString(rotateLockedResourceId),
});
rotatePreference.setEntryValues(new CharSequence[] { "0", "1" });
rotatePreference.setValueIndex(RotationPolicy.isRotationLocked(activity) ?
1 : 0);
rotatePreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean locked = Integer.parseInt((String) newValue) != 0;
MetricsLogger.action(getActivity(), MetricsEvent.ACTION_ROTATION_LOCK,
locked);
RotationPolicy.setRotationLock(activity, locked);
return true;
}
});
} else {
removePreference(KEY_AUTO_ROTATE);
}
rotatePreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean locked = Integer.parseInt((String) newValue) != 0;
MetricsLogger.action(getActivity(), MetricsEvent.ACTION_ROTATION_LOCK,
locked);
RotationPolicy.setRotationLock(activity, locked);
return true;
}
});
4.继续调用:setRotationLock() ,当enable auto_rotate 则调用wm.freezeRotation(rotation); disable auto_rotate 则调用wm.thawRotation();
路径:frameworks\base\core\java\com\android\internal\view\RotationPolicy.java
/**
* Enables or disables natural rotation lock from Accessibility settings.
*
* If rotation is locked for accessibility, the system UI toggle is hidden to avoid confusion.
* 自动旋转屏幕,打开为1,关闭为0,默认为0
* adb shell settings get system hide_rotation_lock_toggle_for_accessibility 0
*/
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);
setRotationLock(enabled, NATURAL_ROTATION);
}
private static boolean areAllRotationsAllowed(Context context) {
return context.getResources().getBoolean(R.bool.config_allowAllRotations);
}
private static void setRotationLock(final boolean enabled, final int rotation) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
try {
IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
if (enabled) {
wm.freezeRotation(rotation);
} else {
wm.thawRotation();
}
} catch (RemoteException exc) {
Log.w(TAG, "Unable to save auto-rotate setting");
}
}
});
}
5.Sensor开启enable auto_rotate 调用 wm.freezeRotation(rotation);
路径:frameworks\base\services\core\java\com\android\server\wm\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_30) {
throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
+ "rotation constant.");
}
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "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);
}
6.通过调用PhoneWindowManager.cpp 中的setUserRotationMode()去设置Settings.System相关的数据库值。
1)用户通过界面设定屏幕选装方向USER_ROTATION = rot
Settings.System.putIntForUser(res,Settings.System.USER_ROTATION,rot,UserHandle.USER_CURRENT);
2)是否开启加速度计自动调整方向 ACCELEROMETER_ROTATION = 0 默认关闭
Settings.System.putIntForUser(res,Settings.System.ACCELEROMETER_ROTATION, 0,UserHandle.USER_CURRENT);
路径:frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java
// User rotation: to be used when all else fails in assigning an orientation to the device
@Override
public void setUserRotationMode(int mode, int rot) {
ContentResolver res = mContext.getContentResolver();
// mUserRotationMode and mUserRotation will be assigned by the content observer
if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
//用户通过界面设定屏幕选装方向USER_ROTATION = rot
Settings.System.putIntForUser(res,
Settings.System.USER_ROTATION,
rot,
UserHandle.USER_CURRENT);
//是否开启加速度计自动调整方向 ACCELEROMETER_ROTATION = 0 默认关闭
Settings.System.putIntForUser(res,
Settings.System.ACCELEROMETER_ROTATION,
0,
UserHandle.USER_CURRENT);
} else {
Settings.System.putIntForUser(res,
Settings.System.ACCELEROMETER_ROTATION,
1,
UserHandle.USER_CURRENT);
}
}
启用监听器Observe去监听Settings.System的数值变化,如果有变动就去调用SettingsObserver.onChange()。同时updateSettings() 会读取屏幕设定,一旦打开自动旋转按钮,就开始调用updateOrientationListenerLp();
读取sensor 数据。
路径:frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java
class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler) {
super(handler);
}
void observe() {
// Observe all users' changes
ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.END_BUTTON_BEHAVIOR), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.WAKE_GESTURE_ENABLED), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.ACCELEROMETER_ROTATION), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.USER_ROTATION), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.POINTER_LOCATION), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.DEFAULT_INPUT_METHOD), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS), false, this,
UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.POLICY_CONTROL), false, this,
UserHandle.USER_ALL);
updateSettings();
}
// this method is added for shutdown animation.
public void unRegister() {
ContentResolver resolver = mContext.getContentResolver();
resolver.unregisterContentObserver(this);
}
@Override public void onChange(boolean selfChange) {
updateSettings();
updateRotation(false);
}
}
public void updateSettings() {
ContentResolver resolver = mContext.getContentResolver();
boolean updateRotation = false;
synchronized (mLock) {
mEndcallBehavior = Settings.System.getIntForUser(resolver,
Settings.System.END_BUTTON_BEHAVIOR,
Settings.System.END_BUTTON_BEHAVIOR_DEFAULT,
UserHandle.USER_CURRENT);
mIncallPowerBehavior = Settings.Secure.getIntForUser(resolver,
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT,
UserHandle.USER_CURRENT);
mIncallBackBehavior = Settings.Secure.getIntForUser(resolver,
Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR,
Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR_DEFAULT,
UserHandle.USER_CURRENT);
// Configure wake gesture.
boolean wakeGestureEnabledSetting = Settings.Secure.getIntForUser(resolver,
Settings.Secure.WAKE_GESTURE_ENABLED, 0,
UserHandle.USER_CURRENT) != 0;
if (mWakeGestureEnabledSetting != wakeGestureEnabledSetting) {
mWakeGestureEnabledSetting = wakeGestureEnabledSetting;
updateWakeGestureListenerLp();
}
// Configure rotation lock.
int userRotation = Settings.System.getIntForUser(resolver,
Settings.System.USER_ROTATION, Surface.ROTATION_0,