前言
在8.0以上在AndroidManifest.xml 设置 android:screenOrientation=“landscape” 以后就崩溃,报了 Only fullscreen activities can request orientation. 报错代码如下,现在通过反射来解决此问题,具体功能如下:
public class ActivityHook {
/**
* java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
* <p>
* 修复android 8.0存在的问题
* <p>
* 在Activity中onCreate()中super之前调用
*
* @param activity
*/
public static void hookOrientation(Activity activity) {
//目标版本8.0及其以上
if (activity.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) {
if (isTranslucentOrFloating(activity)) {
fixOrientation(activity);
}
}
}
/**
* 设置屏幕不固定,绕过检查
*
* @param activity
*/
private static void fixOrientation(Activity activity) {
try {
Class<Activity> activityClass = Activity.class;
Field mActivityInfoField = activityClass.getDeclaredField("mActivityInfo");
mActivityInfoField.setAccessible(true);
ActivityInfo activityInfo = (ActivityInfo) mActivityInfoField.get(activity);
//设置屏幕不固定
activityInfo.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 检查屏幕 横竖屏或者锁定就是固定
*
* @param activity
* @return
*/
private static boolean isTranslucentOrFloating(Activity activity) {
boolean isTranslucentOrFloating = false;
try {
Class<?> styleableClass = Class.forName("com.android.internal.R$styleable");
Field WindowField = styleableClass.getDeclaredField("Window");
WindowField.setAccessible(true);
int[] styleableRes = (int[]) WindowField.get(null);
//先获取到TypedArray
final TypedArray typedArray = activity.obtainStyledAttributes(styleableRes);
Class<?> ActivityInfoClass = ActivityInfo.class;
//调用检查是否屏幕旋转
Method isTranslucentOrFloatingMethod = ActivityInfoClass.getDeclaredMethod("isTranslucentOrFloating", TypedArray.class);
isTranslucentOrFloatingMethod.setAccessible(true);
isTranslucentOrFloating = (boolean) isTranslucentOrFloatingMethod.invoke(null, typedArray);
} catch (Exception e) {
e.printStackTrace();
}
return isTranslucentOrFloating;
}
public static void convertActivityFromTranslucent(Activity activity) {
try {
Method method = Activity.class.getDeclaredMethod("convertFromTranslucent");
method.setAccessible(true);
method.invoke(activity);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
2.在Acitivity中的应用
@Override
protected void onCreate(Bundle savedInstanceState) {
ActivityHook.hookOrientation(this);//hook,绕过检查
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 26) {
ActivityHook.convertActivityFromTranslucent(this);
}
setContentView(R.layout.activity_welcome);
}