1---
2title: Android
3author: Sander van der Burg
4date: 2018-11-18
5---
6# Android
7
8The Android build environment provides three major features and a number of
9supporting features.
10
11Deploying an Android SDK installation with plugins
12--------------------------------------------------
13The first use case is deploying the SDK with a desired set of plugins or subsets
14of an SDK.
15
16```nix
17with import <nixpkgs> {};
18
19let
20 androidComposition = androidenv.composeAndroidPackages {
21 toolsVersion = "25.2.5";
22 platformToolsVersion = "27.0.1";
23 buildToolsVersions = [ "27.0.3" ];
24 includeEmulator = false;
25 emulatorVersion = "27.2.0";
26 platformVersions = [ "24" ];
27 includeSources = false;
28 includeDocs = false;
29 includeSystemImages = false;
30 systemImageTypes = [ "default" ];
31 abiVersions = [ "armeabi-v7a" ];
32 lldbVersions = [ "2.0.2558144" ];
33 cmakeVersions = [ "3.6.4111459" ];
34 includeNDK = false;
35 ndkVersion = "16.1.4479499";
36 useGoogleAPIs = false;
37 useGoogleTVAddOns = false;
38 includeExtras = [
39 "extras;google;gcm"
40 ];
41 };
42in
43androidComposition.androidsdk
44```
45
46The above function invocation states that we want an Android SDK with the above
47specified plugin versions. By default, most plugins are disabled. Notable
48exceptions are the tools, platform-tools and build-tools sub packages.
49
50The following parameters are supported:
51
52* `toolsVersion`, specifies the version of the tools package to use
53* `platformsToolsVersion` specifies the version of the `platform-tools` plugin
54* `buildToolsVersion` specifies the versions of the `build-tools` plugins to
55 use.
56* `includeEmulator` specifies whether to deploy the emulator package (`false`
57 by default). When enabled, the version of the emulator to deploy can be
58 specified by setting the `emulatorVersion` parameter.
59* `includeDocs` specifies whether the documentation catalog should be included.
60* `lldbVersions` specifies what LLDB versions should be deployed.
61* `cmakeVersions` specifies which CMake versions should be deployed.
62* `includeNDK` specifies that the Android NDK bundle should be included.
63 Defaults to: `false`.
64* `ndkVersion` specifies the NDK version that we want to use.
65* `includeExtras` is an array of identifier strings referring to arbitrary
66 add-on packages that should be installed.
67* `platformVersions` specifies which platform SDK versions should be included.
68
69For each platform version that has been specified, we can apply the following
70options:
71
72* `includeSystemImages` specifies whether a system image for each platform SDK
73 should be included.
74* `includeSources` specifies whether the sources for each SDK version should be
75 included.
76* `useGoogleAPIs` specifies that for each selected platform version the
77 Google API should be included.
78* `useGoogleTVAddOns` specifies that for each selected platform version the
79 Google TV add-on should be included.
80
81For each requested system image we can specify the following options:
82
83* `systemImageTypes` specifies what kind of system images should be included.
84 Defaults to: `default`.
85* `abiVersions` specifies what kind of ABI version of each system image should
86 be included. Defaults to: `armeabi-v7a`.
87
88Most of the function arguments have reasonable default settings.
89
90When building the above expression with:
91
92```bash
93$ nix-build
94```
95
96The Android SDK gets deployed with all desired plugin versions.
97
98We can also deploy subsets of the Android SDK. For example, to only the
99`platform-tools` package, you can evaluate the following expression:
100
101```nix
102with import <nixpkgs> {};
103
104let
105 androidComposition = androidenv.composeAndroidPackages {
106 # ...
107 };
108in
109androidComposition.platform-tools
110```
111
112Using predefine Android package compositions
113--------------------------------------------
114In addition to composing an Android package set manually, it is also possible
115to use a predefined composition that contains all basic packages for a specific
116Android version, such as version 9.0 (API-level 28).
117
118The following Nix expression can be used to deploy the entire SDK with all basic
119plugins:
120
121```nix
122with import <nixpkgs> {};
123
124androidenv.androidPkgs_9_0.androidsdk
125```
126
127It is also possible to use one plugin only:
128
129```nix
130with import <nixpkgs> {};
131
132androidenv.androidPkgs_9_0.platform-tools
133```
134
135Building an Android application
136-------------------------------
137In addition to the SDK, it is also possible to build an Ant-based Android
138project and automatically deploy all the Android plugins that a project
139requires.
140
141```nix
142with import <nixpkgs> {};
143
144androidenv.buildApp {
145 name = "MyAndroidApp";
146 src = ./myappsources;
147 release = true;
148
149 # If release is set to true, you need to specify the following parameters
150 keyStore = ./keystore;
151 keyAlias = "myfirstapp";
152 keyStorePassword = "mykeystore";
153 keyAliasPassword = "myfirstapp";
154
155 # Any Android SDK parameters that install all the relevant plugins that a
156 # build requires
157 platformVersions = [ "24" ];
158
159 # When we include the NDK, then ndk-build is invoked before Ant gets invoked
160 includeNDK = true;
161}
162```
163
164Aside from the app-specific build parameters (`name`, `src`, `release` and
165keystore parameters), the `buildApp {}` function supports all the function
166parameters that the SDK composition function (the function shown in the
167previous section) supports.
168
169This build function is particularly useful when it is desired to use
170[Hydra](https://nixos.org/hydra): the Nix-based continuous integration solution
171to build Android apps. An Android APK gets exposed as a build product and can be
172installed on any Android device with a web browser by navigating to the build
173result page.
174
175Spawning emulator instances
176---------------------------
177For testing purposes, it can also be quite convenient to automatically generate
178scripts that spawn emulator instances with all desired configuration settings.
179
180An emulator spawn script can be configured by invoking the `emulateApp {}`
181function:
182
183```nix
184with import <nixpkgs> {};
185
186androidenv.emulateApp {
187 name = "emulate-MyAndroidApp";
188 platformVersion = "28";
189 abiVersion = "x86"; # armeabi-v7a, mips, x86_64
190 systemImageType = "google_apis_playstore";
191}
192```
193
194Additional flags may be applied to the Android SDK's emulator through the runtime environment variable `$NIX_ANDROID_EMULATOR_FLAGS`.
195
196It is also possible to specify an APK to deploy inside the emulator
197and the package and activity names to launch it:
198
199```nix
200with import <nixpkgs> {};
201
202androidenv.emulateApp {
203 name = "emulate-MyAndroidApp";
204 platformVersion = "24";
205 abiVersion = "armeabi-v7a"; # mips, x86, x86_64
206 systemImageType = "default";
207 useGoogleAPIs = false;
208 app = ./MyApp.apk;
209 package = "MyApp";
210 activity = "MainActivity";
211}
212```
213
214In addition to prebuilt APKs, you can also bind the APK parameter to a
215`buildApp {}` function invocation shown in the previous example.
216
217Querying the available versions of each plugin
218----------------------------------------------
219When using any of the previously shown functions, it may be a bit inconvenient
220to find out what options are supported, since the Android SDK provides many
221plugins.
222
223A shell script in the `pkgs/development/mobile/androidenv/` sub directory can be used to retrieve all
224possible options:
225
226```bash
227sh ./querypackages.sh packages build-tools
228```
229
230The above command-line instruction queries all build-tools versions in the
231generated `packages.nix` expression.
232
233Updating the generated expressions
234----------------------------------
235Most of the Nix expressions are generated from XML files that the Android
236package manager uses. To update the expressions run the `generate.sh` script
237that is stored in the `pkgs/development/mobile/androidenv/` sub directory:
238
239```bash
240./generate.sh
241```