Programing

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

lottogame 2020. 6. 12. 22:07
반응형

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>

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

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

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

android:screenOrientation="portrait"

그런 다음 이 줄을 Java 파일에 추가 해야 합니다

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

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을 타겟팅하십시오.


많은 사람들이 문제를 해결 했으므로 문제의 원인에 대해 이야기하겠습니다.

예외 로그에 따르면 :

Caused by: java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
    at android.app.Activity.onCreate(Activity.java:1081)
    at android.support.v4.app.SupportActivity.onCreate(SupportActivity.java:66)
    at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:297)
    at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:84)
    at com.nut.blehunter.ui.DialogContainerActivity.onCreate(DialogContainerActivity.java:43)
    at android.app.Activity.performCreate(Activity.java:7372)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1218)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3147)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302) 
    at android.app.ActivityThread.-wrap12(Unknown Source:0) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891) 
    at android.os.Handler.dispatchMessage(Handler.java:108) 
    at android.os.Looper.loop(Looper.java:166)

Activity.java에서 예외를 트리거 한 코드

    //Need to pay attention mActivityInfo.isFixedOrientation() and ActivityInfo.isTranslucentOrFloating(ta)
    if (getApplicationInfo().targetSdkVersion >= O_MR1 && mActivityInfo.isFixedOrientation()) {
        final TypedArray ta = obtainStyledAttributes(com.android.internal.R.styleable.Window);
        final boolean isTranslucentOrFloating = ActivityInfo.isTranslucentOrFloating(ta);
        ta.recycle();

        //Exception occurred
        if (isTranslucentOrFloating) {
            throw new IllegalStateException(
                    "Only fullscreen opaque activities can request orientation");
        }
    }

mActivityInfo.isFixedOrientation () :

        /**
        * Returns true if the activity's orientation is fixed.
        * @hide
        */
        public boolean isFixedOrientation() {
            return isFixedOrientationLandscape() || isFixedOrientationPortrait()
                    || screenOrientation == SCREEN_ORIENTATION_LOCKED;
        }
        /**
        * Returns true if the activity's orientation is fixed to portrait.
        * @hide
        */
        boolean isFixedOrientationPortrait() {
            return isFixedOrientationPortrait(screenOrientation);
        }

        /**
        * Returns true if the activity's orientation is fixed to portrait.
        * @hide
        */
        public static boolean isFixedOrientationPortrait(@ScreenOrientation int orientation) {
            return orientation == SCREEN_ORIENTATION_PORTRAIT
                    || orientation == SCREEN_ORIENTATION_SENSOR_PORTRAIT
                    || orientation == SCREEN_ORIENTATION_REVERSE_PORTRAIT
                    || orientation == SCREEN_ORIENTATION_USER_PORTRAIT;
        }

        /**
        * Determines whether the {@link Activity} is considered translucent or floating.
        * @hide
        */
        public static boolean isTranslucentOrFloating(TypedArray attributes) {
            final boolean isTranslucent = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsTranslucent, false);
            final boolean isSwipeToDismiss = !attributes.hasValue(com.android.internal.R.styleable.Window_windowIsTranslucent)
                                            && attributes.getBoolean(com.android.internal.R.styleable.Window_windowSwipeToDismiss, false);
            final boolean isFloating = attributes.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false);
            return isFloating || isTranslucent || isSwipeToDismiss;
        }

위의 코드 분석에 따르면 SCREEN_ORIENTATION_LANDSCAPE, SCREEN_ORIENTATION_PORTRAIT 및 기타 관련 속성을 사용할 때 TargetSdkVersion> = 27 인 경우 windowIsTranslucent, windowIsFloating 및 windowSwipeToDismiss 토픽 속성을 사용하면 예외가 트리거됩니다.

문제점이 발견되면 TargetSdkVersion을 변경하거나 필요에 따라 테마의 관련 속성을 제거 할 수 있습니다.


를 사용해야하는 경우 setRequestedOrientation()Android 8.0에서 windowIsTranslucent 속성을 희생 할 수는 없습니다.

values\styles.xml API 레벨 25-(<8.0)

<style name="Base.Theme.DesignDemo" parent="Base.Theme.AppCompat.Light">
        ...
        <item name="android:windowIsTranslucent">true</item>
        ...
    </style>

values-v26\styles.xml API 레벨 26의 경우 (= 8.0)

<style name="Base.Theme.DesignDemo" parent="Base.Theme.AppCompat.Light">
    ...
    <!-- android 8.0(api26),Only fullscreen opaque activities can request orientation -->
    <item name="android:windowIsTranslucent">false</item>
    ...
</style>

values-v27\styles.xml API 레벨 27 이상 (> 8.0)

<style name="Base.Theme.DesignDemo" parent="Base.Theme.AppCompat.Light">
    ...
    <item name="android:windowIsTranslucent">true</item>
    ...
</style>

가장 많은 답변에 동의 할 수 없습니다.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

오류를 일으킨다

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

그러나 이것은 나를 위해 작동합니다

<style name="TranslucentTheme" parent="@style/Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowActionBar">false</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

에서 연장 할 때 활동에 사용하십시오.

InterstitialActivity extends AppCompatActivity

AndroidManifest.xml에서

    <activity
        android:name=".InterstitialActivity"
        ...
        android:screenOrientation="portrait"
        android:theme="@style/TranslucentTheme" />

android:screenOrientation="portrait"Manifiest.xml 에서이 행 제거하십시오.

해당 액티비티는 이전 액티비티에서 오리엔테이션을 가져 오므로가있는 오리엔테이션을 적용 할 필요가 없습니다 <item name="android:windowIsTranslucent">true</item>.


대상 SDK가 파이 (api 레벨 28.0)이고 windowIsTranslucent가 true 인 경우

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

당신은 방향에 접근하려고합니다. 안드로이드 오레오 8.0 (api 레벨 26)에 문제가 있습니다.이 문제를 해결하는 두 가지 방법이 있습니다

  1. 방향을 제거
  2. 또는 windowIsTranslucent를 false로 설정하십시오.

다음과 같이 매니페스트에서 방향을 설정하는 경우

android:screenOrientation="portrait"

또는 이와 같은 활동 수업에서

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

두 장소에서 양식을 제거하십시오.

u windowIsTranslucent를 true로 설정하면 부모 활동에서 방향을 취합니다.


매니페스트 파일에서 두 번째 활동 parentActivityName을 첫 번째 활동으로 설정하고 screenOrientation 매개 변수를 두 번째 활동으로 제거하십시오. 그것은 첫 번째 활동이 부모임을 의미하며 두 번째 활동의 방향을 결정합니다.

<activity
        android:name=".view.FirstActiviy"
        android:screenOrientation="portrait"
        android:theme="@style/AppTheme" />

<activity
        android:name=".view.SecondActivity"
        android:parentActivityName=".view.FirstActiviy"
        android:theme="@style/AppTheme.Transparent" />

나는 같은 문제가 있었고 해결책은 선을 제거하는 것이었다

android:screenOrientation="portrait"

그런 다음 활동에 이것을 추가하십시오.

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

Manifiest.xml에서 활동 방향 설정

android:screenOrientation="unspecified"

Android 버전 7 (Api 레벨 24,25) 및 8 (api 레벨 26,27)의 style.xml 파일 내 테마 사이의 충돌 (버그)입니다.

android:screenOrientation="portrait" : AndroidManifest.xml의 특정 활동 (충돌)

&

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

style.xml 내의 해당 활동에 적용된 테마에서

필요에 따라 다음과 같은 방법으로 해결할 수 있습니다.

1- 충돌을 일으키는 위에서 언급 한 속성 중 하나를 제거하십시오.

2- 필요에 따라 활동 방향을 다음 값 중 하나로 변경하십시오. unspecified또는 behind다음에서 찾을 수 있습니다. android : screenOrientation에 대한 Google 참조 `

3- 프로그래밍 방식으로 런타임에 방향 설정


약간의 연구를 한 후에이 문제는 Google 버그로 인한 것일 수 있습니다. 나를 위해 Activities onCreate 메서드 에이 줄을 남길 수있었습니다.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

내 targetSdkVersion을 26으로 변경했습니다. onCreate에 해당 줄이 있으면 여전히 targetSdkVersion이 27로 설정되어있는 동안 충돌이 발생했습니다. 지금까지 다른 솔루션이 작동하지 않았기 때문에 이것이 임시 수정으로 작동한다는 것을 알았습니다. 지금.


windowIsTranslucent 'true'를 사용하고 방향을 강제로 설정하는 경우 SDK 26 (8.0.0)에서만이 문제에 직면했습니다.

해결책은 다음과 같습니다.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);   

        // fixing portrait mode problem for SDK 26 if using windowIsTranslucent = true
        if (Build.VERSION.SDK_INT == 26) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
        } else {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }        
    }



       <style name="SplashActivty" parent="AppTheme">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowNoTitle">true</item>
    </style>



<!-- Splash screen -->
        <activity
            android:name="edu.aku.family_hifazat.activities.SplashActivity"
            android:label="@string/app_name"
            android:screenOrientation="unspecified"
            android:theme="@style/SplashActivty">

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

        </activity>

이미지를 캡처하거나 갤러리에서 이미지를 가져 오려고 할 때이 오류가 발생했습니다.

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

android:screenOrientation="portrait"

이제 내 활동은이 테마를 사용하고 있습니다.

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

8.0 이상에서 예외가 제거되었습니다.

8.0.0 예외 발생


나를 위해 일한 유일한 것은 변화했다

android:screenOrientation="portrait"

android:screenOrientation="unspecified"

모든 반투명 활동에 대한 매니페스트.

이렇게하면 반투명 액티비티가의 부모 액티비티에서 방향을 상속하는 것처럼 보이기 때문에 모든 API 버전과 호환됩니다 targetApi: 28.

스타일은를 포함하여 그대로 둘 수 있습니다 <item name="android:windowIsTranslucent">true</item>.


이것이 Google의 버그인지 의도 된 동작인지는 모르지만 Gradle에서 compileSdkVersion 및 targetSdkVersion을 다시 26으로 변경하여 (적어도 일시적으로) 해결했습니다 ...


문제를 해결하지 못한 경우 다음과 같이 매니페스트에 광고 활동을 등록하십시오.

<activity
android:name="com.google.android.gms.ads.AdActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
tools:replace="android:theme"
 />

또한 최신 SDK 버전으로 업데이트해야합니다.


아마도 대화 상자 (비 전체 화면)와 같은 활동을 표시하므로 매니페스트 또는 코드에서 screenOrientation제거하십시오 . 문제가 해결됩니다.


이것은 27 이후에 발생했으며 targetSdkVersion 26 replace를 사용하고 Google이 수정하기를 기다립니다.


전체 화면이 아닌 요소에서 "초상화"태그를 제거했으며 모든 것이 제대로 작동했습니다.

android:screenOrientation="portrait"

사용하다

android:screenOrientation="behind"

그리고 테마

<style name="translucent" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowBackground">#beaaaaaa</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowAnimationStyle">@android:style/Animation</item>
    <item name="android:typeface">normal</item>
    <item name="android:windowSoftInputMode">adjustPan</item>
    <item name="windowActionBar">false</item>
</style>

사용자 확장 AppCompatActivity및 작동합니다!


활동이 직접 작성한 경우 활동에서이를 시도 할 수 있습니다.

@Override
public void setRequestedOrientation(int requestedOrientation) {
    try {
        super.setRequestedOrientation(requestedOrientation);
    } catch (IllegalStateException e) {
        // Only fullscreen activities can request orientation
        e.printStackTrace();
    }
}

이것이 가장 쉬운 해결책이어야합니다.


나는 같은 문제가 있었고 <item name="android:windowIsFloating">false</item>styles.xml에서 이것을 설정하여 고쳤다.

참고 : https://stackoverflow.com/questions/48072438/java-lang-illegalstateexception-only-fullscreen-opaque-activities-can-request-o

반응형