升级target version28后出现
java.lang.IllegalStateException: Only fullscreen activities can request orientation / Only fullscreen opaque activities can request orientation
安卓源码全局搜索该报错信息发现:
版本26的源码是这样晒的,
if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen
&& appInfo.targetSdkVersion > O) {
throw new IllegalStateException("Only fullscreen activities can request orientation");
}
版本27的源码是这样晒的:
if (ActivityInfo.isFixedOrientation(requestedOrientation) && !fullscreen
&& appInfo.targetSdkVersion >= O_MR1) {
throw new IllegalStateException("Only fullscreen activities can request orientation");
}
26和27源码是一样(其它版本源码没有这个错误),可以看出全部满足下面四个条件会报错:
1),Activity固定方向,无论是代码里还是清单文件里配置的
2),isTranslucentOrFloating(fullscreen = ent != null && !ActivityInfo.isTranslucentOrFloating(ent.array);)
public static boolean isTranslucentOrFloating(TypedArray attributes) {
final boolean isTranslucent =
attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent,
false);
final boolean isSwipeToDismiss = !attributes.hasValue(
com.android.internal.R.styleable.Window_windowIsTranslucent)
&& attributes.getBoolean(
com.android.internal.R.styleable.Window_windowSwipeToDismiss, false);
final boolean isFloating =
attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating,
false);
return isFloating || isTranslucent || isSwipeToDismiss;
}
3),targetSdkVersion > O
4),报错的手机为26或者27的安卓手机系统
对应上面的原因,只要让其中任一个条件不满足就可以了,所以有以下几种方法,任一条都可以:
1,修改Activity的android:screenOrientation portrait或landscape属性值为behind(表示和前一个Activity方向一致),或者去除设置方向的代码(如去除setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);)。
2,修改主题中的windowIsTranslucent、windowSwipeToDismiss、windowIsFloating等属性值,如
<item name="android:windowIsTranslucent">false</item>
3,将build.gradle中的targetSdkVersion降到26或以下。
4,添加针对8.0和8.1的系统的判断,满足上面任一条件也可以。
当然,网上也有人提供通过反射,修改其中的判断条件ActivityInfo的属性值screenOrientation为SCREEN_ORIENTATION_BEHIND、SCREEN_ORIENTATION_UNSPECIFIED等,本质也是针对上面四种条件的修改,但是个人不建议如此修改,因为不能保证你修改的地方系统其它地方不会用到(导致未知波及)。