2017-03-21 30 views
6

Tôi đang phát triển một ứng dụng dành cho thiết bị di động dựa trên Android với minSdkVersion=15. Tôi muốn hỗ trợ cả hai định hướng cho máy tính bảng và chỉ chụp chân dung cho điện thoại thông minh. Mọi thứ hoạt động như một sự quyến rũ nhưng tôi đang trải qua một lỗi nhỏ khiến tôi phát điên. Khi điện thoại thông minh đang ở chế độ ngang và tôi cố gắng kích hoạt một Hoạt động mới, nó sẽ mở ở chế độ nằm ngang trong một khoảng thời gian và sau đó tự động chuyển sang chế độ dọc. Mỗi một trong những hoạt động của tôi thừa kế một lớp GeneralActivity:Thay đổi hướng hoạt động tự động trên Android

public class GeneralActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     // If smartphone lock orientation to portrait 
     if (!Helper.isTablet(this.getApplicationContext())){ 
      this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
     } 
    } 
} 

tôi phát hiện máy tính bảng với chức năng này:

public class Helper { 
    public static boolean isTablet(Context context){ 
     Configuration config = context.getResources().getConfiguration() 
     return config.smallestScreenWidthDp >= 600; 
    } 
} 

tôi chọn không chỉ định android:screenOrientation bên manifest.xml vì theo cách đó tôi có thể để hỗ trợ tất cả định hướng giao diện cho máy tính bảng. Tôi có thiếu gì đó không?

EDIT

tôi quyết định áp dụng các thực hành tốt nhất gợi ý trong câu trả lời của Jonathan, nhưng vấn đề tôi đã mô tả vẫn còn ở đây. Đây là repo của tôi trên github: https://github.com/giacmarangoni/Android-Orientation-Test

+1

Hi, tôi đang phải đối mặt với cùng một vấn đề .. và nó chỉ xảy ra cho các thiết bị Nougat .. Tôi đã có kịch bản tương tự như của bạn và tôi bị mắc kẹt nặng trên đó. Bạn có may mắn không? –

Trả lời

0

Đây là cách hay để sử dụng tài nguyên và vòng loại kích thước.

Đặt này tài nguyên bool trong res/values ​​như bools.xml hoặc bất cứ điều gì (tên tập tin không quan trọng ở đây):

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

Đặt một này trong res/values-sw600dp và res/values-xlarge :

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

Xem câu trả lời bổ sung này để được trợ giúp thêm các thư mục và tệp này trong Android Studio.

Sau đó, trong phương pháp onCreate các hoạt động của bạn, bạn có thể làm điều này:

if(getResources().getBoolean(R.bool.portrait_only)){ 
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
} 

Devices có hơn 600 dp theo hướng chiều rộng nhỏ nhất, hoặc x-lớn trên trước Android 3.2 thiết bị (tablet , về cơ bản) sẽ hoạt động như bình thường, dựa trên cảm biến và xoay vòng do người dùng khóa, v.v. Mọi thứ khác (điện thoại, khá nhiều) sẽ chỉ là hình ảnh chân dung.

Nguồn: Original answer

+0

Xin chào Jonathan, tôi thực sự muốn cảm ơn vì câu trả lời của bạn. Tôi đã cố gắng áp dụng giải pháp bạn đề xuất và vấn đề tôi mô tả vẫn còn hiện diện. Tôi đẩy dự án của tôi vào một repo git. Kiểm tra chỉnh sửa của tôi nếu bạn muốn. –

+0

Xin chào JJack, tôi sẽ xem xét khi tôi có thời gian rảnh !, hy vọng bạn có thể nhận được câu trả lời sớm. May mắn nhất! –

0

Tôi có giải pháp này phù hợp với tôi. Trong manifest định hướng màn hình khai báo chân dung của bạn

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

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

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

Sau đó, trong hoạt động cơ sở của bạn trong onCreate trước khi bạn gọi super.onCreate nếu thiết bị là một viên thuốc thiết lập các định hướng đến không xác định.

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    if (!getResources().getBoolean(R.bool.portrait_only)) { 
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); 
    } 
    super.onCreate(savedInstanceState); 
} 

Từ các tài liệu:

Unspecified: Không ưu tiên quy định: để hệ thống quyết định định hướng tốt nhất. Đây sẽ là định hướng được chọn bởi hoạt động bên dưới hoặc hướng ưa thích của người dùng nếu hoạt động này là phần cuối của tác vụ.Nếu người dùng tắt định hướng dựa trên cảm biến thông qua việc xoay vòng thiết bị dựa trên cảm biến sẽ bị bỏ qua. Nếu không theo định hướng dựa trên cảm biến mặc định sẽ được tính đến và hướng sẽ thay đổi dựa trên cách người dùng xoay thiết bị.

Điều này làm việc cho tôi và cho đến nay tôi không tìm thấy bất kỳ hạn chế nào. Tôi đã chỉ thử nghiệm này trong giả lập và nó không có vẻ rằng các ứng dụng đang bắt đầu trong bức chân dung và sau đó quay như nó đã xảy ra với các giải pháp khác trên điện thoại. Dù sao, tôi muốn điện thoại hoạt động tốt hơn máy tính bảng chỉ vì chúng được sử dụng nhiều hơn.

Nếu bạn thấy bất kỳ điều gì không hoạt động với giải pháp này, hãy đánh tôi!

+1

Tôi đã thử nó, nhưng khi tôi đang chạy ứng dụng trên máy tính bảng ở chế độ ngang sau đó trong khi khởi chạy bất kỳ hoạt động nào, nó sẽ mở đầu tiên ở chế độ Chân dung và sau đó quay sang chế độ ngang: (Bất kỳ giải pháp/giải pháp nào cho nó ??? –

0

Tôi cũng gặp phải sự cố tương tự đối với thiết bị Android N. Vì vậy, để hỗ trợ cả hai hướng cho máy tính bảng và chỉ chụp chân dung cho điện thoại, tôi đã thực hiện thủ thuật sau:

  1. Đặt chân dung cho từng hoạt động trong Tệp kê khai. Trông xấu, nhưng trong trường hợp này màn hình sẽ không dừng quay: android:screenOrientation="portrait"

  2. Trong bộ BaseActivity của bạn:

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        if (isTablet(){ 
         setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); 
        } 
    } 
    
    protected boolean isTablet() { 
        return getResources().getBoolean(R.bool.tablet); 
    } 
    
0

Thêm dòng này trong tất cả các thẻ hoạt động trong tập tin menifest ...

android:screenOrientation="portrait" 
+0

Không phải tùy chọn, bởi vì sau đó bạn có cùng một vấn đề trên máy tính bảng trong cảnh quan – Huby

4

Tôi gặp sự cố tương tự trên Android N & O và đã tìm thấy giải pháp.

tôi vẫn sử dụng setRequestedOrientation trong phương thức onCreate, nhưng tôi đã thêm này cho mọi hoạt động trong biểu hiện:

android:screenOrientation="behind" 

Điều này đảm bảo rằng hoạt động này ra mắt với định hướng tương tự như các hoạt động trước đó. SetRequestedOrientation sau đó sẽ ghi đè lên nó, nhưng nếu nó giống như hoạt động trước đó bạn không thấy bất cứ điều gì thay đổi như người dùng.

1

Trong hoạt động cơ sở của bạn, bạn có thể đặt một cái gì đó như thế này:

/* Device types. */ 
static int MOBILE_DEVICE = 0; 
static int SEVEN_INCH_TABLET = 1; 
static int TEN_INCH_TABLET = 2; 

private static int deviceType = MOBILE_DEVICE; 
private boolean deviceTypeDetermined = false; 


@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 
@Override 
protected void onCreate(Bundle savedInstanceState) { 

    if (! deviceTypeDetermined) setDeviceType(); 

    /* Screen rotation only for tablets. */ 
    if (getDeviceType() < SEVEN_INCH_TABLET) { 
     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
     lockScreenOrientation(); 

    ...... 
} 



// --------------------------------------------------------------------------------------------- 
static int getDeviceType() { 
    return deviceType; 
} 
// --------------------------------------------------------------------------------------------- 


// --------------------------------------------------------------------------------------------- 
private void setDeviceTypeDetermined() { 
    this.deviceTypeDetermined = true; 
} 
// --------------------------------------------------------------------------------------------- 


// --------------------------------------------------------------------------------------------- 
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 
private void setDeviceType() { 

    /* 
     Let's invest on what kind of screen our APP is invited... 

     We only make a difference in 10", 7" tablets and the rest... 
    */ 

    Display mDisplay = getWindowManager().getDefaultDisplay(); 
    Point mScreenResolution = new Point(); 

    mDisplay.getRealSize(mScreenResolution); 

    int mWidthPixels = mScreenResolution.x; 
    int mHeightPixels = mScreenResolution.y; 

    DisplayMetrics mMetrics = new DisplayMetrics(); 
    getWindowManager().getDefaultDisplay().getMetrics(mMetrics); 

    float mWidthDpi = mMetrics.xdpi; 
    float mHeightDpi = mMetrics.ydpi; 

    float mWidthInches = mWidthPixels/mWidthDpi; 
    float mHeightInches = mHeightPixels/mHeightDpi; 



    double mDiagonalInches = Math.sqrt(
      (mWidthInches * mWidthInches) 
        + (mHeightInches * mHeightInches)); 


    if (mDiagonalInches >= 9) { 

     /* 
      A tablet with 8" x 5" is called a 10", but it is in fact 
      9.43398". Interesting that this kind of things happens in 
      the world of informatics.... ;) 
     */ 

     MyBaseAppCompatActivity.deviceType = TEN_INCH_TABLET; 
    } 

    else if (mDiagonalInches >= 7) { 
     MyBaseAppCompatActivity.deviceType = SEVEN_INCH_TABLET; 
    } 

    else 
    { 
     MyBaseAppCompatActivity.deviceType = MOBILE_DEVICE; 
    } 


    setDeviceTypeDetermined(); 
} 
// --------------------------------------------------------------------------------------------- 


// --------------------------------------------------------------------------------------------- 
void lockScreenOrientation() { 

    /* Screen rotation only for tablets. */ 
    if (deviceType < SEVEN_INCH_TABLET) return; 

    setRequestedOrientation(getResources().getConfiguration().orientation); 
} 
// --------------------------------------------------------------------------------------------- 


// --------------------------------------------------------------------------------------------- 
void unlockScreenOrientation() { 

    /* Screen rotation only for tablets. */ 
    if (deviceType < SEVEN_INCH_TABLET) return; 

    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR); 
} 
// --------------------------------------------------------------------------------------------- 

Và trong hoạt động của bạn trong onCreate:

// --------------------------------------------------------------------------------------------- 
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1) 
protected void onCreate(Bundle savedInstanceState) { 
    // ----------------------------------------------------------------------------------------- 
    super.onCreate(savedInstanceState); 

    if (getDeviceType() >= SEVEN_INCH_TABLET) unlockScreenOrientation(); 

    setContentView(R.layout.main_activity); 

    ......... 

// --------------------------------------------------------------------------------------------- 
+0

Câu trả lời này có thể được cải thiện bằng cách thêm giải thích về những gì bạn đã khắc phục. –

Các vấn đề liên quan