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

时间:2018-01-03 06:41:27

标签: java android android-8.0-oreo android-8.1-oreo

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

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

演示代码: -

var buildDefinitions = buildServer.QueryBuildDefinitions("Project_name").Where(bd=>bd.DateCreated.Date>=DateTime.Now.AddDays(-7).Date);

错误日志: -

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");
        }
}

35 个答案:

答案 0 :(得分:76)

在Android O及更高版本中,当您设置

时会发生此错误
 android:screenOrientation="portrait"
中的

删除该行并使用

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

在你的活动中。

这将解决您的问题。

答案 1 :(得分:63)

Google在v27之后将此异常抛在Activity的onCreate方法上,其含义是:如果一个Activity是半透明的或浮动的,它的方向应该依赖于父(背景)活动,可以&#39;自己做决定。

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

一种特殊情况:如果您在启动器活动中制作半透明,则它具有父级(背景),因此始终与设备一起旋转。想要修复它,你必须采取另一种方式来取代<item name="android:windowIsTranslucent">true</item>样式。

答案 2 :(得分:59)

在android Oreo中,您无法更改具有低于线条风格的活动的方向

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

你必须解决这个问题:

1)您只需删除上一行,您的应用即可正常使用。

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);
    }

答案 3 :(得分:25)

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

  

机器人:screenOrientation = “纵向”

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

答案 4 :(得分:20)

目标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:windowContentOverlay">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:backgroundDimEnabled">false</item>
    </style>

Note:parent =“ api.28需要” parent =“ Theme.AppCompat.Light.NoActionBar”。以前在api 26上有其他功能。虽然运行良好,但在28上开始出现问题。 希望它对这里的人有所帮助。

答案 5 :(得分:14)

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

  

“在...后面”与活动堆栈中紧接其下的活动的方向相同。

答案 6 :(得分:13)

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

变化:

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

为:

<item name="android:windowIsTranslucent">false</item>
style.xml中的

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

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

就在windowIsTranslucent线下方。

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

答案 7 :(得分:9)

很多人已经解决了问题,所以我会谈谈问题的根源。

根据例外日志:

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;
        }

根据上面的代码分析,当TargetSdkVersion&gt; = 27时,当使用SCREEN_ORIENTATION_LANDSCAPE,SCREEN_ORIENTATION_PORTRAIT和其他相关属性时,使用windowIsTranslucent,windowIsFloating和windowSwipeToDismiss主题属性将触发异常。

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

答案 8 :(得分:8)

我不同意最受好评的答案,因为

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" />

答案 9 :(得分:6)

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

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

答案 10 :(得分:4)

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

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

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

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

如果您要在清单中设置方向

android:screenOrientation="portrait"

或 在这样的活动课中

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

从两个地方移走。

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

答案 11 :(得分:4)

清单文件中的

将第二个活动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" />

答案 12 :(得分:4)

values-v26创建styles.xml(v26)

<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>

答案 13 :(得分:3)

我遇到了同样的问题,我的解决方案是消除生产线

android:screenOrientation="portrait"

,然后将其添加到活动中:

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

答案 14 :(得分:2)

对我唯一有用的是更改

android:screenOrientation="portrait"

android:screenOrientation="unspecified"

所有透明活动的清单中

那样,它与所有API版本都兼容,因为半透明活动似乎从targetApi: 28开始是从父活动继承其方向的。

可以保留样式,包括<item name="android:windowIsTranslucent">true</item>

答案 15 :(得分:2)

在Manifiedt.xml中设置活动的方向

/index.php/Site/paper/

答案 16 :(得分:2)

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

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

只需在

中添加两个文件夹
res>values
as  res>values-v26 
and res>values-v27

然后将您的styles.xml和themes.xml文件复制到那里。

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

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

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

它将起作用。

Android 8.0的常见错误

答案 17 :(得分:2)

经过一些研究,看来此问题可能是由于Google错误引起的。对我来说,我可以在我的Activity onCreate方法中保留以下行:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

然后我将targetSdkVersion更改为26。当我的targetSdkVersion仍设置为27时,在onCreate中保留该行仍然会导致崩溃。由于到目前为止没有人对我有用,暂时修复。

答案 18 :(得分:2)

仅当使用windowIsTranslucent'true'并强制设置方向时,我才在SDK 26(8.0.0)中遇到此问题:

这是解决方案:

$element-names[position() gt 1]

答案 19 :(得分:2)

这是android版本7(Api级别24,25)和8(API级别26,27)中style.xml文件内的主题之间的冲突(错误),  当你有

Connection li = DriverManager.getConnection(sourceURL, "Admin", ""); PreparedStatement pstm = li.prepareStatement("SELECT * FROM Milk"); :在AndroidManifest.xml中的特定活动(崩溃)内部

android:screenOrientation="portrait"

在style.xml中应用于该活动的主题中

可以根据您的需要通过以下方法解决:

1-删除上述会引起冲突的属性

2-根据需要将“活动方向”更改为以下值之一:<item name="android:windowIsTranslucent">true</item> unspecified,依此类推,可在此处找到: Google reference for android:screenOrientation `

3-以编程方式在运行时设置方向

答案 20 :(得分:1)

如果您尚未解决问题,只需在清单中注册广告活动,如下所示:

image: samueldebruyn/debian-git

pipelines:
  default:
    - step:
        script:
          - apt-get update
          - apt-get -qq install git-ftp
          - git ftp push --user $FTP_USERNAME --passwd $FTP_PASSWORD sftp://$SFTP_HOST:22/$SFTP_FOLDER

您还需要更新到最新版本的sdk。

答案 21 :(得分:1)

当我尝试捕获图像或从图库中获取图像时出现此错误,对我来说,有效的方法是将两者都删除

 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>

答案 22 :(得分:1)

我不知道这是来自Google的错误还是预期的行为,但我(至少暂时)通过在Gradle中将compileSdkVersion和targetSdkVersion更改回26来解决它...

答案 23 :(得分:1)

此情况发生在27岁之后,请使用targetSdkVersion 26替换,请等待Google修复

答案 24 :(得分:1)

可能您显示的活动看起来像Dialog(非全屏),因此请从清单或代码中删除 screenOrientation 。这将解决问题。

答案 25 :(得分:0)

我通过删除android:screenOrientation="portrait"解决了此问题,并将以下代码添加到我的onCreate

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

我的主题属性为

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

答案 26 :(得分:0)

请检查“活动”的样式,并确保如果您未使用任何与“半透明”相关的东西,请将样式更改为替代样式。这样我们可以解决此问题。

android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"

答案 27 :(得分:0)

有些答案对我来说不清楚,也没有用,

所以这导致了错误:

<activity
android:name=".ForgotPass_ChangePass"
android:screenOrientation="portrait" <--- // this caused the error
android:windowSoftInputMode="stateHidden|adjustPan|adjustResize"/>

android studio 建议将 screenOrientation 设置为 fullSensor

android:screenOrientation="fullSensor"

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

<块引用>

"fullSensor" 方向由设备方向决定 4 个方向中任何一个方向的传感器。这类似于“传感器” 除了这允许 4 种可能的屏幕方向中的任何一个, 无论设备通常会做什么(例如,某些 设备通常不会使用反向纵向或反向横向,但 这使那些)。在 API 级别 9 中添加。

source: android:screenOrientation

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

 <activity
        android:name=".ForgotPass_ChangePass"
        android:screenOrientation="nosensor"
        android:windowSoftInputMode="stateHidden|adjustPan|adjustResize"/>
<块引用>

"nosensor" 方向是在不参考a的情况下确定的 物理方向传感器。传感器被忽略,因此显示 不会根据用户移动设备的方式进行旋转。

see android documentation here

答案 28 :(得分:0)

使用

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>

答案 29 :(得分:0)

我遇到了同样的问题,我只是通过在styles.xml中设置<item name="android:windowIsFloating">false</item>来解决此问题

答案 30 :(得分:0)

我刚刚从非全屏元素中删除了“肖像”标签,一切正常。

android:screenOrientation="portrait"

答案 31 :(得分:0)

仅8.0.0引发异常,高于8.0则已删除异常

8.0.0 throw the exception

答案 32 :(得分:0)

用户扩展AppCompatActivity,它将正常运行!

答案 33 :(得分:-1)

如果活动是您自己创建的,则可以在“活动”中尝试以下操作:

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

这应该是最简单的解决方案。

答案 34 :(得分:-2)

尝试删除主题行:

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

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

在此之后,在您的活动中添加android:screenOrientation="portrait"