Only fullscreen activities can request orientation 解決方法


google出於安全的考慮,對android8.0以后的版本做的處理,當一個Activity固定方向並且是透明的,在8.0以后的版本中就會拋出異常:

     java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation

異常拋出條件如下:

    ActivityInfo.isFixedOrientation(requestedOrientation) —— 表示判斷當前的|Activity是否固定了方向

    fullscreen —— 表示Activity是否是透明的或者是否懸浮在Activity上,是透明的或者懸浮在Activity上fullscreen就等於false

    appInfo.targetSdkVersion >= O —— 表示版本號大於等於26

解決方法

  1. 利用反射,修改mActivityInfo中的變量screenOrientation,設置成SCREEN_ORIENTATION_UNSPECIFIED
  2. override setRequestedOrientation方法,直接return
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
            boolean result = fixOrientation();
            XLog.i(XLog.BASE, "onCreate fixOrientation when Oreo, result = " + result);
        }
        super.onCreate(savedInstanceState);
    }
 

    @Override
    public void setRequestedOrientation(int requestedOrientation) {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
            XLog.i(XLog.BASE, "avoid calling setRequestedOrientation when Oreo.");
            return;
        }
        super.setRequestedOrientation(requestedOrientation);
    }


    private boolean isTranslucentOrFloating(){
        boolean isTranslucentOrFloating = false;
        try {
            int [] styleableRes = (int[]) Class.forName("com.android.internal.R$styleable").getField("Window").get(null);
            final TypedArray ta = obtainStyledAttributes(styleableRes);
            Method m = ActivityInfo.class.getMethod("isTranslucentOrFloating", TypedArray.class);
            m.setAccessible(true);
            isTranslucentOrFloating = (boolean)m.invoke(null, ta);
            m.setAccessible(false);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return isTranslucentOrFloating;
    }

    private boolean fixOrientation(){
        try {
            Field field = Activity.class.getDeclaredField("mActivityInfo");
            field.setAccessible(true);
            ActivityInfo o = (ActivityInfo)field.get(this);
            o.screenOrientation = -1;
            field.setAccessible(false);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM