Compiling to different targets Android - android

Our app is distributed from multiple markets and as the developer I need to make different code run for each of those targets, something like:
if (target == ROCK) do A;
else if (target == PAPER) do B;
and so on, does ADT/Eclipse support these kinds of stuff?
How should I go about doing it?

you can set in the res/values folder a parameter (e. g. string in strings.xml) to check for. This string can be parametered with the target (e. g. screensize in res/values-480x800).

There are two approaches to this, depending on what you want:
Multiple APKs, each with hardcoded options.
A single APK that executes code conditionally.
For approach 1, you can use build flavors in gradle / Android Studio (I don't think ADT supports this). You can basically build multiple versions of a single APK choosing different source files in each. Then, in the Play Store, you can distribute these different files according to your criteria.
For approach 2, you have a few options:
For resources, you can provide different files depending on Language and Region (or MCC).
For code, getResources().getConfiguration().locale.getCountry() to get the country of the device or TelephonyManager.getNetworkOperator() for the MCC

once I had similar problem for J2ME development, I just developed preprocessor, you can try to use it for Android projects

Related

Android: different modules for Tablet & Phone, but one single app published & listed

As stated in my question, I am going to develop an app to be published on Google Play, and that app will properly support phones and tablets.
This means the phone and tablet apps will share pretty much the same features, but will display possibily very different layouts in order to offer the best UX for these respective platforms.
At this point, I wanted to go about as following and was wondering if that was the correct way:
I believe App Bundles will help me achieve that, so let's assume I create a new Android Studio project from scratch.
Then, using File > New > New Module, which opens the module creation dialog, I would generate two Phone * Tablet Module and one Android Library module, a module that will contain all the shared same business logic, common to both aforementionned modules.
Then, using the Manifest, I would add the restriction to target phones and tablets separately.
I believe both app modules will need to have the same package name (application id).
Would that be the correct way ? Am I missing anything ? Is there a better standardized way to do so ?
Thanks for the help !
You only really want the layout to change, right? So just create different layouts for the different devices, you can add the qualifiers on creating a new layout file.
https://developer.android.com/training/multiscreen/screensizes
Check this for further information.

Multiple APK versions with different functionality

I'm developing and app which will (during the development and testing process but NOT in the final version) require slightly different functionality in different .apk release files.
There are few issues in this particular case:
different "testing" APK versions shouldn't contain ANY of the code and resources (so no shared strings and images) from other APK versions (for security/reverse engineering reasons cause different people will have access to different APK versions)
at the end of the development process the app will contain all/most of the features from the "testing" builds.
the app uses multiple modules (developed by different teams)
there might be a few (between 3 and 10) of those versions, all developed concurrently by multiple developers in the same project on the same repository.
The goal is to make it as easy to maintain (including UI/integration tests and CI) as possible. Is there any way to achieve this? We did some experiments with different build variants and flavours + no-op modules/methods but it seems a little bit complex. Any alternative suggestion will be welcomed.
Your question is indeed too broad, I think there is no general solution to your problem because it's too complex, and without knowing the details of the project it's even more difficult to tackle. Actually, your problem sounds much more like an organizational one rather than a programming-related one, the only "solution" I see is to address specific issues.
1. No VCS, no party
there might be a few (between 3 and 10) of those versions, all
developed concurrently by multiple developers in the same project on
the same repository.
I would start by defining your VCS flow, because without a version control system I'm afraid you and your team(s) aren't going anywhere. If you were to use git (don't know how this would be done with other VCS), you would have a few options:
Each feature (team) has its own, long-living, feature-branch. The common code shared by all teams is kept on a develop-branch, on which each feature-branch periodically rebase. You would need to setup your CI to build test apks and run automated tests for each branch. At the end of the development process everything gets merged into master (or develop, or whatever). The advantage would be that each feature (team) would work on a sealed portion of the project and will be able to handle test releases and automated tests autonomously. The disadvantage would be that the common part of the codebase (develop-branch) needs to be handled very carefully, otherwise you might get conflicts-hell.
The whole project is developed on a common develop-branch. Each feature is developed with small increments, each member of each team branches from develop-branch and merges every iteration back on develop-branch. The advantage would be: different features can potentially depend on each other, conflicts are less likely to occur, CI has simpler configuration. Disadvantage: teams are less independent, releasing different apks requires a strategy.
2. Define dependencies
In order to choose a proper strategy, it is crucial to define clearly the dependencies between the features. Would it be possible to have truly parallel development of each feature?
This depends entirely on the specification of the project. For instance, if you were to develop an e-commerce app, you might end up having feature domains like user account, products catalog, orders processing... If all of these features depend on common local storage layer, how are you going to develop them truly in parallel?
Once you've defined the dependencies, you will be able to decide in what degree the features can be developed in parallel. Do different teams need to agree on common interfaces? Could a feature be completed even if other teams are still at 0?
3. Build variants are your friend
different "testing" APK versions shouldn't contain ANY of the code and
resources (so no shared strings and images) from other APK versions
(for security/reverse engineering reasons cause different people will
have access to different APK versions)
Flavors are meant to do exactly what you're looking for, that is, build different apks from the same project but using different subsets of code and/or resources.
Keep in mind that you can have flavors in multiple dimensions (and build types). For instance, you could have one flavor dimension called "network", with 2 flavors "mockedNetwork" and "actualNetwork". Then you could have another dimension "feature", with "featureA", "featureB", "featureC". You could then easily build and release 6 types (well 12 if you have also debug and release build types) of apks, one for each combination (mockedNetworkFeatureA, actualNetworkFeatureA, mockedNetworkFeatureB etc.).
With flavors you could easily replace chunks of the app that you don't want your tester to have. For instance, you could have a strings.xml file with only lorem ipsum strings and then keep actual texts strings only for internal use.
What I would do is to use git. The master branch is kept clean for production and each team can have one or multiple branches to work on. They can change the package name in their branch so your APKs will all be different. The only problem with this approach will be the merges into the master branch that might cause conflicts. But this could be a solution to your problem.

Multiple targets using same android project in eclipse ADT

I have a base android project that gets tweaked and would like to generate different APKs. Typically the changes are help links, icons/images, hiding certain functions etc.
In iOS (Xcode) and in Win store app (VS 2012 exp), it is possible to create multiple targets to control the resources bundled with the target as well us programmatically change behavior using the C flags.
Is it possible to do the same for an android project using eclipse ADT? The main issue I see is that, each APK changes the bundle signature (like com.xxx.yyy) and since every file has that package com.xxx.yyy in the files, it is not possible to use that file in a different project (which has a signature like comm.aaa.bbb).
In eclipse .apk builds with Ant and don't support multiple APKs build. Of course you can write your own script, but it will be difficult.
Fortunately, there is another build system, which is called Gradle and it's supported by android developers.
http://tools.android.com/tech-docs/new-build-system/user-guide
You are interested in a section called "Build Variants"
But not everything is so simple, Eclipse with ADT and Gradle are not compatible but Android Studio yes.
The source of this problem is Java itself, where you can't have things similar to #ifdef and most compiler don't allow completely replacing a class or part of it either.
I actually have a base project from which I build 6 APKs already, and more soon.
Each APK uses its own package name, however the whole code is under a single package, but that doesn't create any issue.
There's however many issues:
- All resources, all classes will be in the target APKs, whether used or not.
- Different behavior means different code or different resources, each of which must be handled differently.
For resources, it's "quite easy", just make replacement resources in the final application projects. However unused resources will be left over.
For classes, that's where it becomes very complicated.
To create slightly different behavior you can use reflection and interfaces, each APK implementing it's own version of the interface using a common name eg myActivityPrj which is retrieved using reflection.
Sometimes it's also easier to test the APK package name from within the code, so in the Application object, I set some boolean as to which APK is actually running. Making sure to use those only from the UI to avoid any performance hit.
To create very different behavior, for example an activity is not used in an APK, well, could use above method and a flag saying available or not, but what a waste of space inside the APK!
Another option is to break-down the central project in smaller pieces, if at all possible!
To actually make APK smaller, I found only one way so far: create a Java project which will copy the central project and then remove and/or replace files within this copy, from a remote source tree (a directory named "replacement-files" which contains a res and src folder).
For resources, that java project will actually parse all strings.xml and remove unused strings from a hard-coded list, can't trust lint output as some resources are used in sub-projects and lint doesn't care.
So far, the APK that includes all features is about 10MB, one variation is about 4MB, whereas it should actually be less than 2MB. Another variation is about 8MB, whereas it should really be 2 or 3MB. The above method is overly complicated and being able to removed unused code and resources is getting more and more complicated.
I've looked at various other solutions, but they're all very complicated with a lot of restrictions, constraints.
After 4 years of development on Android, my only conclusion is that Java is the poorest choice possible for a mobile device: slow, inefficient, resource hungry, and very inflexible. Looking at the NDK, it appears very inconvenient and very limited.

Resources on installation of Android app

When android app is installed, does it keep only the resources required by the device current configuration (resolution, language etc) and remove all other redundant resources?
(What will be the point of keeping high resolution images when it won't use it ever?)
Whatever files you have in your APK will be persistent. it will not get deleted by any chance.
As far as I know, the idea is to make use of a single APK to be compatible with the different types of Android devices available. It is not a good practice to design different apk for different Devices.
But yes, some of your resources will never be used by the device and this is how it works.
if required you can create multiple apks for a single app itself.
And it is well explained here,
http://developer.android.com/guide/google/play/publishing/multiple-apks.html
Well, it is all compiled in one apk file, so no choice. It will keep all the resources.

Multiple Android Application Package .apk files from single source code

I would like an Android build system procedure, command line or Eclipse, to generate several .apk files from a single source codebase. Some common reasons for this - having specific versions for markets with different requirements or a free and paid version.
This question IS NOT ABOUT:
Packaging shared code into Android libraries or into external Java jars
Producing a debug vs. signed release .apk
Google says "you probably need to create separate Android projects for each APK you intend to publish so that you can appropriately develop them separately. You can do this by simply duplicating your existing project and give it a new name." Then they kindly suggest using libraries, which I understand. Then, they mention in passing exactly what I do want: "a build system that can output different resources based on the build configuration"
I know that to accomplish conditional compilation in JAVA one can key off a 'public static final' variable. There is an example of tweaking such a value in build.xml. Any more complete example of an Android Ant build configuration for this or a link to an OSS project doing that now, please? BTW, build.xml is auto-generated, but I have seen people hacking it, so how does that work?
With the package name declared in Manifest.xml as package="com.example.appname", if one needs to emit multiple .apks that vary that name, is one stuck with a separate project for each?
I'm generating 2 different APK's (demo and production) from one single source tree with 3 small modifications:
1) I have public static final DEMO=true; //false; in my Application class and depending on that value I used to switch code between demo/production features
2) There are 2 main activities, like:
package mypackage;
public class MyProduction extends Activity
{
//blah-blah
}
package mypackage.demo;
public class MyDemoActivity extends mypackage.MyProductionActivity
{
//blah-blah
}
3) And in the end 2 separate AndroidManifest.xml files which points to different launcher activities depending on demo/production switch
I'm switching between 2 APK's manually, but see nothing difficult in writing small ANT task to switch between them automatically
One way to do it would be to maintain two separate AndroidManifest.xml, one for each configuration. You can switch back and forth between the two either manually (copying) or automatically (build script).
[edit] This person here has a system to do this kind of thing: http://blog.elsdoerfer.name/2010/04/29/android-build-multiple-versions-of-a-project/
The answer to this screams Gradle, as explained on this website. It's officially built into Android Studio and is encouraged.
It's amazing; I've built 3 separate apps using the same source code, with customized text and graphics, with no special coding whatsoever. Just some directory and Gradle setup is required, and other posts of mine can be found with answers to both.
It seems to explain all the basics really well. For the answer to your specific question, look for the section Product Flavors under Build Variants, where it describes specifying different flavors.
As the website explains, part of the purpose behind this design was to make it more dynamic and more easily allow multiple APKs to be created with essentially the same code, which sounds exactly like what you're doing.
I probably didn't explain it the best, but that website does a pretty good job.
Despite your insistence that this is not about packaging shared code into Android libraries, it sort of is. You've stated that markets may have different requirements or having a free and a paid version. In each of these examples, your two final output APKs have different behavior and/or resources. You can put the vast majority of your code in a shared Android library, and then maintain the differences in your actual projects.
For example, I've worked on apps where they need to be released both to the Android Market and the Amazon AppStore. The Amazon AppStore requires that if you link to a market page for the app, it must be Amazon's (as opposed to the Android Market page). You can store a URL in a resource in the library and use that in your code, but then override that resource in the Amazon project to point to the appropriate Amazon URL.
If you structure it right, you can do similar things in code because your starting point is your Application object which you can subclass and do different things with.
That said, if you want to add an Ant step that changes the package name in the manifest, it is just XML. It shouldn't be hard to modify as a precompilation step.
This article has a good walk-through with examples of how to amend config files at build time; see in particular the Customizing the build and Using a Java configuration file sections. Note that some of the information about build.xml and ant is a little bit out-of-date now.
Here's our situation: we have a single codebase from which we release for several clients. Each of them has various requirements regarding titles, backgrounds and other resources in the application (let alone package names).
Build is handled by a Ruby script that modifies AndroidManifest, copies/replaces certain resources from client-specific folders and then moves on to Android's standart build routine. After the build is done, script resets changed files back to their original, 'default' state.
Well... Maybe it's not optimal and definitely not Android-specific, but that's how we do it.
I had the same problem but packing all in one project with flags is no solution for me. I wrote an example how to do that with Maven:
How to create multiple Android apk files from one codebase organized by a Maven multi module project.
My team build 2 different build using single code base + additional code.
As android build is based on ant script, I use ant script to do this work.
I used xmltask to manipulate manifest xml file and many ant task ( regexp , copy..) to edit source code.
I prepared template project template ( including build.xml , default.properties, local.properties) and copied new source code into those project templates. when copy completed, run build.xml parallel to shorten build time. when build finished, I get multiple apk files.
It's easily to achieve your goal by using Android Studio build variants which use graddle as the build system.
Check here for more detailed information.
I think that the best way remain to use libray for common sources and two different Android project for demo and production package. This because in Java it is very simple to make a reverse engeneering from apk to sources. If you use the same sources for demo and production, someone could hacking your apk downloading the demo package, extracting the java sources and unlock the sources changing the variable to use it as production version.
With library you can preserve part of sources in the production package, in this way there is no way to use demo package as production package.

Categories

Resources