I have an Android handheld app with a couple of product flavours and 1 wear module. I need to only package this wear app with flavour1 and not flavour2.
As I understand this, adding the wear module as a dependency would include it in both flavour1 and flavour2.
I'm aware I could build the wear app manually and then add it to the flavour1's res/raw directory and have a res/xml/wearable_app_desc.xml containing the app's version and path details as outlined here:
https://developer.android.com/training/wearables/apps/packaging.html#PackageManually
But this seems like manual work and I was hoping there is a better way to do this?
if your flavors are flavorA and flavorB,
you can easily do so,
when u link it correctly in the build.gradle
Means:
flavorAWearApp project(':WearAppProject')
All the best, hope this is what u want,
Mike
Related
Short question:
How can I change the package name for debug or release build type in a library module?
Context:
In an Android project with MVP + Clean architecture, we have the repository pattern in a library module. We want to include Firebase on that library with two environments (development and production).
I already created the project in Firebase (com.example.com and com.example.com.dev) and then downloaded the respective google-services.json to src/main and src/debug folders.
Gradle google-services plugin validates the module package name with the client ID defined in the google-services.json, but Android restrict to change the applicationId in a library (I can't find the technical reason why)
Things that I tried:
Have two AndroidManifest.xml with different package property. com.example.com in the src/main and com.example.com.dev in src/debug/ but the second one it is just ignored
Set manifest.srcFile in Gradle sourceSets. The file is in the list when I run ./gradlew sourceSets but the package name doesn't change
Two different flavors in the library module and set different manifests for each one. The package anyway doesn't change.
At this moment I have just two suitable solutions:
1. Keep the Firebase setup and implementation in the app module outside of the repository.
2. Have only one environment for Firebase.
Thanks a lot for any help or advice.
EDIT:
Consider that I need to modify the package in a module (library), not in the app. For some weird reason Gradle shows this error when I try to use applicationIdSuffix or applicationId in a module:
ERROR: Library projects cannot set applicationIdSuffix.
Library projects cannot set applicationId.
This is the designed behaviour of Android Library project.
Two different flavors in the library module and set different
manifests for each one. The package anyway doesn't change.
Probably you need to change your Build Variants to that particular flavor/buildtype then you can see the updated package name taking effect.
See below screenshot.
I spent some time investigating and trying different alternatives to achieve two different package name per flavor or build type in a library module, and my short answer is: You can't, at least without doing something tricky and dirty.
Some guys that recommend using the parameter applicationIdSuffix or applicationId, that option doesn't work because of the design of library modules restricts those parameters to the app module. In a library, the package must be defined in the manifest.
That restriction delimits options to flavors, but, the package attribute in the manifest isn't merged, and you get an error when having different package name for the scr/main/AndroidManifest.xml and src/flavor/AndroidManifest.xml.
A tricky solution is to get the currently selected flavor form the task name and then change the main manifest in the sourceSets.
sourceSets {
main {
manifest.srcFile "src/$flavor_name/AndroidManifest.xml"
}
}
This hack works but in general is a bad idea, and I prefer to change the design of my architecture and implement the repository for both Firebase variants in a different way.
Gradle plugin: 3.2.0
Building iOS and Android apps with only one project is pretty awesome. But is it also possible to build multiple apps with different names, icons, etc.
This could be very helpful if you build apps with the same layout and maybe 95% same of the functions/code/algorithms:
different target-groups (recipes app for fitness, vegans, veggies, eco,...)
different sports (news for football, basketball, tennis ...)
different customers (business app for customer A, B and C)
...
Things, which could be different per app:
App name
App icons
SplashScreen
Design
Settings (API URL, ...)
Some code (default function/components maybe could get overwritten by app-based custom files)
Maybe it would be the perfect solution if you have a directory flavors where you can put all the files which you want to use to overwrite the default code-base.
Somebody here who released something similar or any ideas how to solve this?
This is a problem I have been solving in my projects last days. And I think I have some good (not perfect) solution so far.
Idea. We don`t have any built-in functions to help us handle this case, so we can use some external manipulation that can do the job. What we need is just multiple Android and iOS projects and single JS code base.
Implementation. I`ve come to this project structure:
ios
android
manager
src
ios and android folders is well known to you, they are native project folders.
src is a folder with JS code, you can organize it whatever you want
manager is most interesting one. Here we can store multiple native project files. We can have multiple native project folders in it, for example app1-android app1-ios app2-android app2-ios. And when we want to work on app1 we just copy app1-ios and app1-android to our root ios and android folders, so the actual project is app1. When we are done with app1 we can save android and ios folders to our manager and then just copy app2-ios and app2-android to root ios and android. And we are all good to develop our app2.
We can do it manually. But we are developers and we can make it much easier. I`ve written a PHP script that makes it as easy as php save.php -a app1 and php set.php -a app1 to copy from manager to root and backwards. Moreover, it takes care of not copying some unimportant staff (pods folder in ios, build in android etc.) and running pod install to ensure we have all pod in actual project.
I stick to one package.json file to have all npm modules installed once, so I don`t have to run npm install after each project switch.
Afterall, we can have as much projects as we wish in one repo, we can customize each one independently.
PS If you want me to share my scripts I`ll do it as fast as I can (need some time to prepare it for github and to write some more detailed instructions), just let me know.
I did this for about 100 different native apps per platform (iOS/Android), sharing the same code base. I manage this setup for about 2 years now and I am still happy with it.
Here is the iOS part:
I use targets with different plist/pch files.
Save files that shuld differ per app in a separate directories, named by the app name. Check the corresponding target, if adding the file to the project:
By using the same filename you can "override" the file for different targets.
The Android part:
I use one gradle module for the common part and one module per app for the customizing. I also use gradle variables for common values definitions (minSdkVersion, compileSdkVersion etc.). Only the following settings differs per app: applicationId, versionCode, versionName. Here is an example file for a custom app:
apply plugin: 'com.android.application'
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
applicationId "..."
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 28
versionName "1.0"
}
signingConfigs rootProject.ext.signingConfigs
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
}
dependencies {
compile project(':apps:common')
}
You can override the resources (app icon, images, strings etc.) in the corresponding res folder of an app module (use the same filename for the same resource).
Don't forget to include all your modules in the settings.gradle.
You can use multiple targets.
You can create target by below steps :
Go to project navigator -> Right Click on your app name under target -> Select Duplicate -> from popup select Duplicate only .
And you will find duplicate target. Now you can take another or extra app icon and launch image in your assets and for that target you can set it.
Refer below screenshots for better understanding!
So, select newly maded target and make changes by selecting it from general tab.
You can refer this great tutorial by Appcoda!
We do something similar to what you want do, but on a much more limited range. We have various builds of our app, each with a name, logo, design, API URL...
It's only built for android, so it's essentially a few flavors as mentioned in the comments above. (I don't know what the equivalent system is for iOS)
But we also use https://github.com/luggit/react-native-config that provides a way to share these specific variables/settings between both the native (android and iOS) and javascript code. All you need is setup a .env.myversion file which contains the settings you need, something like:
API_URL=https://my.server.com/
LOGO_FILE=/path/to/the/right/logo
COLORSET=shades_of_blue
The correct file is pulled in at build-time so your app has the correct version of each setting and you can then call these variables from within your code, and branch based on what version you're using. The benefit is that it works everywhere. The downside to this is that you might be shipping some extra stuff with your apps if you have all this in the JS layer rather than defining it in the build system with flavors. I guess it's a tradeoff between convenience and performance/efficiency that you need to decide on based on your use-case.
In Xcode you can simply duplicate your Target and create a new one with a new plist which means you can change the app name, icon, splash bundle and other settings as required.
In XCode you can Make different build confiugrations for different-different apps in single project(means Dev,alpha,beta,Prod,Debug,Release),With the help of this solution you are able to change AppName,AppIcon,BundleId,URLs,SplashScreen etc for different builds.
I created a website, where users can specify their content, icons, name and package name, and many other options like including advertisement SDK in app. After small payment, user can get created APK with certificate or sign app manually. Generation of apk takes a few seconds. APK is ready to upload to PlayStore. This is project was with high price, but my customer is happy.
How it done?
Create some templates for code. You can buy it on some sites.
Split optional code in separate files
If you can't splite code in separate file (for AndroidManifest.xml, for example), you can include comment with some keys (instructions for post-processing)
Generate icons from user content/specified icons.
On user request, just copy all selected files in same directory, with simple text processor remove unnecessary code (use comments from step 3), complile it, ship APK to user.
Basically there are two different options:
Option 1: OS Builds/android flavours:
Using iOS Builds and/or android flavours have some disadvantages in a react-native project:
React-native link only links the first target on Xcode. You’ll have to manually link libraries for further targets. However in react-native 0.60+ there is auto-linking, and this could be fixed with a little tweak to the podfile
React-native run-android may fail to launch the app if the app id differs from the package id.
Might be complex overtime to maintain a single native project with all the different builds/flavours and all the assets and resources that are included in a single project.
Requires some extra knowledge with xcode and android studio/gradel.
Option 2: Natives approach (which I personally prefer)
Based on the answer of Roman Osypov, I have came up with this approach with an implementation.
Currently each react-native project has two native folders, ios and android, each one represents the native project of the platform.
Lets assume we have two different bundles/apps with the same code base but different resources/assets etc..
CabApp TaxiApp
The main idea is to swap but keep in sync the root ios and android folders with their "natives" source.
create a folder in the root of the project called natives
copy the current ios and android folder of the main project to the
natives folder, lets assume it's CabApp, and rename those folder
into the following: CabApp-ios CabApp-android
do the same for TaxiApp, but remember to change the bundleId, the
identifiers, assets etc.. of the native projects
delete ios and android main folders in the root of the project
and add them the .gitignore
install the following dev dependencies yarn add -D rimraf sync-directory ttab
now the first time the project is pulled you need to set your "app"
for example if you want to work on TaxiApp you can execute the
following: yarn ios-TaxApp which you can define in the scripts in
the package.json
yarn rimraf ios && yarn rimraf android && yarn syncdir natives/TaxiApp-ios ios -c && yarn syncdir natives/TaxiApp-android android -c && cd ios && pod install && yarn
Basically this command deletes the root folders ios + android and sync the folders from the natives folders to the root ones.
The final step would be syncing back and watching the modifications from the "temp" ios and android folders back to the natives respective app-platform.
now in your start script for ios for example, you can add the following script
yarn ios-TaxiApp which you can define as:
yarn ttab 'yarn syncdir ios natives/TaxiApp-ios -w -c' & yarn ttab 'yarn syncdir android natives/TaxiApp-android -w -c' & yarn ttab 'yarn react-native run-ios --simulator=\"iPhone 11\"'
I am still working with Eclipse to develop android applications. Now there is a situation where I am supposed to build 2 different applications (You can consider as free and non-free version apk) using same app-code. I have got thousands of links regarding build.gradle and application package-name and others on google, but I don't how to build/use it in Eclipse.
Another question I have is how to point to 2 different images
based on different application.?
If you want to release two different build (paid and free). You need to change the package name. Just goto the manifest file.
For example: for free version
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.free">
and similarly for paid version
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.paid">
Alternatively, I will recommend you to use In app purchase feature and release only build
Try this.. Is there any way to integrate Eclipse with Gradle in Android project?.. There is no simple answer for this question.. Either you use eclipse with gradle and set two flavours with different in your build.gradle
productFlavors {
free {
applicationId 'your.package.name.free'
}
paid {
applicationId 'your.package.name.paid'
}
}
or else just copy your project twice and change package name. If you want to upload both your apps in play store then you need two different package names.
I am using Android Studio for developing Android apps. But I have heard in Android Studio it is better to have only one app in a single (one project per app) if that is right, then it will be very wasteful to open many frames for many projects. But when I searched I found that
Android Studio project = Eclipse workspace
Android Studio module = Eclipse project
Now, if this is true, it means that Android Studio also can support a multi-app project. If yes, then, is every app in Android Studio independent like in Eclipse (i.e. they do not disturb each other by sharing any file or setting)? Or can we have many apps in a single project? If we can then is there any point to take care of?
Thanks!
Yes, you have two options:
Option 1: Create an addition app module
First create your standard Phone & Tablet Android project, including the auto-generated app module.
Add a new app module: File > New > New Module ... > Phone & Tablet Module
Complete the wizard and name your Application app2 for instance.
Now you'll have both app and app2 in the same project.
To actually run app2 you first need to select it in the pull-down menu in the top toolbar of Android Studio, next to the Start and Debug icons. You can also do this though Run Configurations: Run > Run... > Edit Configurations... and modifying Module.
Option 2: Create an addition library module
This is ideal for creating a separate library that is isolated from the app, and can be shared across more apps (or other projects):
Add a new library module: File > New > New Module ... > Java Library.
Complete the wizard and give your library a good name, like libgoodstuff.
Now libgoodstuff and app will reside in the same project.
To make app sources depend on libgoodstuff, you first have to add the library module to the project settings.gradle to look something like this:
include ':app', ':libgoodstuff'
Then in app/build.gradle you have to depend on the library module like this:
apply plugin: 'com.android.application'
···
dependencies {
···
implementation project(path: ':libgoodstuff')
···
}
···
Yes you can. Inside your project if you want to create a new app do the following:
Create a new module by right clicking on your project -> new -> module
Select phone and tablet module
Now you will be able to run either app. This is an excellent way to share code between two apps as it allows you to keep and develop your libraries in one location.
You can definitely have multiple app modules in the same Android Studio project. Having said that, I've yet to find a reason to define multiple app modules in a project.
If you need different version of the same app, Gradle's build variant is powerful enough to satisfy perhaps 99% of the use-cases (I have a project with a dozen variants, each with its own custom code/res).
If you are writing different apps then it's better to make each its own project so apps don't inadvertently change each other's behaviour.
Not sure what you mean by "is every app in Android Studio independent as Eclipse", but each module is its own world by default unless dependencies to other modules are explicitly defined.
Adding this as an answer since I don't have enough reputation for comments yet.
For the answer to your question - Check this question that I have raised. Is this the same boat you were in ?
TL;DR
I was able to have multiple apps in the same Android Studio Project, build and run them without any issues. Another member
corroborated my claims in the comments on the Question.
#Android Studio Pros : Please check the above link and add your insights. This seems to be a confusing aspect.
My Take
I think I agree with #Kai's answer. But there are instances where we want multiple apps to have common library dependencies and don't want to duplicate the library dependencies. Wouldn't multiple apps be fine as long as the common library dependencies have ONLY common code and nothing else. The separate modules hold the individual app related code and that's where the differentiation is.
Yes, it is possible. As the existing answers showed, it’s quite straightforward to create additional application module in the same Android Studio project.
So I’ll try to answer underlying question why anyone might need it.
It’s certainly not worth it to put multiple completely independent apps in one project.
However, if you app is big enough, you might benefit from putting separate features into separate modules. You can also create a separate executable app module for each feature, so that you can:
launch/debug each feature separately
save some time on every compilation/dexing/putting everything into a single apk
encourage teams/developers to work independently, and even in separate repositories.
The main app module can be used only to combine existing features together.
I’ve recently created an article demonstrating this approach where I tried to explain everything in more details: https://medium.com/#domplebump/multiple-application-modules-in-one-android-project-36e86ceb8a9
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.