java.lang.IllegalStateException:只有全屏不透明活动才能请求方向

Shu*_*pal 164 java android android-8.0-oreo android-8.1-oreo

我在Android 8.0 Oreo java.lang.IllegalStateException中从联系簿中检索联系人时遇到问题:只有全屏不透明活动可以请求方向

我试图通过电话联系簿获取我的活动中的联系人,它对Lollipop,Marshmallow,Nougat等非常有用,但它会给我这样的奥利奥错误,请帮助我.我的代码如下.

演示代码: -

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");
        }
}
Run Code Online (Sandbox Code Playgroud)

错误日志: -

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
Run Code Online (Sandbox Code Playgroud)

Rad*_*esh 106

在android Oreo中,您无法更改具有低于线条样式的Activity的方向

 <item name="android:windowIsTranslucent">true</item>
Run Code Online (Sandbox Code Playgroud)

您必须先从该活动的清单中删除以下行

android:screenOrientation="portrait"
Run Code Online (Sandbox Code Playgroud)

其次,您必须将此行添加到java文件中

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

  • 在Android PIE上,这可以按预期工作.所以检查真的应该是:`android.os.Build.VERSION.SDK_INT!= Build.VERSION_CODES.O` (17认同)
  • 我使用带有布尔值“&lt;bool name="allowWindowFullScreenTranslucent"&gt;true&lt;/bool&gt;”的选项 3,并在“&lt;item name="android:windowIsTranslucent"&gt;@bool/allowWindowFullScreenTranslucent&lt;/item&gt;”中引用它。然后在values-v26下的styles.xml中将其设置为“false”,并在values和values-v27中将其设置为“true”。 (6认同)

Rag*_*esh 81

在Android O和更高版本中,当您设置时会发生此错误

 android:screenOrientation="portrait"
Run Code Online (Sandbox Code Playgroud)

在清单中.

删除该行并使用

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Run Code Online (Sandbox Code Playgroud)

在你的活动中.

这将解决您的问题.

  • **从我的样式中删除**`<item name ="android:windowIsTranslucent"> true </ item>`继承自`Theme.AppCompat.Light.NoActionBar`为我工作. (43认同)
  • 这个解决方案有效,但它弄乱了我的splashScreenTheme.谷歌经常邋roll推出耻辱...... (15认同)
  • 通过在Activity类上设置方向来替换清单属性不能解决问题. (8认同)
  • 这是谷歌方面的一个错误.应该在将来的更新中修复.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 将限制您的应用进入景观.确保在创建所有活动时使用此功能. (7认同)
  • "打算"打破那些适用于早期版本的应用程序?这个目标已经明确实现.至少我们有一个解决方案,感谢@Ragesh (3认同)

小智 71

谷歌onCreate在v27之后将这个异常抛在Activity的方法上,它们的意思是:如果一个Activity是半透明的或浮动的,它的方向应该依赖于父(背景)Activity,不能自己做出决定.

即使您android:screenOrientation="portrait"从浮动或半透明活动中删除但在其父(背景)活动上修复方向,它仍然由父级修复,我已经测试过了.

一个特殊情况:如果你在启动器Activity上做半透明,它就没有父(背景),所以总是随设备一起旋转.想要修复它,你必须采取另一种方式来取代<item name="android:windowIsTranslucent">true</item>风格.

  • 我在运行Android PIE的OnePlus上没有此问题。所以不是v27之后,而是v!= 28时 (2认同)

Deb*_*osh 48

当你的目标sdk是28时,问题似乎正在发生.所以在尝试了很多选项后,最终这个工作.

<activity
            android:name=".activities.FilterActivity"
            android:theme="@style/Transparent"
            android:windowSoftInputMode="stateHidden|adjustResize" />
Run Code Online (Sandbox Code Playgroud)

样式:-

<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>
Run Code Online (Sandbox Code Playgroud)

注意:api 28需要parent ="Theme.AppCompat.Light.NoActionBar".之前在api 26上有其他东西.工作得很好但是开始在28处提出问题.希望它可以帮助某人在这里.

  • 对于任何偶然发现此“修复程序”的人,我必须设置`&lt;item name =“ android:windowIsTranslucent”&gt; false &lt;/ item&gt;`,还必须设置`&lt;item name =“ android:windowIsFloating”&gt; false &lt;/ item&gt;`才起作用。 (17认同)
  • 解决方案到底在哪里?“ activity”标签中没有“ screenOrientation”属性,导致崩溃的唯一原因是在将“ android:windowIsTranslucent”设置为true时设置了“ screenOrientation”。 (5认同)

gel*_*yke 27

如果使用全屏透明活动,则无需在活动上指定方向锁定.它将采用父活动的配置设置.因此,如果父活动在清单中有:

机器人:screenOrientation = "画像"

您的半透明活动将具有相同的方向锁定:纵向.

  • 如果我的透明活动是我的启动器活动(即启动屏幕),该怎么办? (2认同)
  • 所有的Android版本都适用吗?还是仅Android O及更高版本? (2认同)

小智 20

我用android:screenOrientation="behind"而不是android:screenOrientation="portrait".基本上,您创建了一个对话框(在一个活动中),对话框不能自己请求方向,它需要父活动来执行此操作(因为父级在后台可见并具有自己的布局).

"后面"与活动堆栈中紧邻其下方的活动相同的方向.


Reg*_*_AG 18

真正有效的唯一解决方案:

更改:

<item name="android:windowIsTranslucent">true</item>
Run Code Online (Sandbox Code Playgroud)

至:

<item name="android:windowIsTranslucent">false</item>
Run Code Online (Sandbox Code Playgroud)

在styles.xml中

但这可能会导致您的启动画面出现问题(启动时出现白屏)...在这种情况下,请将以下行添加到styles.xml:

 <item name="android:windowDisablePreview">true</item> 
Run Code Online (Sandbox Code Playgroud)

就在windowIsTranslucent线下面.

如果以前的提示不起作用的最后机会:目标SDK 26而不是o 27.

  • 更新:使用targetSDK到28不工作:) (2认同)

Bin*_*erz 13

很多人都给了修复,所以我会谈谈问题的根源.

根据异常日志:

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)
Run Code Online (Sandbox Code Playgroud)

在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");
        }
    }
Run Code Online (Sandbox Code Playgroud)

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;
        }
Run Code Online (Sandbox Code Playgroud)

根据上面的代码分析,当TargetSdkVersion> = 27时,当使用SCREEN_ORIENTATION_LANDSCAPE,SCREEN_ORIENTATION_PORTRAIT等相关属性时,使用windowIsTranslucent,windowIsFloating和windowSwipeToDismiss主题属性会触发异常.

找到问题后,您可以根据需要更改TargetSdkVersion或删除主题的相关属性.


小智 13

如果必须使用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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)


han*_*ach 8

我不能同意最多的评价答案,因为

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Run Code Online (Sandbox Code Playgroud)

导致错误

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>
Run Code Online (Sandbox Code Playgroud)

当你延伸时,将它用于你的Activity

InterstitialActivity extends AppCompatActivity
Run Code Online (Sandbox Code Playgroud)

在AndroidManifest.xml中

    <activity
        android:name=".InterstitialActivity"
        ...
        android:screenOrientation="portrait"
        android:theme="@style/TranslucentTheme" />
Run Code Online (Sandbox Code Playgroud)


San*_*ela 8

只需android:screenOrientation="portrait"在Manifiest.xml中删除此行活动

该活动将从其之前的活动中获得方向,因此无需应用具有的方向<item name="android:windowIsTranslucent">true</item>.


Avi*_*aun 6

似乎目标sdk是Pie(API级别28.0)并且windowIsTranslucent为true

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

然后您尝试访问方向。android oreo 8.0(api level 26)附带问题,有两种方法可以解决此问题

  1. 删除方向
  2. 或将windowIsTranslucent设置为false

如果您要在清单中设置方向,像这样

android:screenOrientation="portrait"
Run Code Online (Sandbox Code Playgroud)

或像这样的活动课

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Run Code Online (Sandbox Code Playgroud)

从两个地方删除表格。

并且在将windowIsTranslucent设置为true时观察到,它从父级活动获取方向。


小智 6

我最近遇到了这个问题,这是解决方案。

无需更改您在 android 清单文件中设置的屏幕方向参数。

只需添加两个文件夹即可

res>values
as  res>values-v26 
and res>values-v27
Run Code Online (Sandbox Code Playgroud)

然后将 styles.xml 和 theme.xml 文件复制到此处。

并将以下参数从 TRUE 更改为 FALSE。

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

<item name="android:windowIsTranslucent">false</item>
Run Code Online (Sandbox Code Playgroud)

它会起作用的。

Android 8.0常见bug


小智 5

在清单文件中,将第二个活动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" />
Run Code Online (Sandbox Code Playgroud)


Att*_*lah 5

只需在 Manifyingt.xml 中设置活动的方向

android:screenOrientation="unspecified"
Run Code Online (Sandbox Code Playgroud)

OR 仅限于纵向方向

您还可以在活动中使用,例如在onCreate方法调用之前super.onCreate(...)

@Override
    protected void onCreate(Bundle savedInstanceState) {
        setOrientation(this);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_xml_layout);
        //...
        //...
}

// Method 
public static void setOrientation(Activity context) {
   if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.O)
        context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
      else
        context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Run Code Online (Sandbox Code Playgroud)


Rid*_*zag 5

有些答案对我来说不清楚并且不起作用,

所以这导致了错误:

<activity
android:name=".ForgotPass_ChangePass"
android:screenOrientation="portrait" <--- // this caused the error
android:windowSoftInputMode="stateHidden|adjustPan|adjustResize"/>
Run Code Online (Sandbox Code Playgroud)

android studio 建议将 screenOrientation 设置为 fullSensor

android:screenOrientation="fullSensor"
Run Code Online (Sandbox Code Playgroud)

是的,这将修复错误,但我想将布局保持在纵向模式,并且 fullSensor 将根据传感器进行操作

“fullSensor” 方向由 4 个方向中任意一个的设备方向传感器确定。这与“传感器”类似,只不过它允许 4 种可能的屏幕方向中的任何一种,无论设备通常会做什么(例如,某些设备通常不会使用反向纵向或反向横向,但这会启用这些)。添加到 API 级别 9。

来源:android:screenOrientation

所以对我有用的解决方案我使用了“nosensor”:

 <activity
        android:name=".ForgotPass_ChangePass"
        android:screenOrientation="nosensor"
        android:windowSoftInputMode="stateHidden|adjustPan|adjustResize"/>
Run Code Online (Sandbox Code Playgroud)

“nosensor” 确定方向时不参考物理方向传感器。传感器被忽略,因此显示屏不会根据用户移动设备的方式旋转。

请参阅此处的 Android 文档