我在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
许多人已经给出了解决方案,所以我将谈谈问题的根源。
根据异常日志:
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或删除主题的相关属性。
许多人已经给出了解决方案,所以我将谈谈问题的根源。
根据异常日志:
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或删除主题的相关属性。