Bagaimana cara menonaktifkan perubahan orientasi di Android?

287

Saya memiliki aplikasi yang ingin saya gunakan dalam mode potret, jadi saya telah mendefinisikan android: screenOrientation = "portrait" di manifes XML. Ini berfungsi baik untuk ponsel HTC Magic (dan juga mencegah perubahan orientasi pada ponsel lain).

Tapi saya punya masalah dengan ponsel HTC G1 saat saya membuka perangkat keras keyboard QWERTY (bukan keyboard virtual). Aktivitas saya tetap dalam mode potret, tetapi sepertinya memulai kembali dan kehilangan semua statusnya. Ini tidak terjadi dengan HTC Hero .

Aplikasi saya cukup besar, jadi saya tidak ingin restart dan kehilangan semua statusnya saat keyboard dibuka. Bagaimana saya bisa mencegahnya?

Vidar Vestnes
sumber

Jawaban:

317

Pembaruan April 2013: Jangan lakukan ini. Itu bukan ide yang baik pada tahun 2009 ketika saya pertama kali menjawab pertanyaan dan itu sebenarnya bukan ide yang baik sekarang. Lihat jawaban ini oleh hackbod untuk alasan:

Hindari memuat ulang aktivitas dengan asynctask pada perubahan orientasi di android

Tambahkan android:configChanges="keyboardHidden|orientation"ke AndroidManifest.xml Anda. Ini memberi tahu sistem perubahan konfigurasi apa yang akan Anda tangani sendiri - dalam hal ini dengan tidak melakukan apa pun.

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

Lihat Konfigurasi referensi pengembang untuk lebih jelasnya.

Namun, aplikasi Anda dapat diinterupsi kapan saja, misalnya dengan panggilan telepon, jadi Anda harus menambahkan kode untuk menyimpan status aplikasi Anda ketika dijeda.

Pembaruan: Pada Android 3.2, Anda juga perlu menambahkan "screenSize":

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

Dari panduan Pengembang Menangani Konfigurasi Ubah Diri Anda

Perhatian: Dimulai dengan Android 3.2 (API level 13), "ukuran layar" juga berubah ketika perangkat beralih antara orientasi potret dan lanskap. Dengan demikian, jika Anda ingin mencegah restart runtime karena perubahan orientasi ketika mengembangkan untuk API level 13 atau lebih tinggi (sebagaimana dideklarasikan oleh atribut minSdkVersion dan targetSdkVersion), Anda harus menyertakan nilai "screenSize" di samping nilai "orientasi". Artinya, Anda harus menyatakan android:configChanges="orientation|screenSize". Namun, jika aplikasi Anda menargetkan API level 12 atau lebih rendah, maka aktivitas Anda selalu menangani perubahan konfigurasi itu sendiri (perubahan konfigurasi ini tidak memulai kembali aktivitas Anda, bahkan ketika berjalan pada perangkat Android 3.2 atau lebih tinggi).

Intrikasi
sumber
36
Hanya untuk menambahkan ini dan menjadi sangat eksplisit, Android tanpa ampun dapat membunuh aplikasi Anda kapan saja, terlepas dari perubahan orientasi, jadi Anda harus menggunakan onPause () dan onSaveInstanceState () untuk menyimpan keadaan, apa pun yang terjadi.
Eric Mill
Pembaruan 3.2 sangat berguna dan menghalangi saya. Saya tidak tahu mengapa handler onConfigurationChanged saya tidak menyala dan ini dia. Terima kasih!
sweetlilmre
param ketiga - screenSize tidak dapat ditemukan di 2.3.x, haruskah saya mengubah ke screenLayout?
deadfish
2
@Lumma Tidak, "screenSize" hanya diperlukan untuk Android 3.2 dan yang lebih baru. API tingkat apa yang Anda targetkan? Saya pikir Anda hanya perlu menambahkannya jika Anda menargetkan level 13 atau lebih tinggi. Saya akan memperbarui jawaban untuk menjelaskan.
Intrications
1
Untuk berjaga-jaga jika hal ini bermanfaat bagi orang lain, saya telah menemukan Anda berdua <... android: configChanges = "orientasi" ...> untuk mengabaikan perubahan dan <... android: screenOrientation = "portrait" ...> to tentukan default.
Sogger
97

Anda perlu memodifikasi AndroidManifest.xml sebagai Intrications (sebelumnya Ashton) yang disebutkan dan memastikan aktivitas menangani acara onConfigurationChanged seperti yang Anda inginkan ditangani. Begini tampilannya:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
ubershmekel
sumber
Sebagaimana dicatat oleh Dmitry Zaitsev, lebih baik untuk menempatkan setRequestedOrientation()di onCreate().
Timmmm
3
Tidak onConfigurationChanged()dipanggil sebelumnya onCreate()jika begitu mengatur orientasi sebelum mengatur kontenDilihat di oncreate adalah pendekatan yang lebih baik , pengaturan konfigurasi di tempat itu juga lebih bersih sehingga jawaban ini masih bagus.
Samuel
39

Saya selalu menemukan Anda membutuhkan keduanya

android:screenOrientation="nosensor" android:configChanges="keyboardHidden|orientation"
m00sey
sumber
22

Seperti yang dikatakan, set android:configChangesAktivitas Anda (dalam file manifes) kekeyboardHidden|orientation dan kemudian:

1) Override onConfigurationChanged()

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

2) Tambahkan baris ini ke aktivitas Anda onCreate()

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

Lebih baik daripada menambahkan baris yang sama onConfigurationChanged , karena aplikasi Anda akan beralih ke mode potret dan kemudian kembali ke lansekap (itu akan terjadi hanya satu kali, tetapi itu menjengkelkan).

Anda juga dapat mengatur android:screenOrientation="nosensor"aktivitas Anda (dalam manifes). Tetapi dengan menggunakan cara ini Anda tidak dapat menangani perubahan orientasi sama sekali.

Dmitry Zaytsev
sumber
Apa yang harus saya lakukan jika saya ingin menghindari penciptaan kembali aktivitas setelah rotasi, namun saya ingin memungkinkan pengguna untuk mengunci orientasi melalui pengaturan OS?
pengembang android
@androiddeveloper bahwa pertanyaan terpisah, yang sudah memiliki jawaban: stackoverflow.com/a/14771495/926907
Dmitry Zaytsev
Tautan Anda adalah tentang mengubah konten sendiri ketika konfigurasi berubah, namun saya ingin menghindari rotasi aktivitas (sehingga terlihat seperti apa adanya) jika pengguna telah memilih untuk mengunci orientasi melalui OS. pengaturan (tersedia di beberapa perangkat melalui pengaturan cepat, di laci pemberitahuan).
pengembang android
@androiddeveloper ah, saya pikir saya mengerti. Kemudian lihat tautan ini: developer.android.com/reference/android/... Menurut dokumen, orientasi default harus sudah mempertimbangkan preferensi pengguna. Jika bukan itu masalahnya, maka saya curiga itu adalah perilaku spesifik OS. Saya akan senang mendengar tentang hasil Anda - sekarang saya juga tertarik di dalamnya :)
Dmitry Zaytsev
Saya tahu default akan menangani preferensi pengguna, tetapi itu juga menciptakan kembali aktivitas ketika Anda memutar layar, yang merupakan sesuatu yang saya tidak ingin miliki.
pengembang android
20

Gunakan ini..

    android:screenOrientation="portrait"
Muhammad Aamir Ali
sumber
13

Dalam metode OnCreate aktivitas Anda, gunakan kode ini:

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

Sekarang orientasi Anda akan diatur ke potret dan tidak akan pernah berubah.

Numenor
sumber
4
Dengan itu Anda tidak mencegah memulai kembali aktivitas setiap kali konfigurasi orientasi berubah.
AxeEffect
Juga, ini tidak berfungsi jika Anda memasukkan Aktivitas dari Aktivitas sebelumnya dalam orientasi lanskap.
w3bshark
10

Di file AndroidManifest.xml, untuk setiap aktivitas yang ingin Anda kunci tambahkan screenOrientationbaris terakhir :

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

Atau android: screenOrientation = "landscape" .

Gil Allen
sumber
8

Dalam file androidmanifest.xml Anda :

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

atau

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

Untuk mengunci layar dengan kode Anda harus menggunakan rotasi layar yang sebenarnya (0, 90, 180, 270) dan Anda harus tahu posisi alami layar itu, di smartphone posisi alami akan menjadi potret dan di tablet, itu akan menjadi lanskap.

Inilah kodenya (metode kunci dan buka kunci), ini telah diuji di beberapa perangkat (ponsel cerdas dan tablet) dan berfungsi dengan baik.

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);
}
Oke
sumber
paramater apa yang harus dilewatkan sebagai aktivitas?
WISHY
Aktivitas yang memanggil metode untuk mengunci / membuka orientasinya. Itu metode utilitas statis publik untuk dipanggil dari Kegiatan differents.
PoOk
1
Berfungsi bagus, tapi, serius, Android, mengapa kita harus melakukan semua itu hanya untuk orientasi layar kunci? !!!
Cocorico
Iya. Yang ini mengunci orientasi seperti yang kita lakukan dalam manifes. Ini akan mencegah onConfigurationChanged dari dipanggil lagi. Apakah ada metode yang mengunci UI ke Landscape dan masih memanggil onConfigurationChanged. Sama seperti aplikasi kamera di android tidak
Ajith Memana
Ada bendera SCREEN_ORIENTATION_LOCKED di SDK 18+ yang tampaknya berfungsi tetapi Anda masih ingin menggunakan kode di atas untuk mendukung setiap perangkat
DominicM
2

Dalam Visual Studio Xamarin:

  1. Menambahkan:

using Android.Content.PM; untuk Anda daftar namespace aktivitas.

  1. Menambahkan:

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

sebagai atribut untuk kelas Anda, seperti itu:

[Activity(ScreenOrientation = ScreenOrientation.Portrait)]
public class MainActivity : Activity
{...}
Roy Doron
sumber
Pertanyaan ini menanyakan tentang Android, bukan Xamarin. Android
Trevor Hart
1

Menambahkan

android:configChanges="keyboardHidden|orientation|screenSize" 

ke manifes Anda.

saurabh
sumber
di dalam tag <activity> Anda
Ege Kuzubasioglu
0

Harap dicatat, tidak ada satupun metode yang tampaknya berfungsi sekarang!

Di Android Studio 1, satu cara sederhana adalah menambahkan android:screenOrientation="nosensor".

Ini secara efektif mengunci orientasi layar.

kephalian
sumber