Android8.0注意事项

报Only fullscreen opaque activities can request orientation异常

 


  

原因:在 8.0系统中,targetSdkVersion > 26,透明 Activity 不能设置方向

if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen && 
    appInfo.targetSdkVersion > O) {
	   throw new IllegalStateException("Only fullscreen activities can request orientation");
}

1、ActivityInfo.isFixedOrientation(requestedOrientation)
表示判断当前的 Activity是否固定了方向,true为固定了方向。
2、fullscreen 表示Activity是否是透明的或者是否悬浮在Activity上。以下三种情况fullscreen为false
(1)“windowIsTranslucent” 为 true;
(2)“windowIsTranslucent” 为 false,但“windowSwipeToDismiss” 为 true;
(3)“windowIsFloating“ 为 true;
3、appInfo.targetSdkVersion > O 表示编译版本号大于26

解决:

方法一:透明主体的activity删除android:screenOrientation="sensorPortrait"

方法二:通过代码方式禁止透明主体固定方向操作

1、判断是否为透明主题

2、透明主题则设置屏幕方向为不固定方式

3、重写设置屏幕方法,对于透明主题不执行相关设置

package com.lpf.base.activity;

import androidx.appcompat.app.AppCompatActivity;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.content.res.TypedArray;
import android.os.Build;
import android.os.Bundle;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class BaseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
            fixOrientation();
        }
        super.onCreate(savedInstanceState);
    }

    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;
    }

    @Override
    public void setRequestedOrientation(int requestedOrientation) {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O && isTranslucentOrFloating()) {
            return;
        }
        super.setRequestedOrientation(requestedOrientation);
    }
}

你可能感兴趣的:(android8.0)