Is it possible to programmatically set the app key for Localytics? From the integration guide (https://support.localytics.com/Android_SDK_integration), it seems like you must set it in the Manifest file as meta-data.
<meta-data android:name="LOCALYTICS_APP_KEY" android:value="APP KEY FROM STEP 2"/>
From the following post, it also seems like it's impossible to dynamically set Android meta-data. How to add metadata dynamically (Not in manifest but inside code)?
I'd like to be able to set the app key dynamically based on Gradle buildType so I can have a release app key and a debug app key.
You can use manifest merging to support different app keys for your build types (e.g. debug versus release) or your product flavors (e.g. free versus paid).
To support different app keys for your builds types:
Create src/debug/AndroidManifest.xml and src/release/AndroidManifest.xml.
Remove the meta-data tag from src/main/AndroidManifest.xml.
Add the appropriate meta-data tag to your build type specific manifest.
src/debug/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app" >
<application>
<meta-data
android:name="LOCALYTICS_APP_KEY"
android:value="DEBUG_APP_KEY" />
</application>
</manifest>
src/release/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app" >
<application>
<meta-data
android:name="LOCALYTICS_APP_KEY"
android:value="RELEASE_APP_KEY" />
</application>
</manifest>
For different app keys based on your product flavors, just replace debug and release above with your product flavor names.
There is an override on Localytics.integrate that takes an api key.
Localytics.integrate(this, "API_KEY")
If in case you are using autoIntegrate, use following API which takes Application context as first argument.
Localytics.autoIntegrate(this, "API_KEY");
Related
I'm trying to create bindings for Zendesk library and I faced with a problem.
Zendesk Belvedere library (belvedere-1.0.2.1.aar) contains a file provider in its manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...
...
<application>
<provider
android:name="com.zendesk.belvedere.BelvedereFileProvider"
android:authorities="${applicationId}.belvedere.attachments"
android:exported="false"
android:grantUriPermissions="true" >
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/belvedere_attachment_storage" />
</provider>
</application>
</manifest>
When Gradle is used as build tool, it puts this aar to the APK file and it replaces ${applicationId}.belvedere.attachments with com.your_package_name_here.belvedere.attachments in the merged manifest file. It's fine.
However, Xamarin handles it differently. Here is what I found in the manifest of my final APK:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...
...
<application
...
...
<provider
android:name="com.zendesk.belvedere.BelvedereFileProvider"
android:exported="false"
android:authorities="dollar_openBracket_applicationId_closeBracket"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/belvedere_attachment_storage" />
</provider>
...
...
</application>
</manifest>
Obviously, dollar_openBracket_applicationId_closeBracket is not what I need.
Seems everything works, however it makes impossible to install several Xamarin applications that use these bindings, because all of them would have conflicting providers with the same authority (and user would get INSTALL_FAILED_CONFLICTING_PROVIDER error).
Is there a way to change dollar_openBracket_applicationId_closeBracket in the manifest?
Edit: A small sample that shows the problem: https://gitlab.com/lassana/ZendeskXamarin/
The current Xamarin.Android manifest merge build task, up to and including
version 7.1.0.19, does not provide any bundeID/ApplicationID (${}} substitution in the merged manifest like gradle does.
This is just a limitation in the manifest processing/merge task, thus you are ending up with dollar_openBracket_applicationId_closeBracket in your final manifest and will have to correct both manifests yourself.
The only current solution know to me to avoid the manifest merge task and it's limitation is to:
Remove the file provider entry from the '.aar`'s manifest
Add the complete file provider entry your app's manifest
Note: You have to do both steps
Depending upon how often the .aar is changing and where you are sourcing the .aar file from:
Manually unzip the aar, remove the entry and re-zip the aar (the quickest way)
Automated this in a build step via a shell script using bash or powershell cmds
Write a MSBuild C#-based Task to do it.
Request that the aar manifest be changed upstream (not likely to happen ;-) since it works fine w/ gradle)
FYI: Personally I have seen the ${applicationId} issue you are having a few times. I have written build scripts (bash/.ps1) to do the manifest fix-up as it seems to always be some special case in the .arr's manifest that I am dealing with.
According to Microsoft team, Xamarin.Build.Download (0.4.12-preview) finally fixes this bug.
So, you should follow these steps:
Update the Nuget Package to 0.4.12-preview3
Restart the IDE
Delete all cached locations of NuGet Packages
Delete bin/obj
Rebuild
The main manifest file of your project is the higher priority manifest, so if you add the provider element to main manifest file and apply a merge rule marker for android:authorities attribute, the merger tools replaces the android:authorities value that you declare in the main manifest.
Declare provider element in main manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
...
...
<application>
<provider
android:name="com.zendesk.belvedere.BelvedereFileProvider"
android:authorities="com.example.belvedere.attachments"
tools:replace=”android:authorities” >
</provider>
</application>
I have the same issue mentioned in this post AndroidTest Manifest permission not detected
and this post AndroidManifest in androidTest directory being ignored
--> If I put the test manifest in androidTest, debugAndroidTest, androidTestDebug, it never gets picked up and merged.
the answers about putting the AndroidManifest.xml in the debug folder are correct; that does seem to work. (put the test manifest in src/debug
What I want to know is why can't you put it in the androidTest directory? All the documentation I've read while trying to figure this out makes it sound like you should be able to, and that if you can't then I'm thinking that sounds like some bug in the manifest merger.
For what it's worth, I'm using Android Studio
That is correct and totally agree with you on the confusing documentation. The AndroidManifest.xml under androidTest* source sets would be packaged for the instrumentation APK that does your tests on your actual app APK. If you open the generated APKs for debug and androidTest under build/outputs/apk/ after compiling your app module with the command gradlew assembleDebugAndroidTest (assuming that you haven't changed the testBuildType in you build.gradle, more info here), you'll find that any AndroidManifest.xml configuration added under androidTest will be in the androidTest APK and not in your debug app APK.
And also as you said, in case you need test specific configurations like extra permissions, you'll have to place them in the AndroidManifest.xml under the debug source set instead of main, hence they'll only be available for testing your app but not in your release build. Of course you can always double check by opening the generated APKs after compiling to make sure that the configuration is right for each build variant.
If you need to add extra permissions for tests, you can do it.
You should set the same android:sharedUserId in default AndroidManifest.xml and androidTest/AndroidManifest.xml.
For example:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="com.yourpackagename.uid">
<application
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:replace="android:allowBackup">
</application>
</manifest>
androidTest/AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:sharedUserId="com.yourpackagename.uid">
<uses-permission android:name="android.permission.***" />
</manifest>
For details: https://stackoverflow.com/a/14196493/3901000
In my android app, I added a the following string resource in the
AndroidManifest.xml
<meta-data
android:name="io.fabric.ApiKey"
android:value="#string/fabric_key" />
and in strings.xml
<string name="fabric_key">XXXXXXXXXXXXXXXXXXXXXXXX</string>
when I try to build the project I get the following error:
Error:Execution failed for task ':app:fabricGenerateResourcesDevDebug'.
Crashlytics Developer Tools error.
Any help would be appreciated.
Try refreshing kit-libs folder by right clicking on "kit-libs" and then selecting refresh kits.
I just looked into this pretty closely. This doesn't work because the android:value attribute is taken literally. To use a resource id you'd have to use android:resource attribute instead but the Fabric gradle plugin does not make use of this android:resource attribute at all because it processes the manifest as an XML document rather than as an Android Manifest class.
After decompiling the Fabric source code and figuring out how the DefaultManifestData and StandardAndroidProject classes work, I confirmed the following:
The Easiest Way to Provide a Separate ApiKey for Debug Builds
Leverage manifest merging by creating app/src/debug/AndroidManifest.xml with the following contents (you must use the tools:replace attribute for this to work):
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<!-- Meta-data -->
<meta-data
android:name="io.fabric.ApiKey"
android:value="[yourDebugApiKey]"
tools:replace="android:value"/>
</application>
</manifest>
Your debug ApiKey is located in your project's Organization Settings page.
I have an android Library that outputs an aar library. This library will be built into different projectFlavors of Mobile, TV and Wear apps. I think that each of these platforms' should be the ones that set variables like the app name, icon, and permissions through the manifest and productflavors.
Is there any way to build an AAR without requiring an AndroidManifest.xml and therefore drawables(for the icon)?
More information about what I'm doing can be found at my last question on the subject:
Android Studio Java Library Module vs. Android Library Module
Any android library needs to have an AndroidManifest.xml file, but a name or an icon is not required. It's only needed when there is an activity that is MAIN and LAUNCHER.
You simply could use this manifest and your library will work like a charm.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="[your package]"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="[min supported version]" />
<application/>
</manifest>
You can go with the AndroidManifest.xml below if you don't need to setup any Android component like Activities or Services or add custom properties.
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.your.library.base.package" />
Since we need to have 2 maps keys for an application (debug, release), I would like handle them in the gradle file.
Is there an option to put the keys into the gradle file buildVariants and insert a variable in the manifest, that it uses the key depending on the current variant?
If yes, how?
Since you are using gradle you can do the following:
build.gradle
android {
.. .. ...
buildTypes {
debug {
resValue "string", "google_maps_api_key", "[YOUR DEV KEY]"
}
release {
resValue "string", "google_maps_api_key", "[YOUR PROD KEY]"
}
}
}
And in your AndroidManifest.xml
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="#string/google_maps_api_key"/>
This way you only have one AndroidManifest.xml and you set value based on your build type. Hope this helps.
This can be done pretty simply with the build system. You don't need to worry about doing variable substitution in the manifest; the build system's manifest merger can do the work for you.
Set up your project like this:
app_module
+--src
+--main
+--AndroidManifest.xml
+--debug
+--AndroidManifest.xml
+--release
+--AndroidManifest.xml
You already have the src/main/AndroidManifest.xml file. In this copy, remove the Google Maps API key <meta-data> tag. What you want to do is supply debug- and release-specific versions of this tag in the debug and release manifest files, and let the manifest merger do its thing. In the build-type-specific manifest files, you don't need to supply full manifests with redundant information, but only those parts that will be different. The merger will use the one in src/main for the bulk of it:
src/debug/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sbarta.myapplication" >
<application>
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="DEBUG_VALUE"/>
</application>
</manifest>
src/release/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sbarta.myapplication" >
<application>
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="RELEASE_VALUE"/>
</application>
</manifest>