I am looking for the best way to allow developers / testers to point an app to the UAT server rather than the default, PROD, in an android app. As with .NET or Java, where I would have an app.config or properties file allowing you to change the URL prior to running the app, I would like to understand the common approach on android apps?
The data storage options outlined in http://developer.android.com/guide/topics/data/data-storage.html are clear, but none of them seem to quite fit unless I am missing something.
Shared preferences and InternalStorage seem the best fit, but with shared preferences it looks like I would require root access to modify the file and with InternalStorage no API is provided for parsing the settings, so just wondering if I have missed something obvious.
Any advice?
You can achieve this in a slightly different manner by maintaining different build flavours. With different build flavours, you can have different configuration files for different flavours. So make different build flavours one for production and one for testing and put all your files which are different for production and testing separately in two flavour packages and you can build which ever flavour you want.
Check this link for further reference
Related
We have an Android project where we maintain a single code base for different customers, what will be the fastest/most efficient way to compile for different customers every time? Few options I found and my questions:
writing scripts: to replace resources folder and edit app name, version, etc.
Using Android Library Projects It is gonna be quite impractical to separate current project as Library projects, I am thinking whether it is possible to save some settings and resources files as a Library project and just import different library projects for different compilation?
Storing settings and resources on a remote server Is it possible to store resource files and some app settings (xml, constants, etc) on a remote server, and download them and replace to the app when the user first launch the apk? Where will these files be stored?
Any other options you would suggest?
Android Studio provides a feature called "flavors" that allow you to quickly define different configurations from a single code base. I have just learned about this in the last couple of days, so I don't know a lot more than this.
The best way I've found is a post build script step. Use a default set of resources/assets for your main build. This is your default apk, use it for default testing. Save the unsigned apk this builds. Then for the customer specific APKs, open up the unsigned apk (its just a zip file), overwrite any overwritten files, then sign the new version.
This works fine so long as you don't need to change code for different customers. It also doesn't put any unneeded assets/resources in any build, so you don't leak info to one customer about your other customers by including their files.
If you do need to change code, the best way is to do a runtime check on a variable from a settings file. And overwrite the settings file the same way you do everything else.
As an added bonus, if you need to you can write a very fancy system that would allow the customer to upload his own files to override your defaults (including allowing them to override some of your settings), so you don't need to deal with a dozen change requests. That requires a lot more work though.
in our company we are creating a product that is sold to different customers only changing visuals aspects (logos, trademarks, text, etc ...). We doubt how to handle this as we need to maintain a base (with their testings) and customized versions of these products (different package name and some modifications asides).
The more difficult for us is we handle this with Git and projects libraries that need to keep together. We need to keep easy to create new products and maintain updates for each one quickly
which workflow do you recommended to handle this? we have a mix of git + submodules + branches + libraries projects, but it's hard to create an android libproyect base
I don't fully understand your question so if you could write some more info it would be useful for others to help you. The part I understood was the problem of managing multiple projects that have same code but different resources and manifest files. On our project we had a similar problem developing for 3 different servers where code would stay the same but links, api keys and package names would need to change, even logo images might need to be different sometimes adding "integration icon/development icon" etc. What I did in this case was to create one Android library project where all the code and resources that are shared are stored and in our case 3 other projects that reference the library and have special res/drawable folder and strings in value folder where api keys and other settings are stored. This turned out to be great fit for our purposes since you can just pick a run configuration for project to be run and Android will load required resources. You could do this for any number of projects without any files being duplicated and taking space in your git repository. This approach actually allows you to let your designers change drawables for diffident projects by putting different images in folders without or with just a little involvement from developers. If you are skill full you could even write some ant scripts that build and sign projects for them so they can test on devices to see how real app looks.
I have a small Android application that uses different sets of files (a couple of images, a small SQLite DB and a couple of XML files) depending on the specific task at hand.
I know I can include my files into the main application APK using resources or assets but I would be happy to distribute them in a separated APK.
How can I create a data-only APK file?
How can I distribute it? In particular, do I have to do anything special for a data-only package (for example for associating it to the main application package in some way)?
(I'm intentioned to give the user a link to the data package and ask him to install it. No automatic installation required.)
How can I install my files into the internal or into the external storage area of my application? Is it possible at all to install files into the internal storage area created by the main application installer? Do I have to set any particular permission for this?
My approach to this would be to create a wrapper app that's nothing but a content-provider and serves up the files per request by your main app. This would allow you to supply different data packages for the user -- you could even have your main app select between those relatively easily.
It looks like that the commonly accepted way to have the same application with different contents (or styles, or configurations) is to use an Android Library Project for the common code (that is: the whole application, the "engine", the "app framework") and a standard Android Application Project for the contents (that is: an application that actually contains just data). A little bit confusing, just because the "library" here is actually the whole "app", but this seems to be the way to go.
More in detail:
Create an Android Library Application and put into it as much code as you can (all of the non-changing stuff). Please note that this library cannot be launched and cannot be distributed alone. It must be included in a hosting application.
Create a standard Android Application. Include your library into this project. Put in /res and in /asset all of your data (files, XML, etc.).
Compile everything and distribute.
Repeat this cycle every time you need a different version. Different because of data, style, configuration or anything else. Publish the resulting app with a new name.
For what regards me, I'm not completely satisfied by this approach.
A possible alternative is preprocessing the source code with Ruby, Python, Perl, GIT, bash, Ant, Maven, Rake or any other tool that is able to read a file from here, make some change here and there, and write the file there.
The general outline is something like this:
Make a "template" application. Leave your /res and /assset empty.
Run a custom-made script. The script reads a configuration file, copy the /res and /asset files from your repository into the project /res and /asset directories, changes some Java source file and creates/changes some XML file.
Compile and distribute (with a new name, of course).
Using GIT or other SCMs, you just make a new branch for every new version and compile it. Not very elegant (because it can strongly interfere with the normal use of the SCM) but...
There are a few example of these approaches on the web. I'm not completely satisfied by them, either.
Frankly, what the Android ecosystem should offer to solve this problem is some kind of "in-app package manager". Something like the Eclipse Update Manager. This would allow us to use the same application framework to handle different scenarios.
As an alternative, a solid, officially-supported, template-based code-generation mechanism would be nice. Something in the spirit of "Software Production Line": https://en.wikipedia.org/wiki/Software_production_line . Have a look at fw4spl, for example: http://code.google.com/p/fw4spl/ .
I am developing Android application for which I want to ship several different apks for different languages in the market (every language includes a huge bundle of files and I want to avoid creating one huge apk with all language bundles).
So what I need is to customize a bit the Manifest file for each language: e.g. the package of the application and possibly the application version etc. I know how I can template the manifest so that I can manually insert my values in certain points in the file (see this post). The problem is that I use ant for preparing my production apks, but otherwise I develop using Eclipse and so I need my project working in the IDE too. Eclipse requires complete Manifest file and will not understand of the templating I will use for the ant builds as far as I know (please somebody prove me wrong).
My problem is that I want to avoid maintaining two manifest files that are identical in large part (one templated and one complete for Eclipse). Currently I can think of two possible approaches, but I do not know how to accomplish them:
Use some kind of definition injection in the manifest file: if I am able to inject certain xml file in the body of AndroidManifest file, I can keep the identical part in one xml part and customize only the points of difference
If it is possible to configure Eclipse to use some sequence of ant tasks to build Android projects instead of the prebuild routines I might be able to integrate the way I build my production apks in the IDE.
Please if there is anyone who knows how to accomplish any of the above two, or has any other idea how can I solve my issue: help!
Take a look on ant replace task:
<replace file="${build.out}/src/config.prop" token="###" value="${build.version}-${build.type}"/>
But again you should be careful with values that they are unique.
You could also replace your eclipse manifest with generated manifest by echoxml task.
Or you could reuse this nice task about xml manipulation.
At the company I work for, we pretty much use the approach given by Eugen to automate the build process of apps that e.g. should simply be branded differently by exchanging certain assets, styles, strings and configurations. We tend to set up the project and build process as follows:
Create the Android project and set it up such that it works for a specific branding. This will make sure that you can still build and run from Eclipse. Assuming that the codebase does not change between differently branded releases, that should be fine.
Create an ant build configuration that:
copies any files that are going to be changed to a backup directory
modifies the project files according to a configuration file (see below)
compiles the project sources and signs it with a release key (if making a release build)
copies back the files from step 1, overwriting any changes and returning the project to its original state
Create configuration files for every 'branding', or language specific release in your scenario.
Basically these steps will allow you to create branded/partner/language specific builds by simply providing the appropriate configuration with the ant build command. In our case it looks somewhat like this:
ant partner-release -Dpartner=stackoverflow
where 'stackoverflow' will point to a configuration with the same name. In our case these configuration files are small xml files that contain all the parameters that are to be replaced for that specific build. It could contain strings, but might as well point to other files (e.g. logo images) that should be copied into the assets/resources. For example:
<config>
<version_name>1.00</version_name>
<version_code>1</version_code>
...
</config>
Some more pointers:
We use xmltask to modify any xml files in the project; e.g. the manifest and resources.
Since the aforementioned task is really easy to use, our build configuration files are also set up as xml files, as illustrated above. It's quite human readable and easy and straightforward to change.
You can also use replace and ReplaceRegExp tasks to change configuration-dependent variables in almost any file. The latter can be especially convenient to make build-time changes to source code.
We service multiple clients. One feature we want to offer is an android application which allows the client to custom brand the application (icons, logos, names, etc).
Here are a few stipulations.
Customers of clients will use this app.
You could be a customer of more than one client, but we cannot show the user any kind of list of clients.
Clients cannot share a single app.
The app must be able to look different per client, even though the functionality is the same
Yes, I know it's a PITA to build it this way, but our clients don't want customers of other clients to know they are also our client.
So, what is the best way to build an easily brandable application with as little strain on the developer's sanity as possible?
Keep a separate res/ folder for each version of the app. Give every icon, logo and String the same name but tailor the content for each client, and build a different .apk for each by simply dropping that res folder into the build. I don't think you can make custom qualifiers work for this and just make a single .apk - and this would in any case bundle every client's custom pictures and Strings in to everyone's application.
I would start by developing a script for a global re-name, since you'll need that anyway (can be done fairly simply with find, xargs and sed)
You'll need tools for making the customizations to resources, that could be the SDK & Eclipse plug-in
Perhaps you could create some kind of wizard extending the Eclipse plug-in.
Or with a lot of work but easier usage, you could do something stand alone that drives the necessary command line tools to build the generated package.
You can do what #Jems said or (presuming that the app comunicates with a server) put the "logic" on the server side.
The first time you run the application the server will send you the resources corresponding to your client that you store locally.
Problems with this approach: The first time you may have to download a load of stuff...
Advantages: You just have to change a properties string saying which is the server, or the login to the server to know what it has to send changing the layout without having to deploy another app with different resources.
It really depends if you want to support layout changes on server side.
Build time solution using gradle could be achieved with productFlavors feature, described in http://blog.robustastudio.com/mobile-development/android/building-multiple-editions-of-android-app-gradle/
Flavors (aka customer brands) could be defined in build.gradle file in the following way (different package names are here to deploy each branded apk as separate application):
productFlavors {
vanilla {
applicationId "com.example.multiflavorapp"
}
strawberry {
applicationId "com.example.multiflavorapp.strawberry"
}
}
Specific android resources for brand could be then placed (instead of src/main/res directory) into src/vanilla/res or src/strawberry/res directories (in this case vanilla and strawberry are the brands). Please be aware that using productFlavors feature, gradle does no merging of assets, only simple replacing files without any knowledge about specific res subdirectories.
During building proces gradle creates build variants as combination of build type (debug,release) and productFlavor, more at http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Type-Product-Flavor-Build-Variant.