Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged Manifest error #41

Open
ElegyD opened this issue Aug 27, 2021 · 15 comments
Open

Merged Manifest error #41

ElegyD opened this issue Aug 27, 2021 · 15 comments
Assignees
Labels
type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@ElegyD
Copy link

ElegyD commented Aug 27, 2021

So I followed this guide from the Maps SDK to add the API key to the app.
Now in Android Studio the Merged Manifest view no longer works which in turn also breaks the MissingPermission lint.

Android Studio shows this error when viewing the Merged Manifest:

Merging Errors: Error: Attribute meta-data#com.google.android.geo.API_KEY@value at AndroidManifest.xml:57:13-44 requires a placeholder substitution but no value for <MAPS_API_KEY> is provided. redacted.app main manifest (this file), line 56 Error: Validation failed, exiting redacted.app main manifest (this file)

MissingPermission lint warning, despite the permissions being in AndroidManifest.xml:

Missing permissions required by FusedLocationProviderClient.requestLocationUpdates: android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION

A workaround would be to manually add manifestPlaceholders = [MAPS_API_KEY: ""] to the app build.gradle, but this feels wrong.
Is there a better way to avoid this, or is this more an error by Android Studio or the Android Gradle plugin?

@arriolac arriolac self-assigned this Sep 20, 2021
@arriolac
Copy link
Collaborator

Just to clarify, you saw the error despite having the API key, MAPS_API_KEY, defined in local.properties? I see developers reporting something similar in the past when running their code on another machine that doesn't have the key defined. In which case you'll need to securely share the key or define a default value for the property so you don't get that error. Do you have any other configuration options set up in your usage?

@ElegyD
Copy link
Author

ElegyD commented Sep 21, 2021

Correct, I have a MAPS_API_KEY in local.properties that I'm using in the AndroidManifest.xml like so ${MAPS_API_KEY}. Everything compiles correctly, Maps is working in the app, so the value is applied. But there are still the errors I wrote above.
No configurations options.

@arriolac arriolac added the type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. label Sep 21, 2021
@Dikyashi
Copy link

Dikyashi commented Sep 7, 2022

This issue still exist on following the documentation provided by google on
https://developers.google.com/maps/documentation/android-sdk/secrets-gradle-plugin.

is there any workaround for this or a fix?.

@arriolac
Copy link
Collaborator

arriolac commented Sep 7, 2022

Please provide more info on how to repro this issue as well as the version of the library and AGP that you are using.

@Dikyashi
Copy link

Dikyashi commented Sep 7, 2022

AGP version 7.2.2
Gradle Version 7.3.3

Steps to repro

  1. Have a Manifest with Any Android Permission for example

  2. Follow steps given in the google link above and change the meta data accordingly

  3. A Sample piece of code

  Connectivity Manager cm;

 cm = (ConnectivityManager) this.context.getSystemService(Context.CONNECTIVITY_SERVICE);
 cm.registerNetworkCallback(networkRequest, networkCallback); --> This line is flagged with Missing Permission even when permission is given in the Manifest. This is due to Manifest Merging issue

Workaround

A simple workaround is to define a manifest placeholder in the build.gradle(app module) file.

defaultConfig{
manifestPlaceholders["API_KEY"] = "Any Text Here" 
}

However as this is not mentioned anywhere in the samples/documentation i believe this is a bug.

arriolac added a commit that referenced this issue Sep 7, 2022
@arriolac
Copy link
Collaborator

arriolac commented Sep 7, 2022

I tried to reproduce the issue you mentioned in 707b1a5. Based on your report, the sample app should not be able to be built due to a merged manifest error when introducing a uses-permission declaration on the manifest file, however, I'm not able to see that. @Dikyashi can you check out the sample app and see if you can repro there.

@Dikyashi
Copy link

Dikyashi commented Sep 8, 2022

Hi i tried this with new project with JAVA as the preferred language and the problem still exists.
i used this as metadata

        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="${API_DEVICE_KEY}" />
           

and the callback as follows


 cm = (ConnectivityManager) this.context.getSystemService(Context.CONNECTIVITY_SERVICE);
 cm.registerNetworkCallback(networkRequest, networkCallback); --> This line is flagged with Missing Permission even when permission is given in the Manifest. This is due to Manifest Merging issue
 
 
private ConnectivityManager.NetworkCallback networkCallback = new android.net.ConnectivityManager.NetworkCallback() {
        @Override
        public void onAvailable(@NonNull Network network) {
            NetworkCapabilities networkCapabilities = cm.getNetworkCapabilities(network);
            boolean isInternet = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);

            if (isInternet) {
                validNetwork.add(network);
            }

            checkValidNetwork();
        }

        @Override
        public void onLost(@NonNull Network network) {
            validNetwork.remove(network);
            checkValidNetwork();
        }
    };
    ```

@arriolac
Copy link
Collaborator

arriolac commented Sep 8, 2022

I'm able to see the issue now. I think this might be an issue with AGP as the manifest keys are eventually injected by this plugin so explicitly adding a manifestPlaceholders should not be necessary. Let me dig into this issue a bit more to see what the correct resolution should be.

image

@shashankKuchukulla-whoop

Any resolution to this error?

@ElegyD
Copy link
Author

ElegyD commented Feb 1, 2023

With the latest stable tools (AS Electric Eel 2022.1.1, AGP 7.4.0, Gradle 7.5) I no longer have this issue.

@0neel
Copy link

0neel commented Feb 14, 2023

The issue is still there, though AS is now able to display the merged manifest even if there are errors.

@ArtemBatkov
Copy link

I added a key to the local.propery file but my manifest has no idea what is the "MAP_API_KEY" and it throws errors when building. What I am doing wrong?

@0neel
Copy link

0neel commented Jun 13, 2023

@ArtemBatkov

I added a key to the local.propery file but my manifest has no idea what is the "MAP_API_KEY" and it throws errors when building. What I am doing wrong?

Check if you add this plugin AFTER the com.android.application plugin. Otherwise the secrets plugin silently fails to create the MAP_API_KEY placeholder.

@ArtemBatkov
Copy link

ArtemBatkov commented Jun 13, 2023

@0neel

I added a key to the local.propery file but my manifest has no idea what is the "MAP_API_KEY" and it throws errors when building. What I am doing wrong?

Check if you add this plugin AFTER the com.android.application plugin. Otherwise, the secrets plugin silently fails to create the MAP_API_KEY placeholder.

Alright. Now, I have the following code that may help somebody one day.

First, be sure that your API key works. You can check this if you try Google Maps API through web queries.
https://maps.googleapis.com/maps/api/place/autocomplete/json?input=London&types=(cities)&key=YOUR_KEY
Insert your key in this query and check if you are possible to see any JSON data.

Second, I added the following row to my "local.properties" file.
MAPS_API_KEY=AIzaSyDX9V4L...........TszaLzf8y_Nw-nI

Third, I created an associative variable inside "build.gradle" file.

defaultConfig {
       //other code 
        Properties properties = new Properties()
        properties.load(project.rootProject.file('local.properties').newDataInputStream())
        manifestPlaceholders = [googleMapsApiKey: "${properties.getProperty('MAPS_API_KEY')}"]
       //other code
}

Now we have "googleMapsApiKey" name that'll be used in the Manifest.

Fourth, Android Manifiest should look like this.

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
       // OTHER CODE
        tools:targetApi="31"
        android:name=".App">

        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="${googleMapsApiKey}" />
        <uses-library  android:name="com.google.android.maps"/>

        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

Notice, the teg "meta-data" is between the "application" tag and "activity" one. Also, Google Map Documentation says use the following "meta-data"

<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="${MAPS_API_KEY}" /> 

HOWEVER, I replaced it with this one.

<meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="${googleMapsApiKey}" />
        <uses-library  android:name="com.google.android.maps"/> 

Fifth, if it is still a problem to present a map but you can see Google's logo, you are on the right way. I checked the internet connection and noticed it didn't work. So, please, be sure that your device has the internet spot.

Recently, I used MapView element instead of Fragment, and I had initialization problems, please, change your MapView to Fragment.

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <fragment xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/mapView"
        tools:context=".MapPage"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>

</androidx.constraintlayout.widget.ConstraintLayout> 

@0neel
Copy link

0neel commented Apr 27, 2024

@ArtemBatkov you don't actually need to manually parse the properties file. As mentioned in the original message setting the placeholder to an empty value is enough to fix the merged Manifest view.

defaultConfig {
    manifestPlaceholders = [googleMapsApiKey: ""]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

No branches or pull requests

6 participants