我怎样才能在全球范围强制屏幕方向Android中?(How can I globally force

2019-07-18 22:48发布

有一些是能够迫使屏幕旋转的应用程序。 他们的工作,即使一个应用程序明确希望在另一个方向来看待。 现在我禁用加速旋转系统设置和设置我的首选方向。 一个应用程序仍然可以覆盖此。

这里是能够覆盖一个应用程序的请求的方向的应用程序之一:

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

Answer 1:

我试图kagronick的答案,但不能使它工作。 乱搞了一会儿后,我终于得到它的工作使用系统覆盖的窗口和删除,我发现了所有不必要的的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);

你可以看到我在我在此基础上发布了应用程序的成功: 强制码头旋转 。



Answer 2:

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

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


Answer 3:

顺便说一句,你还可以在全球范围改变屏幕方向,而不会迫使它在不支持的应用程序。 (我知道这个问题是关于重写应用程序的偏好,但是这仍然是有用的,大多是相关的信息。)

  1. 授权访问到系统设置( WRITE_SETTINGS )在AndroidManifest.xml

     <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坚持即使您的应用程序不运行或卸载。 如果我没有记错,用户可以通过手动禁用和启用自动旋转复位此值。



Answer 4:

创建系统视图

创建一个无形的View始终显示在其他应用程序的顶部。 View S可指定自己的定位的喜好,所以您的视图的方向可以用来覆盖的基本看法和应用的方向。

选项

我知道一对夫妇,您可以使用其自身的缺点,实现这一点,每个不同视图类型的。

  1. 系统覆盖窗口( TYPE_SYSTEM_OVERLAY

    需要SYSTEM_ALERT_WINDOW许可。 (以下内容添加到AndroidManifest.xml中 。)

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

    没有权限要求, 除了在MIUI V8 。

    不显示在某些窗口类型,所以它们的方向可能不会受到影响:

    • 来电对话框( TYPE_PRIORITY_PHONE
    • 梦 ( TYPE_DREAM
    • 核心后卫/锁屏( TYPE_KEYGUARD_DIALOGTYPE_KEYGUARD_SCRIM

说明

  1. 创建一个View
  2. 创建WindowManager.LayoutParams
    1. 设置type看重你在上面选择。
    2. 零的widthheight ,以防止重叠时将无法正常应用程序的问题。 (例如,Android将不会让你按“确定”按钮,当您尝试,如果一个窗口是在它的上面,使无障碍服务。)
    3. 设置其screenOrientation取其矫正值你想要的。

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

}
Usage
ScreenOrientationEnforcer screenOrientationEnforcer
    = new ScreenOrientationEnforcer(context);

//Force screen orientation
screenOrientationEnforcer.start();

//Stop forcing screen orientation
screenOrientationEnforcer.stop();

缺点

  • 从我的经验,如果你的应用程序崩溃或者被杀害的观点可能会持续。 重新启动设备似乎解决这个问题。

参考

  • 窗口类型和z顺序之间的映射: PhoneWindowManager.windowTypeToLayerLw
  • 需要为每个窗口类型的权限: PhoneWindowManager.checkAddPermission


Answer 5:

您可以在AndroidManifest.xml中设定的方向。 像这样:

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

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

对SO这样的问题很多,我建议你做一些搜索。



文章来源: How can I globally force screen orientation in Android?