OSDN Git Service

Created Android University lesson for Multiple APKs.
authorScott Main <smain@google.com>
Thu, 8 Dec 2011 04:19:10 +0000 (20:19 -0800)
committerScott Main <smain@google.com>
Thu, 8 Dec 2011 04:21:38 +0000 (20:21 -0800)
Change-Id: I577f76f7b40069d3d5300cf0d40bedb2ab775821

docs/html/training/multiple-apks/api.jd [new file with mode: 0644]
docs/html/training/multiple-apks/index.jd [new file with mode: 0644]
docs/html/training/multiple-apks/multiple.jd [new file with mode: 0644]
docs/html/training/multiple-apks/screensize.jd [new file with mode: 0644]
docs/html/training/multiple-apks/texture.jd [new file with mode: 0644]

diff --git a/docs/html/training/multiple-apks/api.jd b/docs/html/training/multiple-apks/api.jd
new file mode 100644 (file)
index 0000000..292e5d0
--- /dev/null
@@ -0,0 +1,379 @@
+page.title=Creating Multiple APKs for Different API Levels
+parent.title=Creating and Maintaining Multiple APKs
+parent.link=index.html
+
+trainingnavtop=true
+next.title=Creating Multiple APKs for Different Screen Sizes
+next.link=screensize.html
+
+@jd:body
+
+<style type="text/css">
+.blueCell { background-color: #9fc5e8;}
+.greenCell { background-color: #b6d7a8;}
+.redCell { background-color: #ea9999;}
+.blackCell { background-color: #000000;}
+</style>
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Confirm">Confirm You Need Multiple APKs</a></li>
+  <li><a href="#ChartReqs">Chart Your Requirements</a></li>
+  <li><a href="#CreateLibrary">Put All Common Code and Resources in a Library Project</a></li>
+  <li><a href="#CreateAPKs">Create New APK Projects</a></li>
+  <li><a href="#AdjustManifests">Adjust the Manifests</a></li>
+  <li><a href="#PreLaunch">Go Over Pre-launch Checklist</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="http://developer.android.com/guide/market/publishing/multiple-apks.html">Multiple APK
+Support</a></li>
+  <li><a
+href="http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html">
+How to have your (Cup)cake and eat it too</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>When developing your Android application to take advantage of multiple APKs on Android Market,
+it’s important to adopt some good practices from the get-go, and prevent unnecessary headaches
+further into the development process.  This lesson shows you how to create multiple APKs of your
+app, each covering a slightly different range of API levels.  You will also gain some tools
+necessary to make maintaining a multiple APK codebase as painless as possible.</p>
+
+
+<h2 id="Confirm">Confirm You Need Multiple APKs</h2>
+
+<p>When trying to create an application that works across multiple generations of the Android
+platform, naturally you want your application to take advantage of new features on new devices,
+without sacrificing backwards compatibility.  It may seem at the outset as though multiple APK
+support is the best solution, but this often isn’t the case.  The <a
+href="{@docRoot}guide/market/publishing/multiple-apks.html#ApiLevelOptions">Using Single APK
+Instead</a> section of the multiple APK developer guide includes some useful information on how to
+accomplish this with a single APK, including use of our support library. You can also learn how to
+write code that runs only at certain API levels in a single APK, without resorting to
+computationally expensive techniques like reflection from  <a
+href="http://android-developers.blogspot.com/2010/07/how-to-have-your-cupcake-and-eat-it-too.html">
+this article</a>.</p>
+
+<p>If you can manage it, confining your application to a single APK has several
+advantages, including:</p>
+
+<ul>
+<li>Publishing and testing are easier</li>
+<li>There’s only one codebase to maintain</li>
+<li>Your application can adapt to device configuration changes</li>
+<li>App restore across devices just works</li>
+<li>You don’t have to worry about market preference, behavior from "upgrades" from one APK to the
+next, or which APK goes with which class of devices
+</ul>
+
+<p>The rest of this lesson assumes that you’ve researched the topic, studiously absorbed the
+material in the resources linked, and determined that multiple APKs are the right path for your
+application.</p>
+
+<h2 id="ChartReqs">Chart Your Requirements</h2>
+
+<p>Start off by creating a simple chart to quickly determine how many APKs you need, and what API
+range each APK covers.  For handy reference, the <a
+href="{@docRoot}resources/dashboard/platform-versions.html">Platform Versions</a> page of the
+Android Developer website provides data about the relative number of active devices running a given
+version of the Android platform.  Also, although it sounds easy at first, keeping track of which set
+of API levels each APK is going to target gets difficult rather quickly, especially if there’s going
+to be some overlap (there often is).  Fortunately, it’s easy to chart out your requirements quickly,
+easily, and have an easy reference for later.</p>
+
+<p>In order to create your multiple APK chart, start out with a row of cells representing the
+various API levels of the Android platform.  Throw an extra cell at the end to represent future
+versions of Android.</p>
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td>3</td>
+      <td>4</td>
+      <td>5</td>
+      <td>6</td>
+      <td>7</td>
+      <td>8</td>
+      <td>9</td>
+      <td>10</td>
+      <td>11</td>
+      <td>12</td>
+      <td>13</td>
+      <td>+</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Now just color in the chart such that each color represents an APK.  Here’s one example of how
+you might apply each APK to a certain range of API levels.</p>
+
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td class="blueCell">3</td>
+      <td class="blueCell">4</td>
+      <td class="blueCell">5</td>
+      <td class="blueCell">6</td>
+      <td class="greenCell">7</td>
+      <td class="greenCell">8</td>
+      <td class="greenCell">9</td>
+      <td class="greenCell">10</td>
+      <td class="redCell">11</td>
+      <td class="redCell">12</td>
+      <td class="redCell">13</td>
+      <td class="redCell">+</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>Once you’ve created this chart, distribute it to your team.  Team communication on your project
+just got immediately simpler, since instead of asking "How’s the APK for API levels 3 to 6, er, you
+know, the Android 1.x one.  How’s that coming along?"  You can simply say "How’s the Blue APK coming
+along?"</p>
+
+<h2 id="CreateLibrary">Put All Common Code and Resources in a Library Project</h2>
+<p>Whether you’re modifying an existing Android application or starting one from scratch, this is
+the first thing that you should do to the codebase, and by the far the most important.  Everything
+that goes into the library project only needs to be updated once (think language-localized strings,
+color themes, bugs fixed in shared code), which improves your development time and reduces the
+likelihood of mistakes that could have been easily avoided.</p>
+
+<p class="note"><strong>Note:</strong>  While the implementation details of how to create and
+include library projects are beyond the scope of this lesson, you can get up to speed quickly on
+their creation at the following links:</p>
+<ul>
+<li><a
+href="{@docRoot}guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
+a library project (Eclipse)</a></li>
+<li><a
+href="{@docRoot}guide/developing/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
+a library project (Command line)</a></li>
+</ul>
+
+
+<p>If you’re converting an existing application to use multiple APK support,
+scour your codebase for every localized string file, list of values, theme
+colors, menu icons and layout that isn’t going to change across APKs, and put
+it all in the library project.  Code that isn’t going to change much should
+also go in the library project.  You’ll likely find yourself extending these
+classes to add a method or two from APK to APK.</p>
+
+<p>If, on the other hand, you’re creating the application from scratch, try as
+much as possible to write code in the library project <em>first</em>, then only move it down to an
+individual APK if necessary.  This is much easier to manage in the long run than adding it to one,
+then another, then another, then months later trying to figure out whether this blob can be moved up
+to the library section without screwing anything up.</p>
+
+<h2 id="CreateAPKs">Create New APK Projects</h2>
+<p>There should be a separate Android project for each APK you’re going to release.  For easy
+organization, place the library project and all related APK projects under the same parent folder. 
+Also remember that each APK needs to have the same package name, although they don’t necessarily
+need to share the package name with the library.  If you were to have 3 APKs following the scheme
+described earlier, your root directory might look like this:</p>
+
+<pre class="no-pretty-print classic">
+alexlucas:~/code/multi-apks-root$ ls
+foo-blue
+foo-green
+foo-lib
+foo-red
+</pre>
+
+<p>Once the projects are created, add the library project as a reference to each APK project.  If
+possible, define your starting Activity in the library project, and extend that Activity in your APK
+project.  Having a starting activity defined in the library project gives you a chance to put all
+your application initialization in one place, so that each individual APK doesn’t have to
+re-implement "universal" tasks like initializing Analytics, running licensing checks, and any other
+initialization procedures that don’t change much from APK to APK.</p>
+
+
+<h2 id="AdjustManifests">Adjust the Manifests</h2>
+<p>When a user downloads an application which uses multiple APKs through Android Market, the correct
+APK to use is chosen using two simple rules:</p>
+<ul>
+<li>The manifest has to show that particular APK is eligible</li>
+<li>Of the eligible APKs, highest version number wins</li>
+</ul>
+<p>
+By way of example, let’s take the set of multiple APKs described earlier, and assume that we haven’t
+set a max API level for any of the APKs.  Taken individually, the possible range of each APK would
+look like this:</p>
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td class="blueCell">3</td>
+      <td class="blueCell">4</td>
+      <td class="blueCell">5</td>
+      <td class="blueCell">6</td>
+      <td class="blueCell">7</td>
+      <td class="blueCell">8</td>
+      <td class="blueCell">9</td>
+      <td class="blueCell">10</td>
+      <td class="blueCell">11</td>
+      <td class="blueCell">12</td>
+      <td class="blueCell">13</td>
+      <td class="blueCell">+</td>
+    </tr>
+    <tr>
+      <td class="blackCell">3</td>
+      <td class="blackCell">4</td>
+      <td class="blackCell">5</td>
+      <td class="blackCell">6</td>
+      <td class="greenCell">7</td>
+      <td class="greenCell">8</td>
+      <td class="greenCell">9</td>
+      <td class="greenCell">10</td>
+      <td class="greenCell">11</td>
+      <td class="greenCell">12</td>
+      <td class="greenCell">13</td>
+      <td class="greenCell">+</td>
+    </tr>
+    <tr>
+      <td class="blackCell">3</td>
+      <td class="blackCell">4</td>
+      <td class="blackCell">5</td>
+      <td class="blackCell">6</td>
+      <td class="blackCell">7</td>
+      <td class="blackCell">8</td>
+      <td class="blackCell">9</td>
+      <td class="blackCell">10</td>
+      <td class="redCell">11</td>
+      <td class="redCell">12</td>
+      <td class="redCell">13</td>
+      <td class="redCell">+</td>
+    </tr>
+  </tbody>
+</table>
+<p>
+Because it is required that an APK with a higher minSdkVersion also have a
+higher version code, we know that in terms of versionCode values, red &#8805;
+green &#8805; blue.  Therefore we can effectively collapse the chart to look like this:</p>
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td class="blueCell">3</td>
+      <td class="blueCell">4</td>
+      <td class="blueCell">5</td>
+      <td class="blueCell">6</td>
+      <td class="greenCell">7</td>
+      <td class="greenCell">8</td>
+      <td class="greenCell">9</td>
+      <td class="greenCell">10</td>
+      <td class="redCell">11</td>
+      <td class="redCell">12</td>
+      <td class="redCell">13</td>
+      <td class="redCell">+</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>
+Now, let’s further assume that the Red APK has some requirement on it that the other two don’t.  The
+Market Filters page of the Android Developer guide has a whole list of possible culprits.  For the
+sake of example, let’s assume that red requires a front-facing camera.  In fact, the entire point of
+the red APK is to combine the front-facing camera with sweet new functionality that was added in API
+11.  But, it turns out, not all devices that support API 11 even HAVE front-facing cameras!  The
+horror!</p>
+
+<p>Fortunately, if a user is browsing Market from one such device, Android Market will look at the
+manifest, see that Red lists the front-facing camera as a requirement, and quietly ignore it, having
+determined that Red and that device are not a match made in digital heaven.  It will then see that
+Green is not only forward-compatible with devices with API 11 (since no maxSdkVersion was defined),
+but also doesn’t care whether or not there’s a front-facing camera!  The app can still be downloaded
+from Android Market by the user, because despite the whole front-camera mishap, there was still an
+APK that supported that particular API level.</p>
+
+<p>  In order to keep all your APKs on separate "tracks", it’s important to have a good version code
+scheme.  The recommended one can be found on the <a
+href="{@docRoot}guide/market/publishing/multiple-apks.html#VersionCodes">Version Codes</a> area of
+our developer guide.  Since the example set of APKs is only dealing with one of 3 possible
+dimensions, it would be sufficient to separate each APK by 1000, set the first couple digits to the
+minSdkVersion for that particular APK, and increment from there.  This might look like:</p>
+
+<p>Blue: 03001, 03002, 03003, 03004...<br />
+Green: 07001, 07002, 07003, 07004...<br />
+Red:11001, 11002, 11003, 11004...</p>
+
+<p>  Putting this all together, your Android Manifests would likely look something like the following:</p>
+<p>Blue:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="03001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;uses-sdk android:minSdkVersion="3" /&gt;
+    ...
+</pre>
+
+<p>Green:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="07001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;uses-sdk android:minSdkVersion="7" /&gt;
+    ...
+</pre>
+
+<p>Red:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="11001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;uses-sdk android:minSdkVersion="11" /&gt;
+    ...
+</pre>
+
+<h2 id="PreLaunch">Go Over Pre-launch Checklist</h2>
+<p>  Before uploading to Android Market, double-check the following items.  Remember that these are specifically relevant to multiple APKs, and in no way represent a complete checklist for all applications being uploaded to Android Market.</p>
+
+<ul>
+<li>All APKs must have the same package name</li>
+<li>All APKs must be signed with the same certificate</li>
+<li>If the APKs overlap in platform version, the one with the higher minSdkVersion must have a higher version code</li>
+<li>Double check your manifest filters for conflicting information (an APK that only supports cupcake on XLARGE screens isn’t going to be seen by anybody)</li>
+<li>Each APK's manifest must be unique across at least one of supported screen, openGL texture, or platform version</li>
+<li>Try to test each APK on at least one device.  Barring that, you have one of the most customizable device emulators in the business sitting on your development machine.  Go nuts!</li>
+</ul>
+
+<p>It’s also worth inspecting the compiled APK before pushing to market, to make sure there aren’t
+any surprises that could hide your application in Market.  This is actually quite simple using the
+"aapt" tool.  Aapt (the Android Asset Packaging Tool) is part of the build process for creating and
+packaging your Android applications, and is also a very handy tool for inspecting them. </p>
+
+<pre class="no-pretty-print classic">
+&gt;aapt dump badging
+package: name='com.example.hello' versionCode='1' versionName='1.0'
+sdkVersion:'11'
+uses-permission:'android.permission.SEND_SMS'
+application-label:'Hello'
+application-icon-120:'res/drawable-ldpi/icon.png'
+application-icon-160:'res/drawable-mdpi/icon.png'
+application-icon-240:'res/drawable-hdpi/icon.png'
+application: label='Hello' icon='res/drawable-mdpi/icon.png'
+launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
+uses-feature:'android.hardware.telephony'
+uses-feature:'android.hardware.touchscreen'
+main
+supports-screens: 'small' 'normal' 'large' 'xlarge'
+supports-any-density: 'true'
+locales: '--_--'
+densities: '120' '160' '240'
+</pre>
+
+<p>When you examine aapt output, be sure to check that you don’t have conflicting values for
+supports-screens and compatible-screens, and that you don’t have unintended "uses-feature" values
+that were added as a result of permissions you set in the manifest. In the example above, the APK
+won’t be visible to very many devices.</p>
+<p>Why?  By adding the required permission SEND_SMS, the feature requirement of android.hardware.telephony was implicitly added.  Since API 11 is Honeycomb (the version of Android optimized specifically for tablets), and no Honeycomb devices have telephony hardware in them, Market will filter out this APK in all cases, until future devices come along which are higher in API level AND possess telephony hardware.
+</p>
+<p>Fortunately this is easily fixed by adding the following to your manifest:</p>
+<pre>
+&lt;uses-feature android:name="android.hardware.telephony" android:required="false" /&gt;
+</pre>
+<p>Once you’ve completed the pre-launch checklist, upload your APKs to Android Market.  It may take a bit for the application to show up when browsing Android Market, but when it does, perform one last check.  Download the application onto any test devices you may have, to make sure that the APKs are targeting the intended devices.  Congratulations, you’re done!</p>
diff --git a/docs/html/training/multiple-apks/index.jd b/docs/html/training/multiple-apks/index.jd
new file mode 100644 (file)
index 0000000..eee926c
--- /dev/null
@@ -0,0 +1,72 @@
+page.title=Creating and Maintaining Multiple APKs
+
+trainingnavtop=true
+startpage=true
+next.title=Creating Multiple APKs for Different API Levels
+next.link=api.html
+
+@jd:body
+
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- Required platform, tools, add-ons, devices, knowledge, etc. -->
+<h2>Dependencies and prerequisites</h2>
+
+<ul>
+  <li>Android 1.0 and higher</li>
+  <li>You must have an <a href="http://market.android.com/publish">Android Market</a> publisher
+account</li>
+</ul>
+
+<!-- related docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="http://developer.android.com/guide/market/publishing/multiple-apks.html">Multiple APK
+Support</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>Multiple APK support is a feature in Android Market that allows you to publish multiple APKs
+under the same application listing.  Each APK is a complete instance of your application, optimized
+to target specific device configurations.  Each APK can target a specific set of GL
+textures, API levels, screen sizes, or some combination thereof.</p>
+
+<p>This class shows you how to write your multiple APK application using any one of these
+configuration variables.  Each lesson covers basics about how to organize your codebase and target
+the right devices, as well as the smart way to avoid pitfalls such as unnecessary redundancy across
+your codebase, and making mistakes in your manifest that could render an APK invisible to all
+devices in Android Market.  By going through any of these lessons, you'll know how to develop
+multiple APKs the smart way, make sure they're targeting the devices you want them to,
+and know how to catch mistakes <em>before</em> your app goes live.</p>
+
+
+
+<h2>Lessons</h2>
+
+<dl>
+  <dt><b><a href="api.html">Creating Multiple APKs for Different API Levels</a></b></dt>
+    <dd>Learn how to target different versions of the Android platform using multiple APKs.  Also
+learn how to organize your codebase, what to do with your manifest, and how to investigate your APK
+configuration using the <code>aapt</code> tool before pushing live.</dd>
+
+  <dt><b><a href="screensize.html">Creating Multiple APKs for Different Screen Sizes</a></b></dt>
+    <dd>Learn how to target Android devices by screen size using multiple APKs.  Also learn how to
+organize your codebase, what to do with your manifest, and how to investigate your APK configuration
+using the <code>aapt</code> tool before pushing live.</dd>
+
+  <dt><b><a href="texture.html">Creating Multiple APKs for Different GL Textures</a></b></dt>
+        <dd>Learn how to target Android devices based on their support for GL texture.  Also learn
+how to organize your codebase, what to do with your manifest, and how to investigate your APK
+configuration using the <code>aapt</code> tool before pushing live.</dd>
+
+  <dt><b><a href="multiple.html">Creating Multiple APKs with 2+ Dimensions</a></b></dt>
+        <dd>Learn how to target different Android devices based on more than one configuration
+variable (screen size, API version, GL texture).  Examples in the lesson target using a combination
+of API level and screen size.  Also learn how to organize your codebase, what to do with your
+manifest, and how to investigate your APK configuration using the <code>aapt</code> tool before
+pushing live.</dd>
+</dl>
diff --git a/docs/html/training/multiple-apks/multiple.jd b/docs/html/training/multiple-apks/multiple.jd
new file mode 100644 (file)
index 0000000..f872379
--- /dev/null
@@ -0,0 +1,475 @@
+page.title=Creating Multiple APKs with 2+ Dimensions
+parent.title=Creating and Maintaining Multiple APKs
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Creating Multiple APKs for Different GL Textures
+previous.link=texture.html
+
+@jd:body
+
+<style>
+.blueCell { background-color: #9fc5e8;}
+.greenCell { background-color: #b6d7a8;}
+.redCell { background-color: #ea9999;}
+.purpleCell { background-color: #b4a7d6;}
+.blackCell { background-color: #000000;}
+</style>
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Confirm">Confirm You Need Multiple APKs</a></li>
+  <li><a href="#ChartReqs">Chart Your Requirements</a></li>
+  <li><a href="#CreateLibrary">Put All Common Code and Resources in a Library Project.</a></li>
+  <li><a href="#CreateAPKs">Create New APK Projects</a></li>
+  <li><a href="#AdjustManifests">Adjust the Manifests</a></li>
+  <li><a href="#PreLaunch">Go Over Pre-launch Checklist</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="http://developer.android.com/guide/market/publishing/multiple-apks.html">Multiple APK
+Support</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>When developing your Android application to take advantage of multiple APKs on Android Market,
+it’s important to adopt some good practices from the get-go, and prevent unnecessary headaches
+further into the development process.  This lesson shows you how to create multiple APKs of your
+app, each covering a different class of screen size.  You will also gain some tools necessary to
+make maintaining a multiple APK codebase as painless as possible.</p>
+
+
+<h2 id="Confirm">Confirm You Need Multiple APKs</h2>
+
+<p>When trying to create an application that works across the huge range of available Android
+devices, naturally you want your application look its best on each individual device.  You want to
+take advantage of the space of large screens but still work on small ones, to use new Android API
+features or visual textures available on cutting edge devices but not abandon older ones.  It may
+seem at the outset as though multiple APK support is the best solution, but this often isn’t the
+case.  The <a href="{@docRoot}guide/market/publishing/multiple-apks.html#ApiLevelOptions">Using
+Single APK Instead</a> section of the multiple APK guide includes some useful information on how to
+accomplish all of this with a single APK, including use of our <a
+href="http://android-developers.blogspot.com/2011/03/fragments-for-all.html">support library</a>,
+and links to resources throughout the Android Developer guide.</p>
+
+<p>If you can manage it, confining your application to a single APK has several advantages,
+including:</p>
+
+<ul>
+<li>Publishing and Testing are easier</li>
+<li>There’s only one codebase to maintain</li>
+<li>Your application can adapt to device configuration changes</li>
+<li>App restore across devices just works</li>
+<li>You don’t have to worry about market preference, behavior from "upgrades" from one APK to the
+next, or which APK goes with which class of devices</li>
+</ul>
+
+<p>The rest of this lesson assumes that you’ve researched the topic, studiously absorbed the
+material in the resources linked, and determined that multiple APKs are the right path for your
+application.</p>
+
+
+<h2 id="ChartReqs">Chart Your Requirements</h2>
+
+<p>Start off by creating a simple chart to quickly determine how many APKs you need, and what screen
+size(s) each APK covers.  Fortunately, it’s easy to chart out your requirements quickly, easily, and
+have an easy reference for later.  Let’s say you want to split your APKs across two dimensions, API
+and screen size.  Create a table with a row and column for each possible pair of values, and color
+in some "blobs", each color representing one APK.</p>
+
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td>3</td>
+      <td>4</td>
+      <td>5</td>
+      <td>6</td>
+      <td>7</td>
+      <td>8</td>
+      <td>9</td>
+      <td>10</td>
+      <td>11</td>
+      <td>12</td>
+      <td>+</td>
+    </tr>
+    <tr>
+      <td>small</td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+    </tr>
+    <tr>
+      <td>normal</td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+    </tr>
+    <tr>
+      <td>large</td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+    </tr>
+    <tr>
+      <td>large</td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+    </tr>
+  </tbody>
+</table>
+
+<p>
+Above is an example with four APKs. Blue is for all small/normal screen devices, Green is for large
+screen devices, and Red is for xlarge screen devices, all with an API range of 3-10.  Purple is a
+special case, as it’s for all screen sizes, but only for API 11 and up.  More importantly, just by
+glancing at this chart, you immediately know which APK covers any given API/screen-size combo.  To
+boot, you also have swanky codenames for each one, since "Have we tested red on the ?" is a lot
+easier to ask your cubie than "Have we tested  the 3-to-10 xlarge APK against the Xoom?"  Print this
+chart out and hand it to every person working on your codebase.  Life just got a lot easier.</p>
+
+<h2 id="CreateLibrary">Put All Common Code and Resources in a Library Project.</h2>
+
+<p>Whether you’re modifying an existing Android application or starting one from scratch, this is
+the first thing that you should do to the codebase, and by the far the most important.  Everything
+that goes into the library project only needs to be updated once (think language-localized strings,
+color themes, bugs fixed in shared code), which improves your development time and reduces the
+likelihood of mistakes that could have been easily avoided.</p>
+
+<p class="note"><strong>Note:</strong>  While the implementation details of how to create and
+include library projects are beyond the scope of this lesson, you can get up to speed quickly on
+their creation at the following links:</p>
+<ul>
+<li><a
+href="{@docRoot}guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
+a library project (Eclipse)</a></li>
+<li><a
+href="{@docRoot}guide/developing/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
+a library project (Command line)</a></li>
+</ul>
+
+<p>If you’re converting an existing application to use multiple APK support,
+scour your codebase for every localized string file, list of values, theme
+colors, menu icons and layout that isn’t going to change across APKs, and put
+it all in the library project.  Code that isn’t going to change much should
+also go in the library project.  You’ll likely find yourself extending these
+classes to add a method or two from APK to APK.</p>
+
+<p>If, on the other hand, you’re creating the application from scratch, try as
+much as possible to write code in the library project <em>first</em>, then only move it down to an
+individual APK if necessary.  This is much easier to manage in the long run than adding it to one,
+then another, then another, then months later trying to figure out whether this blob can be moved up
+to the library section without screwing anything up.</p>
+
+<h2 id="CreateAPKs">Create New APK Projects</h2>
+<p>There should be a separate Android project for each APK you’re going to release.  For easy
+organization, place the library project and all related APK projects under the same parent folder. 
+Also remember that each APK needs to have the same package name, although they don’t necessarily
+need to share the package name with the library.  If you were to have 3 APKs following the scheme
+described earlier, your root directory might look like this:</p>
+
+<pre class="no-pretty-print classic">
+alexlucas:~/code/multi-apks-root$ ls
+foo-blue
+foo-green
+foo-lib
+foo-purple
+foo-red
+</pre>
+
+<p>Once the projects are created, add the library project as a reference to each APK project.  If
+possible, define your starting Activity in the library project, and extend that Activity in your APK
+project.  Having a starting activity defined in the library project gives you a chance to put all
+your application initialization in one place, so that each individual APK doesn’t have to
+re-implement "universal" tasks like initializing Analytics, running licensing checks, and any other
+initialization procedures that don’t change much from APK to APK.</p>
+
+
+<h2 id="AdjustManifests">Adjust the Manifests</h2>
+<p>When a user downloads an application which uses multiple APKs through Android Market, the correct
+APK to use is chosen using two simple rules:
+
+<ul>
+<li>The manifest has to show that particular APK is eligible</li>
+<li>Of the eligible APKs, highest version number wins.</li>
+</ul>
+
+<p>By way of example, let’s take the set of multiple APKs described earlier, and assume that each
+APK has been set to support all screen sizes larger than its "target" screen size.  Let’s look at
+the sample chart from earlier:</p>
+
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td>3</td>
+      <td>4</td>
+      <td>5</td>
+      <td>6</td>
+      <td>7</td>
+      <td>8</td>
+      <td>9</td>
+      <td>10</td>
+      <td>11</td>
+      <td>12</td>
+      <td>+</td>
+    </tr>
+    <tr>
+      <td>small</td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+    </tr>
+    <tr>
+      <td>normal</td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="blueCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+    </tr>
+    <tr>
+      <td>large</td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="greenCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+    </tr>
+    <tr>
+      <td>large</td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="redCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+      <td class="purpleCell"></td>
+    </tr>
+  </tbody>
+</table>
+<p>Since it’s okay for coverage to overlap, we can describe the area covered by each APK like
+so:</p>
+<ul>
+<li>Blue covers all screens, minSDK 3.</li>
+<li>Green covers Large screens and higher, minSDK 3.</li>
+<li>Red covers XLarge screens (generally tablets), minSDK of 9.</li>
+<li>Purple covers all screens, minSDK of 11.</li>
+</ul>
+<p>Note that there’s a <em>lot</em> of overlap in those rules.  For instance, an
+XLarge device with API 11 can conceivably run any one of the 4 APKs specified.
+However, by using the "highest version number wins" rule, we can set an order of
+preference as follows:</p>
+<p>
+Purple &#8805; Red &#8805; Green &#8805; Blue
+</p><p>
+Why allow all the overlap?  Let’s pretend that the Purple APK has some requirement on it that the
+other two don’t.  The <a href="{@docRoot}guide/appendix/market-filters.html">Market Filters page</a>
+of the Android Developer guide has a whole list of possible culprits.  For the sake of example,
+let’s assume that Purple requires a front-facing camera.  In fact, the entire point of Purple is to
+use entertaining things with the front-facing camera!  But, it turns out, not all API 11+ devices
+even HAVE front-facing cameras!  The horror!</p>
+
+<p>Fortunately, if a user is browsing Market from one such device, Android Market will look at the
+manifest, see that Purple lists the front-facing camera as a requirement, and quietly ignore it,
+having determined that Purple and that device are not a match made in digital heaven.  It will then
+see that Red is not only compatible with xlarge devices, but also doesn’t care whether or not
+there’s a front-facing camera!  The app can still be downloaded from Android Market by the user,
+because despite the whole front-camera mishap, there was still an APK that supported that particular
+API level.</p>
+
+<p>  In order to keep all your APKs on separate "tracks", it’s important to have a good version code
+scheme.  The recommended one can be found on the <a
+href="{@docRoot}guide/market/publishing/multiple-apks.html#VersionCodes">Version Codes</a> area of
+our developer guide.  It’s worth reading the whole section, but the basic gist is for this set of
+APKs, we’d use two digits to represent the minSDK, two to represent the min/max screen size, and 3
+to represent the build number.  That way, when the device upgraded to a new version of Android,
+(say, from 10 to 11), any APKs that are now eligible and preferred over the currently installed one
+would be seen by the device as an "upgrade".  The version number scheme, when applied to the example
+set of APKs, might look like:</p>
+
+<p>Blue: 0304001, 0304002, 0304003...<br />
+Green: 0334001, 0334002, 0334003<br />
+Red: 0344001, 0344002, 0344003...<br />
+Purple: 1104001, 1104002, 1104003...<br />
+</p>
+
+<p>  Putting this all together, your Android Manifests would likely look something like the
+following:</p>
+<p>Blue:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="0304001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;uses-sdk android:minSdkVersion="3" /&gt;
+    &lt;supports-screens android:smallScreens="true"
+        android:normalScreens="true"
+        android:largeScreens="true"
+        android:xlargeScreens="true" /&gt;
+    ...
+</pre>
+
+<p>Green:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="0334001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;uses-sdk android:minSdkVersion="3" /&gt;
+    &lt;supports-screens android:smallScreens="false"
+        android:normalScreens="false"
+        android:largeScreens="true"
+        android:xlargeScreens="true" /&gt;
+    ...
+</pre>
+
+<p>Red:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="0344001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;uses-sdk android:minSdkVersion="3" /&gt;
+    &lt;supports-screens android:smallScreens="false"
+        android:normalScreens="false"
+        android:largeScreens="false"
+        android:xlargeScreens="true" /&gt;
+    ...
+</pre>
+
+<p>Purple:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="1104001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;uses-sdk android:minSdkVersion="11" /&gt;
+    &lt;supports-screens android:smallScreens="true"
+        android:normalScreens="true"
+        android:largeScreens="true"
+        android:xlargeScreens="true" /&gt;
+    ...
+</pre>
+
+<p>
+Note that technically, multiple APK’s will work with either the supports-screens tag, or the
+compatible-screens tag.  Supports-screens is generally preferred, and it’s generally a really bad
+idea to use both-  It makes things needlessly complicated, and increases the opportunity for errors.
+ Also note that instead of taking advantage of the default values (small and normal are always true
+by default), the manifests explicitly set the value for each screen size.  This can save you
+headaches down the line - By way of example, a manifest with a target SDK of &lt; 9 will have xlarge
+automatically set to false, since that size didn’t exist yet.  So be explicit!
+</p>
+
+<h2 id="PreLaunch">Go Over Pre-launch Checklist</h2>
+<p>  Before uploading to Android Market, double-check the following items.  Remember that these are
+specifically relevant to multiple APKs, and in no way represent a complete checklist for all
+applications being uploaded to Android Market.</p>
+<ul>
+<li>All APKs must have the same package name.</li>
+<li>All APKs must be signed with the same certificate.</li>
+<li>If the APKs overlap in platform version, the one with the higher minSdkVersion must have a
+higher version code.</li>
+<li>Every screen size you want your APK to support, set to true in the manifest.  Every screen size
+you want it to avoid, set to false.</li>
+<li>Double check your manifest filters for conflicting information (an APK that only supports
+cupcake on XLARGE screens isn’t going to be seen by anybody)</li>
+<li>Each APK's manifest must be unique across at least one of supported screen, OpenGL texture, or
+platform version.</li>
+<li>Try to test each APK on at least one device.  Barring that, you have one of the most
+customizable device emulators in the business sitting on your development machine.  Go nuts!</li>
+</ul>
+
+<p>It’s also worth inspecting the compiled APK before pushing to market, to make sure there aren’t
+any surprises that could hide your application in Market.  This is actually quite simple using the
+"aapt" tool.  Aapt (the Android Asset Packaging Tool) is part of the build process for creating and
+packaging your Android applications, and is also a very handy tool for inspecting them. </p>
+
+<pre class="no-pretty-print classic">
+&gt;aapt dump badging
+package: name='com.example.hello' versionCode='1' versionName='1.0'
+sdkVersion:'11'
+uses-permission:'android.permission.SEND_SMS'
+application-label:'Hello'
+application-icon-120:'res/drawable-ldpi/icon.png'
+application-icon-160:'res/drawable-mdpi/icon.png'
+application-icon-240:'res/drawable-hdpi/icon.png'
+application: label='Hello' icon='res/drawable-mdpi/icon.png'
+launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
+uses-feature:'android.hardware.telephony'
+uses-feature:'android.hardware.touchscreen'
+main
+supports-screens: 'xlarge'
+supports-any-density: 'true'
+locales: '--_--'
+densities: '120' '160' '240'
+</pre>
+
+<p>When you examine aapt output, be sure to check that you don’t have conflicting values for
+supports-screens and compatible-screens, and that you don’t have unintended "uses-feature" values
+that were added as a result of permissions you set in the manifest. In the example above, the APK
+will be invisible to most, if not all devices.</p>
+<p>Why?  By adding the required permission SEND_SMS, the feature requirement of android.hardware.telephony was implicitly added.  Since most (if not all) xlarge devices are tablets without telephony hardware in them, Market will filter out this APK in these cases, until future devices come along which are both large enough to report as xlarge screen size, and possess telephony hardware.
+</p>
+<p>Fortunately this is easily fixed by adding the following to your manifest:<p>
+<pre>
+&lt;uses-feature android:name="android.hardware.telephony" android:required="false" /&gt;
+</pre>
+
+<p>Once you’ve completed the pre-launch checklist, upload your APKs to Android Market.  It may take a bit for the application to show up when browsing Android Market, but when it does, perform one last check.  Download the application onto any test devices you may have to make sure that the APKs are targeting the intended devices. Congratulations, you’re done!</p>
diff --git a/docs/html/training/multiple-apks/screensize.jd b/docs/html/training/multiple-apks/screensize.jd
new file mode 100644 (file)
index 0000000..28611ec
--- /dev/null
@@ -0,0 +1,355 @@
+page.title=Creating Multiple APKs for Different Screen Sizes
+parent.title=Creating and Maintaining Multiple APKs
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Creating Multiple APKs for Different API Levels
+previous.link=api.html
+next.title=Creating Multiple APKs for Different GL Textures
+next.link=texture.html
+
+@jd:body
+
+<style type="text/css">
+.blueCell { background-color: #9fc5e8;}
+.greenCell { background-color: #b6d7a8;}
+.redCell { background-color: #ea9999;}
+.blackCell { background-color: #000000;}
+</style>
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Confirm">Confirm You Need Multiple APKs</a></li>
+  <li><a href="#ChartReqs">Chart Your Requirements</a></li>
+  <li><a href="#CreateLibrary">Put All Common Code and Resources in a Library Project.</a></li>
+  <li><a href="#CreateAPKs">Create New APK Projects</a></li>
+  <li><a href="#AdjustManifests">Adjust the Manifests</a></li>
+  <li><a href="#PreLaunch">Go Over Pre-launch Checklist</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="http://developer.android.com/guide/market/publishing/multiple-apks.html">Multiple APK
+Support</a></li>
+  <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
+</ul>
+
+</div>
+</div>
+
+
+<p>When developing your Android application to take advantage of multiple APKs on Android Market,
+it’s important to adopt some good practices from the get-go, and prevent unnecessary headaches
+further into the development process.  This lesson shows you how to create multiple APKs of your
+app, each covering a different class of screen size.  You will also gain some tools necessary to
+make maintaining a multiple APK codebase as painless as possible.</p>
+
+
+<h2 id="Confirm">Confirm You Need Multiple APKs</h2>
+
+<p>When trying to create an application that works across multiple sizes of Android devices,
+naturally you want your application to take advantage of all the available space on larger devices,
+without sacrificing compatibility or usability on the smaller screens.  It may seem at the outset as
+though multiple APK support is the best solution, but this often isn’t the case.  The <a
+href="{@docRoot}guide/market/publishing/multiple-apks.html#ApiLevelOptions">Using Single APK
+Instead</a> section of the multiple APK developer guide includes some useful information on how to
+accomplish this with a single APK, including use of our support library. You should also read the 
+guide to <a href="{@docRoot}guide/practices/screens_support.html">supporting multiple screens</a>,
+and there’s even a <a
+href="http://android-developers.blogspot.com/2011/03/fragments-for-all.html">support library</a> you
+can download using the Android SDK, which lets you use fragments on pre-Honeycomb devices (making
+multiple-screen support in a single APK much easier).</p>
+
+<p>If you can manage it, confining your application to a single APK has several advantages,
+including:</p>
+
+<ul>
+<li>Publishing and testing are easier</li>
+<li>There’s only one codebase to maintain</li>
+<li>Your application can adapt to device configuration changes</li>
+<li>App restore across devices just works</li>
+<li>You don’t have to worry about market preference, behavior from "upgrades" from one APK to the
+next, or which APK goes with which class of devices</li>
+</ul>
+
+<p>The rest of this lesson assumes that you’ve researched the topic, studiously absorbed the
+material in the resources linked, and determined that multiple APKs are the right path for your
+application.</p>
+
+<h2 id="ChartReqs">Chart Your Requirements</h2>
+
+<p>Start off by creating a simple chart to quickly determine how many APKs you need, and what screen
+size(s) each APK covers.  Fortunately, it’s easy to chart out your requirements quickly and easily,
+and have a reference for later.  Start out with a row of cells representing the various screen sizes
+available on the Android platform.</p>
+
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td>small</td>
+      <td>normal</td>
+      <td>large</td>
+      <td>xlarge</td>
+    </tr>
+  </tbody>
+</table>
+<p>
+Now just color in the chart such that each color represents an APK.  Here’s one example of how you
+might apply each APK to a certain range of screen sizes.</p>
+
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td class="blueCell">small</td>
+      <td class="blueCell">normal</td>
+      <td class="greenCell">large</td>
+      <td class="redCell">xlarge</td>
+    </tr>
+  </tbody>
+</table>
+<p>
+Depending on your needs, you could also have two APKs, "small and everything else" or "xlarge and
+everything else".  Coloring in the chart also makes intra-team communication easier&mdash;You can
+now simply refer to each APK as "blue", "green", or "red", no matter how many different screen types
+it covers.</p>
+
+<h2 id="CreateLibrary">Put All Common Code and Resources in a Library Project.</h2>
+<p>Whether you’re modifying an existing Android application or starting one from scratch, this is
+the first thing that you should do to the codebase, and by the far the most important.  Everything
+that goes into the library project only needs to be updated once (think language-localized strings,
+color themes, bugs fixed in shared code), which improves your development time and reduces the
+likelihood of mistakes that could have been easily avoided.</p>
+
+<p class="note"><strong>Note:</strong>  While the implementation details of how to create and
+include library projects are beyond the scope of this lesson, you can get up to speed quickly on
+their creation at the following links:</p>
+<ul>
+<li><a
+href="{@docRoot}guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
+a library project (Eclipse)</a></li>
+<li><a
+href="{@docRoot}guide/developing/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
+a library project (Command line)</a></li>
+</ul>
+
+
+
+<p>If you’re converting an existing application to use multiple APK support,
+scour your codebase for every localized string file, list of values, theme
+colors, menu icons and layout that isn’t going to change across APKs, and put
+it all in the library project.  Code that isn’t going to change much should
+also go in the library project.  You’ll likely find yourself extending these
+classes to add a method or two from APK to APK.</p>
+
+<p>If, on the other hand, you’re creating the application from scratch, try as
+much as possible to write code in the library project <em>first</em>, then only move it down to an
+individual APK if necessary.  This is much easier to manage in the long run than adding it to one,
+then another, then another, then months later trying to figure out whether this blob can be moved up
+to the library section without screwing anything up.</p>
+
+
+
+<h2 id="CreateAPKs">Create New APK Projects</h2>
+<p>There should be a separate Android project for each APK you’re going to release.  For easy
+organization, place the library project and all related APK projects under the same parent folder. 
+Also remember that each APK needs to have the same package name, although they don’t necessarily
+need to share the package name with the library.  If you were to have 3 APKs following the scheme
+described earlier, your root directory might look like this:</p>
+
+<pre class="no-pretty-print classic">
+alexlucas:~/code/multi-apks-root$ ls
+foo-blue
+foo-green
+foo-lib
+foo-red
+</pre>
+
+<p>Once the projects are created, add the library project as a reference to each APK project.  If
+possible, define your starting Activity in the library project, and extend that Activity in your APK
+project.  Having a starting activity defined in the library project gives you a chance to put all
+your application initialization in one place, so that each individual APK doesn’t have to
+re-implement "universal" tasks like initializing Analytics, running licensing checks, and any other
+initialization procedures that don’t change much from APK to APK.</p>
+
+
+<h2 id="AdjustManifests">Adjust the Manifests</h2>
+<p>When a user downloads an application which uses multiple APKs through Android Market, the correct
+APK to use is chosen using two simple rules:</p>
+<ul>
+<li>The manifest has to show that particular APK is eligible</li>
+<li>Of the eligible APKs, highest version number wins</li>
+</ul>
+
+<p>
+By way of example, let’s take the set of multiple APKs described earlier, and assume that each APK
+has been set to support all screen sizes larger than its "target" screen size.  Taken individually,
+the possible range of each APK would look like this:
+</p>
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td class="blueCell">small</td>
+      <td class="blueCell">normal</td>
+      <td class="blueCell">large</td>
+      <td class="blueCell">xlarge</td>
+    </tr>
+    <tr>
+      <td class="blackCell">small</td>
+      <td class="blackCell">normal</td>
+      <td class="greenCell">large</td>
+      <td class="greenCell">xlarge</td>
+    </tr>
+    <tr>
+      <td class="blackCell">small</td>
+      <td class="blackCell">normal</td>
+      <td class="blackCell">large</td>
+      <td class="redCell">xlarge</td>
+    </tr>
+  </tbody>
+</table>
+<p>
+However, by using the "highest version number wins" rule, if we set the versionCode attribute in
+each APK such that red &#8805; green &#8805; blue, the chart effectively collapses down to this:</p>
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td class="blueCell">small</td>
+      <td class="blueCell">normal</td>
+      <td class="greenCell">large</td>
+      <td class="redCell">xlarge</td>
+    </tr>
+  </tbody>
+</table>
+<p>
+Now, let’s further assume that the Red APK has some requirement on it that the other two don’t.  The
+<a href="{@docRoot}guide/appendix/market-filters.html">Market Filters page</a> of the Android
+Developer guide has a whole list of possible culprits.  For the sake of example, let’s assume that
+red requires a front-facing camera.  In fact, the entire point of the red APK is to use the extra
+available screen space to do entertaining things with that front-facing camera.  But, it turns out,
+not all xlarge devices even HAVE front-facing cameras!  The horror!</p>
+
+<p>Fortunately, if a user is browsing Market from one such device, Android Market will look at the
+manifest, see that Red lists the front-facing camera as a requirement, and quietly ignore it, having
+determined that Red and that device are not a match made in digital heaven.  It will then see that
+Green is not only compatible with xlarge devices, but also doesn’t care whether or not there’s a
+front-facing camera!  The app can still be downloaded from Android Market by the user, because
+despite the whole front-camera mishap, there was still an APK that supported that particular screen
+size.</p>
+
+<p>  In order to keep all your APKs on separate "tracks", it’s important to have a good version code
+scheme.  The recommended one can be found on the <a
+href="{@docRoot}guide/market/publishing/multiple-apks.html#VersionCodes">Version Codes</a> area of
+our developer guide.  Since the example set of APKs is only dealing with one of 3 possible
+dimensions, it would be sufficient to separate each APK by 1000 and increment from there.  This
+might look like:</p>
+
+<p>Blue: 1001, 1002, 1003, 1004...<br />
+Green: 2001, 2002, 2003, 2004...<br />
+Red:3001, 3002, 3003, 3004...</p>
+
+<p>  Putting this all together, your Android Manifests would likely look something like the
+following:</p>
+
+<p>Blue:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="1001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;supports-screens android:smallScreens="true"
+        android:normalScreens="true"
+        android:largeScreens="true"
+        android:xlargeScreens="true" /&gt;
+    ...
+</pre>
+
+<p>Green:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="2001" android:versionName="1.0" package="com.example.foo">
+    &lt;supports-screens android:smallScreens="false"
+        android:normalScreens="false"
+        android:largeScreens="true"
+        android:xlargeScreens="true" />
+    ...
+</pre>
+
+<p>Red:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="3001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;supports-screens android:smallScreens="false"
+        android:normalScreens="false"
+        android:largeScreens="false"
+        android:xlargeScreens="true" /&gt;
+    ...
+</pre>
+<p>
+Note that technically, multiple APK’s will work with either the supports-screens
+tag, or the compatible-screens tag.  Supports-screens is generally preferred,
+and it’s generally a really bad idea to use both tags in the same manifest.  It
+makes things needlessly complicated, and increases the opportunity for errors.
+Also note that instead of taking advantage of the default values (small and
+normal are always true by default), the manifests explicitly set the value for
+each screen size.  This can save you headaches down the line.  For instance, a manifest with a
+target SDK of &lt; 9 will have xlarge automatically set to false, since that size didn’t exist yet. 
+So be explicit!
+</p>
+
+<h2 id="PreLaunch">Go Over Pre-launch Checklist</h2>
+<p>  Before uploading to Android Market, double-check the following items.  Remember that these are
+specifically relevant to multiple APKs, and in no way represent a complete checklist for all
+applications being uploaded to Android Market.</p>
+<ul>
+<li>All APKs must have the same package name</li>
+<li>All APKs must be signed with the same certificate</li>
+<li>Every screen size you want your APK to support, set to true in the manifest.  Every screen size
+you want it to avoid, set to false</li>
+<li>Double check your manifest filters for conflicting information (an APK that only supports
+cupcake on XLARGE screens isn’t going to be seen by anybody)</li>
+<li>Each APK's manifest must be unique across at least one of supported screen, openGL texture, or
+platform version</li>
+<li>Try to test each APK on at least one device.  Barring that, you have one of the most
+customizable device emulators in the business sitting on your development machine.  Go nuts!</li>
+</ul>
+
+<p>It’s also worth inspecting the compiled APK before pushing to market, to make sure there aren’t
+any surprises that could hide your application in Market.  This is actually quite simple using the
+"aapt" tool.  Aapt (the Android Asset Packaging Tool) is part of the build process for creating and
+packaging your Android applications, and is also a very handy tool for inspecting them. </p>
+
+<pre class="no-pretty-print classic">
+&gt;aapt dump badging
+package: name='com.example.hello' versionCode='1' versionName='1.0'
+sdkVersion:'11'
+uses-permission:'android.permission.SEND_SMS'
+application-label:'Hello'
+application-icon-120:'res/drawable-ldpi/icon.png'
+application-icon-160:'res/drawable-mdpi/icon.png'
+application-icon-240:'res/drawable-hdpi/icon.png'
+application: label='Hello' icon='res/drawable-mdpi/icon.png'
+launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
+uses-feature:'android.hardware.telephony'
+uses-feature:'android.hardware.touchscreen'
+main
+supports-screens: 'xlarge'
+supports-any-density: 'true'
+locales: '--_--'
+densities: '120' '160' '240'
+</pre>
+
+<p>When you examine aapt output, be sure to check that you don’t have conflicting values for
+supports-screens and compatible-screens, and that you don’t have unintended "uses-feature" values
+that were added as a result of permissions you set in the manifest. In the example above, the APK
+will be invisible to most, if not all devices.</p>
+<p>Why?  By adding the required permission SEND_SMS, the feature requirement of android.hardware.telephony was implicitly added.  Since most (if not all) xlarge devices are tablets without telephony hardware in them, Market will filter out this APK in these cases, until future devices come along which are both large enough to report as xlarge screen size, and possess telephony hardware.
+</p>
+<p>Fortunately this is easily fixed by adding the following to your
+manifest:</p>
+<pre>
+&lt;uses-feature android:name="android.hardware.telephony" android:required="false" /&gt;
+</pre>
+<p>Once you’ve completed the pre-launch checklist, upload your APKs to Android Market.  It may take a bit for the application to show up when browsing Android Market, but when it does, perform one last check.  Download the application onto any test devices you may have to make sure that the APKs are targeting the intended devices. Congratulations, you’re done!</p>
diff --git a/docs/html/training/multiple-apks/texture.jd b/docs/html/training/multiple-apks/texture.jd
new file mode 100644 (file)
index 0000000..6f75ef3
--- /dev/null
@@ -0,0 +1,299 @@
+page.title=Creating Multiple APKs for Different GL Textures
+parent.title=Creating and Maintaining Multiple APKs
+parent.link=index.html
+
+trainingnavtop=true
+previous.title=Creating Multiple APKs for Different Screen Sizes
+previous.link=screensize.html
+next.title=Creating Multiple APKs with 2+ Dimensions
+next.link=multiple.html
+
+@jd:body
+
+<style type="text/css">
+.blueCell { background-color: #9fc5e8;}
+.greenCell { background-color: #b6d7a8;}
+.redCell { background-color: #ea9999;}
+</style>
+
+<div id="tb-wrapper">
+<div id="tb">
+
+<!-- table of contents -->
+<h2>This lesson teaches you to</h2>
+<ol>
+  <li><a href="#Confirm">Confirm You Need Multiple APKs</a></li>
+  <li><a href="#ChartReqs">Chart Your Requirements</a></li>
+  <li><a href="#CreateLibrary">Put All Common Code and Resources in a Library Project</a></li>
+  <li><a href="#CreateAPKs">Create New APK Projects</a></li>
+  <li><a href="#AdjustManifests">Adjust the Manifests</a></li>
+  <li><a href="#PreLaunch">Go Over Pre-launch Checklist</a></li>
+</ol>
+
+<!-- other docs (NOT javadocs) -->
+<h2>You should also read</h2>
+<ul>
+  <li><a href="http://developer.android.com/guide/market/publishing/multiple-apks.html">Multiple APK
+Support</a></li>
+</ul>
+
+</div>
+</div>
+
+<p>When developing your Android application to take advantage of multiple APKs on Android Market, it’s important to adopt some good practices from the get-go, and prevent unnecessary headaches further into the development process.  This lesson shows you how to create multiple APKs of your app, each supporting a different subset of OpenGL texture formats.  You will also gain some tools necessary to make maintaining a multiple APK codebase as painless as possible.</p>
+
+
+<h2 id="Confirm">Confirm You Need Multiple APKs</h2>
+
+<p>When trying to create an application that works across all available Android-powered
+devices, naturally you want your application look its best on each individual device, regardless of
+the fact they don’t all support the same set of GL textures.  It may seem at the outset as though
+multiple APK support is the best solution, but this often isn’t the case.  The <a
+href="{@docRoot}guide/market/publishing/multiple-apks.html#ApiLevelOptions">Using Single APK
+Instead</a> section of the multiple APK developer guide includes some useful information on how to
+accomplish this with a single APK, including how to <a
+href="{@docRoot}guide/market/publishing/multiple-apks.html#TextureOptions">detect supported texture
+formats at runtime</a>.  Depending on your situation, it might be easier to bundle all formats with
+your application, and simply pick which one to use at runtime.</p>
+
+<p>If you can manage it, confining your application to a single APK has several advantages,
+including:</p>
+<ul>
+<li>Publishing and Testing are easier</li>
+<li>There’s only one codebase to maintain</li>
+<li>Your application can adapt to device configuration changes</li>
+<li>App restore across devices just works</li>
+<li>You don’t have to worry about market preference, behavior from "upgrades" from one APK to the
+next, or which APK goes with which class of devices</li>
+</ul>
+
+<p>The rest of this lesson assumes that you’ve researched the topic, studiously absorbed the
+material in the resources linked, and determined that multiple APKs are the right path for your
+application.</p>
+
+
+<h2 id="ChartReqs">Chart Your Requirements</h2>
+<p>The Android Developer Guide provides a handy reference of some of common supported textures on
+the <a href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html">supports-gl-texture
+page</a>.  This page also contains some hints as to which phones (or families of phones) support
+particular texture formats.  Note that it’s generally a good idea for one of your APKs to support
+ETC1, as that texture format is supported by all Android-powered devices that support the OpenGL ES
+2.0 spec.</p>
+
+<p>Since most Android-powered devices support more than one texture format, you need to establish an
+order of preference.  Create a chart including all the formats that your application is going to
+support.  The left-most cell is going to be the lowest priority (It will probably be ETC1, a really
+solid default in terms of performance and compatibility).  Then color in the chart such that each
+cell represents an APK.</p>
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td class="blueCell">ETC1</td>
+      <td class="greenCell">ATI</td>
+      <td class="redCell">PowerVR</td>
+    </tr>
+  </tbody>
+</table>
+
+<p>
+Coloring in the chart does more than just make this guide less monochromatic - It also has a way of
+making intra-team communication easier-  You can now simply refer to each APK as "blue", "green", or
+"red", instead of "The one that supports ETC1 texture formats", etc.</p>
+
+<h2 id="CreateLibrary">Put All Common Code and Resources in a Library Project</h2>
+<p>Whether you’re modifying an existing Android application or starting one from scratch, this is
+the first thing that you should do to the codebase, and by the far the most important.  Everything
+that goes into the library project only needs to be updated once (think language-localized strings,
+color themes, bugs fixed in shared code), which improves your development time and reduces the
+likelihood of mistakes that could have been easily avoided.</p>
+
+<p class="note"><strong>Note:</strong>  While the implementation details of how to create and
+include library projects are beyond the scope of this lesson, you can get up to speed quickly on
+their creation at the following links:</p>
+<ul>
+<li><a
+href="{@docRoot}guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject">Setting up
+a library project (Eclipse)</a></li>
+<li><a
+href="{@docRoot}guide/developing/projects/projects-cmdline.html#SettingUpLibraryProject">Setting up
+a library project (Command line)</a></li>
+</ul>
+
+<p>If you’re converting an existing application to use multiple APK support,
+scour your codebase for every localized string file, list of values, theme
+colors, menu icons and layout that isn’t going to change across APKs, and put
+it all in the library project.  Code that isn’t going to change much should
+also go in the library project.  You’ll likely find yourself extending these
+classes to add a method or two from APK to APK.</p>
+
+<p>If, on the other hand, you’re creating the application from scratch, try as
+much as possible to write code in the library project <em>first</em>, then only move it down to an
+individual APK if necessary.  This is much easier to manage in the long run than adding it to one,
+then another, then another, then months later trying to figure out whether this blob can be moved up
+to the library section without screwing anything up.</p>
+
+<h2 id="CreateAPKs">Create New APK Projects</h2>
+<p>There should be a separate Android project for each APK you’re going to release.  For easy
+organization, place the library project and all related APK projects under the same parent folder. 
+Also remember that each APK needs to have the same package name, although they don’t necessarily
+need to share the package name with the library.  If you were to have 3 APKs following the scheme
+described earlier, your root directory might look like this:</p>
+
+<pre class="no-pretty-print classic">
+alexlucas:~/code/multi-apks-root$ ls
+foo-blue
+foo-green
+foo-lib
+foo-red
+</pre>
+
+
+<p>Once the projects are created, add the library project as a reference to each APK project.  If
+possible, define your starting Activity in the library project, and extend that Activity in your APK
+project.  Having a starting activity defined in the library project gives you a chance to put all
+your application initialization in one place, so that each individual APK doesn’t have to
+re-implement "universal" tasks like initializing Analytics, running licensing checks, and any other
+initialization procedures that don’t change much from APK to APK.</p>
+
+
+<h2 id="AdjustManifests">Adjust the Manifests</h2>
+<p>When a user downloads an application which uses multiple APKs through Android Market, the correct
+APK to use is chosen using some simple rules:</p>
+
+<ul>
+<li>The manifest has to show that particular APK is eligible</li>
+<li>Of the eligible APKs, highest version number wins</li>
+<li>If <em>any</em> of the texture formats listed in your APK are supported by the device on market,
+that device is considered eligible</li>
+</ul>
+
+<p>With regards to GL Textures, that last rule is important.  It means that you should, for
+instance, be <em>very</em> careful about using different GL formats in the same application.  If you
+were to use PowerVR 99% of the time, but use ETC1 for, say, your splash screen... Then your manifest
+would necessarily indicate support for both formats.  A device that <em>only</em> supported ETC1
+would be deemed compatible, your app would download, and the user would see some thrilling crash
+messages.  The common case is going to be that if you’re using multiple APKs specifically to target
+different devices based on GL texture support, it’s going to be one texture format per APK.</p>
+
+<p>This actually makes texture support a little bit different than the other two multiple APK
+dimensions, API level and screen size.  Any given device only has one API level, and one screen
+size, and it’s up to the APK to support a range of them.  With textures, the APK will generally
+support one texture, and the device will support many.  There will often be overlap in terms of one
+device supporting many APKs, but the solution is the same:  Version codes.</p>
+
+<p>By way of example, take a few devices, and see how many of the APKs defined earlier fit each
+device.</p>
+<table cellpadding="10" cellspacing="0" border="1">
+  <tbody>
+    <tr>
+      <td>FooPhone</td>
+      <td>Nexus S</td>
+      <td>Evo</td>
+    </tr>
+    <tr>
+      <td class="blueCell">ETC1</td>
+      <td class="blueCell">ETC1</td>
+      <td class="blueCell">ETC1</td>      
+    </tr>
+    <tr>
+      <td></td>
+      <td class="greenCell">PowerVR</td>
+      <td class="redCell">ATI TC</td>
+    </tr>
+  </tbody>
+</table>
+<p> Assuming that PowerVR and ATI formats are both preferred over ETC1 when available, than
+according to the "highest version number wins" rule, if we set the versionCode attribute in each APK
+such that red &#8805; green &#8805; blue, then both Red and Green will always be chosen over Blue on
+devices which support them, and should a device ever come along which supports both Red and Green,
+red will be chosen.
+</p>
+
+<p>  In order to keep all your APKs on separate "tracks," it’s important to have a good version code
+scheme.  The recommended one can be found on the Version Codes area of our developer guide.  Since
+the example set of APKs is only dealing with one of 3 possible dimensions, it would be sufficient to
+separate each APK by 1000 and increment from there.  This might look like:</p>
+
+<p>Blue: 1001, 1002, 1003, 1004...<br />
+Green: 2001, 2002, 2003, 2004...<br />
+Red:3001, 3002, 3003, 3004...</p>
+
+<p>  Putting this all together, your Android Manifests would likely look something like the
+following:</p>
+<p>Blue:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="1001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" /&gt;
+    ...
+</pre>
+
+<p>Green:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="2001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;supports-gl-texture android:name="GL_AMD_compressed_ATC_texture" /&gt;
+    ...
+</pre>
+
+<p>Red:</p>
+<pre>
+&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    android:versionCode="3001" android:versionName="1.0" package="com.example.foo"&gt;
+    &lt;supports-gl-texture android:name="GL_IMG_texture_compression_pvrtc" /&gt;
+    ...
+</pre>
+
+<h2 id="PreLaunch">Go Over Pre-launch Checklist</h2>
+<p>Before uploading to Android Market, double-check the following items.  Remember that these are
+specifically relevant to multiple APKs, and in no way represent a complete checklist for all
+applications being uploaded to Android Market.</p>
+
+<ul>
+<li>All APKs must have the same package name</li>
+<li>All APKs must be signed with the same certificate</li>
+<li>Double check your manifest filters for conflicting information (an APK that only supports
+cupcake on XLARGE screens isn’t going to be seen by anybody)</li>
+<li>Each APK's manifest must be unique across at least one of supported screen, OpenGL texture, or
+platform version</li>
+<li>Try to test each APK on at least one device.  Barring that, you have one of the most
+customizable device emulators in the business sitting on your development machine.  Go nuts!</li>
+</ul>
+
+<p>It’s also worth inspecting the compiled APK before pushing to market, to make sure there aren’t
+any surprises that could hide your application in Market.  This is actually quite simple using the
+"aapt" tool.  Aapt (the Android Asset Packaging Tool) is part of the build process for creating and
+packaging your Android applications, and is also a very handy tool for inspecting them. </p>
+
+<pre class="no-pretty-print classic">
+&gt;aapt dump badging
+package: name='com.example.hello' versionCode='1' versionName='1.0'
+sdkVersion:'11'
+uses-permission:'android.permission.SEND_SMS'
+application-label:'Hello'
+application-icon-120:'res/drawable-ldpi/icon.png'
+application-icon-160:'res/drawable-mdpi/icon.png'
+application-icon-240:'res/drawable-hdpi/icon.png'
+application: label='Hello' icon='res/drawable-mdpi/icon.png'
+launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
+uses-feature:'android.hardware.telephony'
+uses-feature:'android.hardware.touchscreen'
+main
+supports-screens: 'xlarge'
+supports-any-density: 'true'
+locales: '--_--'
+densities: '120' '160' '240'
+</pre>
+
+<p>When you examine aapt output, be sure to check that you don’t have conflicting values for
+supports-screens and compatible-screens, and that you don’t have unintended "uses-feature" values
+that were added as a result of permissions you set in the manifest. In the example above, the APK
+will be invisible to most, if not all devices.</p>
+<p>Why?  By adding the required permission SEND_SMS, the feature requirement of android.hardware.telephony was implicitly added.  Since most (if not all) xlarge devices are tablets without telephony hardware in them, Market will filter out this APK in these cases, until future devices come along which are both large enough to report as xlarge screen size, and possess telephony hardware.  
+</p>
+<p>Fortunately this is easily fixed by adding the following to your manifest:</p>
+<pre>
+&lt;uses-feature android:name="android.hardware.telephony" android:required="false" /&gt;
+</pre>
+<p>Once you’ve completed the pre-launch checklist, upload your APKs to Android Market.  It may take a bit for the application to show up when browsing Android Market, but when it does, perform one last check.  Download the application onto any test devices you may have to make sure that the APKs are targeting the intended devices. Congratulations, you’re done!</p>