如何在Android上禁用方向更改?

如何在Android上禁用方向更改?,android,android-activity,android-orientation,Android,Android Activity,Android Orientation,我有一个应用程序,我只想在纵向模式下使用,所以我定义了 清单XML中的android:screenOrientation=“纵向”。这在手机上正常工作(并防止在其他手机上改变方向) 但当我打开硬件(不是虚拟键盘)时,手机出现了问题。我的活动保持在纵向模式,但似乎重新启动并失去所有状态。版本中不会出现这种情况 我的应用程序相当大,所以我不希望它在键盘打开时重新启动并失去所有状态。我怎样才能防止这种情况发生?2013年4月更新:不要这样做。2009年我第一次回答这个问题时,这不是一个好主意,现在也不

我有一个应用程序,我只想在纵向模式下使用,所以我定义了 清单XML中的android:screenOrientation=“纵向”。这在手机上正常工作(并防止在其他手机上改变方向)

但当我打开硬件(不是虚拟键盘)时,手机出现了问题。我的活动保持在纵向模式,但似乎重新启动并失去所有状态。版本中不会出现这种情况


我的应用程序相当大,所以我不希望它在键盘打开时重新启动并失去所有状态。我怎样才能防止这种情况发生?

2013年4月更新:不要这样做。2009年我第一次回答这个问题时,这不是一个好主意,现在也不是一个好主意。请参阅hackbod的回答,原因如下:

将android:configChanges=“keyboardHidden | orientation”添加到您的AndroidManifest.xml中。这会告诉系统您将自己处理哪些配置更改—在本例中,您什么也不做

<activity android:name="MainActivity"
     android:screenOrientation="portrait"
     android:configChanges="keyboardHidden|orientation">
了解更多详细信息

但是,您的应用程序随时都可能被中断,例如通过电话中断,因此您确实应该添加代码以在应用程序暂停时保存其状态

更新:从Android 3.2开始,您还需要添加“屏幕大小”:

注意:从Android 3.2(API级别13)开始,“屏幕大小” 当设备在纵向和横向之间切换时也会发生变化 方向。因此,如果您想防止由于以下原因而重新启动运行时: API 13级或更高级别(如适用)开发时的方向变化 由minSdkVersion和targetSdkVersion属性声明),您可以 除“方向”外,还必须包括“屏幕大小”值 价值也就是说,你必须申报
android:configChanges=“orientation | screenSize”
。但是,如果您的 应用程序以API级别12或更低为目标,那么您的活动始终 处理此配置更改本身(此配置更改 即使在Android 3.2或更高版本上运行,也不会重新启动活动 更高的设备)


您需要修改前面提到的AndroidManifest.xml(前面是Ashton),并确保活动按照您希望的方式处理onConfigurationChanged事件。它应该是这样的:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

我总是发现你两者都需要

android:screenOrientation="nosensor" android:configChanges="keyboardHidden|orientation"

在您的androidmanifest.xml文件中:

   <activity android:name="MainActivity" android:configChanges="keyboardHidden|orientation">

如上所述,将活动的
android:configChanges
(在清单文件中)设置为
keyboardHidden | orientation
,然后:

1) 覆盖OnConfiguration Changed()

2) 将此行添加到活动的
onCreate()

这比将同一行添加到配置已更改的
中要好,因为您的应用程序将转到纵向模式,然后再回到横向模式(这只会发生一次,但很烦人)


您还可以为您的活动(在清单中)设置
android:screenOrientation=“nosensor”
但是使用这种方式,您根本无法处理方向更改。

在活动的OnCreate方法中使用以下代码:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
现在,您的方向将设置为纵向,并且永远不会改变。

使用此选项

    android:screenOrientation="portrait"

要通过代码锁定屏幕,您必须使用屏幕的实际旋转(0、90、180、270),并且您必须知道屏幕的自然位置,在智能手机中,自然位置为纵向,而在平板电脑中,自然位置为横向

下面是代码(锁定和解锁方法),它已经在一些设备(智能手机和平板电脑)上进行了测试,效果非常好

public static void lockScreenOrientation(Activity activity)
{   
    WindowManager windowManager =  (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);   
    Configuration configuration = activity.getResources().getConfiguration();   
    int rotation = windowManager.getDefaultDisplay().getRotation(); 

    // Search for the natural position of the device    
    if(configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&  
       (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) ||  
       configuration.orientation == Configuration.ORIENTATION_PORTRAIT &&   
       (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270))   
    {   
        // Natural position is Landscape    
        switch (rotation)   
        {   
            case Surface.ROTATION_0:    
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);    
                break;      
            case Surface.ROTATION_90:   
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
            break;      
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
                break;
        }
    }
    else
    {
        // Natural position is Portrait
        switch (rotation) 
        {
            case Surface.ROTATION_0: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
            break;   
            case Surface.ROTATION_90: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
            break;   
            case Surface.ROTATION_180: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
                break;          
            case Surface.ROTATION_270: 
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                break;
        }
    }
}

public static void unlockScreenOrientation(Activity activity)
{
    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}


在AndroidManifest.xml文件中,对于要锁定的每个活动,添加最后一行
screenOrientation

android:label="@string/app_name"
android:name=".Login"
android:screenOrientation="portrait" >

或者android:screenOrientation=“横向”

请注意,现在似乎没有一种方法有效

在1中,一个简单的方法是添加
android:screenOrientation=“nosensor”


这将有效地锁定屏幕方向。

在Visual Studio Xamarin中:

  • 加:
  • 使用Android.Content.PM到您的活动名称空间列表

  • 加:
  • [活动(ScreenOrientation=Android.Content.PM.ScreenOrientation.grait)]

    作为类的属性,如下所示:

    [Activity(ScreenOrientation = ScreenOrientation.Portrait)]
    public class MainActivity : Activity
    {...}
    

    如果您希望应用程序中的所有活动都只使用纵向模式,则可以在应用程序类中简单地使用如下所示

    class YourApplicationName : Application() {
    
    override fun onCreate() {
        super.onCreate()
    
        registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
    
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
                activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            }
    
            override fun onActivityStarted(activity: Activity) {
    
            }
    
            override fun onActivityResumed(activity: Activity) {
    
            }
    
            override fun onActivityPaused(activity: Activity) {
    
            }
    
            override fun onActivityStopped(activity: Activity) {
    
            }
    
            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
    
            }
    
            override fun onActivityDestroyed(activity: Activity) {
    
            }
    
        })
    
    }
    

    }

    为了补充这一点,而且要明确,Android可以在任何时候无情地杀死你的应用程序,不管方向如何变化,所以你应该使用onPause()和onSaveInstanceState()来保存状态,不管发生什么。3.2更新非常有用,正是它阻止了我。我不知道为什么我的OnConfiguration Changed处理程序没有启动,就是这样。谢谢第三个参数-screenSize在2.3.x中找不到,我是否应该更改为screenLayout?@Lumma否,“screenSize”仅适用于Android 3.2及更高版本。你的目标是什么级别的API?我认为你只需要添加它,如果你的目标是13级或以上。我将更新答案以澄清问题。为了防止对其他人有所帮助,我发现你们都可以覆盖更改并定义默认值。也可以尝试查看此处:正如Dmitry Zaitsev所指出的,最好将
    setRequestedOrientation()
    放在
    onCreate()中
    。不会在
    onCreate()之前调用
    onConfigurationChanged()
    如果是这样,在onCreate中设置ContentView之前设置方向是更好的方法,将配置设置在它所属的位置也更简洁,因此这个答案仍然有效。这样,您就不会在每次方向配置更改时阻止重新启动活动。此外,如果在横向中输入上一个活动中的活动,则此操作无效。应将哪个参数作为活动传递?调用方法以锁定/取消锁定的活动
    public static void lockScreenOrientation(Activity activity)
    {   
        WindowManager windowManager =  (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);   
        Configuration configuration = activity.getResources().getConfiguration();   
        int rotation = windowManager.getDefaultDisplay().getRotation(); 
    
        // Search for the natural position of the device    
        if(configuration.orientation == Configuration.ORIENTATION_LANDSCAPE &&  
           (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) ||  
           configuration.orientation == Configuration.ORIENTATION_PORTRAIT &&   
           (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270))   
        {   
            // Natural position is Landscape    
            switch (rotation)   
            {   
                case Surface.ROTATION_0:    
                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);    
                    break;      
                case Surface.ROTATION_90:   
                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
                break;      
                case Surface.ROTATION_180: 
                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                    break;          
                case Surface.ROTATION_270: 
                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
                    break;
            }
        }
        else
        {
            // Natural position is Portrait
            switch (rotation) 
            {
                case Surface.ROTATION_0: 
                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
                break;   
                case Surface.ROTATION_90: 
                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 
                break;   
                case Surface.ROTATION_180: 
                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 
                    break;          
                case Surface.ROTATION_270: 
                    activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 
                    break;
            }
        }
    }
    
    public static void unlockScreenOrientation(Activity activity)
    {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
    }
    
    android:configChanges="keyboardHidden|orientation|screenSize" 
    
    android:label="@string/app_name"
    android:name=".Login"
    android:screenOrientation="portrait" >
    
    [Activity(ScreenOrientation = ScreenOrientation.Portrait)]
    public class MainActivity : Activity
    {...}
    
    class YourApplicationName : Application() {
    
    override fun onCreate() {
        super.onCreate()
    
        registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
    
            override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
                activity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
            }
    
            override fun onActivityStarted(activity: Activity) {
    
            }
    
            override fun onActivityResumed(activity: Activity) {
    
            }
    
            override fun onActivityPaused(activity: Activity) {
    
            }
    
            override fun onActivityStopped(activity: Activity) {
    
            }
    
            override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
    
            }
    
            override fun onActivityDestroyed(activity: Activity) {
    
            }
    
        })
    
    }