Android Studio zwei Varianten mit unterschiedlichen Manifestdateien

71

Ich habe Probleme beim Definieren von zwei verschiedenen Manifestdateien für meine Varianten in Android Studio. Dies ist meine aktuelle Projektstruktur:

Aktuelle Projektstruktur

Das AndroidManifest.xmlim freeGeschmack sieht so aus:

<?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>

Das AndroidManifest.xmlin der mainVariante hat keine Verwendungsberechtigungen, enthält jedoch den Rest des Manifestcodes, der von allen Varianten gemeinsam genutzt wird.

Das AndroidManifest.xmlim proGeschmack sieht so aus:

<?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 definiert die beiden Geschmacksrichtungen wie

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'
    }
}

Das Ergebnis, das ich erwarte, ist, dass die verschiedenen Geschmacksrichtungen unterschiedliche Verwendungsberechtigungen definieren. Das ist nicht der Fall. Das Ergebnis ist derzeit, dass beide Geschmacksrichtungen nur die in der Pro-Geschmacksrichtung definierten <uses-permission android:name="com.android.vending.CHECK_LICENSE" />definieren AndroidManifest.xml.

Ich habe versucht:

  • Projekt reinigen
  • Projekt neu erstellen
  • Starten Sie Android Studio neu
  • Gradle synchronisieren

Aber ohne Erfolg. Wie soll ich das beheben? Jede Hilfe wird geschätzt.

BEARBEITEN 1

Ich änderte die Lage der einzelnen Aromen AndroidManifest.xmlDatei von jedem der resOrdner freeund proOrdner. Das Ergebnis davon:

  1. Pro Flavour zeigt die Lizenzberechtigung wie erwartet an.
  2. Free Flavour zeigt Berechtigungen aus beiden AndroidManifest.xml Dateien, Lizenz- und Netzwerkberechtigungen (sollte nur Netzwerk sein)

Dies scheint ein Problem der Projektstruktur zu sein. Was soll man daraus machen?

BEARBEITEN 2

Ich habe die Zusammenführungsberichte gezogen, wie Commonsware angedeutet hat. Dies sind die Berichte zu uses-permissions

Kostenlos:

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

Profi:

uses-permission#com.android.vending.CHECK_LICENSE
MERGED from qwknoteGIT:licencing-library:unspecified:26:5
Marcus
quelle
Ich bin mir nicht ganz sicher, welche Sie verwenden müssen (du bist ein Kommentar, keine Antwort), aber du kannst wahrscheinlich das bekommen, was du willst, indem du einige der tools:nodeDeklarationstools verwendest. Android.com/tech-docs/new-build -System / Benutzerhandbuch /…
Budius
"Das Ergebnis ist derzeit, dass beide Geschmacksrichtungen nur die <Verwendungsberechtigung android: name =" com.android.vending.CHECK_LICENSE "/> definieren, wie in AndroidManifest.xml in der Pro-Variante definiert." - wie haben Sie dies festgestellt? ?
CommonsWare
@CommonsWare Ich habe beide Varianten auf meinem HTC one x installiert, und wenn ich die Berechtigungen für jede einzelne überprüfe, sagen beide "Lizenzkontrolle für Google Play" (Übersetzt von meinem Telefon mit schwedischem Gebietsschema, möglicherweise keine exakte Übersetzung in Englisch ). Keiner von ihnen erklärt Internetberechtigungen.
Marcus
1
Schauen Sie sich die Manifest-Fusionsberichte an app/build/output/apk/und sehen Sie, was sie Ihnen sagen.
CommonsWare
1
Ihr Problem kommt aus einer Bibliothek, nicht aus Ihren Aromen. Insbesondere qwknoteGIT:licencing-libraryfordert CHECK_LICENSE. Wenn Sie diese Bibliothek nicht in allen Geschmacksrichtungen verwenden, verwenden Sie eine aromatisierte compileAnweisung (z. B. proCompile), um diese Bibliothek nur in dieser Geschmacksrichtung zu verwenden.
CommonsWare

Antworten:

54

Technischer Hintergrund:

Unter diesem Link werden die Techniken und Parameter erläutert, die für das Zusammenführen von Manifesten verwendet werden können: http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger#TOC-tools:node -Marker

Eine davon ist die tools:node, die darauf hinweist, wie sich bestimmte XML-Knoten im Manifest beim Zusammenführen verhalten sollen.

Lösung:

Um einige Berechtigungen in einem und in einem anderen Manifest zu erhalten, fügen Sie ALLE Berechtigungen hinzu, die Sie benötigen, mainund entfernen Sie im Flavour-Manifest diejenigen, die Sie nicht benötigen, wie im folgenden Beispiel:

free Entfernen Sie die Schecklizenz

<uses-permission
   android:name="com.android.vending.CHECK_LICENSE" 
   tools:node="remove"/>
Budius
quelle
13
Nur eine Frage, anstatt sie im Hauptmanifest hinzuzufügen und aus der "kostenlosen" Version zu entfernen, warum können wir nicht android:name="com.android.vending.CHECK_LICENSE"einfach nur ein einziges "Pro" -Versionsmanifest hinzufügen
Rajkiran
24

Ihr Problem kommt aus einer Bibliothek, nicht aus Ihren Aromen. Insbesondere qwknoteGIT:licencing-libraryfordert CHECK_LICENSE.

Wenn Sie diese Bibliothek nicht in allen Geschmacksrichtungen verwenden, verwenden Sie eine aromatisierte compileAnweisung (z. B. proCompile), um diese Bibliothek nur in dieser Geschmacksrichtung zu verwenden.

Wenn Sie die Bibliothek für alle Geschmacksrichtungen verwenden, sich jedoch sicher sind, dass Sie die Berechtigung für eine Geschmacksrichtung nicht benötigen tools:node, kann im Manifest der Geschmacksrichtung ein Attribut verwendet werden, um die von der Bibliothek bereitgestellte Berechtigung auszublenden.

Und der offensichtliche Fusionsbericht ist dein Freund. :-)

CommonsWare
quelle
Vielen Dank für Ihre Bemühungen, obwohl ich zwei Antworten nicht akzeptieren kann, geben Sie eine gute Erklärung und eine funktionierende Lösung. +1
Marcus
@Marcus können Sie eine akzeptierte Antwort ändern. Meiner Meinung nach sollte diese Antwort akzeptiert werden.
Ely
6

Dies sollte zumindest das Problem lösen. Ich finde es nützlich, das genaue Manifest anzugeben, das für jede Variante verwendet werden soll. Prost! Es verweist explizit auf die Manifestdatei unter jedem Variantenordner.

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

}
Rowland Mtetezi
quelle
4
Es ist nicht erforderlich, den Pfad der AndroidManifest.xmlDateien anzugeben. Gradle selbst übernimmt sie aus den Flavour-Ordnern, es sei denn, Sie haben ihren Standardpfad geändert (was ich nicht empfehlen würde).
GoRoS
3
Nützlich jedoch, wenn Sie noch ein Projektlayout im Maven-Stil haben
Nicolas Cornette
Ja, @GoRos, wie gesagt, dies ist nützlich, wenn Sie den genauen Pfad angeben. Menschen haben verschiedene Gründe, warum sie das tun müssten.
Rowland Mtetezi
4

Geben Sie Ihr Manifest ausschließlich unter sourceSets in Ihrer App build.gradle an

 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 '.'
                }
            }
       }
    }
Ebin Joy
quelle
1

Sie sollten Ihren Code ändern:

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

zum:

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

Siehe https://developer.android.com/studio/build/manifest-merge mit param tools: node = "merge"

Manifest mit hoher Priorität (kostenlos):

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

Manifest mit niedriger Priorität (Main):

<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>

Zusammengeführtes offensichtliches Ergebnis:

<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>
Alexandr Larin
quelle
0

Ich bin auf dasselbe Problem gestoßen und habe festgestellt, dass ich den Flavour-Ordner "pro" und "tree" unter das lib-Projekt gestellt habe. Das Problem wurde behoben, nachdem ich den Flavour-Ordner unter das App-Projekt verschoben habe

Trinea
quelle