In this tutorial, I will show you how you can build an APK (an Android app) using terminal on Linux without IDE or Android Studio.

Install JDK 7

Remove the existing OpenJDK, execute the following command on terminal:

sudo apt-get remove openjdk*

Download oracle jdk 7 on the official website. Extract the oracle jdk 7 tarball to your home directory:

tar -zxvf jdk-7u80-linux-x64.tar.gz --directory $HOME

Open the .bashrc file.

vi $HOME/.bashrc

Add the following line to set the JDK 7 path:

export PATH="$HOME/jdk1.7.0_80/bin:$PATH"

Save the file and exit.

Then Reload the .bashrc file:

source $HOME/.bashrc

Check if the jdk path has been set up correctly:

java -version

Install Android SDK Tools 23.0.5

The SDK Tools package is deprecated and no longer used in Android 8. Since Android 8, it use the new Android SDK Command-Line tools package.

As stated in https://developer.android.com/tools/releases/platforms, the required Android SDK Tools version is 23.0.5.

Download Android SDK Tools 23.0.5 on http://dl-ssl.google.com/android/repository/tools_r23.0.5-linux.zip

wget http://dl-ssl.google.com/android/repository/tools_r23.0.5-linux.zip

Create Android SDK installation directory on your home directory.

mkdir $HOME/android5sdk

Extract the Android SDK Tools to Android SDK installation directory:

unzip tools_r23.0.5-linux.zip -d $HOME/android5sdk

Change the Android SDK Tools directory permissions and ownership:

sudo chmod -R 755 $HOME/android5sdk/tools
sudo chown -R $USER:$USER $HOME/android5sdk/tools

Open the .bashrc file.

vi $HOME/.bashrc

Add the following lines to set Android SDK environment variable ANDROID_HOME and the Android SDK Tools path:

export ANDROID_HOME="$HOME/android5sdk"
export PATH="$HOME/jdk1.7.0_80/bin:$ANDROID_HOME/tools:$PATH"

Save the file and exit.

Then reload the .bashrc file:

source $HOME/.bashrc

Install Android SDK Build-tools 23.0.1

Run android command on the terminal and Android SDK Manager window will show up:

android

Click Deselect All

Android SDK Manager

Check Android SDK Build-tools version 23.0.1 option. Then click Install package

Android SDK Manager

A prompt shows up and click Accept License. Then click Install.

Android SDK Manager
Android SDK Manager

After the installation process finished, open the .bashrc file and set the Android SDK Build-tools path.

export PATH="$HOME/jdk1.7.0_80/bin:$ANDROID_HOME/tools:$ANDROID_HOME/build-tools/23.0.1:$PATH"

Save the file and exit.

Then Reload the .bashrc file:

source $HOME/.bashrc

Install SDK Platform for Android 5 API Level 21

Run android command on the terminal and Android SDK Manager window will show up:

android

Click Deselect All

Android SDK Manager

Find and check the SDK Platform API Level 21 option. Then click Install package

Android SDK Manager

A prompt appears and click Accept License. Then click Install.

Android SDK Manager

Create and Build an Simple Android Project

First, we need to make a project directory on the home directory:

mkdir $HOME/HelloAndroid
cd $HOME/HelloAndroid

Open the .bashrc file and set the Android project path.

export PROJ="$HOME/HelloAndroid"

Create the src directory that contains all .java (JAVA) files.

mkdir src

Every Android app has a unique application ID that looks like a Java package name, such as com.example.myapplication. This ID uniquely identifies your app in Google Play Store. If you want to upload a new version of your app, the application ID (and the certificate you sign it with) must be the same as the original APK. if you change the application ID, Google Play Store treats the APK as a completely different app.

Create the unique application ID directory structure inside the src directory.

mkdir -p src/com/example/helloandroid

Create the layout directory holds all the XML layout files for your projects.

mkdir -p res/layout

Create the drawable directory holds all the images for your project.

mkdir -p res/drawable

Create the values directory is used to store the values for the resources that are used in android projects to include features of color, styles, dimensions etc.

mkdir -p res/values

Every app project must have an AndroidManifest.xml file, with precisely that name, at the project directory. The manifest file describes essential information about your app to the Android build tools, the Android operating system, and Google Play.

Create a AndroidManifest.xml file contains information of your package, including components of the application such as activities, services, broadcast receivers, content providers etc. Add the following lines:

<?xml version='1.0'?>
<manifest xmlns:a='http://schemas.android.com/apk/res/android' package='com.example.helloandroid' a:versionCode='0' a:versionName='0'>
    <application a:label='A Hello Android'>
        <activity a:name='com.example.helloandroid.MainActivity'>
             <intent-filter>
                <category a:name='android.intent.category.LAUNCHER'/>
                <action a:name='android.intent.action.MAIN'/>
             </intent-filter>
        </activity>
    </application>
</manifest>

Create a src/com/example/helloandroid/MainActivity.java file and add the following codes:

package com.example.helloandroid;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
   }
}

Create a res/values/strings.xml file which contains all the strings which will be used frequently in project and add the following codes:

<resources>
    <string name="app_name">A Hello Android</string>
    <string name="hello_msg">Hello Android!</string>
</resources>

Create a res/values/activity_main.xml file which defines the architecture for the UI in an Activity or a component of a UI and add the following lines:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent" >
   
   <TextView
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_centerHorizontal="true"
      android:layout_centerVertical="true"
      android:text="@string/hello_msg"
      tools:context=".MainActivity" />
</RelativeLayout>

Now, we need generate the R.java file:

aapt package -f -m -J $PROJ/src -M $PROJ/AndroidManifest.xml -S $PROJ/res -I $ANDROID_HOME/platforms/android-21/android.jar
  • -f option instructs aapt to force overwrite of existing files
  • -m option instructs aapt to create directories under the location specified by -J option
  • -J option specifies where R.java file will be created
  • -S option specifies where the resource directory is
  • -I option instructs aapt to include the android.jar

Next, we compile the .java files:

javac -d obj -sourcepath src -classpath $ANDROID_HOME/platforms/android-21/android.jar src/com/example/helloandroid/*.java
  • -d option specifies where the class files (compiled .java files) will be saved
  • -sourcepath option specifies where to find source files (.java files)
  • -classpath option specifies where the android library (.jar files) or the external libraries are. Use : to separate the .jar files

The compiled .class files are in obj directory, but Android runtime can't read them. We have to translate them in a file called classes.dex which will be read by the dalvik Android runtime:

dx --dex --output=$PROJ/bin/classes.dex $PROJ/obj

But if your project uses external libraries, then:

dx --dex --output=$PROJ/bin/classes.dex $PROJ/*.jar $PROJ/obj

Now we create the APK file:

aapt package -f -m -F $PROJ/bin/hello.unaligned.apk -M $PROJ/AndroidManifest.xml -S $PROJ/res -I $ANDROID_HOME/platforms/android-21/android.jar
  • -f option instructs aapt to force overwrite of existing files
  • -m option instructs aapt to create directories under the location specified by -J option
  • -F option specifies where the APK file will be created
  • -M option specifies full path to AndroidManifest.xml to include in APK file
  • -S option specifies directory in which to find resources
  • -I option instructs aapt to include the android.jar

Add the classes.dex file to the APK file:

aapt add $PROJ/bin/hello.unaligned.apk $PROJ/bin/classes.dex

The generated APK can’t be installed yet by Android because it's unaligned and unsigned.

To sign the APK, we firstly create a new keystore with the command keytool given by Java JDK:

keytool -genkeypair -alias samuel -validity 365 -keystore mykey.keystore -keyalg RSA -keysize 2048
  • -genkeypair option instructs keytool to generate a public key/private key pair and the generated key pair is inserted into a Java KeyStore file as a self signed key pair
  • -alias option specifies the name for the certificate
  • -validity option specifies the number of days the certificate attached to the key pair should be valid
  • -keystore option specifies the name of the KeyStore file to store the generated key pair in
  • -keyalg option specifies the name of the algorithm used to generate the key
  • -keysize option specifies the size in bits of the key to generate

When prompted, supply the certificate and password information.

Enter keystore password:  (choose a password)
What is your first and last name?
  [Unknown]:  samuel yang
What is the name of your organizational unit?
  [Unknown]:  development
What is the name of your organization?
  [Unknown]:  hemimorphite
What is the name of your City or Locality?
  [Unknown]:  jakarta
What is the name of your State or Province?
  [Unknown]:  jakarta
What is the two-letter country code for this unit?
  [Unknown]:  id
Is CN=samuel yang, OU=development, O=hemimorphite, L=jakarta, ST=jakarta, C=id correct?
  [no]:  yes

Enter key password for 
        (RETURN if same as keystore password):  (choose a password or enter)

Next, we sign the APK file with the command jarsigner given by Java JDK:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore mykey.keystore $PROJ/bin/hello.unaligned.apk
  • -verbose option indicates that the jarsigner use the verbose mode when signing
  • -sigalg option specifies the name of the signature algorithm to use to sign the APK file.
  • -digestalg option specifies the name of the message digest algorithm to use when digesting the entries of a APK file.
  • -keystore option specifies the name of the KeyStore file to be used

Next, we align the APK file to optimize your APK file.

zipalign -f 4 $PROJ/bin/hello.unaligned.apk $PROJ/bin/hello.apk
  • -f option instructs the zipalign to overwrite existing output file
  • 4 option instructs the zipalign to align to 4 bytes on both 32-bit and 64-bit systems

Run the APK File on Android Emulator

Download the genymotion installer on the official website.

Next, open terminal and run the installer:

./genymotion-3.4.0-linux_x64.bin

After finished installing, open the emulator and click add virtual machine.

Genymotion Emulator

A window will show up, search the virtual device name (eg. Samsung Galaxy S5) and double click the virtual device.

Genymotion Emulator

Just click Next and then click Install.

Genymotion Emulator
Genymotion Emulator
Genymotion Emulator
Genymotion Emulator

Wait until the download is complete.

After the download is complete, start the virtual device.

Genymotion Emulator
Genymotion Emulator

Drag and drop the APK file into the emulator. A window will show up. Click continue.

Genymotion Emulator

if everything is fine with your set-up and application, it will display following emulator window.

Genymotion Emulator