我在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:windowContentOverlay">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
注意:api 28需要parent =“Theme.AppCompat.Light.NoActionBar”。之前在api 26上有其他东西。工作得很好但是开始在28处提出问题。希望它可以帮助某人在这里。
只需在Manifest.xml中删除此行android:screenOrientation="portrait"
的活动
该活动将从其之前的活动中获得方向,因此无需应用具有<item name="android:windowIsTranslucent">true</item>
的方向。
在清单文件中将第二个活动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" />
values-v26
create 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>
我有同样的问题,我的解决方案是消除这条线
android:screenOrientation="portrait"
然后在活动中添加:
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
这是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
等,可在此处找到: Google reference for android:screenOrientation`
3-在运行时以编程方式设置方向
只需在Manifest.xml中设置活动的方向
android:screenOrientation="unspecified"
经过一些研究,似乎这个问题可能是由于谷歌的bug。对我来说,我能够在我的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>
唯一对我有用的是改变
android:screenOrientation="portrait"
至
android:screenOrientation="unspecified"
在所有半透明活动的清单中。
这样,它与所有API版本兼容,因为半透明活动似乎从targetApi: 28
的父活动继承其方向。
风格可以保留,因为它包括<item name="android:windowIsTranslucent">true</item>
。
我不知道这是来自Google的错误还是预期的行为,但我(至少暂时)通过在Gradle中将compileSdkVersion和targetSdkVersion更改回26来解决它...
在Android O和更高版本中,当您设置时会发生此错误
android:screenOrientation="portrait"
在清单中。
删除该行并使用
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
在你的活动中。
这将解决您的问题。
如果您尚未解决问题,只需在清单中注册广告活动,如下所示:
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
tools:replace="android:theme"
/>
您还需要更新到最新版本的sdk。
可能您显示的Activity看起来像Dialog(非全屏),因此从Manifest或代码中删除screenOrientation。这将解决问题。
这发生在27之后,使用targetSdkVersion 26替换,等待google修复它
当我尝试捕获图像或从图库中获取图像时,我收到此错误对我来说有效的方法是删除它们
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>
用户扩展AppCompatActivity
它会工作!!
我刚从非全屏元素中删除了“肖像”标签,一切都很顺利。
android:screenOrientation="portrait"
我有同样的问题,我只是通过设置:styles.xml中的<item name="android:windowIsFloating">false</item>
来修复它
如果您自己创建了活动,可以在活动中尝试:
@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 Oreo中,您无法更改具有低于线条样式的Activity的方向
<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);
}
谷歌在v27之后将这个例外抛在了Activity的onCreate
方法上,它们的意思是:如果一个Activity是半透明的或浮动的,它的方向应该依赖于父(背景)Activity,不能自己做出决定。
即使您从浮动或半透明活动中移除android:screenOrientation="portrait"
但在其父(背景)活动上修复方向,它仍然由父级修复,我已经测试过了。
一个特殊情况:如果你在启动器Activity上做半透明,它就没有父(背景),所以总是随设备一起旋转。想要解决它,你必须采取另一种方式来取代<item name="android:windowIsTranslucent">true</item>
风格。
如果使用全屏透明活动,则无需在活动上指定方向锁定。它将采用父活动的配置设置。因此,如果父活动在清单中有:
机器人:screenOrientation = “画像”
您的半透明活动将具有相同的方向锁定:纵向。
真正有效的唯一解决方案:
更改:
<item name="android:windowIsTranslucent">true</item>
至:
<item name="android:windowIsTranslucent">false</item>
在styles.xml中
但这可能会导致您的启动画面出现问题(启动时出现白屏)...在这种情况下,请将以下行添加到styles.xml:
<item name="android:windowDisablePreview">true</item>
就在windowIsTranslucent线下面。
如果以前的提示不起作用的最后机会:目标SDK 26而不是27。
我使用android:screenOrientation="behind"
而不是android:screenOrientation="portrait"
。基本上,您创建了一个对话框(在一个活动中),对话框本身不能请求方向,它需要父活动来执行此操作(因为父级在后台可见并具有自己的布局)。
“后面”与活动堆栈中紧邻其下方的活动相同的方向。
很多人都给了修复,所以我会谈谈问题的根源。
根据异常日志:
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或删除主题的相关属性。
我不能同意最多的评价答案,因为
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>
当你延伸时,将它用于你的Activity
InterstitialActivity extends AppCompatActivity
在AndroidManifest.xml中
<activity
android:name=".InterstitialActivity"
...
android:screenOrientation="portrait"
android:theme="@style/TranslucentTheme" />