如何在Android中全局强制屏幕定向?
有许多应用程序能够强制屏幕旋转。即使应用程序明确希望以另一个方向查看,它们也可以工作。现在我正在禁用加速计旋转系统设置并设置我的首选方向。应用程序仍然可以覆盖此功能 以下是一个能够覆盖应用程序请求方向的应用程序:如何在Android中全局强制屏幕定向?,android,android-layout,orientation,Android,Android Layout,Orientation,有许多应用程序能够强制屏幕旋转。即使应用程序明确希望以另一个方向查看,它们也可以工作。现在我正在禁用加速计旋转系统设置并设置我的首选方向。应用程序仍然可以覆盖此功能 以下是一个能够覆盖应用程序请求方向的应用程序: 这可以通过创建一个隐藏的系统对话框来完成。这有点像黑客,但它已经疯狂到可以工作了 wm = (WindowManager) content.getSystemService(Service.WINDOW_SERVICE); orientationChanger = n
这可以通过创建一个隐藏的系统对话框来完成。这有点像黑客,但它已经疯狂到可以工作了
wm = (WindowManager) content.getSystemService(Service.WINDOW_SERVICE);
orientationChanger = new LinearLayout(content);
orientationChanger.setClickable(false);
orientationChanger.setFocusable(false);
orientationChanger.setFocusableInTouchMode(false);
orientationChanger.setLongClickable(false);
orientationLayout = new WindowManager.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
windowType, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.RGBA_8888);
wm.addView(orientationChanger, orientationLayout);
orientationChanger.setVisibility(View.GONE);
orientationLayout.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
wm.updateViewLayout(orientationChanger, orientationLayout);
orientationChanger.setVisibility(View.VISIBLE);
我试过卡格罗尼克的答案,但没能成功。在混乱了一段时间后,我最终通过使用系统覆盖窗口和删除我发现都不必要的LayoutParams使它工作起来。以下是我的最终解决方案:
orientationChanger = new LinearLayout(this);
// Using TYPE_SYSTEM_OVERLAY is crucial to make your window appear on top
// You'll need the permission android.permission.SYSTEM_ALERT_WINDOW
WindowManager.LayoutParams orientationLayout = new WindowManager.LayoutParams(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, 0, PixelFormat.RGBA_8888);
// Use whatever constant you need for your desired rotation
orientationLayout.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
WindowManager wm = (WindowManager) this.getSystemService(Service.WINDOW_SERVICE);
wm.addView(orientationChanger, orientationLayout);
orientationChanger.setVisibility(View.VISIBLE);
你可以在我基于此发布的应用程序中看到我的成功:。另外,你还可以全局更改屏幕方向,而无需在不受支持的应用程序中强制更改屏幕方向。(我知道这个问题是关于覆盖应用程序的首选项的,但这仍然是有用的,而且主要是相关的信息。)
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
Settings.System.putInt(
getContentResolver(),
Settings.System.ACCELEROMETER_ROTATION,
0
);
Settings.System.putInt(
getContentResolver(),
Settings.System.USER_ROTATION,
Surface.ROTATION_0 //Or a different ROTATION_ constant
);
- 根据我的经验,如果你的应用程序崩溃或被杀死,这个视图可能会一直存在。重启设备似乎可以解决这个问题
- 窗口类型和z顺序之间的映射:
- 每种窗口类型所需的权限:
windowType=LayoutParams.TYPE\u APPLICATION\u OVERLAY
:)
Settings.System.putInt(
getContentResolver(),
Settings.System.USER_ROTATION,
Surface.ROTATION_0 //Or a different ROTATION_ constant
);
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
public class ScreenOrientationEnforcer {
private final View view;
private final WindowManager windows;
public ScreenOrientationEnforcer(Context context) {
windows = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
view = new View(context);
}
public void start() {
WindowManager.LayoutParams layout = generateLayout();
windows.addView(view, layout);
view.setVisibility(View.VISIBLE);
}
public void stop() {
windows.removeView(view);
}
private WindowManager.LayoutParams generateLayout() {
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
//So we don't need a permission or activity
//Note that this won't work on some devices running MIUI
layoutParams.type = WindowManager.LayoutParams.TYPE_TOAST;
//Just in case the window type somehow doesn't enforce this
layoutParams.flags =
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
//Prevents breaking apps that detect overlying windows enabling
//(eg UBank app, or enabling an accessibility service)
layoutParams.width = 0;
layoutParams.height = 0;
//Try to make it completely invisible
layoutParams.format = PixelFormat.TRANSPARENT;
layoutParams.alpha = 0f;
//The orientation to force
layoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
return layoutParams;
}
}
ScreenOrientationEnforcer screenOrientationEnforcer
= new ScreenOrientationEnforcer(context);
//Force screen orientation
screenOrientationEnforcer.start();
//Stop forcing screen orientation
screenOrientationEnforcer.stop();