'Setting AndroidManifest's activity screenRotation different per flavor

Is there a way to dynamically set the activity screenOrientation in AndroidManifest from gradle's build.config?

I need to have a flavor which allows rotation, and another flavor which is portrait only.

I've read through http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger but their examples seem to only work for normal string labels.

I've tried two methods.

With gradle's manifestPlaceholders: build.gradle:

productFlavors {
  flavorRotation {
    manifestPlaceholders = [ROTATION_PREF: "unspecified"]
  }
  flavorNoRotation {
    manifestPlaceholders = [ROTATION_PREF: "portrait"]
  }
}

with AndroidManifest.xml:

...
  <activity android:name=".ui.ActivityName"
    android:screenOrientation="${ROTATION_PREF}"/>
...

This doesn't seem to work, no error is given but the rotation isn't locked to portrait when I build "flavorNoRotation"


And tried with gradle's resValue: build.gradle:

productFlavors {
  flavorRotation {
    resValue "string", "orientation", "unspecified"
  }
  flavorNoRotation {
    resValue "string", "orientation", "portrait"
  }
}

with manifest:

...
<activity android:name=".ui.ActivityName"
  android:screenOrientation="@string/orientation"/>
...

This way, it builds fine but when I try to install to device it just fails with Android Studio giving the message: "Installation failed with message INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION. It is possible that this issue is resolved by uninstalling an existing version of the apk if it is present, and then re-installing."

Where clicking "OK" just gives an event log error "Error Installing APK". So, is there any way have a different orientation between build types/flavors?

I'd prefer to avoid doing this programmatically in a BaseActivity.


Edit: Sorry, I tried playing around some more and the first method I tried actually does work. I must have made a mistake on my side earlier by installing the wrong build flavor to my own device.

The only problem is that Android Studio gives a warning on the "android:screenOrientation="${ROTATION_PREF}" property saying it can't find it, although it will build fine and work.

Thanks for the answer attempts.



Solution 1:[1]

1-Create screen.xml file inside res/values folder and code

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="screen_type">phone</string>
</resources>

2-In your activity inside onCreate() after setContentView() check device type

//checking tablets and phones
String screenType = getResources().getString(R.string.screen_type); if (screenType.equals("7-inch-tablet") || screenType.equals("10-inch-tablet")) {

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

} else {

   setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} 

Hope it will help.

Solution 2:[2]

Not that way. What I've done is this; create a "parent" activity class where you check for what kind of layout you want to use, something like this: (just make sure you call super first in the child Activity) And here you could check the build version.

public class DaddyActivity extends Activity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // set landscape or portrait
        if (getResources().getBoolean(R.bool.landscape)) {
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        } else {
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        }
    }
}

It looks for an XML with only one boolean: landscape. This is that XML (for normal screen):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <bool name="landscape">false</bool>
</resources>

Solution 3:[3]

Seperate the source file

ex) .../src/flavorRotation/res/values/strings.xml

<string name="orientation">unspecified</string>

.../src/main/res/values/strings.xml

<string name="orientation">portrait</string>

Solution 4:[4]

The best way to do so is add 2 flavors in gradle and then for "portrait" flavor create directory with same name and copy the manifest file and add screenOrientation to portrait

in-app gradle add this:

flavorDimensions "default"
productFlavors {
    any {
        applicationIdSuffix ".any"
    }

    portrait {
        applicationIdSuffix ".portrait"
    }
}

Add dir name "portrait" instead landscape as shown in image

then in new manifest file in potrait directory add below under activity

        android:screenOrientation="portrait"

Solution 5:[5]

Yes, there is a way to configure per flavor orientation at the build.gradle level, and it's indeed very easy, but may be a little confusing at first because most people will try to use a string resource, since orientation is defined as a "string" in the manifest, but it is actually an integer under the hood.

Using the OP flavors, it will look like this:

productFlavors {
  flavorRotation {
    // 0 = unspecified
    resValue "integer", "orientation", "0"
  }
  flavorNoRotation {
    // 1 = portrait
    resValue "integer", "orientation", "1"
  }
}

You can see the predefined values in this source (search for ORIENTATION_UNSPECIFIED to find the first definition)

And then we use this gradle provided integer resource in the manifest:

<activity android:name=".ui.ActivityName"
    ...
    android:screenOrientation="@integer/orientation">
    ...
</activity>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Dharmendra Pratap
Solution 2 Flummox - don't be evil SE
Solution 3 BlueMist
Solution 4 patel dhruval
Solution 5 Loudenvier