Building two different Android apps that differ only by manifest - android

I need to create two different Android apps using the same code. The user should be able to install both the apps on the same device.
The differences between the two apps are just a few strings, including the application name. These strings have been isolated to a string resource file called Custom.xml.
My plan to achieve two versions is rather simple. In the nightly build script:
1. Run Ant to create the first application .apk file.
2. Rename the generated .apk file
3. Replace Custom.xml with a different one
4. Run Ant once again
This may work except for one thing that I am not sure about. It is the package name in AndroidManifest.xml->manifest->package attribute. I guess this has to be different if the apps have to coexist. Does changing the package name have any impact on the rest of the code? I hope this package name is not tied to the package name used in java files.
Also, does anyone see any problem with my overall strategy? Thank you in advance for your help.

No, it does not have any impact, unless you use your hardcoded package name in the code.
There is an official example of renaming the package to build a debuggable version of the app.

Related

How do I remove unused languages from the final APK file with Xamarin.Android?

I've added some of the Android support libraries to my project and now I'm basically facing the same problem as described in this question:
Android Studio exports strings from support library to APK
Since I can't use Gradle settings with Xamarin, I can't use the solution described in the StackOverflow answer.
Does anyone have an idea, how I can keep only specific localization in my final APK file?
Generally, in Xamarin, The AndroidManifest handles special instructions for uses of libraries The Android.App.UsesLibraryAttribute(string name, bool required) sets specific inclusions and exclusion that will be in the generated Manifest.XML.
Also as far as I know there are only three ways to set link exclusions, the first and second are mentioned by #sunseeker, however Xamarin documentation and dev notes strongly recommend not using Full as indicated above and in general advocate using the following:
SdkOnly(default)
the second also mentioned above is for specific exclusions, it is also recommended not using this unless you are sure a particular package is not getting called "behind the scenes" by an extended class further up in the hierarchy.
Finally in the third method is to set LinkMode to None, while specific linkings are stipulated using the AndroidManifest interface.
Some other ways to get efficiencies are to:
set AndroidUseSharedRuntime property to true at least while debugging to reduce package size.
set AotAssemblies property to true when you have a stable build to precompile the libraries that are included.
set EmbedAssembliesIntoApk to false unless it is a release build.
That's about as far build knowledge goes with Xamarin, hope it helps.
Can't really check it now, but have you had a look at AndroidLinkSkip and AndroidLinkMode (reference) tags in a solution .csproj file?
So, it'd be something like
<AndroidLinkMode>Full</AndroidLinkMode>
<AndroidLinkSkip>Mono.Android.Export;I18N;I18N.West</AndroidLinkSkip>
Also, have a look at MandroidI18n. From the same reference above:
Specifies the internationalization support included with the
Application, such as collation and sorting tables. The value is a
comma- or semicolon-separated list of one or more of the
case-insensitive values
<MandroidExtraArgs>-i18n=west</MandroidExtraArgs>
or
<MandroidI18n>West</MandroidI18n>
So I've finally managed to do this in a sane way
Download Apktool from https://ibotpeaches.github.io/Apktool/
Create your final .apk with Xamarin and decompile it with apktool d MyApp.apk
Go into the MyApp directory that Apktool has created and look for the res directory
Remove all values directories that end with a language identifier that you don't need, e.g if your app only supports the German language, remove values-fr, values-es, etc..., but not values-de. Don't remove non-language directories, e.g values-v11!
Recompile your app with apktool b MyApp
The recompiled app package is now in MyApp/dist/MyApp.apk. Take this file and sign it with the signtool, then zipalign it.
Upload the apk to Google Play
I'm sure this process can be automated, I'll update this answer as soon as I have a script for that.
Have you tried solution from Borris Spinner:
You can provide AndroidResgenExtraArgs in your project file and add -c en,de etc.
See aapt documentation:
-c specify which configurations to include. The default is all
configurations. The value of the parameter should be a comma
separated list of configuration values. Locales should be specified
as either a language or language-region pair. Some examples:
en
port,en
port,land,en_US

How to Use Ant Script replace strings, switch resources folders, auto generate R.java and compile final Apk?

We hope to build multiple applications based on the same source code. The base source code will be stored in SVN so at daily development we just need to modify one codebase.
While for different customers, we hope to given some some level of branding. Mostly changing images and titles, these can be done by just change the resources.
After some research, We find that it is really touch to do these multiple version applications. The main problem is that R.java is generated based on the package name. And package name identify the application. In the source code there are many files import this package.name.R, which means for different application, there will be different package name, and different R's reference need to be change in most source code file.
We find some articles on web about using Ant to do this task, but none of them are really specified. We hope someone could help!
Generally the workflow will be like this:
Changing the package name in AndroidManifest.xml
Go over all source code file, find and replace anything referenced to R to the new package name.
Switch the res folder to the new client's res folder (We will have this folder ready)
Auto generate R.java file.
Start normal compile and build process.
Get Apk.
We hope someone could point out how can we achieve these task by using Ant, or any other better solution.
Thank you!
I think you should create an Android Library Project (http://developer.android.com/tools/projects/index.html#LibraryProjects) with the common code, check it into VCS, and then create separate projects for every customer which you should also check into VCS to keep track of them.
You will be able to generate different customized versions from same source code.

Customizing parts of Android Manifest

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.

Building Android project to different packages

I'm trying to find the best way to build/package an Android app for 6+ different customers. I could use different branches in SVN for all of the customers, but the only difference between the apps are some values in the resource folder (drawables, strings, etc).
I wrote an ant script that imports the standard Android build.xml. This script does the following:
Reads the customer names from a properties file.
For each customer the following is done:
The package name in AndroidManifest.xml is changed (by hooking into the -pre-build target).
The custom resources are copied into the res directory in the build (by hooking into the -pre-compile target).
The package name is changed back to the default value (by hooking into the -post-compile target).
The APK is copied to a specific location an named something like customer-versionno.apk.
This seemed to work well until I just now wrote the part that changes the package name. Because of the package name change the location of the R class is also changed, meaning that the build fails as the Java classes import the R class from the standard package.
I don't want to have a build script that changes code. I want to be able to do this with minimum changes to any files.
Soo..the questions are really:
Are there any good/simple solutions for my problem?
Am I approaching this problem in the wrong way? Are there better ways to easily package the same app to 6+ different customers?
Do you really need to change the package name? Changing the package name is a pain to do automatically. That being said, here is my solution to the problem:
My scenario is that I have one app that gets deployed to 30-200 different signed APK files where the only difference between the files are some resources (drawables, strings, values etc), and the package name.
I do this by working on a generic version of the app that serves as the template project. Once this works and I am ready to deploy I invoke a bash script that loops through the following steps for each target:
Clean the project completely
Swap out res dir and package name using sed.
Builds and signs the APK
This balances the horrific deply time with fast developemnt time. I really don't see another more elegant/robust solution than this.
And finally a small tip: In android manifest use relative package names like ".Application" instead of "com.mycompany.myproject.Application". This way you only need to change the package name in ONE location.
Is it possible to solve this with making 6+ different projects that includes your main projekt. This way you are able to override resources and make different apk's

Renaming an android app to install a second modified version at the same time

I have been using apktool to decompile apps and make changes to better fit my touchpad.
One app in particular (swype) I would like to make a duplicate of with a different size keyboard I can switch to. I have tried changing in the manifest.xml any reference to com.swype I changed to com.thumbswype but when rebuilding the app it says some error about PathNotExist.
I also tried changing the app_name inside res/values/strings and while only changing this allowed me to rebuild the app It still wanted to overwrite the existing swype when I installed it.
The manifest is referring to class names in the compiled code, which would be in package comp.swype. So when you change the manifest but don’t change the compiled code, it can no longer find classes with the specified fully-qualified names.
And the Android system uses fully-qualified class names to identify installed apps. That’s why you can’t have two apps installed at the same time using the same fully-qualified names.

Categories

Resources