My Android app is targeted to 20+ market, each with several different properties in the Manifest.xml.
To release 20+ apk one after another is really time-consuming, and I tried to use the windows batch file to do the release job in a single click.
For now, I use the solution provided by the tutorial here to change the field in the Manifest.xml, but I don't know ant well, so I use a very hack method to do the job in batch file like below:
start cmd.exe /c "ant config-google-play release_mine"
REM the line below is for waiting for the former task to finish
ping 1.1.1.1 -n 1 -w 90000 > nul
start cmd.exe /c "ant config-eoemarket release_mine"
ping 1.1.1.1 -n 1 -w 90000 > nul
....
Is there some elegant way to accomplish this? like just editing targets in build.xml to do it in ant, etc.
First off, why are you always starting a new cmd process? If you just called Ant 20x+ times in your build script it would start building the next build right after the current one would be finished.
Secondly I would advise you to have 20x+ different AndroidManifest.xml files (have a prefix or suffix for each file, so that none of them are named exactly "AndroidManifest.xml") and then you just rename them to AndroidManifest.xml before each build. You can do that with the custom_rules.xml Ant build file (put it next to your build.xml) like this:
<project name="custom_rules">
<target name="config-google-play">
<property name="version" value="google_play" />
</target>
<target name="-pre-build">
<copy tofile="${basedir}/AndroidManifest.xml" overwrite="true">
<fileset file="${basedir}/AndroidManifest.xml.${version}" />
</copy>
</target>
</project>
Here I assumed you renamed your manifests as AndroidManifest.xml.xxxxx. Note also the "-pre-build" target which is invoked before the actual build of the apk starts.
Then just add other "config-" targets and set it's values to whatever you renamed your AndroidManifest.xml(s) to. Then write your build script with 20x+ lines of Ant with "ant config-xxxxx release" where xxxxx is the appropriate config of your build.
My final solution:
Define task:
<target name="modify_manifest">
<property
name="version.market"
value="${channel}"/>
<property
name="out.final.file"
location="${out.absolute.dir}/${ant.project.name}_${channel}_${project.version.name}.apk"/>
<antcalltarget="release"/>
</target>
Then include ant-contrib*.jar as the answer here so that I can use loop in ant. Then define a new task below
<target name="deploy" >
<foreach
delimiter=","
list="${market_channels}"
param="channel"
target="modify_manifest" >
</foreach>
</target>
Use “ant deploy” to do the task.
market_channels should be defined in ant.property as follow:
market_channels=google-play,other,...
Related
Ive been driving myself crazy trying to rebuild my custom_rules.xml into something in gradle and its proving to be quite difficult. So my next step is Im trying to just import the last few things I cant do in gradle as an build.xml.
However this doesnt seem to do anything. When I try using
ant.importBuild 'build.xml'
I get no feed back or no echos from my script. Ive read through gradles documentation a lot especially on ant and for the life of me I cant figure out what Im supposed to do once the build gets imported. How does the script get executed?
This is my build.xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
<target name="postPackage" >
<property name="config_path" location="${cert.dir}" />
<property name="out.pre.widevine.signed.file" location="release-pre-widevine-sign.apk" />
<property name="out.widevine.signed.file" location="release-widevine-signed.apk" />
<echo>sign with widevine certificate</echo>
<touch file="res/raw/wv.properties"/>
<copy file="${out.packaged.file}" tofile="${out.pre.widevine.signed.file}"/>
<java jar="apksigtool.jar" failonerror="true" fork="true">
<arg value="${out.packaged.file}"/>
<arg value="private_key.der" />
<arg value="my.crt" />
</java>
<copy file="${out.packaged.file}" tofile="${out.widevine.signed.file}"/>
</target>
</project>
I was able to accomplish this by using the following snippet in a method
ant.importBuild 'build.xml'
postPackage.doFirst{println("Im starting")}
postPackage.execute()
ant.importBuild will create an equally named Gradle task for each Ant target found in the Ant build. You can then invoke those tasks from the command line and/or make other tasks depend on them. For more information, see "16.2. Importing an Ant build" in the Gradle User Guide,
Hmm I think this Kotlin is working for me;
val t : Task = tasks.named("war").get()
t.actions.forEach { a -> a.execute(t) }
I have developed an Android app, which communicates with a server. I have 2 servers. One is for development, the other one is for production.
In my Android source code, I have to manually change the server URL when make a build.
For example:
for debug mode release, I use:
String url = "http://develop/service"
for production release, I use:
string url = "http://production/service"
The url variable is passed to request sending function like sendReqToServer(url); .
I am tired of making manual change on this url change for different release. Instead, I would like to use Ant script to specify the url by using a command line when making different release build , something like ant release-develop (use development server) & ant release-product (use production server).
To achieve this, I think in build.xml I need to create <target name="release-develop"> & <target name="release-product">. but I am not sure how to make the ant script to specify the url for my app through command line?
Could someone please provide me more detailed information about how to do it?
You can use replace task to override/replace url. It will look like this:
<target name="release-product">
<replace file="path to your *.java class which contains url" token="#URL#" value="http://production/service">
<!-- compile app -->
</target>
<target name="release-develop">
<replace file="path to your *.java class which contains url" token="#URL#" value="http://develop/service">
<!-- compile app -->
</target>
This is not the best solution because you will need to change your source code. Better will be to create config file from which you will read url. In this case it will look like this:
YourUrlClass.java
String url = Config.getUrl(); // get Url method will read url from config file
Appconfig.ini
url=http://develop/service
build.xml
<target name="release-product">
<echo file="appconfig.ini" override="true">url=http://product/product</echo>
<!-- compile app using appconfig.ini -->
</target>
<target name="release-develop">
<echo file="appconfig.ini" override="true">url=http://develop/product</echo>
<!-- compile app using appconfig.ini -->
</target>
Of course you don't need to create appconfig.ini file using <echo/> task. The idea is that you can override appconfig.ini file using different version.
I'd probaby go with config files like other answers, but here's another possibility that I usually do to only log for development builds :
if( BuildConfig.DEBUG )
{
//set develop
}
else
{
//set release
}
This BuildConfig.DEBUG is set based on if its compiled in debug or release mode.
you may use a property ${url} in all targets that need the server url :
<target name="release">
<echo> Deployment => ${url} started !</echo>
...
</target>
and start your antfile via :
ant -f yourfile.xml -Durl=http://develop/service
or
ant -f yourfile.xml -Durl=http://production/service
If you have more specific properties, create a propertyfile for every deploytarget and in your antfile use :
<property file="/config/${deploymode}.properties"/>
afterwards start your antfile via :
ant -f yourfile.xml -Ddeploymode=test
or
ant -f yourfile.xml -Ddeploymode=production
So far I have been focusing on my application's programming and paid little attention to making the build process smarter. Thus I have been doing things pretty much manually (the "dumb way"), including updating by hand android:versionCode and android:versionName in AndroidManifest.xml.
I would like now to automatically (i.e. upon Build or upon Export):
Fetch from git the latest tag/branch containing build and version codes.
Parse them so that I can assign them to the respective fields in AndroidManifest.xml.
Modify AndroidManifest.xml accordingly.
Proceed with the normal build process (Eclipse+ADT, no Ant whatsoever), as if I did 1-2-3 by hand...
I found a few clues about a "pre-build step", builders and build.xml, but I have no idea where to find those and where to start.
Any tips or pointers on where I could find more information on the subject? (a step-by-step tutorial would be ideal)
Update 1: I found this thread to be suggesting that I:
Right-click on the project, Properties > Builders
Add a builder that points to the project's Ant build file.
Order that builder to be invoked before the Java builder
Fine, but where is the project's Ant build file? Where do I find it?
Update 2: Apparently, it's possible to export the entire project into an Ant file. But I am not sure that's I want. Must a pre-build step always include an Ant build file?
Update 3: Is building an Ant file, only for the pre-build step, the right approach?
Here's what I use to dynamically assign a versionCode and versionName to AndroidManifest.xml. It works only when building with ant, so you'll have to install it first. Then go to the project directory in your command line and execute "android update project -p .", which will create the necessary files for building with ant, like local.properties and build.xml.
Then open build.xml and place this inside:
<target name="-pre-build" depends="-custom-git-version,-custom-manifest-version">
</target>
<!-- Packages the application. -->
<target name="-post-build">
<antcall target="-custom-restore-manifest"/>
<property name="suffix" value="${git.commits}-${git.version}.apk" />
<exec executable="sed" inputstring="${out.final.file}" outputproperty="out.final.renamedfile">
<arg value="s/\.apk/-${suffix}/" />
</exec>
<copy file="${out.final.file}" tofile="${out.final.renamedfile}" />
<echo>Final file copied to: ${out.final.renamedfile}</echo>
</target>
<!-- Custom targets -->
<target name="-custom-git-version">
<exec executable="sh" outputproperty="git.commits">
<arg value="-c" />
<arg value="git log --pretty=format:'' | wc -l" />
</exec>
<echo>git.commits: ${git.commits}</echo>
<exec executable="git" outputproperty="git.version">
<arg value="describe" />
<arg value="--tags" />
<arg value="--long" />
</exec>
<echo>git.version: ${git.version}</echo>
</target>
<target name="-custom-manifest-version">
<echo>Creating backup of AndroidManifest.xml</echo>
<copy file="AndroidManifest.xml" tofile="AndroidManifest.xml.antbak" preservelastmodified="true" />
<replaceregexp
file="AndroidManifest.xml"
match='android:versionCode="(\d+)"'
replace='android:versionCode="${git.commits}"' />
<replaceregexp
file="AndroidManifest.xml"
match='android:versionName="(\d+\.\d+)\.\d+"'
replace='android:versionName="\1.${git.commits}"' />
</target>
<target name="-custom-restore-manifest">
<echo>Restoring backup of AndroidManifest.xml</echo>
<move file="AndroidManifest.xml.antbak"
tofile="AndroidManifest.xml"
preservelastmodified="true"
overwrite="true" />
</target>
The output of this is not exactly what you want, but it is a start - feel free to modify it :) The result is something like "yourapp--.apk
Using this you'll build your application with executing "ant clean debug", or "ant clean release", depending on what you want. You can also create "ant.properties" file with this content:
key.store=keystore_file
key.store.password=some_password
key.alias=some_alias
key.alias.password=some_other_password
to enable automatic signing of your app.
You should also read this: http://developer.android.com/tools/building/building-cmdline.html
You are on the right track with setting up a pre-build step, but the ant build file is something you'll create yourself from scratch. Eclipse has some ant scripts that it uses externally that handle the automated compilation, packaging and stuff, but you want to create a separate one that just does these extra steps you want.
So, you're going to have to learn a bit about ant scripting to get this done. Some of those links you found give you the basic idea of how to create a simple ant file. To add to that, some of the ant tasks you will probably need to use are:
Exec - You will need this to execute your git command that gets your version info. It has an argument called resultProperty you can use to store the output of the command into a property that ant can access. (or you can just have the command output to a file and ant can access that.)
ReplaceRegExp - You will need this to replace tokens (maybe #VERSIONCODE# and #VERSIONNAME# ) you place in your AndroidManifest.xml where the values should eventually go, with the values returned by the exec.
You will probably also want to execute an exec task at the beginning to restore your AndroidManifest.xml file to it's original state (with the tokens in place) so it's repeatable without manual cleanup. I would provide more info on the git commands you need to run within these exec tasks, but I'm afraid all my experience is with Subversion, so you'll have to fill in the gaps there.
You should consider building with maven-android. Once you have your project building cleanly, use the version-update plugin to automatically increment your version number.
Writing a build script with maven-android can't be described as easy - but the payoff is worth the effort and you should consider this avenue.
Also, this tutorial might come in handy (I use a variant of the technique described here for my own builds)
EDIT (2014):
Consider migrating to Android Studio and using Gradle. See: How to autoincrement versionCode in Android Gradle
The way I managed to achieve this: build > execute shell (we needed some php code to receive some info from a db) and the string replacement happens in php:
#!/usr/bin/php
<?php
$filename = $WORKSPACE."/src/com/me/myapp/MyActivity.java";
$file = #file_get_contents($filename);
if($file) {
$repl = preg_replace("OriginalString", "NewString", $file);
file_put_contents($filename, $repl);
echo "\n\nReplaced some stuff in $filename";
}
?>
Getting an IDE to automatically increment build numbers is a long discussed issue - I'm always surprised that something that seems so basic (to me) is so much work.
The highest scored question and answer (by quite a bit) for this topic are here:
https://stackoverflow.com/a/8156809/150016
My problem is that the solution depends on .net and I'd prefer to avoid a .net dependency for Eclipse solution. I also want to avoid any dependency on VCS.
So, I'm looking for a solution that is portable and 'Eclipse-ish'. I think the best candidates are an Ant solution (which I will post) or a Java app similar to the dotNet app in the linked answer above.
(I didn't add my answer to that question because it has an accepted answer and is already a very long post. If the moderators prefer I will delete this question and add my answer to the question above.)
I was hoping for something comparatively simple but I don't think any solution to this problem really is simple.
In the project's properties dialog, under Builders, you can configure a script to run prior to building your apk.
In the properties dialog, select Builders from the list on the left. Click New to add a new script. On the dialog that pops up, select Program. On the ensuing dialog, call your Builder Program what you like in the Name field. Put the path to the script in the Location field. Give it a working directory in the Working Directory field. Note that you can specify variables in these fields (e.g., we use ${build_project:/libs/update_version.sh} to reference a script in the project's lib directory).
You'll want this to run before any of the other builders, so move it to the top of the list using the Up button.
On the Build Options tab of the Dialog (it's right under the Name field towards the top), you can select options for when you want this program to run.
I'm assuming something like Linux, Unix, or MacOS here. In those systems you can use grep or its variants to get the current versionCode, increment it, and then awk or similar to modify the file accordingly. Or, you could write a Ruby, Python, Perl, etc. script to replace the versionCode in the AndroidManifest.xml file. I suppose there are equivalent tools on Windows, but I'm not very familiar with that environment.
Have you tried to 'Maven-ise' your android project build ?
If you use the "maven-android-plugin", you can keep track of your project build with pom.xml's "version" tag.
In pom.xml you can increment the build version by using "versions-maven-plugin"
To reflect the incremented build number to to your AndroidManifest.xml you can use the Synchronizing Version technique within your pom file.
This way you can auto-increment the android project build number by running the "versions-maven-plugin" every time the app builds. The solution is also portable in the same way the Ant solution is.
I hope this can also solve the problem you have mentioned (and what I have understand). Please correct me if something is missing.
Here is a solution that uses Ant. I must admit that getting Ant setup was a bit of a hassle, but it seems to be a widely used and powerful adjunct to Eclipse, so I believe it will turn out to be valuable for me in other ways.
Ant is the preferred solution for building Android SDK apps without Eclipse (as described here), but is not part of the ADT so you probably won't have it if you have just been using Eclipse.
So, the first step is to download and install Ant from here.
Next add Ant to your path and make sure that your path also points to the JDK (rather then the JRE). On Windows I found that I also had to create JAVA_HOME and point it to the root of the JDK.
We only need Ant for the auto-increment step - the intention is not to replace Eclipse and use it for the whole build - but it is useful to do a few steps in that direction to ensure that Ant is working. So, go to the root of your project and type
> android update project --path .
This creates a build.xml for your project. Once I had done that I was able to do
> ant release
and Ant built my project. If you want to keep going in that direction I found this article useful.
Next, I edited my project's new build.xml and added the following task (it can go anywhere, just not in the middle of another task/target)
<target name="update.buildnum">
<buildnumber/>
<!-- this task creates (and increments) Ant property 'build.number' which I use below -->
<echo>Current build number:${build.number}</echo>
<echoxml file="res/values/buildnum.xml">
<resources>
<string name="buildnum">${build.number}</string>
</resources>
</echoxml>
</target>
The task used above auto-increments a build number in a file (which it will create) called 'build.number' in your project's root. The rest of the task above puts the current build number into a resource string so that your application can retrieve it with this code:
String build = context.getString( com.your.app.R.string. buildnum );
int appBuild = ( int ) Integer.parseInt( build );
Some people will prefer a solution that writes the build number to the application code in the AndroidManifest.xml. Here is an answer that includes a task to do that, but it requires a 3rd party Ant task (xmltask), and I'm a bit hesitant to have a 3rd party task modifying my manifest (which is now pretty huge) on every build. If you do decide to use that task then the corresponding Android code to get the build number would be:
String packageName = ctx.getPackageName();
PackageInfo pInfo = ctx.getPackageManager().getPackageInfo( packageName, 0);
int appVer = pInfo.versionCode;
Finally, you need to get Eclipse to run this Ant task every time you do a build.
Go to your project's properties, find the Builders, and click the button to add a new Builder. There are tons of options here but you only need to specify a few.
Give the builder some name by setting the Name: field.
Select the Buildfile:. I used the 'browse workspace' option to select it, and then it filled the field with "${workspace_loc:/appname/build.xml}"
Select targets from a list on the targets tab. In my case I had to remove the 'help' task (the default task in the build.mxl generated above), and then add the 'build.number' task. I suggest you only set a target for Manual Build:.
I moved the new Builder to be the first build step.
One issue with this solution is that every time you get Eclipse to deploy (run) your application it is considered to be a new manual build, even if the project hasn't changed. So, if you deploy your application to several devices, each device will have a different build with its own build number. One thing that will ameliorate this problem a bit is that Google says that a future ADT will allow for mutiple deployments in one operation.
This (above) was tested with Ant 1.8.4, Eclipse Indigo SR2 (3.7.2), ADT 20 preview 2 and SDK Tools 20, on Win7 32bit.
My solution is based on using Ant (without XMLTask)
<property name="version.file" value="version.properties"/>
<property name="manifest.file" value="AndroidManifest.xml"/>
<!--build.slot: 0.1.2.3.4.5-->
<property name="build.slot" value="2"/>
<target name="all">
<antcall target="increment.build"/>
<antcall target="update.manifest"/>
</target>
<target name="increment.build">
<propertyfile file="${version.file}">
<entry key="build.no" type="int" default="0" operation="+" value="1" />
</propertyfile>
</target>
<scriptdef name="setBuildNo" language="javascript">
<attribute name="verName" />
<attribute name="buildNo" />
<attribute name="buildSlot" />
<attribute name="property" />
<![CDATA[
var verNums = attributes.get("vername").split(".");
var buildNo = attributes.get("buildno");
var buildSlot = attributes.get("buildslot");
if (!(buildSlot > 1 && buildSlot < 10))
buildSlot = 2;
var newVer = "";
for (var i = 0; i < Math.min(verNums.length, buildSlot); i++)
newVer += (verNums[i].trim() || "0") + ".";
for (var i = verNums.length; i < buildSlot; i++)
newVer += "0" + ".";
project.setProperty(attributes.get("property"), newVer + buildNo);
]]>
</scriptdef>
<target name="debug">
<setBuildNo verName="1" buildNo="999" property="a"/>
<setBuildNo verName="2." buildNo="999" property="b"/>
<setBuildNo verName="3.3" buildNo="999" property="c"/>
<setBuildNo verName="4.4." buildNo="999" property="d"/>
<setBuildNo verName="5.5.5" buildNo="999" property="e"/>
<setBuildNo verName="6.6.6." buildNo="999" property="f"/>
<setBuildNo verName="7.7.7.7" buildNo="999" property="g"/>
<echo>1 => ${a}</echo>
<echo>2. => ${b}</echo>
<echo>3.3 => ${c}</echo>
<echo>4.4. => ${d}</echo>
<echo>5.5.5 => ${e}</echo>
<echo>6.6.6. => ${f}</echo>
<echo>7.7.7.7 => ${g}</echo>
</target>
<target name="update.manifest">
<fail message="File not found: "${manifest.file}"" status="1">
<condition>
<not>
<available file="${manifest.file}" />
</not>
</condition>
</fail>
<!-- Reads build version -->
<loadproperties srcfile="${version.file}">
<filterchain>
<linecontains>
<contains value="build.no="/>
</linecontains>
</filterchain>
</loadproperties>
<!-- Reads versionName from AndroidManifest -->
<xmlproperty file="${manifest.file}" collapseAttributes="true"/>
<fail unless="manifest.android:versionName" message="Attribute "android:versionName" undefined into "${manifest.file}"" status="1"/>
<property name="version.name" value="${manifest.android:versionName}"/>
<!-- Create a new version -->
<setBuildNo verName="${version.name}" buildNo="${build.no}" buildSlot="${build.slot}" property="new.version.name"/>
<!-- Replaces using regexp -->
<replaceregexp
file="${manifest.file}"
match="android:versionName.*=.*".*${version.name}.*""
replace="android:versionName="${new.version.name}""/>
<!-- Replaces for check and generates a exception (if not found version) -->
<replace
file="${manifest.file}"
token="android:versionName="${new.version.name}""
value="android:versionName="${new.version.name}""
failOnNoReplacements="true"/>
<!--<echo>${version.file}</echo>
<echo>${manifest.file}</echo>-->
<echo>Auto Increment Build: ${version.name} => ${new.version.name}</echo>
</target>
Using
ant [-Dmanifest.file=<file>] [-Dversion.file=<file>] [-Dbuild.slot=<number>]
-Dmanifest.file - path and filename AndroidManifest.xml. Default: AndroidManifest.xml in a folder with build.xml
-Dversion.file - path and file name in which to store the number Build version. Default: version.properties folder with build.xml
-Dbuild.slot - position of build number in version array. Default: 2, ie X.X.build.
Auto Increment Build in Eclipse
Project | Properties | Builders | New | Ant Build
Main
Build file
<path>/build.xml
Arguments
-Dmanifest.file=${workspace_loc://AndroidManifest.xml} -Dversion.file=${workspace_loc://version.properties}
Refresh
[x] Refresh resources upon completion
(*) Specify resources
[Specify resources]
<Project>
[x] AndroidManifest.xml
Build Options
[x] Specify working set of relevant resources
[Specify resources]
<Project>
[x] res
[x] src
[x] AndroidManifest.xml
My solution used some of the code found in other answers, XMLTask, and Groovy to automatically increment the build number. I also included a rule to do a git commit and tag to link the build number to a specific point in the version control - useful for bug tracking.
<taskdef name="xmltask" classname="com.oopsconsultancy.xmltask.ant.XmlTask"/>
<path id="groovy.classpath">
<fileset dir="/Users/deepwinter1/.gvm/groovy/current/lib/">
<include name="*.jar"/>
</fileset>
</path>
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy">
<classpath refid="groovy.classpath"/>
</taskdef>
<target name="update.build.number">
<xmltask source="AndroidManifest.xml">
<copy path="manifest/#android:versionCode" property="buildNum"/>
</xmltask>
<groovy>
buildNum = Integer.valueOf(properties["buildNum"])
properties["buildNum"] = buildNum + 1
</groovy>
<xmltask source="AndroidManifest.xml" dest="AndroidManifest.xml">
<replace path="manifest/#android:versionCode"
withText="${buildNum}"/>
</xmltask>
<antcall target="commit.and.tag.build">
<param name="buildNum" value="${buildNum}"/>
</antcall>
</target>
<target name="commit.and.tag.build">
<exec executable="git">
<arg value="commit"/>
<arg value="-a"/>
<arg value="-m"/>
<arg value="Build Number ${buildNum}"/>
</exec>
<exec executable="git">
<arg value="tag"/>
<arg value="b${buildNum}"/>
</exec>
</target>
a "bit" better workaround answer you can find here...
https://stackoverflow.com/a/8156809/304270
Tiny c# tool which will execute before everynew new build and increase appropriate value in manifest file..
I'm working on an Open-source project. As it is intended that anyone can download the source and build it themselves, I do not want to hard-code the package name anywhere - including the directory structure.
I use ant for building. Apparently I can modify build.xml, but I believe this is overwritten by android update. Whatever is used will be committed to the Git repo, and it should not be too complicated.
Currently the process to build the code straight from the Git repo is fairly simple. Here's an excerpt from the README file:
$ cd ~/src/isokeys/IsoKeys
$ android list targets # I build against API level 10.
$ android update project --name IsoKeys --target 1 --path ./ # Only needed first time.
$ ant debug && adb -d install -r bin/IsoKeys-debug.apk
To me, it makes sense to put the package name in local.properties, because this is .gitignore'd. As the package name won't be anywhere else, the build will fail without doing this. So there needs to be at least 1 extra step in the README, but I want to keep it to a minimum.
Edit: Of course, another requirement is that diffs make sense - which they don't if you manually rename the package name.
I did something similar (but not for this reason) which required updating the manifest at build time. The way I accomplished this was by making a second AndroidManifest and putting it under a directory named config.
So in config/AndroidManifest you could have something like this:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="#CONFIG.APP_PACKAGE_NAME#"
android:versionCode="#CONFIG.APP_VERSION_CODE#"
android:versionName="#CONFIG.APP_VERSION#">
<!-- EVERYTHING ELSE GOES HERE -->
</manifest>
Then you can use the regular bare bones build.xml ant script with just a few modifications (no need to copy the whole script from the android build system as they added some hooks for you to use without reinventing the wheel).
The build script should be reading local.properties by default, but if not add (or uncomment) a line like this:
<property file="local.properties" />
In your build script you should see a task called "-pre-build", change it like this:
<target name="-pre-build">
<copy file="config/AndroidManifest.xml" todir="." overwrite="true" encoding="utf-8">
<filterset>
<filter token="CONFIG.APP_PACKAGE_NAME" value="${app.packagename}" />
<filter token="CONFIG.APP_VERSION" value="${app.version}" />
<filter token="CONFIG.APP_VERSION_CODE" value="${app.versioncode}" />
</filterset>
</copy>
</target>
Then your local.properties file you would put the package name, version name/code like so:
app.version=1.0
app.versioncode=1
app.packagename=com.mypackage.name
Now you just need to make sure in your manifest that you fully qualify all of your activities/services/broadcast listeners etc.. That means you always specify the full package of your source code. If you want the package for your own source code to be dynamic you could replace out each of the prefixes to each class.. But that seems kind of silly.. It is easy enough to package your code up under your own package name and they can use it from any project by simply including the source or a jar in their project.
-- UPDATE --
Oh and one other thing you can do to notify the user that they must define a package name is use the fail tag in your build xml like this:
<fail message="app.packagename is missing. This must be defined in your local.properties file" unless="app.packagename" />
Put this after the line which reads the local.properties file
With thanks to Matt Wolfe for his help, I'm posting a partial answer with my efforts so far.
I noticed that the default barebones build.xml would also import custom_rules.xml:
<import file="custom_rules.xml" optional="true" />
So I created this file and started tinkering. This is what I have come up with so far:
<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules" default="debug">
<target name="-pre-build">
<fail message="Please define app.packagename in your local.properties file." unless="app.packagename" />
<taskdef resource="net/sf/antcontrib/antcontrib.properties">
<classpath>
<pathelement location="/usr/share/java/ant-contrib.jar"/>
</classpath>
</taskdef>
<!-- How do I check for propertyregex?
<fail message="Depends on ant-contrib's propertyregex for app.packagename.path." unless="propertyregex" />
-->
<propertyregex property="app.packagename.path"
input="${app.packagename}/"
regexp="\."
replace="/"
global="true"
/>
<copy todir="build/" overwrite="true" encoding="utf-8">
<fileset dir="./">
<include name="AndroidManifest.xml" />
<include name="res/**" />
<include name="lib/**" />
</fileset>
<filterset>
<filter token="CONFIG.APP_PACKAGE_NAME" value="${app.packagename}" />
</filterset>
</copy>
<copy todir="build/src/${app.packagename.path}" overwrite="true" encoding="utf-8">
<fileset dir="./src/isokeys/">
<include name="**" />
</fileset>
<filterset>
<filter token="CONFIG.APP_PACKAGE_NAME" value="${app.packagename}" />
</filterset>
</copy>
</target>
<target name="-pre-clean" description="Removes output files created by -pre-build.">
<delete file="build/AndroidManifest.xml" verbose="${verbose}" />
<delete dir="build/res/" verbose="${verbose}" />
<delete dir="build/lib/" verbose="${verbose}" />
<delete dir="build/src/" verbose="${verbose}" />
</target>
<!-- NOW CHANGE DIRECTORY TO build/ BEFORE HANDING BACK OVER TO build.xml!!! -->
</project>
This sets everything up in build/ (which has the added bonus of keeping things neat and tidy), now the intention is for the sdk tools build.xml to run from this build/ directory. However, I can't find any way of cd'ing.
Easiest way might be replace the package name as late as possible. This way, you don't even have to touch your code. There is a nice article named Renaming the Android Manifest package(http://www.piwai.info/renaming-android-manifest-package/). Summary:
You can use aapt --rename-manifest-package to modify the package name
Alternatively, if you want package name replacement to be a part of the ant build process, you can override the -package-resources target:
copy the -package-resources target from SDK's build.xml
add manifestpackage parameter