我如何全局强制在Android的屏幕方向?

有一些应用程序能够强制屏幕旋转。 即使应用程序明确希望以另一个方向进行查看,它们也可以工作。 现在我禁用加速度计旋转系统设置并设置我的首选方向。 应用程序仍然可以覆盖此。

以下是可以覆盖应用程序请求方向的应用程序之一:

https://play.google.com/store/apps/details?id=nl.fameit.rotate&hl=en

Solutions Collecting From Web of "我如何全局强制在Android的屏幕方向?"

我试过kagronick的答案,但不能使它的工作。 在弄乱了一下之后,我最终使用系统覆盖窗口工作,并删除了我发现的LayoutParams,这些都是不必要的。 这是我最终的解决scheme:

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

你可以在我发布的应用程序中看到我的成功: Force Dock Rotation 。

这可以通过创build一个隐藏的系统对话框来完成。 它的一种黑客,但它的工作疯狂。

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

另外,您还可以全局更改屏幕方向而不强制在不支持的应用程序中。 (我知道这个问题是关于覆盖应用程序的偏好,但这仍然是有用的,主要是相关的信息。)

  1. 在AndroidManifest.xml中授予对系统设置( WRITE_SETTINGS )的 访问权限

     <uses-permission android:name="android.permission.WRITE_SETTINGS" /> 
  2. 导入Settings

     import android.provider.Settings; 
  3. 确保Android屏幕自动旋转被禁用

     Settings.System.putInt( getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0 ); 
  4. USER_ROTATION设置为所需的设置,该设置应该是ROTATION_常量之一 。 这些值代表设备自然方向的屏幕旋转,可以是横向或纵向。

     Settings.System.putInt( getContentResolver(), Settings.System.USER_ROTATION, Surface.ROTATION_0 //Or a different ROTATION_ constant ); 

请注意,即使您的应用程序未运行或已卸载,对USER_ROTATION更改仍然存在。 如果我记得正确,用户可以通过手动禁用和启用自动旋转来重置此值。

创build一个系统视图

创build一个总是显示在其他应用程序之上的不可见ViewView可以指定他们自己的方向偏好,所以你的视图的方向可以用来覆盖底层视图和应用程序的方向。

选项

我知道有几种不同的视图types可以用来实现这一点,每种视图都有它自己的缺点。

  1. 系统覆盖窗口( TYPE_SYSTEM_OVERLAY

    需要SYSTEM_ALERT_WINDOW权限。 (将以下内容添加到AndroidManifest.xml中 。)

     <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 
  2. Toast窗口( TYPE_TOAST

    除了MIUI V8以外,不需要任何权限。

    不显示在一些窗口types,所以他们的方向可能不会受到影响:

    • 来电对话( TYPE_PRIORITY_PHONE
    • 梦 ( TYPE_DREAM
    • 钥匙防盗/locking画面( TYPE_KEYGUARD_DIALOGTYPE_KEYGUARD_SCRIM

说明

  1. 创build一个View
  2. 创build一个WindowManager.LayoutParams
    1. type设置为您在上面select的值。
    2. 将其widthheight调整为零,以防止重叠时无法运行的应用程序出现问题。 (例如,如果窗口位于顶部,则尝试启用辅助function服务时,Android不会让您按“确定”button。)
    3. 将其screenOrientation设置为所需的任何方向值 。

履行

 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(); 

缺点

  • 根据我的经验,如果您的应用程序崩溃或死亡,则视图可能会持续存在。 重新启动设备似乎解决这个问题。

参考

  • 窗口types和z顺序之间的映射: PhoneWindowManager.windowTypeToLayerLw
  • 每个窗口types所需的权限: PhoneWindowManager.checkAddPermission

您可以在AndroidManifest.xml中设置方向。 喜欢这个:

 <activity android:name=".YourActivity" android:label="@string/your_app_name" android:screenOrientation="portrait"> 

我不认为你可以为整个应用程序设置它,但需要专门为您正在显示的每个活动进行设置。

很多像这样的问题,我build议你做一些search。