Android 一种用于临时打开和关闭屏幕自动旋转的方法

这种方法的前提是你需要能编译Android framework。如果不能,可以试试 这个

其实在frameworks/base/services/java/com/android/server/wm/WindowManagerService.java中有下面两个方法:

    /**
     * Temporarily pauses rotation changes until resumed.
     *
     * This can be used to prevent rotation changes from occurring while the user is
     * performing certain operations, such as drag and drop.
     *
     * This call nests and must be matched by an equal number of calls to
     * {@link #resumeRotationLocked}.
     */
    void pauseRotationLocked() {
        mDeferredRotationPauseCount += 1;
    }
    /**
     * Resumes normal rotation changes after being paused.
     */
    void resumeRotationLocked() {
        if (mDeferredRotationPauseCount > 0) {
            mDeferredRotationPauseCount -= 1;
            if (mDeferredRotationPauseCount == 0) {
                boolean changed = updateRotationUncheckedLocked(false);
                if (changed) {
                    mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
                }
            }
        }
    }

代码注释很清楚的说明了这两个方法的功能,但是这两个方法的访问权限并没有把他们提供给外界。

我们在这里添加两个自己的方法:

    public void myPauseRotationLocked() {
        pauseRotationLocked();
    }
    public void myResumeRotationLocked() {
        resumeRotationLocked();
    }

WindowsManagerService通过AIDL与外界通信,这里我们需要添加AIDL接口定义。 在framework/base/core/java/android/view/IWindowManager.aidl中添加两个接口:

void myPauseRotationLocked();
void myResumeRotationLocked()

我们希望最后能通过getSystemService(Context.WINDOW_SERVICE)的方式来方便的调取这两个方法,所以我们还需要做一些事情。 首先在framework/core/java/android/view/WindowManagerGlobal.java中加入:

     public void myPauseRotationLocked() {
         try {
             sWindowManagerService.myPauseRotationLocked();
         } catch (RemoteException e) {
             Log.e(TAG, "myPauseRotationLocked ERROR!", e);
         }
     }
 
     public void myResumeRotationLocked() {
         try {
             sWindowManagerService.myResumeRotationLocked();
         } catch(RemoteException e) {
             Log.e(TAG, "myPauseRotationLocked ERROR!", e);
         }
     }

这里的sWindowManagerService为IWindowManager的实例。

然后在framework/basecore/java/android/view/WindowManager.java中加入:

public void myPauseRotationLocked();
public void myResumeRotationLocked();

WindowManager的具体实现在: framework/base/core/java/android/view/WindowManagerImpl.java 添加下面两个方法:

      @Override
      public void myPauseRotationLocked() {
          mGlobal.myPauseRotationLocked();
      }
  
     @Override
      public void myResumeRotationLocked() {
         mGlobal.myReresumeRotationLocked();
     }

查看一下mGlobal的类型为WindowManagerGlobal。

至此,大部分工作都已经完成了,由于我们这里变更了framework的API,所以需要

make update-api

最后编译android framework和service即大功告成 !

使用方法

WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
//关闭自动旋转
wm.myPauseRotationLocked();

//打开自动旋转
wm.myResumeRotationLocked();

特别注意这两个方法需要成对使用,否则容易造成状态混乱。