简体   繁体   中英

Change main Android screen orientation?

I have had a device, which apparently had something broken with the orientation, because after reboot, for about an hour, it would rotate the screen in response to a change of orientation - and then it would stop responding, both on the "desktop" level and application level.

So, I found Change Screen Orientation programmatically using a Button , and I assumed I can create a "icon button only" app, which when pressed, would not run a new application, but instead just try to change the orientation.

The skeleton for the "icon/button-only" app is a copy of Lock screen (it.reyboz.screenlock) . I posted this project on a gist - but since it is hard to have folders (and binary files) by default in a gist, this is the procedure you can use to get the code:

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

Basically, I'm just trying to do the following in 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;
 }

... however, nothing happens when I click the app icon and run this code.

So, my question is - is it possible in principle to force a change of the device orientation on a "desktop" level? If so, is it dependent on Android version (possibly vendor branded) or not - and how?

Was just curious so tried out Sam's solution and made some changes :

Would need this permission in Manifest

Permission <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

Also this permissions is a dangerous permission but if you are installing the app from Play store you need not worry about that.

I made a window service something like this :

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

And from your Activity while development make sure you include ACTION_MANAGE_OVERLAY_PERMISSION ; again you don't need to worry this for users who will install the app through Google Play Store . Here using the below code to allow permission for devices above 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);
}

And now just start your service and pass extras for Portrait or Landscape I am using 1 for Landscape and 2 for Portrait

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

Hope this helps :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM