This document describes the usage of common tools used for Android development on the command line, particularly Android (android), Android Debug Bridge (adb) and how they can be used to create an Android application project and how to install and debug an Android app using the command line.
After reading this document, you should be familiar in using the common tools for Android development stated above in creating, installing and debugging Android apps.
Prerequisites
To properly follow this material, you must have the following in place:
(1) You have installed the latest Java Development Kit (JDK) from Oracle. (java.com/download)
(2) You must have installed Android SDK. If you have not done so yet, you can download the Android SDK here: developer.android.com/sdk
(The Android SDK can be downloaded separately as a stand alone installer, or as part of the bigger Android Studio installer)
The Android SDK and the associated commands work roughly exactly the same way on Windows, Mac OS X and Linux. Therefore, the instructions given here should be applicable regardless of your operating system.
The "android" command
If you have the Android SDK in place, you can locate the "android" command inside the tools directory. To try it, open up your command line, and issue the following kind of command (obviously replacing the beginning with the complete path to the actual directory where you have installed the SDK files):
<your android sdk directory>/tools/android
Then press ENTER. By default, the Android SDK Manager will be displayed:
The Android SDK Manager lets you download and install, uninstall, and update necessary packages (SDK tools and platforms) that you need to develop an Android app. Full information about this GUI tool can be found on the Android developer site:
Full information about the Android SDK Manager on developer.android.com
Going back to the command line, to list some of the things that can be done with the android tool, try this:
<your android sdk directory>/tools/android -h
or
<your android sdk directory>/tools/android --help
You should see commands with corresponding descriptions like the following below:
Usage: android [global options] action [action options] Global options: -s --silent : Silent mode, shows errors only. -v --verbose : Verbose mode, shows errors, warnings and all messages. --clear-cache: Clear the SDK Manager repository manifest cache. -h --help : Help on a specific command. Valid actions are composed of a verb and an optional direct object: - sdk : Displays the SDK Manager window. - avd : Displays the AVD Manager window. - list : Lists existing targets or virtual devices. - list avd : Lists existing Android Virtual Devices. - list target : Lists existing targets. - list device : Lists existing devices. - list sdk : Lists remote SDK repository. - create avd : Creates a new Android Virtual Device. - move avd : Moves or renames an Android Virtual Device. - delete avd : Deletes an Android Virtual Device. - update avd : Updates an Android Virtual Device to match the folders of a new SDK. - create project : Creates a new Android project. - update project : Updates an Android project (must already have an AndroidManifest.xml). - create test-project : Creates a new Android project for a test package. - update test-project : Updates the Android project for a test package (must already have an AndroidManifest.xml). - create lib-project : Creates a new Android library project. - update lib-project : Updates an Android library project (must already have an AndroidManifest.xml). - create uitest-project : Creates a new UI test project. - update adb : Updates adb to support the USB devices declared in the SDK add-ons. - update sdk : Updates the SDK by suggesting new platforms to install if available.
List Targets
To display the list of available Android target(s) / SDK versions that are available on the current system, try this:
<your android sdk directory>/tools/android list targets
You should see available targets like the following:
Available Android targets: id: 1 or "android-23" Name: Android 6.0 Type: Platform API level: 23 Revision: 2 Skins: HVGA, QVGA, WQVGA400, WQVGA432, WSVGA, WVGA800 (default), WVGA854, WXGA720, WXGA800, WXGA800-7in Tag/ABIs : default/armeabi-v7a, default/x86_64
(Followed by other targets, if available)
Take note of the "id" line in this list, as that is the value that you can use in other places to refer to the specific version of an Android SDK target.
List Devices
To display a list of available Android device(s) that are currently configured, try this:
<your android sdk directory>/tools/android list devices
You should see available device definitions like the following:
Available devices definitions: id: 1 or "Galaxy Nexus" Name: Galaxy Nexus OEM : Google
(Followed by other devices, if available)
The Android Emulator
The Android Emulator emulates a complete Android device in software on a desktop computer. Therefore, to do Android development, you will not necessarily need to have an actual physical device at your disposal. You can locate the Android emulator tool as part of the Android SDK here:
<your android sdk directory>/tools/emulator
Full information about the Android Emulator on developer.android.com
Creating an Android Virtual Device
To run an instance of the Android operating system inside the emulator, you will first need to create an Android Virtual Device. You can do this with the following kind of a command:
<your android sdk directory>/tools/android create avd --name <desired avd name> --target <target platform> ## from list of targets, can be ID or name --abi <processor type> ## optional, depending on the target
Sample:
<your android sdk directory>/tools/android create avd --name Lollipop --target 1 --abi default/armeabi-v7a
Type the entire command on one line. Then press ENTER in the end. You should see something like this:
Created AVD 'Lollipop' based on Android 5.0.1, ARM (armeabi-v7a) processor, with the following hardware config: hw.accelerometer=yes hw.audioInput=yes hw.battery=yes hw.cpu.model=cortex-a8 hw.dPad=no hw.device.hash2=MD5:6930e145748b87e87d3f40cabd140a41 hw.device.manufacturer=Google hw.device.name=Galaxy Nexus hw.gps=yes hw.keyboard=no hw.lcd.density=320 hw.mainKeys=no hw.ramSize=512 hw.sdCard=no hw.sensors.orientation=yes hw.sensors.proximity=yes hw.trackBall=no vm.heapSize=48
Cool! You have successfully created your Android Virtual Device.
Running your virtual device
To execute your new Android Virtual Device in an emulator, you can simply do this:
<your android sdk directory>/tools/emulator -avd <name of avd>
You should see and Android Emulator starting up and something like below in the terminal window:
emulator: WARNING: Increasing RAM size to 1GB Creating filesystem with parameters: Size: 576716800 Block size: 4096 Blocks per group: 32768 Inodes per group: 7040 Inode size: 256 Journal blocks: 2200 Label: Blocks: 140800 Block groups: 5 Reserved block group size: 39 Created filesystem with 11/35200 inodes and 4536/140800 blocks resize2fs 1.42.13 (17-May-2015) The filesystem is already 140800 (4k) blocks long. Nothing to do!
The emulator itself should have opened in a new window, running a complete copy of the Android operating system.
Creating a new Android application
To create the initial source code for a new Android application, try this:
<your android sdk directory>/tools/android create project --target <target ID> ## from the list of targets --name <desired project name> ## optional --path <project directory> --activity <activity name> ## usually the MainActivity --package <java package name> --gradle --gradle-version <android gradle plugin version>
For example:
<your android sdk directory>/tools/android create project --target 5 --name myApp --path SampleAndroidProject --activity MainActivity --package my.app --gradle --gradle-version 1.1.3
Again, the entire command would be written on one line. In the end, press ENTER. You should see something like this in your terminal window:
Created directory SampleAndroidProject/src/main/java Created directory SampleAndroidProject/src/main/java/my/app Added file ./src/main/java/my/app/MainActivity.java Created directory SampleAndroidProject/src/androidTest/java Created directory SampleAndroidProject/src/androidTest/java/my/app Added file ./src/androidTest/java/my/app/MainActivityTest.java Created directory SampleAndroidProject/src/main/res Created directory SampleAndroidProject/src/main/res/values Added file ./src/main/res/values/strings.xml Created directory SampleAndroidProject/src/main/res/layout Added file ./src/main/res/layout/main.xml Created directory SampleAndroidProject/src/main/res/drawable-xhdpi Created directory SampleAndroidProject/src/main/res/drawable-hdpi Created directory SampleAndroidProject/src/main/res/drawable-mdpi Created directory SampleAndroidProject/src/main/res/drawable-ldpi Added file ./src/main/AndroidManifest.xml Added file ./build.gradle Created directory SampleAndroidProject/gradle/wrapper
Awesome! You have successfully created an Android project.
Project Directory Contents
After successfully creating a project, navigate to your project directory. You should have the following files and directories in place:
build.gradle gradle/ gradlew gradlew.bat local.properties src/
Adjust the created project
It appears that the project creation script is stuck in an older version of Gradle, which is no longer compatible with newer versions of the overall Android build system. To address the problem, we will need to edit the "gradle-wrapper.properties" file under the "wrapper" subdirectory of the "gradle" directory in the created project source. In that file, by default, you find a line like this:
distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip
This can be changed to this:
distributionUrl=http\://services.gradle.org/distributions/gradle-2.2.1-all.zip
(essentially, we change gradle version from 1.12 to 2.2.1, as it should be).
Likewise, in the generated "build.gradle" file, you should change the line that says "runProguard false" to "minifyEnabled true" (apparently, the syntax for this was changed at a point during the Android build system development cycle, but the "android create project" script is yet to be updated accordingly).
Compiling an Android Project
Before you compile your project, you must be connected to the internet in order for the gradle wrapper script to download the appropriate gradle software components. Once ready, to compile your Android project, navigate to your project directory on your command line (change directory), and do this:
For Mac or Linux:
./gradlew build
For Windows:
gradlew.bat build
The "gradlew" script is a wrapper script that then downloads all the necessary components that are needed to run the complete Gradle build. Once any necessary downloading is completed, the wrapper continues to execute the actual build. In the end, you should find the final APK installer in the "build" -> "outputs" -> "apk" directory under your project directory:
$ ls build/outputs/apk/ SampleAndroidProject-debug-unaligned.apk SampleAndroidProject-debug.apk SampleAndroidProject-release-unsigned.apk
The installer to use is the second one in the list above (*-debug.apk).
The APK file
The Android Application Package, most commonly known as APK, is the installer and distribution file format for Android apps. Once your Gradle build has successfully completed, you should have an APK file that was generated from your source code.
The Android Debug Bridge
Android Debug Bridge (adb) is a command line tool used to communicate with a connected android device or emulator. It is commonly used for installation and debugging of apps during development.
You can locate the Android Debug Bridge executable (adb or adb.exe) here:
<your android sdk directory>/platform-tools/
For complete official information about Android Debug Bridge, refer to the link below:
Full information about the Android Debug Bridge on developer.android.com
Bear in mind that before you install and debug an app, you must have one of the following in place:
(1) Connected Android device
(2) Running Android Emulator
Select the appropriate device
If you have a device connected, or an emulator running, to check if it is connected, try this:
<your android sdk directory>/platform-tools/adb devices
This command will list all physical Android gadgets (tablets, phones, etc.) that you have connected to your development computer (via USB or otherwise), as well as any Android emulator instances that you may have running. If ever you plug in several devices, and/or run several emulators simultaneously, observing this list becomes increasingly important in selecting which one of them you would wish to interact with.
You should see something like the following:
List of devices attached emulator-5554 device J501A1ZR55043323 device
To select a specific Android instance (whether device or emulator) to use, you can use the -s parameter of adb to specify which device to use, followed by the device ID from the list above. For example:
<your android sdk directory>/platform-tools/adb -s emulator-5554 <operations-to-execute>
Installing an Android app
If this is your first time to install the particular app on the device or emulator, you can simply do this:
<your android sdk directory>/platform-tools/adb install <your APK file>
Then press ENTER and the following kind of information should be displayed in your terminal window:
5840 KB/s (7624580 bytes in 1.274s) pkg: /data/local/tmp/myapp.apk Success
Congratulations. You have successfully installed your Android app. It should now appear in the application menu of the device or emulator.
Replacing or reinstalling an app
To replace a previously installed app, the -r parameter of adb can be used. Try this:
<your android sdk directory>/platform-tools/adb install -r <your APK file>
Take note that the -r parameter means to replace an existing application. So, doing this ..
<your android sdk directory>/platform-tools/adb install <your APK file>
.. would generate an error, as shown below, since you are trying to install the same version of the app without using the -r parameter.
1654 KB/s (7624580 bytes in 4.499s) pkg: /data/local/tmp/myapp.apk Failure [INSTALL_FAILED_ALREADY_EXISTS]
Debugging with adb logcat
The logcat command of adb is used to display system messages of a running Android OS (whether device or emulator). This is extremely useful to find out what is happening to an application or a device. Any and all messages generated by the device are shown here, giving a wealth of information for any kind of troubleshooting requirements.
Try this:
<your android sdk directory>/platform-tools/adb logcat
You should see logs in your terminal window something like the following:
* daemon not running. starting it now on port 5037 * adb I 473 7034 usb_osx.cpp:259] Found vid=0bb4 pid=0c02 serial=J501A1ZR55043323 adb I 473 7034 usb_osx.cpp:259] * daemon started successfully * --------- beginning of /dev/log/system D/ActivityThread(19921): SVC-BIND_SERVICE handled : 0 / BindServiceData{token=android.os.BinderProxy@423157e0 intent=Intent { pkg=com.google.android.gms cmp=com.google.android.gms/.auth.GetToken }} D/ActivityThread(19921): SVC-Creating service: CreateServiceData{token=android.os.BinderProxy@422d8168 className=com.google.android.gms.auth.DefaultAuthDelegateService packageName=com.google.android.gms intent=null} D/ActivityThread(19921): SVC-CREATE_SERVICE handled : 0 / CreateServiceData{token=android.os.BinderProxy@422d8168 className=com.google.android.gms.auth.DefaultAuthDelegateService packageName=com.google.android.gms intent=null} D/ActivityThread(19921): SVC-BIND_SERVICE handled : 0 / BindServiceData{token=android.os.BinderProxy@422d8168 intent=Intent { pkg=com.google.android.gms cmp=com.google.android.gms/.auth.DefaultAuthDelegateService }} D/ActivityThread(19921): SVC-UNBIND_SERVICE handled : 0 / BindServiceData{token=android.os.BinderProxy@422d8168 intent=Intent { pkg=com.google.android.gms cmp=com.google.android.gms/.auth.DefaultAuthDelegateService }} D/ActivityThread(19921): SVC-Destroying service: com.google.android.gms.auth.DefaultAuthDelegateService@42372618 D/ActivityThread(19921): SVC-STOP_SERVICE handled : 0 / android.os.BinderProxy@422d8168 D/ActivityThread(19921): SVC-UNBIND_SERVICE handled : 0 / BindServiceData{token=android.os.BinderProxy@423157e0 intent=Intent { pkg=com.google.android.gms cmp=com.google.android.gms/.auth.GetToken }} ----- More logs ------
The logcat command of adb is commonly used by app developers and testers to trace the cause of crashes in an Android app during development.
Filtering logs
To filter logs using the logcat command of adb. You can do this:
<your android sdk directory>/platform-tools/adb logcat *:#
The asterisk (*) character means ALL logs and the hash (#) character is the filter, which can be one of the following:
V Verbose (default) D Debug I Info W Warn E Error F Fatal
For example, doing this ...
<your android sdk directory>/platform-tools/adb logcat *:W
... would result to something like the following:
--------- beginning of /dev/log/system W/SocketClient( 156): write error (Broken pipe) W/ActivityManager( 719): Unable to start service Intent { act=com.cleanmaster.api.RT_ACCESS cmp=com.cmcm.skey/com.cmcm.rtstub.RTApiService } U=0: not found W/ActivityManager( 719): Unable to start service Intent { act=com.cleanmaster.api.RT_ACCESS cmp=com.cmcm.rtstub/.RTApiService } U=0: not found --------- beginning of /dev/log/main W/MediatekClassFactory( 3129): Tablet not exist!, Get obj from default class E/ ( 3129): appName=com.cleanmaster.mguard:gamebox.web, acAppName=/system/bin/surfaceflinger E/ ( 3129): 0 ----- More logs -----
Note:
When filtering logs, a priority is followed from top to bottom. If *:W is used, Warnings are displayed first followed by Errors then Fatal logs. Like in the sample above. Thus, filtering with Verbose (default) will display the logs starting from Verbose down to Fatal.
Furthermore, you can also filter logs with a keyword. Try this (this only works on a Unix-like environment, such as Mac OS X or Linux):
<your android sdk directory>/platform-tools/adb logcat | grep -i <keyword>
For example, doing this ...
<your android sdk directory>/platform-tools/adb logcat | grep -i exception
... would result to something like the following:
W/System.err( 719): java.lang.SecurityException: WifiService: Neither user 10032 nor current process has android.permission.CHANGE_WIFI_STATE. W/System.err( 3819): java.lang.NullPointerException W/System.err( 719): java.lang.SecurityException: WifiService: Neither user 10324 nor current process has android.permission.CHANGE_WIFI_STATE.
The pipe (|) character means that logs from the logcat command of adb will be an input for grep (a command used to search for strings). The -i parameter of grep means ignore case.
Interrupting logcat
You can at any time interrupt the logcat command by pressing Ctrl+C in your terminal window. You should then have returned to your command line.
Congratulations!
You have completed this tutorial. You have successfully created an Android application purely on the command line.
#DevelopTheImpossible