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

当前回答

我也有同样的问题,我只是通过设置这个来修复它:<item name="android:windowIsFloating">false</item> in styles.xml

其他回答

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

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

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

or

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

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

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

2)或者您可以首先从该活动的清单中删除以下行

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

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

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

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

< name = android: windowIsTranslucent >项目真正的< - >项目

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

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

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

android:screenOrientation="portrait"

或 在这样的活动课上

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

从这两个地方移开。

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

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

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

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

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

这就是导致错误的原因:

<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个方向。这类似于"sensor" 除了允许4种屏幕方向中的任意一种, 不管设备通常会做什么(例如,一些 设备通常不会使用反向竖屏或反向横屏,但是 这使这些成为可能)。在API级别9中添加。

来源:android: screenOrientation

所以我使用了“nosensor”来解决问题:

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

"nosensor"不参考a确定方向 物理方向传感器。传感器被忽略,所以显示 不会根据用户移动设备的方式旋转。

点击这里查看android文档