Kiểm tra hướng trên điện thoại Android


Câu trả lời:


676

Cấu hình hiện tại, như được sử dụng để xác định tài nguyên nào cần truy xuất, có sẵn từ Configurationđối tượng Tài nguyên :

getResources().getConfiguration().orientation;

Bạn có thể kiểm tra định hướng bằng cách xem giá trị của nó:

int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
    // In landscape
} else {
    // In portrait
}

Thông tin thêm có thể được tìm thấy trong Nhà phát triển Android .


2
Ôi xin lỗi tôi đã hiểu nhầm, tôi nghĩ bạn đang nói rằng dịch vụ sẽ không thấy cấu hình thay đổi nếu cấu hình thay đổi. Những gì bạn đang mô tả là ... tốt, nó không nhìn thấy gì cả, vì không có gì thay đổi, vì trình khởi chạy đã khóa hướng màn hình và không cho phép nó thay đổi. Vì vậy, chính xác là .orientation không thay đổi, vì định hướng không thay đổi. Màn hình vẫn là chân dung.
hackbod

Điều gần nhất tôi có thể làm là đọc định hướng từ các cảm biến liên quan đến toán học mà tôi không thực sự quan tâm lắm để tìm ra vào lúc này.
Archimedes Trajano

13
Không có gì phải khó chịu về. Màn hình chưa được quay, nó vẫn ở chế độ dọc, không có góc quay để xem. Nếu bạn muốn theo dõi cách người dùng di chuyển điện thoại của họ bất kể màn hình được xoay như thế nào, thì có, bạn cần phải trực tiếp xem cảm biến và quyết định cách bạn muốn diễn giải thông tin bạn nhận được về cách thiết bị di chuyển.
hackbod

4
Điều này sẽ thất bại nếu hướng màn hình được cố định.
AndroidDev

7
Nếu hoạt động khóa màn hình ( android:screenOrientation="portrait"), phương thức này sẽ trả về cùng một giá trị bất kể người dùng xoay thiết bị như thế nào. Trong trường hợp đó, bạn sẽ sử dụng gia tốc kế hoặc cảm biến trọng lực để tìm ra hướng chính xác.
Mèo

169

Nếu bạn sử dụng getResource (). GetConfiguration (). Định hướng trên một số thiết bị, bạn sẽ hiểu sai. Chúng tôi đã sử dụng phương pháp đó ban đầu trong http://apphance.com . Nhờ đăng nhập từ xa của Apphance, chúng tôi có thể thấy nó trên các thiết bị khác nhau và chúng tôi thấy rằng sự phân mảnh đóng vai trò của nó ở đây. Tôi thấy các trường hợp kỳ lạ: ví dụ: xen kẽ chân dung và hình vuông (?!) Trên HTC Desire HD:

CONDITION[17:37:10.345] screen: rotation: 270 orientation: square
CONDITION[17:37:12.774] screen: rotation: 0 orientation: portrait
CONDITION[17:37:15.898] screen: rotation: 90
CONDITION[17:37:21.451] screen: rotation: 0
CONDITION[17:38:42.120] screen: rotation: 270 orientation: square

hoặc không thay đổi định hướng nào cả:

CONDITION[11:34:41.134] screen: rotation: 0
CONDITION[11:35:04.533] screen: rotation: 90
CONDITION[11:35:06.312] screen: rotation: 0
CONDITION[11:35:07.938] screen: rotation: 90
CONDITION[11:35:09.336] screen: rotation: 0

Mặt khác, width () và height () luôn luôn chính xác (nó được sử dụng bởi trình quản lý cửa sổ, vì vậy nó sẽ tốt hơn). Tôi muốn nói rằng ý tưởng tốt nhất là kiểm tra chiều rộng / chiều cao LUÔN. Nếu bạn nghĩ về một khoảnh khắc, đây chính xác là những gì bạn muốn - để biết nếu chiều rộng nhỏ hơn chiều cao (chân dung), ngược lại (phong cảnh) hoặc nếu chúng giống nhau (vuông).

Sau đó, nó đi xuống mã đơn giản này:

public int getScreenOrientation()
{
    Display getOrient = getWindowManager().getDefaultDisplay();
    int orientation = Configuration.ORIENTATION_UNDEFINED;
    if(getOrient.getWidth()==getOrient.getHeight()){
        orientation = Configuration.ORIENTATION_SQUARE;
    } else{ 
        if(getOrient.getWidth() < getOrient.getHeight()){
            orientation = Configuration.ORIENTATION_PORTRAIT;
        }else { 
             orientation = Configuration.ORIENTATION_LANDSCAPE;
        }
    }
    return orientation;
}

3
Cảm ơn! Khởi tạo "định hướng" là không cần thiết mặc dù.
MrMaffen

getWidthgetHeightkhông được phản đối
FindOut_Quran

3
@ user3441905, đúng vậy. Sử dụng getSize(Point outSize)thay thế. Tôi đang sử dụng API 23.
WindRider

@ jarek-potiuk nó bị phản đối.
Hades

53

Một cách khác để giải quyết vấn đề này là không dựa vào giá trị trả về chính xác từ màn hình mà dựa vào giải quyết tài nguyên Android.

Tạo tập tin layouts.xmltrong các thư mục res/values-landres/values-portvới nội dung sau:

res / value-land / layouts.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="is_landscape">true</bool>
</resources>

res / value-port / layouts.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="is_landscape">false</bool>
</resources>

Trong mã nguồn của bạn, bây giờ bạn có thể truy cập vào hướng hiện tại như sau:

context.getResources().getBoolean(R.bool.is_landscape)

1
Tôi thích điều này vì nó sử dụng bất cứ cách nào hệ thống đã xác định định hướng
KrustyGString

1
Câu trả lời tốt nhất cho kiểm tra phong cảnh / chân dung!
vtlinh

Giá trị của nó trong tệp giá trị mặc định là gì?
Shashank Mishra

46

Một cách đầy đủ để xác định hướng hiện tại của điện thoại:

    public String getRotation(Context context){
    final int rotation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();
           switch (rotation) {
            case Surface.ROTATION_0:
                return "portrait";
            case Surface.ROTATION_90:
                return "landscape";
            case Surface.ROTATION_180:
                return "reverse portrait";
            default:
                return "reverse landscape";
            }
        }

Chear Bình Nguyên


6
Có một lỗi đánh máy trong bài viết của bạn - nên nói .getRotation () không getOrientation
Keith

1
+1 cho điều này. Tôi cần phải biết định hướng chính xác, không chỉ là phong cảnh vs chân dung. getOrientation () là chính xác trừ khi bạn sử dụng SDK 8+ trong trường hợp bạn nên sử dụng getRotation (). Các chế độ 'đảo ngược' được hỗ trợ trong SDK 9+.
Paul

6
@Keith @Paul Tôi không nhớ cách getOrientation()hoạt động, nhưng điều này không đúng nếu sử dụng getRotation(). Nhận "Returns the rotation of the screen from its "natural" orientation." nguồn quay . Vì vậy, trên điện thoại cho biết ROTATION_0 là chân dung có thể đúng, nhưng trên máy tính bảng, hướng "tự nhiên" của nó có khả năng là phong cảnh và ROTATION_0 sẽ trả về phong cảnh thay vì dọc.
jp36

Có vẻ như đây là phương pháp ưa thích tham gia về phía trước: developer.android.com/reference/android/view/iêu
jaysqrd

Đây là một câu trả lời sai. Tại sao nó được bình chọn? Các giá trị getOrientation (float [] R, float []) tính toán hướng của thiết bị dựa trên ma trận xoay.
dùng1914692

29

Dưới đây là đoạn giới thiệu đoạn mã làm thế nào để có được hướng màn hình được đề xuất bởi hackbodMartijn :

Kích hoạt khi thay đổi Định hướng:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
        int nCurrentOrientation = _getScreenOrientation();
    _doSomeThingWhenChangeOrientation(nCurrentOrientation);
}

Nhận định hướng hiện tại như hackbod khuyến nghị:

private int _getScreenOrientation(){    
    return getResources().getConfiguration().orientation;
}

Có giải pháp thay thế để có được hướng màn hình hiện tại ❷ theo giải pháp Martijn :

private int _getScreenOrientation(){
        Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
        return display.getOrientation();
}

Lưu ý : Tôi đã thử cả hai triển khai ❷ &, nhưng trên RealDevice (NexusOne SDK 2.3) Định hướng, nó trả về hướng sai.

★ Vì vậy, tôi khuyên bạn nên sử dụng giải pháp để có được Hướng màn hình có lợi thế hơn: rõ ràng, đơn giản và hoạt động như một nét duyên dáng.

★ Kiểm tra cẩn thận việc trả lại định hướng để đảm bảo chính xác như mong đợi của chúng tôi (Có thể bị giới hạn tùy thuộc vào thông số kỹ thuật của thiết bị vật lý)

Hy vọng nó sẽ giúp


16
int ot = getResources().getConfiguration().orientation;
switch(ot)
        {

        case  Configuration.ORIENTATION_LANDSCAPE:

            Log.d("my orient" ,"ORIENTATION_LANDSCAPE");
        break;
        case Configuration.ORIENTATION_PORTRAIT:
            Log.d("my orient" ,"ORIENTATION_PORTRAIT");
            break;

        case Configuration.ORIENTATION_SQUARE:
            Log.d("my orient" ,"ORIENTATION_SQUARE");
            break;
        case Configuration.ORIENTATION_UNDEFINED:
            Log.d("my orient" ,"ORIENTATION_UNDEFINED");
            break;
            default:
            Log.d("my orient", "default val");
            break;
        }

13

Sử dụng getResources().getConfiguration().orientationnó đúng cách.

Bạn chỉ cần coi chừng các loại cảnh quan khác nhau, phong cảnh mà thiết bị thường sử dụng và loại khác.

Vẫn không hiểu làm thế nào để quản lý điều đó.


12

Một thời gian đã trôi qua vì hầu hết các câu trả lời này đã được đăng và một số sử dụng các phương pháp và hằng số không dùng nữa.

Tôi đã cập nhật mã của Jarek để không sử dụng các phương thức và hằng số này nữa:

protected int getScreenOrientation()
{
    Display getOrient = getWindowManager().getDefaultDisplay();
    Point size = new Point();

    getOrient.getSize(size);

    int orientation;
    if (size.x < size.y)
    {
        orientation = Configuration.ORIENTATION_PORTRAIT;
    }
    else
    {
        orientation = Configuration.ORIENTATION_LANDSCAPE;
    }
    return orientation;
}

Lưu ý rằng chế độ Configuration.ORIENTATION_SQUAREkhông được hỗ trợ nữa.

Tôi thấy điều này đáng tin cậy trên tất cả các thiết bị mà tôi đã thử nghiệm trái ngược với phương pháp gợi ý sử dụng getResources().getConfiguration().orientation


Lưu ý rằng getOrient.getSize (kích thước) yêu cầu 13 cấp độ api
Lester

6

Kiểm tra hướng màn hình trong thời gian chạy.

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();

    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();        
    }
}

5

Có một cách khác để làm điều đó:

public int getOrientation()
{
    if(getResources().getDisplayMetrics().widthPixels>getResources().getDisplayMetrics().heightPixels)
    { 
        Toast t = Toast.makeText(this,"LANDSCAPE",Toast.LENGTH_SHORT);
        t.show();
        return 1;
    }
    else
    {
        Toast t = Toast.makeText(this,"PORTRAIT",Toast.LENGTH_SHORT);
        t.show();
        return 2;
    }       
}


4

Đã thử nghiệm vào năm 2019 trên API 28, bất kể người dùng có đặt hướng dọc hay không và với mã tối thiểu so với câu trả lời lỗi thời khác, sau đây sẽ cung cấp hướng chính xác:

/** @return The {@link Configuration#ORIENTATION_SQUARE}, {@link Configuration#ORIENTATION_PORTRAIT}, {@link Configuration#ORIENTATION_LANDSCAPE} constants based on the current phone screen pixel relations. */
private int getScreenOrientation()
{
    DisplayMetrics dm = context.getResources().getDisplayMetrics(); // Screen rotation effected

    if(dm.widthPixels == dm.heightPixels)
        return Configuration.ORIENTATION_SQUARE;
    else
        return dm.widthPixels < dm.heightPixels ? Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE;
}

2

Tôi nghĩ mã này có thể hoạt động sau khi thay đổi định hướng có hiệu lực

Display getOrient = getWindowManager().getDefaultDisplay();

int orientation = getOrient.getOrientation();

ghi đè hàm Activity.onConfigurationChanged (Cấu hình newConfig) và sử dụng newConfig, định hướng nếu bạn muốn nhận thông báo về hướng mới trước khi gọi setContentView.


2

Tôi nghĩ rằng việc sử dụng getRotationv () không giúp ích gì vì http://developer.android.com/reference/android/view/Display.html#getRotation%28%29 getRotation () Trả về góc quay của màn hình từ "tự nhiên" của nó sự định hướng.

vì vậy trừ khi bạn biết định hướng "tự nhiên", xoay vòng là vô nghĩa.

tôi tìm thấy một cách dễ dàng hơn,

  Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
  Point size = new Point();
  display.getSize(size);
  int width = size.x;
  int height = size.y;
  if(width>height)
    // its landscape

Xin vui lòng cho tôi biết nếu có vấn đề với ai đó?


2

như vậy đây là lớp phủ tất cả các điện thoại như oneplus3

public static boolean isScreenOriatationPortrait(Context context) {
         return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
         }

đúng mã như sau:

public static int getRotation(Context context){
        final int rotation = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getOrientation();

        if(rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180){
            return Configuration.ORIENTATION_PORTRAIT;
        }

        if(rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270){
            return Configuration.ORIENTATION_LANDSCAPE;
        }

        return -1;
    }

1

Bài cũ tôi biết. Dù định hướng có thể là gì hay bị tráo đổi, v.v. Tôi đã thiết kế chức năng này được sử dụng để đặt thiết bị theo đúng hướng mà không cần biết cách tổ chức các tính năng dọc và ngang trên thiết bị.

   private void initActivityScreenOrientPortrait()
    {
        // Avoid screen rotations (use the manifests android:screenOrientation setting)
        // Set this to nosensor or potrait

        // Set window fullscreen
        this.activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        DisplayMetrics metrics = new DisplayMetrics();
        this.activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);

         // Test if it is VISUAL in portrait mode by simply checking it's size
        boolean bIsVisualPortrait = ( metrics.heightPixels >= metrics.widthPixels ); 

        if( !bIsVisualPortrait )
        { 
            // Swap the orientation to match the VISUAL portrait mode
            if( this.activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT )
             { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); }
            else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ); }
        }
        else { this.activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); }

    }

Hoạt động như một lá bùa!


1

Sử dụng theo cách này

    int orientation = getResources().getConfiguration().orientation;
    String Orintaion = "";
    switch (orientation)
    {
        case Configuration.ORIENTATION_UNDEFINED: Orintaion = "Undefined"; break;
        case Configuration.ORIENTATION_LANDSCAPE: Orintaion = "Landscrape"; break;
        case Configuration.ORIENTATION_PORTRAIT:  Orintaion = "Portrait"; break;
        default: Orintaion = "Square";break;
    }

trong Chuỗi bạn có Oriantion


1

Có nhiều cách để làm điều này, đoạn mã này hoạt động với tôi

 if (this.getWindow().getWindowManager().getDefaultDisplay()
                .getOrientation() == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
             // portrait mode
} else if (this.getWindow().getWindowManager().getDefaultDisplay()
                .getOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
                      // landscape
        }

1

Tôi nghĩ giải pháp này dễ

if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
  user_todat_latout = true;
} else {
  user_todat_latout = false;
}

Nói chung, câu trả lời sẽ hữu ích hơn nhiều nếu chúng bao gồm một lời giải thích về những gì mã được dự định làm và tại sao điều đó giải quyết vấn đề mà không giới thiệu người khác.
Tom Aranda

vâng xin lỗi vì tôi nghĩ rằng nó không cần giải thích chính xác khối định hướng kiểm tra mã này nếu cấu hình bằng nhau.ORIENTATION_PORTRAIT có nghĩa là ứng dụng trong chân dung :)
Issac Nabil

1

Mã hai dòng đơn giản

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
    // do something in landscape
} else {
    //do in potrait
}

0

Đơn giản và dễ dàng :)

  1. Tạo bố cục 2 xml (tức là Chân dung và Phong cảnh)
  2. Tại tệp java, viết:

    private int intOrientation;

    tại onCreatephương thức và trước khi setContentViewviết:

    intOrientation = getResources().getConfiguration().orientation;
    if (intOrientation == Configuration.ORIENTATION_PORTRAIT)
        setContentView(R.layout.activity_main);
    else
        setContentView(R.layout.layout_land);   // I tested it and it works fine.

0

Điều đáng chú ý là ngày nay, có ít lý do hơn để kiểm tra định hướng rõ ràng getResources().getConfiguration().orientationnếu bạn làm như vậy vì lý do bố cục, vì Hỗ trợ nhiều cửa sổ được giới thiệu trong Android 7 / API 24+ có thể gây rối với bố cục của bạn khá nhiều sự định hướng. Tốt hơn nên xem xét sử dụng <ConstraintLayout>bố cục thay thế phụ thuộc vào chiều rộng hoặc chiều cao có sẵn , cùng với các thủ thuật khác để xác định bố cục nào đang được sử dụng, ví dụ: sự hiện diện hay không của các mảnh nhất định được gắn vào Hoạt động của bạn.


0

Bạn có thể sử dụng cái này (dựa vào đây ):

public static boolean isPortrait(Activity activity) {
    final int currentOrientation = getCurrentOrientation(activity);
    return currentOrientation == ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT || currentOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}

public static int getCurrentOrientation(Activity activity) {
    //code based on https://www.captechconsulting.com/blog/eric-miles/programmatically-locking-android-screen-orientation
    final Display display = activity.getWindowManager().getDefaultDisplay();
    final int rotation = display.getRotation();
    final Point size = new Point();
    display.getSize(size);
    int result;
    if (rotation == Surface.ROTATION_0
            || rotation == Surface.ROTATION_180) {
        // if rotation is 0 or 180 and width is greater than height, we have
        // a tablet
        if (size.x > size.y) {
            if (rotation == Surface.ROTATION_0) {
                result = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            } else {
                result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
            }
        } else {
            // we have a phone
            if (rotation == Surface.ROTATION_0) {
                result = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
            } else {
                result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
            }
        }
    } else {
        // if rotation is 90 or 270 and width is greater than height, we
        // have a phone
        if (size.x > size.y) {
            if (rotation == Surface.ROTATION_90) {
                result = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
            } else {
                result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
            }
        } else {
            // we have a tablet
            if (rotation == Surface.ROTATION_90) {
                result = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
            } else {
                result = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
            }
        }
    }
    return result;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.