Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-26867] Android: IllegalStateException: Only fullscreen opaque activities can request orientation

GitHub Issuen/a
TypeBug
PriorityCritical
StatusClosed
ResolutionNot Our Bug
Resolution Date2019-03-09T03:49:15.000+0000
Affected Version/sRelease 8.0.0
Fix Version/sn/a
ComponentsAndroid
Labelsn/a
ReporterHans Knöchel
AssigneeAlan Hutton
Created2019-02-28T08:47:36.000+0000
Updated2019-03-25T22:57:59.000+0000

Description

The following crash was reported by several beta testers on certain devices (e.g. Honor, running Android 8.0.0):
java.lang.RuntimeException: Unable to start activity ComponentInfo

{com.example.app/org.appcelerator.titanium.TiTranslucentActivity}: java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3297)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3405)
at android.app.ActivityThread.-wrap12(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1994)
at android.os.Handler.dispatchMessage(Handler.java:108)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7523)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
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:321)
at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:84)
at org.appcelerator.titanium.TiBaseActivity.onCreate(TiBaseActivity.java:740)
at org.appcelerator.titanium.TiActivity.onCreate(TiActivity.java:21)
at android.app.Activity.performCreate(Activity.java:7383)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1218)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3250)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3405) 
at android.app.ActivityThread.-wrap12(Unknown Source:0) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1994) 
at android.os.Handler.dispatchMessage(Handler.java:108) 
at android.os.Looper.loop(Looper.java:166) 
at android.app.ActivityThread.main(ActivityThread.java:7523) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921) 
2019-02-28 09:34:23.503 30168-30168/? E/TiExceptionHandler: (main) [32,1389] Unable to start activity ComponentInfo{com.example.app/org.appcelerator.titanium.TiTranslucentActivity}
: java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation

android.app.Activity.onCreate(Activity.java:1081)
android.support.v4.app.SupportActivity.onCreate(SupportActivity.java:66)
android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:321)
android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:84)
org.appcelerator.titanium.TiBaseActivity.onCreate(TiBaseActivity.java:740)
org.appcelerator.titanium.TiActivity.onCreate(TiActivity.java:21)
android.app.Activity.performCreate(Activity.java:7383)
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1218)
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3250)
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3405)
android.app.ActivityThread.-wrap12(Unknown Source:0)
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1994)
android.os.Handler.dispatchMessage(Handler.java:108)
android.os.Looper.loop(Looper.java:166)
android.app.ActivityThread.main(ActivityThread.java:7523)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
We force portrait in our AndroidManifest file to ensure the device cannot move to landscape:
<application android:screenOrientation="portrait" android:theme="@style/Theme.MyApp">
        <!-- Titanium activities (force portrait) -->
        <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="org.appcelerator.titanium.TiActivity" android:screenOrientation="portrait"/>
        <activity android:configChanges="keyboardHidden|orientation|screenSize" android:name="org.appcelerator.titanium.TiTranslucentActivity" android:screenOrientation="portrait" android:theme="@style/Theme.AppCompat.Translucent"/>
        <activity android:configChanges="keyboardHidden|orientation|screenSize" android:screenOrientation="portrait" android:name=".ExampleAppActivity">
          <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
          </intent-filter>
        </activity>
      </application>
Any advice is appreciated. This is currently a blocker without workaround.

Comments

  1. Joshua Quick 2019-02-28

    You are running into this: [TIMOB-26157] This is something Google doesn't support anymore. The work-around posted in the above ticket are the only solutions that I'm aware of... which means it can't be portrait-only anymore or you get rid of the translucency. The fix we've implemented in the above ticket catches Google's exception when configuring it via JavaScript. In your case, you're setting it up via the "AndroidManifest.xml" which means it's being configured within Google's onCreate() method. Putting a try/catch around the super.onCreate() isn't going to work in this case because the activity will be in a bad state. I don't think there is any good work-around that we can do... other than have our build system remove the orientation setting from the translucent activity in the manifest.
  2. Hans Knöchel 2019-02-28

    We indeed use the modal: true flag (mainly for iOS). So if we remove that one for Android, it could fix it and we could re-enable the portrait flags added to <application>? We removed it to temporarily fix it, but thats not ideal.
  3. Joshua Quick 2019-02-28

    Removing the modal: true will only work-around it for opaque activities. It won't work for a "translucent" activity. So, you would have to get rid of your translucent activity usage too. They can't have a fixed orientation. That's what Google took away _(why... I have no idea.)_. If you want to layer translucent UI over an existing window that is portrait-only, then your only other option is to use a translucent View instead.
  4. Joshua Quick 2019-02-28

    *Side Note:* In your "AndroidManifest.xml", each of your activity is set to the following...
       android:confgChanges="keyboardHidden|orientation|screenSize"
       
    You need more than those 3, otherwise the UI in your window will disappear. For example, if you display your app and connect a bluetooth keyboard, your UI will disappear. You'll want to change all of the Titanium activities in your "AndroidManifest.xml" to the bellow...
       android:confgChanges="keyboard|keyboardHidden|orientation|fontScale|screenSize|smallestScreenSize|screenLayout|density"
       
  5. Hans Knöchel 2019-02-28

    Thanks Josh! We don't use translucent windows as far as I can think of. Is there a way to verify that? A general guide on forcing portrait mode would be cool! [The one from Ben Bahrenburg](https://bencoding.com/2016/02/11/android-orientation-locking-for-titanium/) seems a bit outdated then.
  6. Joshua Quick 2019-02-28

    Happy to help! I saw TiTranslucentActivity in your attached "AndroidManifest.xml" snippet. But that activity will only be used when your Ti.UI.Window has "modal" set to true, has an "opacity" value set, or a "backgroundColor" with an alpha value. You can see it in our native code here... https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/ui/src/java/ti/modules/titanium/ui/WindowProxy.java#L326 You can set up a window/activity to be portrait in code instead of via XML as shown below. If you do it in code, then the exception you are seeing will be caught by Titanium, but the negative consequence is that it won't be portrait-only.
       var window = Ti.UI.createWindow({
       	orientationModes: [Ti.UI.PORTRAIT],
       });
       window.open();
       
  7. Joshua Quick 2019-03-09

    Unfortunately, this is not something we can fix in code. The issue is on the XML side which is being handled by Google's onCreate() method. While we *can* put a try/catch are that method, the activity and the app will be left in a bad state. I don't think there is a good way to display an error dialog either since the UI will be in a bad state. But we do log the exception which adequately describes the issue. I think that's the best we can do for now.

JSON Source