【问题标题】:Change main Android screen orientation?更改主 Android 屏幕方向?
【发布时间】:2017-04-05 08:49:24
【问题描述】:

我有一个设备,它的方向显然有问题,因为重新启动后,大约一个小时,它会旋转屏幕以响应方向的变化 - 然后它会停止响应,两者都在“桌面”级别和应用程序级别。

所以,我找到了Change Screen Orientation programmatically using a Button,并假设我可以创建一个“仅图标按钮”应用程序,当按下该应用程序时,它不会运行新应用程序,而只是尝试更改方向。

“仅图标/按钮”应用的框架是 Lock screen (it.reyboz.screenlock) 的副本。我在 gist 上发布了这个项目 - 但由于默认情况下很难在 gist 中包含文件夹(和二进制文件),这是您可以用来获取代码的过程:

git clone https://gist.github.com/e6422677cababc17526d0cb57aceb76a.git dl_archive_git

cd dl_archive_git

bash run-me-to-unpack.sh

# check upacked dir:
tree rotate-btn-droid

cd rotate-btn-droid/

# change your SDK path (ASDKPATH) in buildme.sh, and then:
bash buildme.sh
# if your java install is not in the path, then call the last command with JAVA_HOME prepended:
# JAVA_HOME=/path/to/jdkXXX bash buildme.sh

基本上,我只是想在MainActivity.java 中执行以下操作:

Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int orientation = display.getOrientation();
// OR: orientation = getRequestedOrientation(); // inside an Activity

switch(orientation) {
  case Configuration.ORIENTATION_PORTRAIT:
    setRequestedOrientation (Build.VERSION.SDK_INT < 9 ?
                            ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE :
                            ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
    break;
  case Configuration.ORIENTATION_LANDSCAPE:
    setRequestedOrientation (Build.VERSION.SDK_INT < 9 ?
                            ActivityInfo.SCREEN_ORIENTATION_PORTRAIT :
                            ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
    break;
 }

...但是,当我单击应用程序图标并运行此代码时,没有任何反应。

所以,我的问题是 - 原则上是否可以在“桌面”级别强制更改设备方向?如果是这样,它是否依赖于 Android 版本(可能是供应商品牌) - 以及如何?

【问题讨论】:

  • 如果您关注this here,我不确定它是否可能在设备级别因为它明确表示它将仅更改此活动的所需方向
  • 有一个解决方法here,如果您的设备 api 为 18 或以下,您可以使用this here
  • 感谢@shadygoneinsane - 将确保我检查解决方法;如果其中任何一项有效,将报告

标签: java android android-orientation


【解决方案1】:

只是好奇所以尝试了Sam's solution 并进行了一些更改:

Manifest 中需要此权限

权限&lt;uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/&gt;

此外,此权限是一个危险的权限,但如果您是从 Play 商店安装应用程序,则无需担心。

我做了一个类似这样的窗口服务:

public class MyServiceNew extends Service {

private View view;

public MyServiceNew() {
}

@Override
public IBinder onBind(Intent intent) {
    throw new UnsupportedOperationException("Not yet implemented");
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    int flag = intent.getExtras().getInt("Flag");
    WindowManager.LayoutParams layout;
    if (flag == 1) {
        layout = generateLayoutLandscape();
    } else {
        layout = generateLayoutPortrait();
    }
    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    wm.addView(view, layout);
    return super.onStartCommand(intent, flags, startId);
}

private WindowManager.LayoutParams generateLayoutPortrait() {
    Toast.makeText(this, "Port", Toast.LENGTH_LONG).show();
    view = new View(this);
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSPARENT);
    params.alpha = 0f;
    params.width = 0;
    params.height = 0;

    //The orientation to force
    params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
    return params;
}

private WindowManager.LayoutParams generateLayoutLandscape() {
    Toast.makeText(this, "Land", Toast.LENGTH_LONG).show();
    view = new View(this);
    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSPARENT);
    params.alpha = 0f;
    params.width = 0;
    params.height = 0;

    //The orientation to force
    params.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
    return params;
 }
}

在开发过程中,请确保包含 ACTION_MANAGE_OVERLAY_PERMISSION ;对于将通过Google Play Store 安装应用程序的用户,您无需担心这一点。这里使用下面的代码来允许 M 以上设备的权限:

public void requestSystemAlertPermission(int requestCode) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
        return;
    final String packageName = getPackageName();
    final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + packageName));
    startActivityForResult(intent, requestCode);
}

现在只需启动您的服务并为纵向或横向传递附加信息 我将 1 用于横向,2 用于纵向

Intent intentLand = new Intent(SoNew.this, MyServiceNew.class);
intentLand.putExtra("Flag", 2); //or change 1 for Port
startService(intentLand);

希望这会有所帮助:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 2014-02-08
    相关资源
    最近更新 更多