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

当前回答

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

其他回答

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

Use

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>

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

android:screenOrientation="unspecified"

或限制为纵向方向

你也可以在super.onCreate(…)之前使用in Activity, in 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);
}

在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版本7 (Api级别24,25)和8 (Api级别26,27)的style.xml文件中的主题之间的冲突(错误), 当你有

android: screenOrientation =“肖像” :在AndroidManifest.xml中的特定活动(崩溃)内

&

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

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

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

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

2-更改活动方向为这些值之一,你需要:未指定或后面,等等,可以在这里找到:谷歌参考android:screenOrientation `

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