ป้องกันการหมุนหน้าจอบน Android


315

ฉันมีหนึ่งในกิจกรรมของฉันที่ฉันต้องการป้องกันไม่ให้หมุนเนื่องจากฉันเริ่มต้น AsyncTask และการหมุนหน้าจอทำให้รีสตาร์ท

มีวิธีที่จะบอกกิจกรรมนี้ "อย่าหมุนหน้าจอแม้ว่าผู้ใช้จะเขย่าโทรศัพท์ของเขาอย่างบ้าคลั่ง"?



11
คุณสามารถจัดการกับการเปลี่ยนการวางแนวหน้าจอและ AsyncTasks การป้องกันการเปลี่ยนแนวหน้าจอเป็นเพียงวิธีการแก้ปัญหาที่ขี้เกียจ และมันก็ไม่ยากที่จะทำให้ AsyncTask มีชีวิตอยู่ตลอดการเปลี่ยนแปลงการวางแนว :)
Romain Guy


56
มันจะมีประโยชน์มากขึ้นในการจัดหาโซลูชันจริงหรือรหัส Romain แทนที่จะเป็นเพียงแค่ใส่ "วิธีแก้ไขปัญหาที่มีอยู่และไม่ยาก"
Peter vdL

2
คุณสามารถใช้ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
mcy

คำตอบ:


467

เพิ่ม

android:screenOrientation="portrait" 

หรือ

 android:screenOrientation="landscape" 

ถึง<activity>องค์ประกอบ / s ในรายการและคุณทำเสร็จแล้ว


95
โปรดทราบว่านี่เป็นเพียงการซ่อนข้อบกพร่องในแอปของคุณทำให้ผู้ใช้มีโอกาสเดินทางข้ามแอปน้อยลง แต่พวกเขาจะยังคง การเปลี่ยนแปลงการกำหนดค่าใด ๆ อาจทำให้กิจกรรมของคุณเริ่มต้นใหม่ คุณต้องเขียนกิจกรรมของคุณอย่างถูกต้องเพื่อจัดการกับภารกิจ async เมื่อเริ่มต้นใหม่
hackbod

1
สิ่งนี้ไม่ได้ผลสำหรับฉันในกรณีเดียว ฉันตั้งค่าหน้าจอเป็นแนวนอนก่อนเปิดแอป เมื่อฉันเปิดแอพหน้าจอหมุนเป็นแนวตั้งและทำให้เกิดการเรียกครั้งที่สองไปยัง asynctask
user522559

2
คุณต้องตั้งค่าเป็น "เปิดในโหมดแนวตั้ง" และ "อยู่ในโหมดแนวตั้งเสมอ" การทำเพียง 1 เดียวนั้นไร้จุดหมาย
Carol

1
@hackbod โดยไม่คำนึงถึงนี้เป็น # หมายเลข 1 ของ google ตีสำหรับ "หุ่นยนต์ app ป้องกันการหมุนหน้าจอ" ความต้องการของฉันมีอะไรจะทำอย่างไรกับงาน async
chiliNUT

7
@hackbod แล้วเราจะเขียนกิจกรรมของเราอย่างถูกต้องเพื่อจัดการกับปัญหานี้ได้อย่างไร?
user41805

127

คุณสามารถปฏิบัติตามตรรกะด้านล่างเพื่อป้องกันหน้าจอหมุนอัตโนมัติในขณะที่คุณAsyncTaskกำลังทำงาน:

  1. getRequestedOrientation()เก็บวางหน้าจอปัจจุบันของคุณภายในกิจกรรมของคุณโดยใช้
  2. setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR)ปิดการใช้งานการวางแนวหน้าจออัตโนมัติโดยใช้
  3. Run / AsyncTaskดำเนินการของคุณ
  4. ในตอนท้ายของคุณเรียกคืนสถานะการปฐมนิเทศก่อนหน้านี้ของคุณโดยใช้AsyncTasksetRequestedOrientation(oldOrientation)

โปรดทราบว่ามีหลายวิธีที่จะเข้าถึงActivity(ซึ่งทำงานในหัวข้อ UI) AsyncTaskคุณสมบัติภายใน คุณสามารถใช้AsyncTaskคลาสของคุณเป็นคลาสภายในหรือใช้ข้อความHandlerที่กระตุ้นActiviyคลาสของคุณ


9
ดีกว่าคำตอบที่เลือก
Matej

3
แนวคิดที่ยอดเยี่ยม :) คุณไม่มีการวางแนวหน้าจอในปัจจุบันของคุณคุณสามารถใช้ ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
fligant

ดูเหมือนว่าจะไม่น่าเชื่อ @emre ขอบคุณ! ดูเหมือนว่า"ดีเกินจริง!" สังเกตเห็นการอภิปรายจำนวนมากเกี่ยวกับปัญหา: stackoverflow.com/q/3821423/294884 ... ผู้เชี่ยวชาญ android มีข้อเสียอยู่ที่นี่หรือไม่! ขอบคุณอีกครั้ง .. มาก
Fattie

3
อึ!! สิ่งนี้ไม่ทำงานหากอุปกรณ์เกิดขึ้นกับ BEGIN ในโหมดภูมิทัศน์ อะไรกันเนี่ย! Sux: O
Fattie

@Emre รหัสนี้ใช้ไม่ได้ในบางกรณี เช่นหากผู้ใช้เปลี่ยนการวางแนวของเขาระหว่างการเริ่มต้นของ AsyncTask ของคุณและจุดสิ้นสุดของมัน คุณจะได้รับการบันทึกและเรียกคืนการวางแนวที่ไม่ถูกต้องแล้ว
Pacerier

27

ในไฟล์ Manifest ของคุณสำหรับแต่ละกิจกรรมที่คุณต้องการล็อคการหมุนหน้าจอเพิ่ม: ถ้าคุณต้องการล็อคในโหมดแนวนอน:

<activity
        ...
        ...
        android:screenOrientation="landscape">

หรือถ้าคุณต้องการล็อคในโหมดแนวตั้ง:

<activity
            ...
            ...
            android:screenOrientation="portrait">

24

วิธีที่ง่ายที่สุดที่ฉันพบคือทำ

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

ภายในบนสร้างหลังจาก

setContentView(R.layout.activity_main);

ดังนั้น...

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

7

แทนที่จะเข้าสู่ AndroidManifest คุณสามารถทำสิ่งนี้ได้:

screenOrientation = getResources().getConfiguration().orientation;
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
... AsyncTask

screenOrientation = getResources().getConfiguration().orientation;


@Override
protected void onPostExecute(String things) {
    context.setRequestedOrientation(PlayListFragment.screenOrientation);
    or 
    context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
}

ข้อเสียเปรียบเพียงอย่างเดียวที่นี่คือมันต้องมีระดับ API 18 หรือสูงกว่า โดยพื้นฐานแล้วนี่คือปลายหอก


ส่วนนี้จะปิดใช้งานปุ่มโฮมและแอพล่าสุดและแม้หลังจากปลดล็อคด้วย SCREEN_ORIENTATION_FULL_SENSOR ซึ่งอยู่ในสถานะปิดใช้งาน ใน Android N.
kAmol

6

Activity.java

@Override     
 public void onConfigurationChanged(Configuration newConfig) {       
        try {     
            super.onConfigurationChanged(newConfig);      
            if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {      
                // land      
            } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {      
               // port       
            }    
        } catch (Exception ex) {       
     }   

AndroidManifest.xml

 <application android:icon="@drawable/icon" android:label="@string/app_name">
  <activity android:name="QRCodeActivity" android:label="@string/app_name"
  android:screenOrientation="landscape" >
   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  </activity>

 </application>

2

แอ็ตทริบิวต์ต่อไปนี้บน ACTIVITY ใน AndroidManifest.xml เป็นสิ่งที่คุณต้องการ:

android:configChanges="orientation"

ดังนั้นโหนดกิจกรรมแบบเต็มจะเป็น:

<activity android:name="Activity1"
          android:icon="@drawable/icon"
          android:label="App Name"
          android:excludeFromRecents="true"
          android:configChanges="orientation">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>

1

เพิ่ม:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
        ...
        ...
        ...
}

1

เพิ่มสิ่งต่อไปนี้ลงใน AndroidManifest.xml ของคุณ

[แอป> src> หลัก> AndroidManifest.xml]

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

ตัวอย่าง:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xxx.zzzzzz.yyyyy">

   <uses-permission android:name="A-PERMISSION" />

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

</manifest>

0

หากคุณกำลังใช้Android Developer Tools (ADT) และEclipse คุณสามารถไปที่ AndroidManifest.xml -> แท็บแอปพลิเคชัน -> ลงไปและเลือกกิจกรรมของคุณ สุดท้ายเลือกการวางแนวที่คุณต้องการ คุณสามารถเลือกหนึ่งในตัวเลือกมากมาย


0

คุณต้องเพิ่มรหัสต่อไปนี้ในไฟล์ manifest.xml กิจกรรมที่ไม่ควรหมุนในกิจกรรมนั้นให้เพิ่มองค์ประกอบนี้

android:screenOrientation="portrait"

จากนั้นมันจะไม่หมุน


0

คุณสามารถลองด้วยวิธีนี้

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itclanbd.spaceusers">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<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=".Login_Activity"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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


0

ใช้AsyncTaskLoaderเพื่อให้ข้อมูลของคุณปลอดภัยแม้ว่ากิจกรรมจะเปลี่ยนไปแทนที่จะใช้AsyncTaskซึ่งเป็นวิธีที่ดีกว่าในการสร้างแอปมากกว่าป้องกันการหมุนหน้าจอ


0

ป้องกันการหมุนหน้าจอเพียงเพิ่มบรรทัดต่อไปนี้ในรายการของคุณ

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

มันใช้งานได้สำหรับฉัน


0

ผู้ใช้"portrait"ในไฟล์ AndroidManifest.xml ของคุณอาจเป็นทางออกที่ดี แต่มันบังคับให้อุปกรณ์บางอย่าง (ที่ทำงานได้ดีที่สุดในแนวนอน) ไปเป็นแนวตั้งไม่ได้รับการวางแนวที่เหมาะสม ในเวอร์ชั่น Android ล่าสุดคุณจะได้รับข้อผิดพลาด "nosensor"ดังนั้นคำแนะนำของฉันดีกว่าที่จะใช้

<activity
        ...
        ...
        android:screenOrientation="nosensor">
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.