Android4.1 Rotation 小结

本文详细介绍了Android 4.1中如何控制屏幕旋转,包括当开启或关闭“自动旋转屏幕”时的操作。关键在于`RotationPolicy`类的`setRotationLockForAccessibility`方法,它会调用`WindowManagerService`的`freezeRotation`或`thawRotation`。`freezeRotation`用于冻结屏幕到特定旋转角度,而`thawRotation`则解除旋转锁定。这些操作涉及权限设置及数据库更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1, 操作Android 辅助功能:
  •          获取启动时的旋转方向:
               -------> RotationPolicy.isRotationLocked()  : packages/apps/Settings/src/com/android/settings/AccessibilitySettings.java
                         ---->isRotationLocked()  : frameworks/base/core/java/com/android/internal/view/RotationPolicy.java
                                   ---->  Settings.System.ACCELEROMETER_ROTATION ----- 获取系统中的设置属性。
 61     /**
 62      * Returns true if rotation lock is enabled.
 63      */
 64     public static boolean isRotationLocked(Context context) {
 65         return Settings.System.getInt(context.getContentResolver(),
 66                 Settings.System.ACCELEROMETER_ROTATION, 0) == 0;
 67     }

  •         当  enable 或者 disable "Auto-rotate screen" 的时候
    •  RotationPolicy.setRotationLockForAccessibility()     :   packages/apps/Settings/src/com/android/settings/AccessibilitySettings.java
      • setRotationLockForAccessibility()   :   frameworks/base/core/java/com/android/internal/view/RotationPolicy.java
      • 102     public static void setRotationLockForAccessibility(Context context, final boolean enabled) {
        103         Settings.System.putInt(context.getContentResolver(),
        104                 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, enabled ? 1 : 0);
        105
        106         AsyncTask.execute(new Runnable() {
        107             @Override
        108             public void run() {
        109                 try {
        110                     IWindowManager wm = IWindowManager.Stub.asInterface(
        111                             ServiceManager.getService(Context.WINDOW_SERVICE));
        112                     if (enabled) {
        113                         wm.freezeRotation(Surface.ROTATION_0);
        114                     } else {
        115                         wm.thawRotation();
        116                     }
        117                 } catch (RemoteException exc) {
        118                     Log.w(TAG, "Unable to save auto-rotate setting");
        119                 }
        120             }
        121         });
        122     }

        • 如果enable: 调用WindowManagerService的freezeRotation()
        • 否则调用wm.thawRotation() ----- 即WindowManagerService的thawRotation()
      • freezeRotation()   ---------- frameworks/base/services/java/com/android/server/wm/WindowManagerService.java
        •  5663     /**
           5664      * Freeze rotation changes.  (Enable "rotation lock".)
           5665      * Persists across reboots.
           5666      * @param rotation The desired rotation to freeze to, or -1 to use the
           5667      * current rotation.
           5668      */
           5669     public void freezeRotation(int rotation) {
           5670         if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
           5671                 "freezeRotation()")) {
           5672             throw new SecurityException("Requires SET_ORIENTATION permission");
           5673         }
           5674         if (rotation < -1 || rotation > Surface.ROTATION_270) {
           5675             throw new IllegalArgumentException("Rotation argument must be -1 or a valid "
           5676                     + "rotation constant.");
           5677         }
           5678
           5679         if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
           5680
           5681         mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
           5682                 rotation == -1 ? mRotation : rotation);
           5683         updateRotationUnchecked(false, false);
           5684     

        • setUserRotationMode()  ------frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
        •    通过PhoneWindowManager.setUserRotationMode()去设置Settings.System相关的数据库值,在PhoneWindowManager中会有一个Observe去监听Settings.System的数值变化,如果有变动就去调用SettingsObserver.onChange()  .
        •  updateRotationUnchecked   -------   WindowManagerService.updateRotationUnchecked()

               


               分析: thawRotation()    ----------- 释放rotation ----- 无论什么时候都使能旋转:
                                   调用 setUserRotationMode()  -----mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
                    分析setUserRotationMode : 
 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) {
            Settings.System.putIntForUser(res,
                    Settings.System.USER_ROTATION,
                    rot,
                    UserHandle.USER_CURRENT);
            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);
        }
}



          ---------------- 也就是说,如果在启动系统之前,调用thawrotation(), 就是强制地执行Settings.System.ACCELEROMETER_ROTATION;这样系统就会一直默认旋转。
     以前遇到有一个问题:在系统启动时,强制打开系统旋转,这样在辅助功能的设置就会无效,正是这个原因。
 
    private final class BootCompletedReceiver extends BroadcastReceiver {
      @Override
      public void onReceive(Context context, Intent intent) {
        // At any given time accessories could be inserted
        // one on the board, one on the dock and one on HDMI:
        // observe three UEVENTs
        init();  // set initial status
   /*     try{
          IWindowManager wm = IWindowManager.Stub.asInterface(
                        ServiceManager.getService(Context.WINDOW_SERVICE));
          wm.thawRotation();
        }catch(Exception e){

        }*/
        for (int i = 0; i < uEventInfo.size(); ++i) {
            UEventInfo uei = uEventInfo.get(i);
            startObserving("DEVPATH="+uei.getDevPath());
        }
      }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值