web-dev-qa-db-fra.com

java.lang.IllegalStateException: seules les activités opaques plein écran peuvent demander une orientation

Je suis confronté au problème lors de la récupération des contacts du carnet de contacts dans Android 8.0 Oreo Java.lang.IllegalStateException: seules les activités opaques plein écran peuvent demander une orientation

J'essaie d'obtenir le contact dans mon activité à partir du répertoire de contacts téléphoniques et cela fonctionne parfaitement pour Lollipop, Guimauve, Nougat, etc. Mon code est ci-dessous.

Code de démonstration: -

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

Journal des erreurs: -

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
89
Shubham Sejpal

Le problème semble se produire lorsque votre sdk cible a 28 ans. Après avoir essayé de nombreuses options, cela a finalement fonctionné.

 <activity
        Android:name=".activities.FilterActivity"
        Android:theme="@style/Transparent"
        Android:windowSoftInputMode="stateHidden|adjustResize" />

style:-

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

Remarque: parent = "Theme.AppCompat.Light.NoActionBar" est nécessaire pour api 28. Auparavant, quelque chose d'autre était à l'api 26. Fonctionnait bien, mais a commencé à poser problème à 28 . J'espère que cela aidera quelqu'un.

13
Debasish Ghosh

Dans Android O et versions ultérieures, cette erreur se produit lorsque vous définissez

 Android:screenOrientation="portrait"

dans manifeste.

Supprimer cette ligne et utiliser

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

dans votre activité. 

Cela résoudra votre problème.

64
Ragesh Ramesh

Après la v27, Google lance cette exception sur la méthode onCreate d'Activity après v27. Leur signification est la suivante: si une activité est translucide ou flottante, son orientation doit être basée sur l'activité parent (arrière-plan), elle ne peut pas prendre de décision. 

Même si vous supprimez Android:screenOrientation="portrait" de l'activité flottante ou translucide mais que vous corrigez l'orientation de son activité parent (arrière-plan), il est toujours corrigé par le parent, que j'ai déjà testé.

Une situation particulière: si vous rendez translucide une activité de lanceur, celle-ci n’a pas de parent (arrière-plan), faites-la toujours pivoter avec le périphérique. Vous voulez résoudre ce problème, vous devez utiliser un autre moyen pour remplacer le style <item name="Android:windowIsTranslucent">true</item>.

52
Steven Sun

Dans Android Oreo, vous ne pouvez pas modifier l'orientation de l'activité qui a un style inférieur

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

Vous devez d'abord supprimer sous la ligne du manifeste pour cette activité

Android:screenOrientation="portrait"

Deuxièmement, vous devez ajouter cette ligne au fichier Java 

    //Android O fix bug orientation
    if (Android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
46
Radesh

Si vous utilisez une activité transparente en plein écran, il n'est pas nécessaire de spécifier le verrou d'orientation de l'activité. Il faudra les paramètres de configuration de l'activité parent. Donc, si l'activité parent a dans le manifeste: 

Android: screenOrientation = "portrait"

votre activité translucide aura le même verrou d'orientation: portrait. 

23
gellyke

J'ai utilisé Android:screenOrientation="behind" au lieu de Android:screenOrientation="portrait". Fondamentalement, vous avez créé une boîte de dialogue (dans une activité) et cette boîte de dialogue ne peut pas demander d'orientation par elle-même. Pour ce faire, elle a besoin d'une activité parent (car un parent est visible en arrière-plan et possède sa propre présentation).

"derrière" La même orientation que l'activité qui se trouve immédiatement sous celle-ci dans la pile d'activités.

11
Paul

La seule solution qui fonctionne vraiment:

Changement:

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

à:

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

dans styles.xml

Mais cela pourrait entraîner un problème avec votre écran de démarrage (écran blanc au démarrage) ... Dans ce cas, ajoutez la ligne suivante à votre fichier styles.xml:

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

juste en dessous de la ligne windowIsTranslucent.

Dernière chance si les astuces précédentes ne fonctionnent pas: ciblez le SDK 26 à la place du o 27.

9
Regis_AG

Beaucoup de gens ont donné une solution, je vais donc parler de la source du problème.

Selon le journal des exceptions:

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)

Le code qui a déclenché l'exception dans 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;
        }

Selon l'analyse de code ci-dessus, lorsque TargetSdkVersion> = 27, lors de l'utilisation de SCREEN_ORIENTATION_LANDSCAPE, SCREEN_ORIENTATION_PORTRAIT et d'autres attributs associés, l'utilisation des attributs de sujet windowIsTranslucent, windowIsFloating et windowSwipeToDismiss déclenchera une exception.

Une fois le problème détecté, vous pouvez modifier TargetSdkVersion ou supprimer les attributs associés du thème en fonction de vos besoins.

9
Bingerz

Je ne peux pas accepter la réponse la mieux notée, car 

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

provoque une erreur 

Java.lang.IllegalStateException: seules les activités opaques plein écran peuvent demande d'orientation

mais cela fait que ça marche pour moi

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

et utilisez-le pour votre activité, quand vous allez de 

InterstitialActivity extends AppCompatActivity

dans AndroidManifest.xml

    <activity
        Android:name=".InterstitialActivity"
        ...
        Android:screenOrientation="portrait"
        Android:theme="@style/TranslucentTheme" />
6
hannes ach

Supprimez simplement cette ligne Android:screenOrientation="portrait" d'activité dans Manifest.xml

Cette activité obtiendra une orientation de son activité précédente. Il n'est donc pas nécessaire d'appliquer l'orientation qui a <item name="Android:windowIsTranslucent">true</item>

5
Sanket Kachhela

il semble que le sdk cible est "pie" (niveau d'api 28.0) et que windowIsTranslucent est vrai

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

et vous essayez d'accéder à l'orientation. le problème vient avec Android oreo 8.0 (niveau d'api 26), il y a deux façons de résoudre ce problème

  1. enlever l'orientation
  2. ou définissez windowIsTranslucent sur false

si vous définissez l'orientation dans manifeste comme ceci

Android:screenOrientation="portrait"

ou en classe d'activité comme celle-ci

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

enlever la forme des deux endroits.

et observé lorsque vous définissez windowIsTranslucent sur true, il prend l'orientation de l'activité parent.

4
Avinash Jadaun

values-v26create 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>
3
leigo

dans le fichier manifeste, définissez la deuxième activité parentActivityName comme première activité et supprimez le paramètre screenOrientation de la deuxième activité. cela signifie que votre première activité est le parent et décide de l'orientation de votre deuxième activité. 

<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" />
3
mustafa.ertrk

J'ai rencontré ce problème uniquement dans le SDK 26 (8.0.0) si vous utilisiez windowIsTranslucent 'true' et définissiez l'orientation avec force:

Voici la solution:

    @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>
2
Hamza Khan

Après quelques recherches, il semble que ce problème soit probablement dû à un bug de Google. Pour moi, j'ai pu laisser cette ligne dans ma méthode d'Activités onCreate:

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

ET j'ai changé mon targetSdkVersion à 26. Le fait d'avoir cette ligne dans mon onCreate entraînait toujours un crash, alors que targetSdkVersion était toujours réglé sur 27. Comme aucune solution n'a encore fonctionné pour moi jusqu'à présent, j'ai constaté que cela fonctionnait temporairement à présent.

2
NaturallyAsh

J'ai eu le même problème, et ma solution a été d'éliminer la ligne

Android:screenOrientation="portrait"

puis ajoutez ceci à l'activité:

if (Android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
2
jrivas

Il s'agit d'un conflit (bogue) entre les thèmes du fichier style.xml dans les versions Android 7 (niveaux d'API 24,25) et 8 (niveaux d'API 26,27), lorsque vous avez

Android:screenOrientation="portrait":inside activité spécifique (qui se bloque) dans AndroidManifest.xml

Et 

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

dans le thème qui s'appliquait à cette activité dans style.xml

Il peut être résolu par ces moyens en fonction de vos besoins:

1- Supprimer l'une des propriétés mentionnées ci-dessus qui créent des conflits

2- Modifiez l'orientation de l'activité en l'une de ces valeurs selon vos besoins: unspecified ou behind et ainsi de suite, que vous pouvez trouver ici: Référence Google pour Android: screenOrientation ` 3- Définissez l'orientation par programmation dans temps d'exécution

2
Hamed Jaliliani

La seule chose qui a fonctionné pour moi a été de changer

Android:screenOrientation="portrait"

à

Android:screenOrientation="unspecified"

dans le manifeste pour toutes les activités translucides.

De cette façon, il est compatible avec toutes les versions de l'API car l'activité translucide semble hériter de son orientation de l'activité parent à partir de targetApi: 28.

Le style peut être laissé tel quel, y compris <item name="Android:windowIsTranslucent">true</item>.

2
Max Heimer

Si vous présentez probablement une activité ressemblant à un dialogue (non plein écran), supprimez donc Orientation de l'écran de Manifeste ou du code. Cela résoudra le problème.

1
Balflear

cela s'est produit après 27 ans, utilisez targetSdkVersion 26 replace, attendez que Google le corrige

1
yihang wu

Il suffit de définir l'orientation de l'activité dans Manifest.xml

Android:screenOrientation="unspecified"
1
Attaullah

Je ne sais pas s'il s'agit d'un bogue de Google ou d'un comportement souhaité, mais je l'ai (au moins momentanément) résolu en modifiant la version compileSdkVersion et targetSdkVersion de 26 dans Gradle ...

1
Seven

Si vous n'avez pas résolu votre problème, enregistrez l'activité de la publicité dans le manifeste comme suit:

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

Vous devez également mettre à jour la dernière version du sdk.

1
Gardax

seulement 8.0.0 lève l'exception, au dessus de 8.0 a supprimer l'exception

 8.0.0 throw the exception

0
Mingo

J'avais cette erreur quand j'essaie de capturer une image ou de prendre une image de la galerie

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

et

Android:screenOrientation="portrait"

maintenant mon activité utilise ce thème:

  <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>
0
Nouman Ch

J'ai eu le même problème et je l'ai corrigé en définissant simplement ceci: <item name="Android:windowIsFloating">false</item> dans styles.xml

0

L'utilisateur rallonge AppCompatActivity & cela fonctionnera !!

0
Najib Puthawala

Essayez de supprimer les lignes de votre thème:

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

et

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

après cela, ajoutez Android:screenOrientation="portrait" dans votre activité.

0
paul_parkbom

Utilisation

Android:screenOrientation="behind"

Et thème

<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>
0
Mostafa Imran

Je viens de supprimer les balises "portrait" des éléments non plein écran et tout s'est bien passé.

Android:screenOrientation="portrait"
0
Victor Tavares