Not able launch Android Instant App with Google-Play-Services (Maps basically) - android

The purpose of posting images is to spot the errors easily as it is not the normal manifest file.
I'm trying to display Google Maps inside an instant app application. Now the application gets installed successfully (and runs smoothly) if I try to run it via app module i.e. normal install (which means I have included all the necessary gradle dependencies and API key) but if I try to run it as an instant app (not instant run) I'm facing this error:
and it takes me to debug/xml file:
Any idea?

This problem occurs when you include the google-play-services dependency in a non-base feature module. The underlying issue is that although the
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
element is added to the base feature's AndroidManifest.xml, the referenced id (#integer/google_play_services_version) is not available since the dependency is defined, and scoped, in another feature module.
The easiest, and most maintainable, workaround is to add the google-play-services dependency to the base feature module. Everything included in the base is available to non-base features, but as this error shows the opposite is not true.

Related

Android - How should you manage multiple modules? Manifests, grades, etc.

I understand this question is vague, but can someone outline the rules and/or how we should be dealing with multiple modules?
I've been trying to separate my app out into a base feature module, application module and instant app module.
However I've been having a nightmare building it.
I've tried searching online but there isn't really much documentation in it?
Ive got two activities in my base module manifest, as I want these in both my installed and instant app. Do I then need to copy these activity manifest entries into my other manifests? I tried running my installed apk without adding in these activities (I thought it might pull it from the base module) but then android studio says can't find default activity to launch the application with. So I need to copy the activity entries into all manifests?
I've also got manifest entry conflicts from all the libraries I'm using. FacebookInitProvider , FacebookInitProvider, CrashlyticsInitProvider etc. I don't have these entries in any manifest, they are adding themselves in to every manifest causing merge conflicts when building.
With the build grades, I've put in the base just the libraries necessary to run the base / instant app (to keep it as small as possible). The installed gradle then has all the extra libraries for the full sized application. If I use
implementation project(":base")
Will it automatically pull in all the dependencies that base uses? Or do I need to redeclare these?
I ask because after getting the app to build, firebase and firestore was causing an exception on getting the instance with the message "Firestore module not found" which makes it look like it hasn't pulled in the dependencies properly?
I apologise for the lengthy post, but I'm honestly at the end of my tether here. Truly stuck!
Im not sure I understand all your project structure correctly so I will give you general information on an app with modules:
Lets say you have the application called "appone" and have a module called "moduleone"
In the module gradle file you declare the minimum you need for the module to work properly by itself and in the manifest just configuration specific for the module that will not be required to be defined in the appone manifest.
Now in the appone manifest, this is the main file, you will have to set here the activity declarations and app permissions (not in moduleone), android studio merges the two files automatically so when you compile it will make one manifest file with both manifests contents so this is what can make conflicts if you declare the same or conflicting data on both files.
In the appone build.gradle file this is where you declare the implementation project(':moduleone'), and the implementation of libraries required by appone.
If for example moduleone uses firebase library and in appone you also directly require access to the firebase library you could declare it in both build.gradle files, you just need to make sure both use the same version.
Also you will need to declare moduleone on the settings.gradle file using: include ':moduleone'
appone is declared as an com.android.application and moduleone is declared as com.android.library.
Also appone has in its manifest an activity declared with the LAUNCHER category.

Extra activity entries in manifest due to third party library

I'm using google-play-services library in my app which is a eclipse project.
When final apk creating, it's containing some extra entries in manifest.xml file which is showing as containing ads alert when publishing app.
Extra entries showing like -
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:name="com.google.android.gms.ads.AdActivity"
android:theme="#android:style/Theme.Translucent" />
How could we ignore/remove these entries from final apk?
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:name="com.google.android.gms.ads.AdActivity"
android:theme="#android:style/Theme.Translucent"
tools:node="remove" />
I think tools:node="remove"can be used for gradle build or will work for eclipse build as well?
It is added by admob library. So if you don't want it and you don't want your app to contain ads, you should exclude admob from your project.
tools:node="remove" is for removing unwanted permission from other libraries that is used in your project and yes, it won't work in eclipse.
UPDATE:
Seems that you are using an old version of google-play-services which contains all modules as a single .jar file. I suggest that you find out which module of google-play-service you need for this project and only add that one with it's dependencies instead of adding all modules of google-play-services as a single jar. And this version you are using possibly is version 8.4.0 of google-play-service (or even older than it) so it is much better to use one of the newer versions.
For using only the module that your project needs and using a latest version of it, you should do as follows. Let's assume that you just need 'play-services-maps`. So you go to
<android-sdk-folder>/extras/google/m2repository/com/google/android/gms/play-services-maps
and open one of the recent versions like 11.0.4 (or less but I suggest to choose one of 10+ versions) and get the .aar file and add it to your eclipse project (if you don't know how to use .aar file in eclipse read this). Also open the play-services-maps-x.x.x.pom file to see what is the other library that maps needs (which are play-services-base and play-services-basement in this example) and go to their folder and add their .aar files to your project too and check their .pom files as well to include tehir dependencies.
Yes, it is kind of tedious job, but it is the way to add this gradle-based-distributed libraries to eclipse.

Android Studio 3 difference between library module and feature module

In Android Studio 3 there are at least two new module types. First is Instant app module and the second one is feature module. With Instant App module it's quite obvious but feature module from my perspective is the same as the library module. So what is the real difference between library and feature modules and when I should use library module and when feature module?
I would complete Marcin Orlowski scheme like this.
You could picture library module in the same way as dependencies of a given feature or base module.
Hence the library modules will not be packaged in Instant APP APK.
A feature module is a module that applies com.android.feature plugin.
This module type has a dual nature:
When consumed by an application (com.android.application) during build, it produces an aar and works just like a library
When consumed by an Instant App APK (com.android.instantapp), it generates an Instant App APK
Developers should write feature modules just like library modules. The tools provided are responsible for applying the correct nature when used during a build.
In the simplest case an Instant app can have a single feature module.
If there is more than one feature module, these feature-to-feature
dependencies can be defined through the api configuration. In any
case, there must only be a single base feature which is marked with a
baseFeature attribute.
Main source: https://codelabs.developers.google.com/codelabs/android-instant-apps/#3
This all for Instant Apps so you only need it if you are making your app supporting instant app feature
See https://developer.android.com/topic/instant-apps/getting-started/structure.html#basic-app
Android SDK is the core features and software tools that allow you to create an app for the Android Platform. An SDK contains lots of libraries and tools which you will use to develop your application.
A Library is a collection of pre-built compiled code which you can use to extend your application's features. For example, you may need to show some graphics in your application. Instead of creating this from scratch, you may choose to use a pre-built library someone else has developed which will give you the features you need thus saving you some time.
A module is a small part of the application which can be tested and debugged on its own without needing the whole application. This is same for any programming language. Suppose you are building an app with Login feature. To test if the login feature works, you don't need the whole app. Thus the Login part is a module of your application.
The app module builds an app. A library module builds a library.
An app is what a user uses. The output of an app module is an APK, the package of an Android application.
A library is a collection of code that represents something that you want to use in multiple applications or otherwise want to keep in a separate "container" than the rest of the app code. The output of a library module is an AAR And Jar.
Use Feature for linked feature of your instant app (to launch it with deeplink).
Use Library for code dependency in your app or in your Feature modules.

Android Wear: how to share code between the wearable and handheld modules?

I am making an Android app with Wear capabilities.
I want to share some code between the wearable and handheld modules. Specifically, I want to share communication code that uses Google Play Services classes, e.g. com.google.android.gms.common.api.GoogleApiClient.
The obvious way to do this is to have a module (I called it common) and add a dependency to it in both the handheld and the wearable modules.
Since this common module uses Play Services, I need to make it depend on com.google.android.gms:play-services.
I was not sure what to put for the version number - the official documentation here says to use 5.0.77, but that does not work, as the latest SDK does not have this version anywhere, instead it comes with 5.0.89 and 5.2.08.
If I use 5.0.89, the Wearable app does not work, with this error: Google Play services out of date. Requires 5089000 but found 5077534. The version on the watch is older than the one I used to compile.
Instead of depending on com.google.android.gms:play-services the common module could depend on com.google.android.gms:play-services-wearable but then there is a conflict when building because the handheld module depends on com.google.android.gms:play-services, and these two artefacts use the same package name (com.google.android.gms), and so the gradle build fails.
What's the solution?
.
EDIT after discussing a bit and to make my question clearer.
To be able to use communication APIs in my common module I have two choices:
Make common depend on com.google.android.gms:play-services
Make common depend on com.google.android.gms:play-services-wear
⇒ Solution 1 does not work because the version available (5.0.89) for development is more recent than the one on the watch (5.0.77).
⇒ Solution 2 does not work because the handheld module already depends on com.google.android.gms:play-services, which conflicts with com.google.android.gms:play-services-wear.
I bumped into the same problem a few days ago. My shared module depended on com.google.android.gms:play-services as well, so Gradle refused to build and kept nagging at me:
Error: more than one library with package name 'com.google.android.gms
I added this line to my mobile project's gradle file and the error disappeared magically:
compile(project(':sharedModule')) {
transitive = false
}
Take a look here: https://github.com/tajchert/SWear_Weather
I had created common project that is shared between mobile and wear, and contains my constants. Remember to set there dummy manifest file and:
apply plugin: 'com.android.library' in build.gradle file.
I had also encountered problem with play-services version - I had solved it by using
compile 'com.google.android.gms:play-services-wearable:+'
compile 'com.google.android.support:wearable:+'
instead of specifying particular version - to be honest it should be separete question - as it is out of scope of previous (sharing code between projects).
It is possible to need invalidate cache/restart after changing - you can/should remove build paths in your projects to get rid of all other versions.

Android Library Manifest vs. App Manifest

I've read similar questions here, but am still not clear on a couple of things. Using a Library Project means that my overall project will have two manifests -- one for the library and the other for the "main" app project -- and I'm not clear what goes in which or if there is some redundancy.
I'm developing an app widget with "lite" and "paid" versions, so will have almost all code in a library project. Being a widget, the library will have at least a receiver, a service, a configuration activity, plus a couple of other activities. So where should the full declarations of these components -- including intents, filters, etc. -- be declared? Do they go in the manifest for the library, or in the manifest for the application package itself, referencing the classes in the library (e.g. android:name="com.foo.mylibrary.MyService")?
Some examples I've looked at seem to declare them in both manifests, but I suspect that putting these in one or the other is a no-op.
Using a Library Project means that my overall project will have two manifests -- one for the library and the other for the "main" app project -- and I'm not clear what goes in which or if there is some redundancy.
The library project manifest is not presently used.
Gradle for Android, and therefore Android Studio, support library projects and AARs publishing a manifest. This can include things like activity declarations, required permissions or features, or minimum supported Android SDK levels.
The rules for how library manifests are merged with the app's own manifest -- particularly when you take build types and product flavors into account -- is a bit complex.
So where should the full declarations of these components -- including intents, filters, etc. -- be declared?
In the host project.
The library could publish those components, and the Android Studio host project can then remove them if needed.
Do they go in the manifest for the library, or in the manifest for the application package itself, referencing the classes in the library (e.g. android:name="com.foo.mylibrary.MyService")?
The latter.
In either (with Gradle for Android and Android Studio). In theory, it is easier for the library to publish the components, so the app author does not have to. Personally, I am not a huge fan of this, as too many developers will wind up shipping unnecessary manifest entries.
As of ADT r20 Preview 3 it is now possible to merge manifests. So common configuration can now be put into the library manifest. See https://stackoverflow.com/a/10400355/262789 for more information.
Version 13 of Intellij IDEA is necessary for manifest merging support (manifestmerger.enabled=true). Also the Grade based build system appears to be necessary for Android Studio support.
Any referenced android elements like activities, receivers, services, etc. MUST go into your Application manifest or they won't be recognized by the OS. As you guessed, the Library manifest file is pretty much an empty implementation
UPDATE
As CommonsWare points out above, the Android build tools will now attempt to merge the various manifests on your behalf. Leaving up the original answer for posterity

Categories

Resources