Android Studio具有不同清单文件的两种样式


71

我在Android Studio中为自己的口味定义两个不同的清单文件时遇到问题。这是我当前的项目结构:

当前项目结构

AndroidManifest.xmlfree味道如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="se.example.package">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
</manifest>

AndroidManifest.xmlmain味道没有用途的权限,但其中包含的是所有口味之间共享清单代码的其余部分。

AndroidManifest.xmlpro味道如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="se.example.package">
    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />
</manifest>

build.gradle定义了两种风格,例如

productFlavors {
    free {
        applicationId 'se.example.package.free'
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 1
        versionName '1.0'
    }
    pro {
        minSdkVersion 14
        applicationId 'se.example.package.pro'
        targetSdkVersion 21
        versionCode 2
        versionName '1.1'
    }
}

我期望的结果是不同的口味定义了不同的使用权限。不是这种情况。当前的结果是,这两种风味仅定义了pro风味中<uses-permission android:name="com.android.vending.CHECK_LICENSE" />定义的AndroidManifest.xml

我试过了:

  • 清洁项目
  • 重建项目
  • 重新启动Android Studio
  • 同步gradle

但是没有成功。我该如何解决?任何帮助表示赞赏。

编辑1

我将每个风味AndroidManifest.xml文件的位置从每个res文件夹更改为freepro文件夹。结果:

  1. Pro Favourite会显示预期的许可证许可。
  2. 免费版本显示来自AndroidManifest.xml 文件,许可证和网络权限的权限(应仅是网络)

感觉就像是项目结构的问题。该怎么做?

编辑2

我按照Commonsware的提示提取了合并报告,这些是有关 uses-permissions

自由:

uses-permission#com.android.vending.CHECK_LICENSE
ADDED from qwknoteGIT:licencing-library:unspecified:26:5
    android:name
        ADDED from qwknoteGIT:licencing-library:unspecified:26:22

优点:

uses-permission#com.android.vending.CHECK_LICENSE
MERGED from qwknoteGIT:licencing-library:unspecified:26:5

我不确定要在哪个上使用(您是评论而不是答案),但是您可能可以通过使用一些tools:node声明工具
Budius

“结果是,目前这两个版本仅按照专业版本中的AndroidManifest.xml定义了<uses-permission android:name =“ com.android.vending.CHECK_LICENSE” />。”-您如何确定的?
CommonsWare 2015年

@CommonsWare我在HTC one x上都安装了两种版本,当我检查每种版本的权限时,它们都说“ Google Play的许可控制”(从我的手机翻译成瑞典语言,可能不是英文的确切翻译) )。他们都没有宣布互联网许可。
Marcus 2015年

1
查看清单合并报告app/build/output/apk/,看看它们告诉您什么。
CommonsWare 2015年

1
您的问题来自图书馆,而不是您的口味。具体来说,qwknoteGIT:licencing-library是要求CHECK_LICENSE。如果您未在所有版本中都使用该库,请使用带有修饰符的compile语句(例如proCompile)仅在该版本中使用该库。
CommonsWare

Answers:


54

技术背景:

在此链接上,它说明了可用于清单合并的技术和参数:http : //tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger#TOC-tools : node -标记

具体来说就是tools:node指出清单上的某些XML节点在合并时应如何表现。

解:

要在一个清单中实现某些权限,而在其他清单中实现不同权限,请将所需的所有权限添加到中,main然后在口味清单中删除不需要的权限,如以下示例所示:

free 删除支票许可证

<uses-permission
   android:name="com.android.vending.CHECK_LICENSE" 
   tools:node="remove"/>

13
只是一个问题,而不是将其添加到主清单中并将其从“免费”版本中删除,我们为什么不能android:name="com.android.vending.CHECK_LICENSE"仅将其添加到单个“专业”版本清单中
Rajkiran

24

您的问题来自图书馆,而不是您的口味。具体来说,qwknoteGIT:licencing-library是要求CHECK_LICENSE

如果您未在所有版本中都使用该库,请使用带有修饰符的compile语句(例如proCompile)仅在该版本中使用该库。

如果您对所有口味使用该库,但是确信自己不需要一种口味的权限,tools:node则可以在该口味的清单中使用属性来阻止该库提供的权限。

清单合并报告是您的朋友。:-)


非常感谢您的努力,尽管我不能接受两个答案,但您提供了很好的解释和可行的解决方案。+1
Marcus

@Marcus,您可以更改一个已接受的答案。我认为这个答案应该被接受。
伊利(Ely)

6

至少这应该可以解决问题。我发现在指定每个变体使用的确切清单时很有用。干杯! 它明确地定向到每个变体文件夹下的清单文件。

    android {
      productFlavors {
        prod {
          manifest.srcFile "prod/AndroidManifest.xml"
        }
        dev {
          manifest.srcFile "dev/AndroidManifest.xml"
        }
      }
      ...

}

4
无需指定AndroidManifest.xml文件的路径,gradle本身将从风味文件夹中获取文件,除非您更改了它们的默认路径(我不建议这样做)。
GoRoS

3
但是在仍然具有行家风格的项目布局时很有用
Nicolas Cornette

是的,就像我说的那样,@ GoRos在您指定确切路径时很有用。人们出于各种原因需要这样做。
Rowland Mtetezi '18

4

在您的App build.gradle中的sourceSets下专门指定清单

 android {
    productFlavors {
                bizdartFlavourNoCallLog {
            minSdkVersion 16
            applicationIdSuffix '.bizdart'
            targetSdkVersion 26
            dimension "tier"
            sourceSets {
                main {
                    manifest.srcFile "src/bizdartFlavourNoCallLog/AndroidManifest.xml"
                }
            }
            copy {
                from 'src/bizdartFlavourNoCallLog/'
                include '*.json'
                into '.'
                }
            }
       }
    }

1

您应该更改代码:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="se.example.package">

对于:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.your.appid">

1

参见https://developer.android.com/studio/build/manifest-merge与param工具:node =“ merge”

高优先级清单(免费):

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    tools:node="merge">
</activity>

低优先级清单(主要):

<activity android:name="com.example.ActivityOne"
    android:windowSoftInputMode="stateUnchanged">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

合并清单结果:

<activity android:name="com.example.ActivityOne"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="stateUnchanged">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

0

我遇到了同样的问题,我发现这是因为我在lib项目下放置了“ pro”和“ tree” flavor文件夹,而在我将applos文件夹移到了app项目下后,问题得以解决。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.