[java] java.lang.IllegalStateException : 전체 화면 불투명 활동 만 방향을 요청할 수 있습니다.

Android 8.0 Oreo java.lang.IllegalStateException의 주소록에서 연락처를 검색하는 중에 문제가 발생했습니다. 전체 화면 불투명 한 활동 만 방향을 요청할 수 있습니다.

전화 문의 서에서 내 활동의 연락처를 얻으려고하는데 Lollipop, Marshmallow, Nougat 등에 완벽하게 작동하지만 Oreo에게 오류가 발생합니다. 내 코드는 다음과 같습니다.

데모 코드 :-

private void loadContacts() {
            contactAsync = new ContactLoaderAsync();
            contactAsync.execute();
        }

        private class ContactLoaderAsync extends AsyncTask<Void, Void, Void> {
            private Cursor numCursor;

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                Uri numContacts = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
                String[] numProjection = new String[]{ContactsContract.CommonDataKinds.Phone.CONTACT_ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.TYPE};
                if (android.os.Build.VERSION.SDK_INT < 11) {
                    numCursor = InviteByContactActivity.this.managedQuery(numContacts, numProjection, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE NOCASE ASC");
                } else {
                    CursorLoader cursorLoader = new CursorLoader(InviteByContactActivity.this, numContacts, numProjection, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE NOCASE ASC");
                    numCursor = cursorLoader.loadInBackground();
                }

            }

            @Override
            protected Void doInBackground(Void... params) {
                if (numCursor.moveToFirst()) {
                    try {
                        final int contactIdIndex = numCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
                        final int displayNameIndex = numCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
                        final int numberIndex = numCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
                        final int typeIndex = numCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE);
                        String displayName, number, type;
                        do {
                            displayName = numCursor.getString(displayNameIndex);
                            number = numCursor.getString(numberIndex);
                            type = getContactTypeString(numCursor.getString(typeIndex), true);
                            final ContactModel contact = new ContactModel(displayName, type, number);
                            phoneNumber = number.replaceAll(" ", "").replaceAll("\\(", "").replaceAll("\\)", "").replaceAll("-", "");

                            if (phoneNumber != null || displayName != null) {
                                contacts.add(phoneNumber);
                                contactsName.add(displayName);
                                contactsChecked.add(false);

                                filterdNames.add(phoneNumber);
                                filterdContactNames.add(displayName);
                                filterdCheckedNames.add(false);
                            }
                        } while (numCursor.moveToNext());
                    } finally {
                        numCursor.close();
                    }
                }


                Collections.sort(contacts, new Comparator<String>() {
                    @Override
                    public int compare(String lhs, String rhs) {
                        return lhs.compareToIgnoreCase(rhs);
                    }
                });

                InviteByContactActivity.this.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mContactAdapter.notifyDataSetChanged();
                    }
                });

                return null;
            }
        }

        private String getContactTypeString(String typeNum, boolean isPhone) {
            String type = PHONE_TYPES.get(typeNum);
            if (type == null)
                return "other";
            return type;
        }

        static HashMap<String, String> PHONE_TYPES = new HashMap<String, String>();

        static {
            PHONE_TYPES.put(ContactsContract.CommonDataKinds.Phone.TYPE_HOME + "", "home");
            PHONE_TYPES.put(ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE + "", "mobile");
            PHONE_TYPES.put(ContactsContract.CommonDataKinds.Phone.TYPE_WORK + "", "work");
        }
}

오류 기록:-

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example, PID: 6573
                                                             java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/com.example.Activity.InviteByContactActivity}: java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
                                                              Caused by: java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation



답변

대상 SDK가 28 일 때 문제가 발생하는 것 같습니다. 따라서 많은 옵션을 시도한 후에 마침내 작동했습니다.

<activity
            android:name=".activities.FilterActivity"
            android:theme="@style/Transparent"
            android:windowSoftInputMode="stateHidden|adjustResize" />

스타일:-

<style name="Transparent" parent="Theme.AppCompat.Light.NoActionBar">
     <item name="android:windowIsTranslucent">true</item>
     <item name="android:windowBackground">@android:color/transparent</item>
     <item name="android:windowIsFloating">true</item>
     <item name="android:windowContentOverlay">@null</item>
     <item name="android:windowNoTitle">true</item>
     <item name="android:backgroundDimEnabled">false</item>
 </style>

참고 : parent = “Theme.AppCompat.Light.NoActionBar”는 api 28에 필요합니다. 이전에는 api 26에 다른 ​​것이 있었지만 28 일에 문제를 일으키기 시작했습니다. 누군가에게 도움이되기를 바랍니다. 편집 : 일부만 <item name="android:windowIsTranslucent">false</item> and <item name="android:windowIsFloating">false</item>
작동하여 설정했습니다. 솔루션 작동 방식에 따라 달라질 수 있습니다. 제 경우에는 true로 설정하여 작동했습니다.


답변

Android Oreo (API 26)에서는 스타일이 아래 줄이있는 활동의 방향을 변경할 수 없습니다

 <item name="android:windowIsTranslucent">true</item>

또는

 <item name="android:windowIsFloating">true</item>

이 문제를 해결하는 몇 가지 방법이 있습니다.

1) 단순히 위의 줄을 제거하거나 false 로 설정하면 앱이 제대로 작동합니다.

2) 또는 먼저 해당 활동에 대한 매니페스트에서 아래 줄을 제거 할 수 있습니다

android:screenOrientation="portrait"

그런 다음 이 줄을 활동에 추가 해야합니다 (onCreate ()).

    //android O fix bug orientation
    if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

3) 당신은 새로운 만들 수 styles.xml있는 values-v26폴더와 당신이 추가 style.xml. ( AbdelHady 의견 감사합니다 )

 <item name="android:windowIsTranslucent">false</item>
 <item name="android:windowIsFloating">false</item>


답변

Android O 이상에서 설정하면이 오류가 발생합니다.

 android:screenOrientation="portrait"

매니페스트에서.

그 줄을 제거하고 사용하십시오

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

당신의 활동에서.

문제가 해결됩니다.


답변

Google은 onCreatev27 이후 Activity의 메소드 에서이 예외를 throw합니다 .의 의미는 다음과 같습니다. 활동이 반투명하거나 부동이면 방향은 부모 (배경) 활동에 의존해야하며 자체 결정을 내릴 수 없습니다.

android:screenOrientation="portrait"부동 또는 반투명 액티비티에서 제거 하지만 부모 (배경) 액티비티에서 방향을 수정 하더라도 여전히 부모에 의해 고정되어 있지만 이미 테스트했습니다.

하나의 특별한 상황 : 런처 활동에서 반투명하게 만들면 부모 (배경)가 없으므로 항상 장치와 함께 회전하십시오. 그것을 고치려면 <item name="android:windowIsTranslucent">true</item>스타일 을 바꾸는 다른 방법을 사용해야합니다 .


답변

전체 화면 투명 활동을 사용하는 경우 활동에 방향 잠금을 지정할 필요가 없습니다. 상위 활동의 ​​구성 설정이 사용됩니다. 따라서 부모 활동에 매니페스트가있는 경우 :

android : screenOrientation = “세로”

반투명 액티비티의 방향 잠금은 세로입니다.


답변

android:screenOrientation="behind"대신에 사용 했습니다 android:screenOrientation="portrait". 기본적으로 대화 상자 (활동에서)를 만들고 대화 상자 자체에서 오리엔테이션을 요청할 수 없습니다. 부모는 백그라운드에서 볼 수 있고 자체 레이아웃이 있기 때문에 부모 활동이 필요합니다.

“뒤에”활동 스택에서 바로 아래에있는 활동과 동일한 방향입니다.


답변

실제로 작동하는 유일한 솔루션 :

변화:

<item name="android:windowIsTranslucent">true</item>

에:

<item name="android:windowIsTranslucent">false</item>

styles.xml에서

그러나 이로 인해 스플래시 화면 (시작시 흰색 화면)에 문제가 발생할 수 있습니다.이 경우 styles.xml에 다음 줄을 추가하십시오.

 <item name="android:windowDisablePreview">true</item> 

windowIsTranslucent 줄 바로 아래에 있습니다.

이전 팁이 작동하지 않는 경우 마지막 기회 : 27 대신 SDK 26을 타겟팅하십시오.