Gradle:如何为需要相同 Activity 但具有不同意图过滤器的不同 buildType 合并 Android 清单文件

Posted

技术标签:

【中文标题】Gradle:如何为需要相同 Activity 但具有不同意图过滤器的不同 buildType 合并 Android 清单文件【英文标题】:Gradle: How to merge Android manifest files for different buildTypes which need the same Activity, but with different intent-filters 【发布时间】:2013-09-13 12:33:15 【问题描述】:

所以我正在尝试使用 gradle 创建一个单独的 buildType,但是该 buildType 需要为同一个 Activity 使用不同的特征。在这种情况下,我的启动活动需要一个不同的意图过滤器,具体取决于 buildType。这可能吗?

我在 gradle 中收到以下错误:

:Tinder:processUtestManifest
[androidManifest.xml:67, AndroidManifest.xml:38] Trying to merge incompatible /manifest/application/activity[@name=com.<company_name>.activities.ActivitySplash] element:
  <activity
      @android:name="com.<company_name>.activities.ActivitySplash"
      <intent-filter>
          <action
--            @android:name="android.intent.action.MAIN">
  <activity
      @android:name="com.<company_name>.activities.ActivitySplash"
      <intent-filter>
          <action
++            @android:name="com.apphance.android.LAUNCH">

【问题讨论】:

【参考方案1】:

目前无法单独合并意图过滤器,因此我建议将整个 &lt;activity&gt; 节点复制到

src/buildtype1/AndroidManifest.xml

src/buildtype2/AndroidManifest.xml

它会自动合并到最终清单中(当然您也希望将其从主清单中删除)。

【讨论】:

感谢 Xav,当我使用此模型并尝试在 Android Studio 中构建时,我得到:“Android Packager: [] java.util.zip.ZipException: duplicate entry: AndroidManifest.xml " 有什么想法吗? 您是否正在自定义源集?如果您不这样做,或者如果您这样做,则不应该发生这种情况,您需要使我提到的路径与您的实际结构相匹配。 感谢 Xav,我尝试按照您的建议设置我的项目,但此设置显然导致了 Android 注释的另一个问题,因此我无法确定这是否解决了我的合并问题。另一个问题是***.com/questions/18833642/…。如果您不介意看一看,我将不胜感激! @XavierDucrohet 我也在尝试解决 Gradle 合并/覆盖问题,但我的问题与活动和意图过滤器无关,而是与清单属性有关,例如 android:sharedUserId。使用了您建议的文件夹结构,但它不起作用。您能提出解决方案吗? @KevinTan 目前没有明显的解决方案,但我们正在努力尽快改进清单合并【参考方案2】:

让我发布一个完整的解决方案。在这种情况下,应用程序管理图像和视频的意图过滤器。但是,对于特定口味,我们只想捕获视频,而不是图像。

假设你的活动是这样定义的:

<activity
    android:name=".MainActivity"
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:label="@string/app_name"
    android:launchMode="singleTop"
    android:screenOrientation="landscape"
    android:theme="@style/CameraTheme">

    <intent-filter>
        <action android:name="android.media.action.IMAGE_CAPTURE"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>

    <intent-filter>
        <action android:name="android.media.action.VIDEO_CAPTURE"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

对于名为 myFlavor 的风味,我假设你已经拥有,你必须在 AndroidManifest.xml 文件中拥有它:

<!-- Remove the intent filter for images. MyFlavor is only for videos. -->
<activity
    android:name="com.androidsx.heliumvideochanger.MainActivity"
    tools:node="merge">

    <intent-filter tools:node="remove">
        <action android:name="android.media.action.IMAGE_CAPTURE"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

与 Gradle 同步,并检查最终清单,通常位于 myApp/build/intermediates/manifests/full/myFlavor/debug/AndroidManifest.xml

【讨论】:

【参考方案3】:

将消费应用/lib 中的 AndroidManifest 更改为:

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
...
<activity android:name="com.<company_name>.activities.ActivitySplash">

收件人:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
...
<activity android:name="com.<company_name>.activities.ActivitySplash"
    tools:merge="override">

【讨论】:

这个方法对我有用。您只需要在子(覆盖)AndroidManifes.xml 中添加 tools:merge="override" 添加后我仍然得到“尝试合并不兼容”:( 这个解决方案有点烂。在这里查看一个工作的***.com/questions/21239844/…

以上是关于Gradle:如何为需要相同 Activity 但具有不同意图过滤器的不同 buildType 合并 Android 清单文件的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Gradle 文件集合中的每个文件执行 shell 命令?

如何为 REST 和 GraphQL 使用相同的 RoleGuard?

如何为 gradle 发布任务设置超时?

如何为 Kotlin (Gradle) 构建导入 ShadowJar 插件?

如何为多个产品托管相同的代码?

如何为 gradle 任务命令行参数提供 flyway 密码?