1. 程式人生 > >Android Activity螢幕旋轉方向完全控制

Android Activity螢幕旋轉方向完全控制

我們知道,系統提供了Android:configChanges="orientation" 清單檔案屬性以監聽螢幕旋轉,進而觸發onConfigurationChanged方法。

但這有時不能完全滿足我們的需求。比如典型的應用場景:視訊播放器的螢幕方向鎖功能。

下面貢獻螢幕旋轉完全控制類ActivityRotationController,解決一切螢幕旋轉問題。

  1. import android.app.Activity;  
  2. import android.content.ContentResolver;  
  3. import android.content.pm.ActivityInfo;  
  4. import android.provider.Settings;  
  5. import android.provider.Settings.SettingNotFoundException;  
  6. import android.view.OrientationEventListener;  
  7. /** 
  8.  * 該類可以對Activity旋轉和方向進行更加靈活的控制。 
  9.  * 注意,使用該類進行方向控制的Activity不要在清單檔案中新增: 
  10.  * android:configChanges="orientation"  
  11.  *  
  12.  * 典型的應用場景: 
  13.  * 視訊播放器的螢幕方向鎖功能。 
  14.  * 當鎖住螢幕方向後,Activity就不會隨著手機方向的旋轉而改變方向。一旦開啟鎖,Activity將會立即隨著螢幕的方向而改變。
     
  15.  *  
  16.  * 一般呼叫程式碼: 
  17.  *  
  18.  * 預設開啟鎖 
  19.  * ActivityRotationController controller=new ActivityRotationController(this); 
  20.  *  
  21.  * 開啟鎖 
  22.  * controller.openActivityRotation(); 
  23.  *  
  24.  * 關閉鎖 
  25.  * controller.closeActivityRotation(); 
  26.  *  
  27.  * 關閉監聽,恢復到系統之前旋轉設定 
  28.  * controller.disable() 
  29.  *  
  30.  * 要求的許可權 
  31.  * @permission android.permission.WRITE_SETTINGS
     
  32.  */
  33. publicclass ActivityRotationController extends OrientationEventListener {  
  34.     privateint systemRotation;  
  35.     privateboolean activityRotation;  
  36.     privateint activityOrientation;  
  37.     private Activity activity;  
  38.     public ActivityRotationController(Activity activity) {  
  39.         super(activity);  
  40.         this.activity = activity;  
  41.         activityOrientation = activity.getResources().getConfiguration().orientation;  
  42.         try {  
  43.             systemRotation = getScreenRotation(activity.getContentResolver());  
  44.         } catch (SettingNotFoundException e) {  
  45.             e.printStackTrace();  
  46.             systemRotation = -1;  
  47.         }  
  48.         openActivityRotation();  
  49.         enable();  
  50.     }  
  51.     /** 
  52.      * 開啟Activity旋轉。 
  53.      * 如果打開了螢幕旋轉,Activity將接收螢幕旋轉事件並執行onConfigurationChanged方法。 
  54.      */
  55.     publicvoid openActivityRotation() {  
  56.         activityRotation = true;  
  57.     }  
  58.     /** 
  59.      * 關閉Activity旋轉。 
  60.      * 無論是否開啟螢幕旋轉,Activity都不能接收到螢幕旋轉事件。 
  61.      */
  62.     publicvoid closeActivityRotation() {  
  63.         activityRotation = false;  
  64.     }  
  65.     /** 
  66.      * 檢查Activity能否旋轉 
  67.      */
  68.     publicboolean isActivityRotationEnabled() {  
  69.         return activityRotation;  
  70.     }  
  71.     /** 
  72.      * 獲取Activity當前方向。 
  73.      * 注意,Activity方向不是螢幕方向。只有開啟Activity旋轉,Activity方向才和螢幕方向保持一致。 
  74.      */
  75.     publicint getActivityOrientation() {  
  76.         return activityOrientation;  
  77.     }  
  78.     /** 
  79.      * 開啟對螢幕旋轉的監聽,並設定螢幕為可旋轉。 
  80.      */
  81.     @Override
  82.     publicvoid enable() {  
  83.         super.enable();  
  84.         setScreenRotation(activity.getContentResolver(), 0);  
  85.     }  
  86.     /** 
  87.      * 關閉對螢幕旋轉的監聽,並恢復到系統之前旋轉設定。 
  88.      */
  89.     @Override
  90.     publicvoid disable() {  
  91.         super.disable();  
  92.         if (systemRotation == -1) {  
  93.             return;  
  94.         }  
  95.         setScreenRotation(activity.getContentResolver(), systemRotation);  
  96.     }  
  97.     @Override
  98.     publicvoid onOrientationChanged(int orientation) {  
  99.         if (orientation < 0) {  
  100.             return;  
  101.         }  
  102.         int newOrientation= ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;  
  103.         if (orientation >= 0 && orientation <= 60) {  
  104.             newOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;  
  105.         }elseif (orientation >60 && orientation <120) {  
  106.             newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;  
  107.         }elseif (orientation >=120 && orientation <=240) {  
  108.             newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;  
  109.         }elseif (orientation >240 && orientation <300) {  
  110.             newOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;  
  111.         }elseif (orientation >=300 && orientation <=360) {  
  112.             newOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;  
  113.         }else{  
  114.             return;  
  115.         }  
  116.         if ((newOrientation != orientation) && activityRotation) {  
  117.             activity.setRequestedOrientation(newOrientation);  
  118.             activityOrientation = newOrientation;  
  119.         }  
  120.     }  
  121.     privatevoid setScreenRotation(ContentResolver cr, int rotation) {  
  122.         Settings.System.putInt(cr, Settings.System.ACCELEROMETER_ROTATION,  
  123.                 rotation);  
  124.     }  
  125.     privateint getScreenRotation(ContentResolver cr)  
  126.             throws SettingNotFoundException {  
  127.         return Settings.System.getInt(cr,  
  128.                 Settings.System.ACCELEROMETER_ROTATION);  
  129.     }  
  130. }  

作者:薄荷記賬  (轉載請註明原作者)