Saturday, 30 March 2013

Set up Android SDK and NDK

This describes how I got the tools required to develop an Android application written in Java with a portion of 'native' C code. It's only really worth using native code when you have existing libraries written in C you wish to use without rewriting them in Java
This required installing and setting up Android Development Tools which includes the Standard Development Kit and additionally the NDK (Native Development Kit) because I needed to include some complex C-library that I didn't want to translate into Java because it would have taken ages and be *very* difficult.

Get Android Development Tools

Download the ADT (including the SDK) from http://developer.android.com/tools/index.html  It was about 365MB so I go and have a cuppa.  A windows version is available however I used the Mac OSX version adt-bundle-mac-x86_64.zip which contained five elements:
  • Eclipse + ADT plugin
  • Android SDK Tools
  • Android Platform-tools
  • The latest Android platform
  • The latest Android system image for the emulator
Move the downloaded file somewhere near the top of your Mac's hierarchy (I found having the shortest possible path was useful for a later step) and unzip it - that's pretty much all there is to installation.  To run Eclipse double click the icon in the unzipped folder - it's then a good idea to 'right-click the Eclipse icon and add it permanently to the dock.  The following screenshots show how to create a new project.

The screen you see when you open Eclipse.



Open the Android SDK Manager and any packages you need.  The versions of the API you need to install depends on the target(s) you are developing for however you can always install more later should you need them.  I also installed Documentation to help me learn how to code for Android. 
Here is a helpful shortlist of Android codenames and the related APIs; there is a comprehensive official list:
KitKat:                       19
Jellybean:                  16, 17, 18
Ice Cream Sandwich:  14, 15
Honeycomb:               11,12, 13
Gingerbread:              9, 10
Froyo:                        8
Eclair:                        5, 6, 7

Next click on the 'New' icon in the top-left of the Eclipse window and choose Android Application Project.

You are then asked to fill in some information that is used to set up some important attributes of your project (have a look at the manifest later on).

Some more options which I didn't really care about as this was my first time with android - I may get more detailed in another post if I get any more expert!
I can't really add anything useful to these screenshots at the moment.  I hope these posts are useful to people out there on the internet, if they're not they are incredibly useful for me to remember how I did these things. 

I realise a series of screenshots isn't the best blog post ever created.  Some explanatory text might help others to understand what I was doing.  However this is mostly for me at the moment and these screenshots help me a lot.  If you want a better explanation please say so in the comments.


These last two screens didn't really mean that much to me first time round - but they are quite important.  Choosing Blank Activity and None limit the amount of 'autocode' added to the .m and .h files in your virgin project.  As I'm learning Android I prefer minimum autocode so I can learn to program what I need manually.  I'm not sure I'd like too much autocode once I'm more adept and coding either to be honest.



Installing Android NDK

http://developer.android.com/tools/sdk/ndk/index.html is just over 200MB so I used bittorrent to download the file having generated the .torrent using www.burnbit.com.


At time of writing the download was NDK release 8c for Apple's Darwin open source operating system that forms the basis for Mac OS X and Intel processors with filename “android ndk r8c darwin x86 tar.bz2”

I unpacked the .bz2 file (just double click it) and found the following useful to read:
README.TXT
docs/OVERVIEW.html
docs/INSTALL.html

The latter of those 3 useful reads (INSTALL.html) states that GNU Make 3.81 and GNU Awk are required in the development system. I already had Xcode vers. 4.1 installed and followed Stack Overflow advice to go to Xcode->Preferences->Downloads to install command line tools to make this available. 'Command Line Tools' is also available from Downloads for Apple Developers without having to install or go through Xcode (requires sign-in to developer account). (“https://developer.apple.com/downloads/index.action?name=for%20Xcode%20-”).

I moved the entire android-ndk-r8c folder (I'll refer to this as $NDK as does the documentation) at the top level of my filesystem ready to continue with the install. The documentation isn't too clear on how to install; my first attempt was to open a terminal, navigate to $NDK and execute: “make GNUmakefile”.

The result was:
Android NDK: The APP variable is undefined or empty.
Android NDK: Please define it to one of:
Android NDK: You can also add new applications by writing an Application.mk file.
Android NDK: See docs/APPLICATION-MK.TXT for details.
build/core/main.mk:71: *** Android NDK: Aborting . Stop.

This showed that it is at least partially working and made me think that there is nothing to 'install' as usual because everything is built each time ndk_build is called during an Android app build (probably by Eclipse). Then I found a tip from stackoverflow.com (http://stackoverflow.com/questions/4454653/android-ndk-on-mac-osx-quick-install-w-o-developer-tools) that suggested adding the NDK directory of pre-builts to the path to solve someone's problem:
A version of make is included with the Android NDK. Simply add {NDK install dir}/prebuilt/darwin-x86/bin to your PATH and you'll be able to build with the NDK.”

I ran these three commands in terminal to temporarily add the bin directory to my Mac's path:
1 echo $PATH
2 export PATH=$PATH:/android-ndk-r8c/prebuilt/darwin-x86/bin
3 echo $PATH

Looking in this bin directory I found awk, make and sed executables which are part of Apple's command line tools. I considered these commands that came with the NDK were alternatives to those that come with Apple command line tools so decided not to make the change to $PATH permanent, but still made the change to stick with the stackoverflow tip.

However I did want to add ndk-build command to the path permanently as this command must be used while in the application project's directory.  I did this in terminal according to instructions on the all knowing stackoverflow (http://stackoverflow.com/a/10907174/1742626):

cd ~
emacs .profile
[in emacs] source ~/.bashrc
[in emacs] Ctrl-x, Ctrl-c, y
emacs .bashrc
[in emacs] export PATH = $PATH:/android-ndk-r8c/<enter>
[in emacs] Ctrl-x, Ctrl-c, y

Now I can execute ndk-build on the command line without typing the full $NDK path. This is important because in order for the $project path to be set correctly I need to be in the application project/jni folder where the C source code to be 'ndk-built' sits.

Having sorted all that out, time for a test.  I found two guides to help me:
http://mobile.tutsplus.com/tutorials/android/ndk-tutorial/ briefly describes when to use native code in android development and how to install NDK but *very* briefly.  It then goes on to a useful little example using C code in an Android app that writes some text to Logcat thereby showing how to add native C code to your app and proving it works with your install.

http://developer.android.com/tools/sdk/ndk/index.html#GetStarted is Android's official documentation for NDK and a required read.

Following instructions on this page:
When loading project in Eclipse get Unable to resolve target 'android-3' error in the console and the folders are marked with a red x.

The solution was to install more stuff using the SDK Manager pictured much earlier on in this post was at: http://sagistech.blogspot.co.uk/2010/05/android-sdk-error-unable-to-resolve.html

Restarted Eclipse removed the red X but there was another problem:
Errors running builder 'Android Pre Compiler' on project 'tests'.
Element not found: /Hellojni/tests/gen.

http://code.google.com/p/beginning-android-games/issues/detail?id=39 suggests it's a file permission problem. In Finder the folders in Hellojni are read only for 'wheel' and 'everyone' but read/write for 'mattmapleston'. Changing 'wheel' to read/write removes the errors which must be done for several folders.

Next step is to run the Command Line 'android update project -p . -s' when in the hello-jni folder but android command is not found.
http://stackoverflow.com/questions/10784321/android-update-project-path-command-not-found suggests that I need to add tools and platform-tools to PATH. These directories are in the ADT-bundle-mac folder (the ADK installation).

So I edited the .bashrc file to set the path to '$PATH:/Android/android-ndk-r8c/:/Android/adt-bundle-mac/sdk/tools/:/Android/adt-bundle-mac/sdk/platform-tools/' (I moved the adt-bundle-mac to same place as ndk). Restarted Terminal. Command 'android' now opens the SDK manager and the update command works giving the following result:

Updated local.properties
No project name specified, using Activity name 'HelloJni'.
If you wish to change it, edit the first line of build.xml.
Added file ./build.xml
Added file ./proguard-project.txt
Error: The project either has no target set or the target is invalid.
Please provide a --target to the 'android update' command.
Updated local.properties
No project name specified, using project folder name 'tests'.
If you wish to change it, edit the first line of build.xml.
Added file ./tests/build.xml
Added file ./tests/proguard-project.txt
Matts-MacBook-Air:hello-jni mattmapleston$ android update project -p . -s
Updated local.properties
Updated file ./proguard-project.txt
Error: The project either has no target set or the target is invalid.
Please provide a --target to the 'android update' command.
Updated local.properties
Updated file ./tests/proguard-project.txt

I ignored the errors as build.xml was created in the project

Next step is to compile the native code by typing ndk-build in terminal while in the project's folder – the big test of the installation and the ability to compile native C code for use in an Android application developed in Eclipse IDE using Java. The result was:
/Android/android-ndk-r8c/build/core/add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 3 in ./AndroidManifest.xml
Gdbserver : [arm-linux-androideabi-4.6] libs/armeabi/gdbserver
Gdbsetup : libs/armeabi/gdb.setup
Compile thumb : hello-jni <= hello-jni.c
SharedLibrary : libhello-jni.so
Install : libhello-jni.so => libs/armeabi/libhello-jni.so

Then I clicked the run button in Eclipse and it worked - showing a window with my Hello World in it :). Also changed the text in hello-jni.c file and re-ran successfully (needed a ndk-build followed by project clean).

SUCCESS - Android SDK worked and so did NDK!

Native-audio example

This is another project I used to test that the SDK/NDK worked - native audio.
Start a new project from existing code in Eclipse and browse to $NDK/samples/native-audio/
I got an error about not being able to resolve android-10 target so I installed the SDK for API 10 in the SDK manager within Eclipse.

In terminal I navigated to the native-audio folder and ran android update -p . -s which resulted in:
Updated local.properties
No project name specified, using Activity name 'NativeAudio'.
If you wish to change it, edit the first line of build.xml.
Added file ./build.xml
Added file ./proguard-project.txt
Error: The project either has no target set or the target is invalid.
Please provide a --target to the 'android update' command.

Then ndk-build resulted in:
/Android/android-ndk-r8c/build/core/add-application.mk:128: Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 9 in ./AndroidManifest.xml
Compile thumb : native-audio-jni <= native-audio-jni.c
SharedLibrary : libnative-audio-jni.so
Install : libnative-audio-jni.so => libs/armeabi/libnative-audio-jni.so

Then back in Eclipse, making sure the NativeAudio package is selected, I clicked the Run button

Selected Android Application and OK.

Chose my phone which was plugged in via USB with USB debugging turned on and clicked OK.


That's all there is to getting to a point where you have the tools to develop Android applications using both Java as usual and native C code if required.  I believe it's only really worth using native code when you have existing libraries written in C you wish to use without rewriting them in Java.  At least that's why I did it.

Screenshots on Galaxy S2 are taken by pressing Home quickly followed by Power.