Android'de yön değiştirme değişikliğini nasıl devre dışı bırakabilirim?


287

Ben sadece portre modunda kullanmak istiyorum bir uygulama var, bu yüzden manifest XML'de android: screenOrientation = "portrait" tanımladım. Bu, HTC Magic telefon için sorunsuz çalışır (ve diğer telefonlarda da yön değişikliklerini önler).

Ancak , donanım QWERTY klavyesini açarken (sanal klavyeyi değil) HTC G1 telefonunda bir sorunum var . Etkinliğim portre modunda kalıyor, ancak yeniden başlatılıyor ve tüm durumlarını kaybediyor gibi görünüyor. Bu, HTC Hero sürümünde gerçekleşmez.

Uygulamam oldukça büyük, bu yüzden klavye açıldığında yeniden başlamasını ve tüm durumlarını kaybetmesini istemiyorum. Bunu nasıl önleyebilirim?


2
Ayrıca buraya bakmayı deneyin: stackoverflow.com/questions/2366706/…
Andy Weinstein

Yanıtlar:


317

Nisan 2013 Güncellemesi: Bunu yapma. 2009 yılında soruyu ilk cevapladığımda iyi bir fikir değildi ve şimdi gerçekten iyi bir fikir değil. Nedenlerle hackbod'un bu cevabına bakın:

Android'de yön değiştirme konusunda zaman uyumsuz etkinlik yeniden yükleme kaçının

android:configChanges="keyboardHidden|orientation"AndroidManifest.xml'inize ekleyin . Bu, sisteme hangi yapılandırma değişikliklerini kendiniz gerçekleştireceğinizi söyler - bu durumda hiçbir şey yapmadan.

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

Daha fazla bilgi için bkz. Geliştirici referansı yapılandırmaDeğiştirmeleri .

Ancak, uygulamanız herhangi bir zamanda, örneğin bir telefon görüşmesi ile kesilebilir; bu nedenle, duraklatıldığında uygulamanızın durumunu kaydetmek için gerçekten kod eklemeniz gerekir.

Güncelleme: Android 3.2'den itibaren "screenSize" eklemeniz gerekiyor:

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

Geliştirici kılavuzundan Yapılandırmayı Kullanma Kendinizi Değiştirin

Dikkat: Android 3.2'den (API seviye 13) başlayarak, cihaz ekran ve yatay yön arasında geçiş yaptığında "ekran boyutu" da değişir. Bu nedenle, API düzeyi 13 veya üstü için geliştirirken (minSdkVersion ve targetSdkVersion öznitelikleri tarafından bildirildiği gibi) yön değiştirme nedeniyle çalışma zamanı yeniden başlatmalarını önlemek istiyorsanız, "yönlendirme" değerine ek olarak "screenSize" değerini de eklemeniz gerekir. Yani, beyan etmelisin android:configChanges="orientation|screenSize". Ancak, uygulamanız API seviye 12 veya daha düşük bir sürümü hedefliyorsa, etkinliğiniz her zaman bu yapılandırma değişikliğini kendisi yapar (bu yapılandırma değişikliği, bir Android 3.2 veya daha yüksek cihazda çalışırken bile etkinliğinizi yeniden başlatmaz).


36
Sadece buna eklemek ve gerçekten açık olmak için, Android, yönlendirme değişikliklerinden bağımsız olarak uygulamanızı herhangi bir zamanda acımasızca öldürebilir, bu nedenle ne olursa olsun durumu kaydetmek için onPause () ve onSaveInstanceState () yöntemlerini kullanmalısınız.
Eric Mill

3.2 güncellemesi çok faydalı oldu ve beni engelleyen şeydi. Neden benim onConfigurationChanged işleyicisinin ateşlenmediği hakkında hiçbir fikrim yoktu ve bu kadar. Teşekkürler!
tatlım

üçüncü param - screenSize 2.3.x içinde bulunamıyor, screenLayout olarak değiştirmeli miyim?
deadfish

2
@ Lumum Hayır, "screenSize" yalnızca Android 3.2 ve daha yeni sürümler için gereklidir. Hangi düzey API'yı hedefliyorsunuz? Yalnızca seviye 13 veya üstünü hedefliyorsanız eklemeniz gerektiğini düşünüyorum. Açıklığa kavuşturmak için cevabı güncelleyeceğim.
Karmaşıklar

1
Diğer insanlara yardımcı olması durumunda, değişiklikleri geçersiz kılmak için hem <... android: configChanges = "orientation" ...> bulduk ve <... android: screenOrientation = "portrait" ...> varsayılanı tanımla.
Sogger

97

Sen AndroidManifest.xml değiştirmeniz gerekir Intrications (daha önce Ashton) sözü ve bunu ele istediğiniz gibi emin etkinlik kolları onConfigurationChanged olay olun. İşte böyle görünmeli:

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

Dmitry Zaitsev'in tarafından belirtildiği gibi, durduğu yerde daha iyidir setRequestedOrientation()in onCreate().
Timmmm

3
Does not onConfigurationChanged()önce denilen olsun onCreate()OnCreate içinde contentViews ayarlamadan önce yönünü ayarlayarak bu yüzden eğer daha iyi bir yaklaşım, ait olduğu yapılandırmayı ayarı da temizleyici Bu cevap hala iyi duruyor böylece.
Samuel

39

Her zaman ikinize de ihtiyacınız olduğunu buldum

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

22

Daha önce de belirtildiği gibi, android:configChangesEtkinliğinizi (manifest dosyasında) şu şekilde ayarlayın keyboardHidden|orientation:

1) Geçersiz kılma onConfigurationChanged()

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    //here you can handle orientation change
}

2) Bu satırı etkinliklerinize ekleyin onCreate()

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

onConfigurationChangedUygulamanız dikey moda ve ardından manzaraya geri döneceğinden aynı satırı eklemekten daha iyidir (sadece bir kez olacak, ancak sinir bozucu).

Ayrıca android:screenOrientation="nosensor"etkinliğiniz için ayarlayabilirsiniz (bildirimde). Ancak bu şekilde, yön değişikliklerini hiç idare edemezsiniz.


Döndürme sonrasında etkinliğin yeniden oluşturulmasını önlemek istersem ne yapmalıyım, ancak kullanıcının OS ayarlarını kullanarak yönlendirmeyi kilitlemesine izin vermek istiyorum?
android geliştirici

@androiddeveloper, zaten bir cevabı olan ayrı bir soru: stackoverflow.com/a/14771495/926907
Dmitry Zaytsev

Bağlantınız, yapılandırma değiştiğinde içeriği kendim değiştirmektir, ancak kullanıcının yönlendirmeyi işletim sistemi aracılığıyla kilitlemeyi seçmesi durumunda etkinliğin dönüşünden kaçınmak istiyorum (tam olarak göründüğü gibi kalacaktır). ayarlar (bazı cihazlarda, bildirim çekmecesindeki hızlı ayarlar aracılığıyla kullanılabilir).
android geliştirici

@androiddeveloper ah, sanırım anladım. Ardından şu bağlantıya bir göz atın: developer.android.com/reference/android/… Dokümanlara göre, varsayılan yönlendirme zaten kullanıcı tercihini hesaba katmalıdır. Durum böyle değilse, işletim sistemine özgü bir davranış olduğundan şüpheleniyorum. Sonuçlarınızı duymaktan memnuniyet duyarım - şimdi ben de ilgileniyorum :)
Dmitry Zaytsev

Varsayılanın kullanıcının tercihlerini işleyeceğini biliyorum, ancak ekranı döndürdüğünüzde etkinliği yeniden oluşturur, bu da sahip olmak istemediğim bir şeydir.
android geliştirici


13

Etkinliğinizin OnCreate yönteminde şu kodu kullanın:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

Şimdi yönünüz dikey olarak ayarlanacak ve asla değişmeyecek.


4
Bununla birlikte, yönlendirme yapılandırması her değiştiğinde etkinliğin yeniden başlatılmasını engellemezsiniz.
AxeEffect

Ayrıca, önceki bir Etkinliğin Etkinliğini yatay yönde girerseniz bu da çalışmaz.
w3bshark

10

AndroidManifest.xml dosyasında, kilitlemek istediğiniz her etkinlik için son screenOrientationsatırı ekleyin :

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

Veya android: screenOrientation = "manzara" .


8

Senin içinde AndroidManifest.xml dosyası:

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

veya

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

6

Ekranı kodla kilitlemek için ekranın gerçek dönüşünü kullanmanız gerekir (0, 90, 180, 270) ve bunun doğal konumunu bilmeniz gerekir, bir akıllı telefonda doğal konum portre ve bir tablette, manzara olacak.

İşte kod (kilitleme ve kilit açma yöntemleri), bazı cihazlarda (akıllı telefonlar ve tabletler) test edildi ve harika çalışıyor.

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

hangi parametre aktivite olarak geçmelidir?
İSTEK

Yönünü kilitlemek / kilidini açmak için yöntemi çağıran Etkinlik. Bu, farklı Etkinlikler'den çağrılacak genel bir statik yardımcı yöntemdir.
PoOk

1
Harika çalışıyor, ama cidden, Android, neden sadece kilit ekranı yönlendirme için tüm bu şeyleri yapmak zorundayız? !!!
Cocorico

Evet. Bu, manifest'te yaptığımız gibi yönlendirmeyi kilitler. Bu, onConfigurationChanged öğesinin artık çağrılmasını önleyecektir. Kullanıcı Arabirimini Yatay olarak kilitleyen ve hala onConfigurationChanged öğesini çağıran bir yöntem var mı? Android'deki kamera uygulaması gibi
Ajith Memana

SDK 18+ üzerinde çalışıyor gibi görünen bir SCREEN_ORIENTATION_LOCKED bayrağı var, ancak yine de her cihazı desteklemek için yukarıdaki kodu kullanmak istiyorsunuz
DominicM

2

Visual Studio Xamarin'de:

  1. Ekle:

using Android.Content.PM; etkinlik ad alanı listesine.

  1. Ekle:

[Activity(ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait)]

sınıfınıza bir özellik olarak, şöyle:

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

Bu soru Android hakkında soruyor, Xamarin değil. Android
Trevor Hart


0

Lütfen unutmayın, yöntemlerin hiçbiri işe yaramıyor!

In Android Studio 1 basit bir yolu eklemektir android:screenOrientation="nosensor" .

Bu, ekran yönünü etkili bir şekilde kilitler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.