Using the New "Manifestmerger" Property in Android

Using the new manifestmerger property in Android

Add the following line to your project.properties file of your application project.

manifestmerger.enabled=true 

Introduced with Android SDK Tools, Revision 20 (June 2012):

https://developer.android.com/studio/releases/sdk-tools

Build System

    * Added automatic merging of library project manifest files into the including project's manifest.
      Enable this feature with the manifestmerger.enabled property.

How to use the new manifest merger (of Android Studio and Gradle)?

1. Disabling elements

You can always explicitly disable permissions and features in your app's manifest and override any library values. And i found that you can disable elements from library.

Example

Consider the following code from the above link:

<activity-alias android:name="foo.bar.alias">
<meta-data
android:name="zoo"
tools:node="remove" />
</activity-alias>

By having this code inside your manifest you ensure that the merger finds any <activity-alias> elements with android:name="foo.bar.alias" attribute and removes a <meta-data> element if it has the android:name="zoo" attribute. It removes just the "zoo" meta data. Not the activity alias. If you specify this in your main manifest it will be effective on anything that has been merged so far (elements from libraries).

Example #2

Since you requested an example with activities, this is what I've come up with:

<activity android:name="com.example.ui.MyActivity" tools:node="remove" />

This line will make the merger remove any activities with android:name="com.example.ui.MyActivity" attribute that have been merged so far. So if you specify this in your main manifest it will effectively remove any com.example.ui.MyActivity entries that might have been merged from libraries.

2. Overriding attributes from library

The order in which the values are merged are described here. Basically, it goes like this: libraries, then main manifest, then flavors and build types manifests if you use those.

What are build types?

The default are "debug" and "release". You can define your own and override settings like signing or proguard. For your purposes you could say it's the equivalent of run configurations.

It works like this: you put your default and shared values inside the main manifest. Then in flavor manifests you override the values you need. Google "gradle flavors" for more info.

The following example is taken from a previous version of manifest merger documentation.

Override an attribute coming from a library

Using tools:replace="x, y, z" will override x,y,z attributes from the
imported library’s activity XML declarations.

Higher Priority declaration

<activity
android:name="com.foo.bar.ActivityOne"
android:screenOrientation="portrait"
android:theme="@theme1"
tools:replace="theme"/>

with a lower priority declaration :

<activity
android:name="com.foo.bar.ActivityOne"
android:theme="@olddogtheme"
android:windowSoftInputMode="stateUnchanged"
android:exported="true">

will result in :

<activity
android:name="com.foo.bar.ActivityOne"
android:screenOrientation="portrait"
android:theme="@theme1"
android:windowSoftInputMode="stateUnchanged"
android:exported="true"/>

3. Disabling manifest merger altogether

See Disable Manifest Merger in Android Gradle Build.

android.applicationVariants.all { variant ->
variant.processResources.manifestFile = file('src/main/AndroidManifest.xml')
variant.processManifest.enabled=false
}

In what file do you put this?

At the end of your module's (not root project) build.gradle.

4. Are manifests from dependencies merged?

Yes they are (they're libraries).

Is there a way to block merging certain library manifests?

Not that I know of, sorry.

5. Any tutorials?

Depends on what are you trying to achive. So far it always worked for me out-of-the-box.

  • e.g. http://www.myandroidsolutions.com/2014/04/10/android-gradle-manifest-merge/
  • The manifest merger documentation (link below).

I don't know about any videos.

6. Anything I should be aware of?

You can check the generated manifest if you get suspicious about extra permissions etc. It's located in project/module/build/intermediates/manifests/full/[flavor]/build-type/AndroidManifest.xml.

Source: https://developer.android.com/studio/build/manifest-merge

Android Studio error: Manifest merger failed: Apps targeting Android 12

You need to specify android:exported="false" or android:exported="true"

Manifest:

<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.MyApplication.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

as mentioned in the document:

If your app targets Android 12 and contains activities, services, or
broadcast receivers that use intent filters, you must explicitly
declare the android: exported attribute for these app components.

Warning: If an activity, service, or broadcast receiver uses intent
filters and doesn't have an explicitly-declared value for
android:exported, your app can't be installed on a device that runs
Android 12.

Also check when to use true/false for the 'android:exported' value.

Manifest Merger failed with multiple errors in Android Studio

Open application manifest (AndroidManifest.xml) and click on Merged Manifest tab on bottom of your edit pane. Check the image below:

Sample Image

From image you can see Error in the right column, try to solve the error. It may help some one with the same problem. Read more here.

Also, once you found the error and if you get that error from external library that you are using, You have to let compiler to ignore the attribute from the external library.
//add this attribute in application tag in the manifest

   tools:replace="android:allowBackup" 

//Add this in the manifest tag at the top

xmlns:tools="http://schemas.android.com/tools"

Manifest merging in Android Studio

1. create sample project

Sample Image

2. add new module

Sample Image

Sample Image

Sample Image

3. Module Setting

Sample Image

Sample Image

Sample Image

4. Remove files in App Module

Move app/~~~/values/style.xml to common/~~~/values/style.xml

Sample Image

Sample Image

edit 1.

<!-- app/~~~/AndroidManifest.xml -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="kr.susemi99.manifestmergerforandroidstudio" >

<application >
<activity
android:name="kr.susemi99.common.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

edit 2.


    <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"> <!-- add this line -->
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

edit 3.

package kr.susemi99.common;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
int id = item.getItemId();

if (id == R.id.action_settings)
{
Toast.makeText(getApplicationContext(), "test toast", Toast.LENGTH_LONG).show();
}

return super.onOptionsItemSelected(item);
}
}

Sample Image

See all http://susemi99.kr/2368

Manifest merger failed targeting Android 12

The issue was caused by 3 activities missing the android:exported attribute in the androidx.test:core library version 1.3.0. Upgrading to version 1.4.0-beta01 fixed the issue.

If you are getting errors after targeting Android 12, the easiest way to debug this is to:

  • downgrade to a prior sdk version
  • rebuild project
  • after a successful build, open your project's AndroidManifest.xml.
  • at the bottom of the window, click on the Merged Manifest tab
  • look for any <activity> that includes an <intent-filter> tag and is missing the android:exported attribute

If you want to make sure these activities are the issue, add them directly to your project's AndroidManifest.xml file with the missing android:exported attribute added and try rebuilding the project.

So if <activity android:name="com.domain.ProblemActivity"> is missing the android:exported attribute, add it to your AndroidManifest.xml file like so:

<activity 
android:name="com.domain.ProblemActivity"
android:exported="true" >

Rebuild targeting Android 12 and if it works, then you found the bug!

Thanks @MikePenz for pointing me in the right direction.

Android maven - manifestmerger property

The feature has been added in the android-maven-plugin and the details are available from the link : https://github.com/jayway/maven-android-plugin/pull/135

Manifest Merger failed with multiple errors in Android Studio for react native

As the message have stated, property android:exported must be defined for an component that has an intent filter

<?xml version="1.0" encoding="utf-8"?>
<manifest>
<application>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>


Related Topics



Leave a reply



Submit