Bagaimana cara menonaktifkan mode lansekap di Android?


Jawaban:


1633

Tambahkan android:screenOrientation="portrait"ke aktivitas di AndroidManifest.xml. Sebagai contoh:

<activity android:name=".SomeActivity"
    android:label="@string/app_name"
    android:screenOrientation="portrait" />

EDIT: Karena ini telah menjadi jawaban yang sangat populer, saya merasa sangat bersalah karena memaksa potret jarang merupakan solusi yang tepat untuk masalah yang sering diterapkan.
Peringatan utama dengan potret paksa:

  • Ini tidak membebaskan Anda dari keharusan untuk memikirkan kegiatan siklus hidup aktivitas atau kondisi penyimpanan / pengembalian yang benar. Ada banyak hal selain rotasi aplikasi yang dapat memicu penghancuran / rekreasi aktivitas, termasuk hal-hal yang tidak dapat dihindari seperti multitasking. Tidak ada jalan pintas; belajar menggunakan bundel dan retainInstancefragmen.
  • Perlu diingat bahwa tidak seperti pengalaman iPhone yang cukup seragam, ada beberapa perangkat di mana potret bukanlah orientasi yang jelas populer. Saat pengguna menggunakan perangkat dengan keyboard perangkat keras atau game pad a Nvidia Shield, pada Chromebooks , pada foldables , atau pada Samsung DeX , memaksa potret dapat membuat pengalaman aplikasi Anda menjadi terbatas atau kerumitan kegunaan yang besar. Jika aplikasi Anda tidak memiliki argumen UX yang kuat yang akan mengarah pada pengalaman negatif untuk mendukung orientasi lain, Anda mungkin tidak boleh memaksakan lansekap. Saya berbicara tentang hal-hal seperti "ini adalah aplikasi mesin kasir untuk satu model spesifik tablet yang selalu digunakan di dock perangkat keras tetap."

Jadi sebagian besar aplikasi seharusnya membiarkan sensor ponsel, perangkat lunak, dan konfigurasi fisik membuat keputusan sendiri tentang bagaimana pengguna ingin berinteraksi dengan aplikasi Anda. Namun, beberapa kasus mungkin masih ingin Anda pikirkan, jika Anda tidak puas dengan perilaku sensororientasi default dalam use case Anda:

  • Jika masalah utama Anda adalah perubahan yang tidak disengaja mengubah aktivitas di tengah yang Anda pikir sensor dan perangkat lunak perangkat tidak akan dapat mengatasi dengan baik (misalnya, dalam permainan berbasis kemiringan) pertimbangkan untuk mendukung lanskap dan potret, tetapi gunakan nosensoruntuk orientasi. Ini memaksa lansekap di sebagian besar tablet dan potret di sebagian besar ponsel, tetapi saya masih tidak akan merekomendasikan ini untuk sebagian besar aplikasi "normal" (beberapa pengguna hanya ingin mengetikkan softkeyboard lansekap di ponsel mereka, dan banyak pengguna tablet membaca dalam potret - dan Anda harus membiarkannya).
  • Jika Anda masih perlu memaksa potret karena alasan tertentu, sensorPortraitmungkin lebih baik daripada portraituntuk Android 2.3+; ini memungkinkan potret terbalik, yang cukup umum dalam penggunaan tablet.

54
Dimungkinkan untuk melakukannya untuk seluruh aplikasi. Lihat ini stackoverflow.com/a/9784269/1300707
Liam George Betsworth

1
Saya perhatikan bahwa ada potret lain: sensorPortait. Apa perbedaan antara sensorPortait dan potret?
Jacky

1
Jika Anda membaca dokumen Google : "Orientasi potret, tetapi dapat berupa potret normal atau terbalik berdasarkan sensor perangkat. Ditambahkan dalam API level 9." Jadi - yaitu - "potret, sisi kanan atas atau bawah, hanya Android 2.3+."
Yoni Samlan

2
Seperti yang saya catat dalam jawaban saya di bawah ini - untuk mengatasi beberapa masalah, "nosensor" kemungkinan merupakan pilihan yang lebih baik.
Mike Weir

1
Saya harus mengatakan saya tidak setuju. Tidak semua pengalaman kompatibel dengan mode lansekap pada ponsel, jadi Anda harus membiarkan UX memutuskan, bukan sensor. Ini tidak terjadi pada tablet.
Renzo Tissoni

110

Saya tidak mengetahui AndroidManifest.xmlperalihan file sampai membaca posting ini, jadi di aplikasi saya saya telah menggunakan ini sebagai gantinya:

setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);     //  Fixed Portrait orientation

9
ini dapat membuat aktivitas Anda melompat pada pemuatan pertama jika perangkat tidak dalam orientasi yang ditentukan.
Dori

Saya menggunakan metode ini, saya memanggilnya di OnCreate lalu saya akan membaca data dari beberapa file aset. Jika saya akan memulai aplikasi dengan perangkat dalam orientasi lanskap itu akan berputar tetapi ini akan mengakibatkan salah membaca aset inisialisasi, untuk beberapa alasan aneh (mungkin harus menunggu rotasi untuk menyelesaikan beberapa cara). Menggunakan alternatif xml tidak menyebabkan masalah ini.
Radu Simionescu

1
Itu mungkin menjadi masalah dengan urutan memulai untuk program Android. Anda dapat mencoba memindahkan setRequestedOrientation () ke onResume () ???
Kaya

45

Tambahkan ini android:screenOrientation="portrait"dalam file manifes Anda tempat Anda mendeklarasikan aktivitas Anda seperti ini

<activity android:name=".yourActivity"
    ....
    android:screenOrientation="portrait" />

Jika Anda ingin menggunakan kode java coba

setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

sebelum Anda memanggil setContentViewmetode untuk aktivitas Anda di onCreate().

Semoga bantuan ini dan mudah dimengerti untuk semua ...


29

Banyak jawaban di sini menyarankan untuk digunakan "portrait"dalam file AndroidManifest.xml Anda. Ini mungkin tampak seperti solusi yang baik - tetapi seperti dicatat dalam dokumentasi, Anda memilih perangkat yang mungkin hanya memiliki lanskap. Anda juga memaksa perangkat tertentu (yang berfungsi terbaik dalam lanskap) untuk masuk ke potret, bukan mendapatkan orientasi yang tepat.

Saran saya adalah menggunakan "nosensor"sebagai gantinya. Ini akan meninggalkan perangkat untuk menggunakan orientasi pilihan standarnya, tidak akan memblokir pembelian / unduhan di Google Play, dan akan memastikan sensor tidak mengacaukan game (NDK, dalam kasus saya) Anda.


Karena banyak yang memilih ini, saya ingin menunjukkan bahwa saya telah pergi dengan jawaban lain yang menyarankan "potret" seperti yang dilakukan oleh perangkat tertentu yang sebenarnya tidak terduga ketika ingin menerapkan rotasi layar dalam aplikasi, yang menjadi persyaratan nanti untuk saya. Saya juga ragu aplikasi dengan "potret" akan diblokir oleh pengaturan Google Play apa pun.
Mike Weir

Google Play sebenarnya menyaring aplikasi potret-hanya pada perangkat lanskap saja, lihat catatan di halaman ini: developer.android.com/guide/topics/manifest/… ("nilai yang Anda nyatakan memungkinkan penyaringan oleh layanan seperti Google Mainkan ")
miracle2k

14

Jika Anda ingin pengaturan pengguna,

maka saya akan merekomendasikan setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

Anda dapat mengubah pengaturan dari menu pengaturan.

Saya memerlukan ini karena penghitung waktu saya harus sesuai dengan apa yang ada di layar, dan memutar layar akan menghancurkan aktivitas saat ini.


14

Cukup tambahkan Suka Baris ini di Manifes Anda

android: screenOrientation = "portrait"

<manifest
    package="com.example.speedtest"
    android:versionCode="1"
    android:versionName="1.0" >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >


        <activity
            android:name="ComparisionActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
        </activity>

    </application>

</manifest>   

9

Anda dapat melakukan ini untuk seluruh aplikasi Anda tanpa harus membuat semua aktivitas Anda memperpanjang kelas dasar bersama.

Caranya adalah pertama-tama memastikan Anda menyertakan subkelas Aplikasi dalam proyek Anda. Di onCreate (), yang dipanggil saat aplikasi Anda pertama kali dijalankan, Anda mendaftarkan objek ActivityLifecycleCallbacks (API level 14+) untuk menerima pemberitahuan peristiwa siklus hidup aktivitas.

Ini memberi Anda kesempatan untuk mengeksekusi kode Anda sendiri setiap kali aktivitas di aplikasi Anda dimulai (atau dihentikan, atau dilanjutkan, atau apa pun). Pada titik ini Anda dapat memanggil setRequestedOrientation () pada aktivitas yang baru dibuat.

Dan jangan lupa untuk menambahkan aplikasi: name = ". MyApp" di file manifes Anda.

class MyApp extends Application {

    @Override
    public void onCreate() {
        super.onCreate();  

        // register to be informed of activities starting up
        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {

            @Override
            public void onActivityCreated(Activity activity, 
                                          Bundle savedInstanceState) {

                // new activity created; force its orientation to portrait
                activity.setRequestedOrientation(
                    ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
            ....
        });
    }
}

7

Gunakan ini di onCreate () dari Kegiatan

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

7

Anda harus berubah android:screenOrientation="sensorPortrait"di AndroidManifest.xml


6

Cukup tambahkan atribut ini di tag aktivitas Anda.

 android:screenOrientation="portrait"

6

Jika Anda tidak ingin melalui kerumitan menambahkan orientasi di setiap entri nyata aktivitas yang lebih baik, buat kelas BaseActivity (mewarisi 'Aktivitas' atau 'AppCompatActivity') yang akan diwarisi oleh setiap aktivitas aplikasi Anda alih-alih 'Aktivitas 'atau' AppCompatActivity 'dan tambahkan saja kode berikut di BaseActivity Anda:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    // rest of your code......
}

5

Tambahkan android:screenOrientation="portrait"ke aktivitas yang Anda ingin menonaktifkan mode lansekap.


5

Jika Anda ingin menonaktifkan Landscape mode for your android app(atau satu aktivitas) yang perlu Anda lakukan adalah menambahkan,

android:screenOrientation="portrait"ke tag aktivitas dalam AndroidManifest.xmlfile.

Suka:

<activity android:name="YourActivityName" 
    android:icon="@drawable/ic_launcher" 
    android:label="Your App Name" 
    android:screenOrientation="portrait">

Cara Lain, Pendekatan Programatis.

Jika Anda ingin melakukan ini yaitu secara programatik. menggunakan kode Java. Anda dapat melakukannya dengan menambahkan kode di bawah ini di kelas Java dari aktivitas yang Anda tidak ingin ditampilkan dalam mode lansekap.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

Saya harap ini membantu Anda. Untuk lebih jelasnya Anda dapat mengunjungi di sini, masukkan deskripsi tautan di sini


2
Karena begitu banyak jawaban memberikan saran yang bertentangan dengan saran bagus dari @Phoenix dan @ Yoni, saya pikir intinya adalah mengulangi apa yang mereka sarankan:android:screenOrientation="nosensor">
DSlomer64

1
@ DSlomer64 Ya. Jika Anda ingin mengatasi perangkat tablet, maka Anda harus menggunakan nilai nosensor sebagai gantinya
IntelliJ Amiya

5

Cara mengubah orientasi di beberapa tampilan

Alih-alih mengunci orientasi seluruh aktivitas, Anda dapat menggunakan kelas ini untuk secara dinamis mengunci orientasi dari salah satu tampilan Anda secara pragmatis: -

Jadikan pemandangan Anda Landscape

OrientationUtils.lockOrientationLandscape(mActivity);

Buat Potret Anda

OrientationUtils.lockOrientationPortrait(mActivity);

Buka Orientasi

OrientationUtils.unlockOrientation(mActivity);

Kelas Util Orientasi

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Build;
import android.view.Surface;
import android.view.WindowManager;

/*  * This class is used to lock orientation of android app in nay android devices 
 */

public class OrientationUtils {
    private OrientationUtils() {
    }

    /** Locks the device window in landscape mode. */
    public static void lockOrientationLandscape(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
    }

    /** Locks the device window in portrait mode. */
    public static void lockOrientationPortrait(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    /** Locks the device window in actual screen mode. */
    public static void lockOrientation(Activity activity) {
        final int orientation = activity.getResources().getConfiguration().orientation;
        final int rotation = ((WindowManager) activity.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
                .getRotation();

        // Copied from Android docs, since we don't have these values in Froyo
        // 2.2
        int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8;
        int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9;

        // Build.VERSION.SDK_INT <= Build.VERSION_CODES.FROYO
        if (!(Build.VERSION.SDK_INT <= Build.VERSION_CODES.FROYO)) {
            SCREEN_ORIENTATION_REVERSE_LANDSCAPE = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            SCREEN_ORIENTATION_REVERSE_PORTRAIT = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        }

        if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90) {
            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            }
        } else if (rotation == Surface.ROTATION_180 || rotation == Surface.ROTATION_270) {
            if (orientation == Configuration.ORIENTATION_PORTRAIT) {
                activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_PORTRAIT);
            } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
            }
        }
    }

    /** Unlocks the device window in user defined screen mode. */
    public static void unlockOrientation(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
    }

}

4

menggunakan

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

4

Anda harus mengatur orientasi setiap aktivitas.

<activity
                android:name="com.example.SplashScreen2"
                android:label="@string/app_name"
                android:screenOrientation="portrait"
                android:theme="@android:style/Theme.Black.NoTitleBar" >
            </activity>
            <activity
                android:name="com.example.Registration"
                android:label="@string/app_name"
                android:screenOrientation="portrait"
                android:theme="@android:style/Theme.Black.NoTitleBar" >
            </activity>
            <activity
                android:name="com.example.Verification"
                android:label="@string/app_name"
                android:screenOrientation="portrait"
                android:theme="@android:style/Theme.Black.NoTitleBar" >
            </activity>
            <activity
                android:name="com.example.WelcomeAlmostDone"
                android:label="@string/app_name"
                android:screenOrientation="portrait"
                android:theme="@android:style/Theme.Black.NoTitleBar" >
            </activity>
            <activity
                android:name="com.example.PasswordRegistration"
                android:label="@string/app_name"
                android:screenOrientation="portrait"
                android:theme="@android:style/Theme.Black.NoTitleBar" >
            </activity>

4

tambahkan kelas di dalam metode oncreate ()

 setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

4

Jika Anda menggunakan Xamarin C # beberapa solusi ini tidak akan berfungsi. Inilah solusi yang saya temukan untuk berhasil.

[Activity(MainLauncher = true, Icon = "@drawable/icon", ScreenOrientation = ScreenOrientation.Portrait)]

Di atas kelas berfungsi dengan baik, mirip dengan solusi lain, juga tidak berlaku secara global dan perlu ditempatkan di setiap header aktivitas.


4

Anda dapat memaksa aktivitas khusus Anda untuk selalu tetap dalam mode potret dengan menulis ini di manifes.xml Anda

 <activity android:name=".MainActivity"
        android:screenOrientation="portrait"></activity>

Anda juga dapat memaksa aktivitas Anda untuk tetap dalam mode posrait dengan menulis baris berikut dalam metode onCreate () aktivitas Anda

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_layout);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

}

3
<android . . . >
    . . .
    <manifest . . . >
        . . .
        <application>
            <activity android:name=".MyActivity" 
                android:screenOrientation="portrait" 
                android:configChanges="keyboardHidden|orientation">
            </activity>
        </application>
    </manifest>
</android>

3

Tambahkan di bawah ini memuji proyek Anda,

npm instal

npm saya bereaksi-asli-orientasi-loker

maka Anda menggunakan kelas manifes seperti, React_Native (Folder Proyek Anda) / android / app / src / main / AndroidManifest.xml

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

<application
  android:name=".MainApplication"
  android:label="@string/app_name"
  android:icon="@mipmap/ic_launcher"
  android:allowBackup="false"
  android:theme="@style/AppTheme">
  <activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:screenOrientation="landscape"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    android:windowSoftInputMode="adjustResize">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
  </activity>
  <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
</application>

Terima kasih!


2

Dalam <apphome>/platform/androiddirektori yang dibuat AndroidManifest.xml(menyalinnya dari yang dihasilkan). Kemudian tambahkan android:screenOrientation=" portrait" ke SEMUA elemen aktivitas.


2
 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="in.co.nurture.bajajfinserv">
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>


    <application

        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity" android:screenOrientation="portrait">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

kita dapat membatasi Kegiatan dalam mode potret atau lansekap dengan menggunakan atribut atau android: screenOrientation.

jika kami memiliki lebih dari satu aktivitas dalam program saya, maka Anda memiliki kebebasan untuk membatasi aktivitas apa pun dalam mode apa pun dan tidak pernah memengaruhi aktivitas lain yang tidak Anda inginkan.


2

Baik di kelas manifes.

<activity android:name=".yourActivity"
    ....
    android:screenOrientation="portrait" />

atau secara terprogram

setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

Catatan: Anda harus memanggil ini sebelum setContentViewmetode untuk aktivitas Anda di onCreate().


2

Menambahkan android:screenOrientation="portrait"di AndroidManifest.xml berkas.

Sebagai contoh :

<activity android:name=".MapScreen" 
 android:screenOrientation="portrait"></activity>

1

Dengan harapan dapat membantu orang lain, atribut berikut pada ACTIVITY di AndroidManifest.xml adalah yang Anda butuhkan:

android: configChanges = "orientasi"

Jadi, simpul aktivitas lengkap:

<activity android:name="Activity1" 
    android:icon="@drawable/icon" 
    android:label="App Name" 
    android:configChanges="orientation">

Ada begitu banyak jawaban yang tersisa, Anda harus memberikan lebih banyak informasi, mengapa orang harus menggunakan Anda. Terutama dokumen yang mengatakan tidak menggunakan Opsi ini: "Catatan: Menggunakan atribut ini harus dihindari dan digunakan hanya sebagai upaya terakhir. Silakan baca Menangani Perubahan Waktu Runtime untuk informasi lebih lanjut tentang cara menangani restart dengan benar karena perubahan konfigurasi." developer.android.com/guide/topics/manifest/…
Murmel

1

Dalam kotlin, hal yang sama dapat dicapai secara terprogram menggunakan di bawah ini

requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT

1

Ini bekerja untuk saya, Coba tambahkan kode ini di file AndroidManifest

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:screenOrientation="portrait"
        android:theme="@style/AppTheme">
        ....
        ....
        </application>

Saya akan menjadi solusi yang hebat, karena Anda tidak harus menetapkan per aktivitas. Sayangnya, tidak berfungsi di aplikasi saya.
Myroslav Kolodii

1

Masukkan ke dalam manifes Anda.

<activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:screenOrientation="sensorPortrait" />

Orientasinya akan tegak, tetapi jika telepon pengguna terbalik, itu menunjukkan cara yang benar juga. (Jadi layar Anda akan berputar 180 derajat).


Sistem mengabaikan atribut ini jika aktivitas berjalan dalam mode multi-jendela .


0

jika aktivitas Anda terkait dengan status orientasi perangkat pertama, dapatkan orientasi perangkat saat ini dalam onCreatemetode dan kemudian perbaiki selamanya:

        int deviceRotation = ((WindowManager) getBaseContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();

        if(deviceRotation == Surface.ROTATION_0) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
        else if(deviceRotation == Surface.ROTATION_180)
        {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
        }
        else if(deviceRotation == Surface.ROTATION_90)
        {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        }
        else if(deviceRotation == Surface.ROTATION_270)
        {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
        }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.