illegalstateexception:只有全屏不透明活动可以请求方向

我在Android 8.0 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
124749 次浏览

在Android O和以后,当你设置

 android:screenOrientation="portrait"

在清单。

去掉那条线,然后使用

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

在你的活动中。

这将解决你的问题。

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

即使你从浮动或半透明的活动中删除android:screenOrientation="portrait",但在它的父(背景)活动上固定方向,它仍然由父固定,我已经测试过了。

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

我不知道这是否是一个bug从谷歌或一个有意的行为,但我(至少暂时)解决了它通过改变compileSdkVersion和targetSdkVersion回到26在Gradle…

如果你还没有解决你的问题,就像这样在清单中注册广告活动:

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

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

可能Activity看起来像Dialog(非全屏),所以从清单或代码中删除screenOrientation。这将解决问题。

我不同意评分最高的答案,因为

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

导致错误

< p > . lang。只有全屏不透明活动可以 请求取向< / p >

但这对我有用

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

唯一有效的解决方法是:

变化:

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

:

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

在styles.xml

但这可能会导致溅屏(启动时出现白色屏幕)出现问题……在这种情况下,在styles.xml中添加以下行:

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

就在窗口和半透明线的下面。

如果前面的提示不起作用,最后一次机会:将目标SDK 26改为27。

如果使用全屏透明活动,则不需要在活动上指定方向锁。它将接受父活动的配置设置。如果父活动在manifest中有:

android: screenOrientation =“肖像”

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

许多人已经给出了解决方案,所以我将谈谈问题的根源。

根据异常日志:

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>=27时,当使用SCREEN_ORIENTATION_LANDSCAPE、SCREEN_ORIENTATION_PORTRAIT等相关属性时,使用windowIsTranslucent、windowIsFloating、windowSwipeToDismiss主题属性会触发异常。

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

在安卓奥利奥(API 26),你不能改变活动的方向,有以下一行(s)的风格

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

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

你有几种方法来解决这个问题:

1)你可以简单地删除上面的行(或将其转换为),你的应用程序就可以正常工作。

2) 你可以首先从manifest下面的行中为该活动删除

android:screenOrientation="portrait"

然后你必须添加这一行到你的活动(在onCreate())

'>=' change to '!='感谢Entreco注释

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

你可以在values-v26文件夹中创建新的styles.xml,并将其添加到你的style.xml中。(感谢AbdelHady注释)

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

这发生在27之后,使用targetSdkVersion 26替换,等待谷歌修复它

在manifest文件中,将第二个活动paren战术vityname设置为第一个活动,并删除第二个活动的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);
}

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

android:screenOrientation="unspecified"

或限制为纵向方向

你也可以使用在活动中,在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);
}

我使用android:screenOrientation="behind"代替android:screenOrientation="portrait"。基本上,你创建了一个对话框(在一个活动中),对话框不能自己请求方向,它需要父活动来做这件事(因为父活动在后台可见,并且有自己的布局)。

"behind"与activity堆栈中紧接在它下面的activity方向相同。

在做了一些研究之后,这个问题似乎是由于谷歌错误造成的。对我来说,我可以在我的Activities onCreate方法中留下这一行:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

我把targetSdkVersion改成了26。有一行在我的onCreate仍然导致崩溃,而我的targetSdkVersion仍然设置为27。由于到目前为止还没有其他的解决方案对我有效,所以我发现这只是暂时的解决方案。

我只在SDK 26(8.0.0)中遇到过这个问题,如果使用windowIsTranslucent 'true'并强制设置方向:

下面是解决方案:

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

扩展AppCompatActivity &会有用的!!

当你的目标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>
< p >注意:父母= " Theme.AppCompat.Light。api 28需要NoActionBar。之前在api 26有其他东西。工作得很好,但在28岁开始出现问题。 希望它能帮助到这里的人。 编辑:对于某些仅通过设置<item name="android:windowIsTranslucent">false</item> and <item name="android:windowIsFloating">false</item> 工作。这可能取决于您实现解决方案的方式。在我的例子中,它通过将它们设置为true来工作。< / p >

只需删除manifest .xml中活动的android:screenOrientation="portrait"

该活动将从它之前的活动中获取方向,因此不需要应用具有<item name="android:windowIsTranslucent">true</item>的方向。

如果你必须使用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 for api level 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);

而且

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.0抛出异常,8.0以上已经删除异常

8.0.0抛出异常

这是一个冲突(错误)在style.xml文件在android版本7 (Api级别24,25)&8 (api等级26,27), 当你有

< p > android:screenOrientation="portrait" :在AndroidManifest.xml

.xml中的特定活动(崩溃)

,

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

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

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

1-删除上述导致冲突的属性中的一个

2-更改活动方向为这些值之一,你需要:unspecifiedbehind等,可以在这里找到:谷歌参考android:screenOrientation ' < / p >

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

如果activity是你自己创建的,你可以在activity中尝试:

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

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

试着删除主题中的线条:

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

而且

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

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

唯一对我有效的就是改变

android:screenOrientation="portrait"

android:screenOrientation="unspecified"

在所有半透明活动的清单中。

这样它与所有API版本兼容,因为半透明活动似乎从targetApi: 28继承了父活动的方向。

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

我只是从非全屏元素中删除了“portrait”标签,一切都很好。

android:screenOrientation="portrait"

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

使用

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>

它似乎当目标sdk是馅饼(api级别28.0)和windowIsTranslucent是真的

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

你试着获得方向。问题来自android oreo 8.0 (api级别26),有两种方法来解决这个问题

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

如果你在manifest中像这样设置方向

android:screenOrientation="portrait"
< p >或 在这样的activity类中

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

从这两个地方移开。

并且当你将windowIsTranslucent设置为true时,它会从父activity中获取方向。

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

不需要改变你在android manifest文件中设置的屏幕方向参数。

只需添加两个文件夹

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常见bug

请检查你的活动样式,并确保如果你没有使用任何半透明相关的东西,改变样式为交替。这样我们就能解决这个问题。

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

我通过删除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>

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

这就是导致错误的原因:

<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将基于传感器的行为

< p >“fullSensor"方向由设备方向决定 传感器的任何4个方向。这类似于“传感器”; 除了允许4种屏幕方向中的任意一种, 不管设备通常会做什么(例如,一些 设备通常不会使用反向竖屏或反向横屏,但是 这使这些成为可能)。

来源:android:screenOrientation

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

 <activity
android:name=".ForgotPass_ChangePass"
android:screenOrientation="nosensor"
android:windowSoftInputMode="stateHidden|adjustPan|adjustResize"/>
< p >“nosensor"方向是不参考a而确定的 物理方向传感器。传感器被忽略,所以显示

见android文档这里