NOW Hiring

Quick links

This tutorial describes how to create Android applications with Android Studio. It is usually based on the latest and greatest Android and Android Studio release.

1. Introduction into development of Android applications

1.1. The Android operating system

Android is an operating system based on the Linux kernel. The project responsible for developing the Android system is called the Android Open Source Project (AOSP) and it lead by Google.

This Android operating system can be divided into the four areas as depicted in the following graphic. An Android application developer typically works with the two layers on top to create new Android applications.

Android software layers

The levels can be described as:

  • Applications - The Android Open Source Project contains several default application, like the Browser, Camera, Gallery, Music, Phone and more.

  • Application framework - An API which allows high-level interactions with the Android system from Android applications.

  • Libraries and runtime - The libraries for many common framework functions, like, graphic rendering, data storage, web browsing. It also contains the Android Runtime, as well as the core Java libraries for running Android applications.

  • Linux kernel - Communication layer for the underlying hardware.

Android is published in different version, which are listed in the following table.

Table 1. Android versions

Code name

Version

API level

Nougat

N

24

Marshmallow

6.0

23

Lollipop

5.1

22

Lollipop

5.0

21

KitKat

4.4 - 4.4.4

19

Jelly Bean

4.1.x - 4.3.x

16 - 18

Ice Cream Sandwich

4.0.1 - 4.0.4

14 -15

Honeycomb

3.2.x

13

Honeycomb

3.0 - 3.1

11 - 12

Gingerbread

2.3 - 2.3.7

9-10

Froyo

2.2.x

8

Eclair

2.1

7

Eclair

2.0 - 2.0.1

5 -6

Donut

1.6

4

Cupcake

1.5

3

(no code name)

1.1

2

(no code name)

1.0

1

1.2. How to develop Android applications

Android applications are primarily written in the Java programming language.

During development the developer creates the Android specific configuration files and writes the application logic in the Java programming language.

The Android development tooling converts these application files into an Android application. If the developer trigger the deployment, the whole Android application is compiled, packaged, deployed and potentially started.

The Android Software Development Kit (Android SDK) and the Gradle tooling contains the necessary tools to create, compile and package Android applications. The Android team provides a Gradle plug-in to build Android applications. You find the available versions of this plug-in under the following URL: https://jcenter.bintray.com/com/android/tools/build/gradle/

The Android SDK contains the Android debug bridge (adb). adb is a tool that allows you to connect to a virtual or real Android device, for the purpose of managing the device or debugging your application.

1.3. Android Developer Tools and Android Studio

Google provides an IDE called Android Studio as the preferred development environment for creating Android applications. This IDE is based on the IntelliJ IDE.

The Android tools provide specialized editors for Android specific files. Most of Android’s configuration files are based on XML. In this case these editors allow you to switch between the XML representation of the file and a structured user interface for entering the data.

Using Eclipse for Android development

The Google development team focus their future development on Android Studio. At the time of this writing the Eclipse Gradle tooling does not support Android applications.

Please register for https://bugs.eclipse.org/bugs/show_bug.cgi?id=468315 to get this fixed in Eclipse.

Vote for Grade support in Eclipse

In addition you can try to convince Google to support Eclipse. Please go to https://code.google.com/p/android/issues/detail?id=81451 and press the star sign.

Vote for Eclipse support by Google

1.4. Conversion process from source code to Android application

This is background information about the build process. It is not necessary for you to develop Android applicatoins. Feel free to skip.

The Java source files are converted to Java class files by the Java compiler. The Android SDK contains a tool called dx which converts Java class files into a .dex (Dalvik Executable) file. All class files of the application are placed in this .dex file. During this conversion process redundant information in the class files are optimized in the .dex file. For example, if the same String is found in different class files, the .dex file contains only one reference of this String.

These .dex files are therefore much smaller in size than the corresponding class files.

The .dex file and the resources of an Android project, e.g., the images and XML files, are packed into an .apk (Android Package) file. The program aapt (Android Asset Packaging Tool) performs this step.

The resulting .apk file contains all necessary data to run the Android application and can be deployed to an Android device via the adb tool.

As of Android 5.0 the Android RunTime (ART) is used as runtime for all Android applications. ART uses Ahead Of Time compilation. During the installation of an application on an Android device, the application code is translated into machine code. This results in approx. 30% larger compile code, but allows faster execution at startup.

This also saves battery life, as the compilation is only done once, during the first start of the application.

The dex2oat tool takes the .dex file created by the Android tool change and compiles that into an Executable and Linkable Format (ELF file). This file contains the dex code, compiled native code and meta-data. Keeping the .dex code allows that existing tools still work.

The garbage collection in ART has been optimized to reduce times in which the application freezes.

1.5. Google Play

Google offers the Google Play service, a marketplace in which programmers can offer their application to Android users. Customers use the Google Play application which allows them to buy and install applications from the Google Play service.

Google Play also offers an update service. If a application developer uploads a new version of his application to Google Play, this service notifies existing users about the update allows them to install the update.

Google Play provides access to services and libraries for Android application programmers, too. For example, it provides a service to use and display Google Maps. Providing these services via Google Play has the advantage that they are available for older Android releases. Google can update them without the need for an update of the Android release on the phone.

2. Installation of Android Studio

2.1. System requirements

Development for Android can be done on a reasonably sized computer. For a nice experience a modern computer is recommended, for example, a 2.6 GHz CPU with at least 8 GB of memory. An SSD speeds up the start of the Android emulator significantly.

2.2. Requirements for using Linux

The Android SDK is 32-bit, therefore on a 64-bit Linux system you need to have the package ia32-libs installed. For Ubuntu you can do this via the following command.

apt-get install ia32-libs

Please check your distribution documentation if you are using a different flavor of Linux.

2.3. Download Android Studio

Download Android Studio from the following URL: http://developer.android.com/sdk/index.html

The download comes in two flavors, SDK Tools only and Android Studio Packages. You want to download the Android Studio Package for your operation system.

Installation of Android Studio

2.4. Installation of Android Studio

Installation for Windows is simple, just launch the .exe you downloaded. On Max OSX drag and drop Android Studio into the Applications folder.

On Linux unpack the downloaded ZIP file into an appropriate location for your applications. To launch Android Studio, navigate to the android-studio/bin/ directory in a terminal and execute studio.sh.

The first time you start Android Studio you can select if you want to import your setting from an existing installation.

Configuration wizard of Android Studio

Afterwards click through the setup guide.

Configuration wizard of Android Studio
Configuration wizard of Android Studio
Configuration wizard of Android Studio

Once you reach the last page, press the Finish button.

Configuration wizard of Android Studio

3. Exercise: Getting started with Android Studio

3.1. Target of this exercise

In this exercise you create an Android project and start it on an Android virtual device.

3.2. Create a new Android project

Press the Start a new Android Studio project link to get started. Alternatively you can select the File ▸ New Project…​ entry from the menu, if you already created a project earlier.

Creating a new Android Studio project

Use the following data of input for your project. Project location and package name are derived from your input. If you want another package name, press the small Edit hyperlink.

Table 2. Setting for your Android project
Property Value

Application name

Test App

Company Domain

android.vogella.com

Package Name

com.vogella.android.testapp

API (Minimum, Target, Compile with)

Latest

Template

Empty Activity

Creating a new Android Studio project
Creating a new Android Studio project

Android Studio automatically downloads the required Android SDK, if that has not already been done. Depending on your installation, the next dialog might not be displayed.

Creating a new Android Studio project

Afterwards select the Empty Activity template.

Creating a new Android Studio project

On the last page, ensure that "Backwards Compability is not selected.

Creating a new Android Studio project

3.3. Review the generated project

The wizard generates now an Android project. Review the generated project structure and files.

as first70
The Android view does not show the real file structure. It shows a logical view of the application.

3.4. Create a virtual device (AVD)

Define a new Android Virtual Device (AVD) by opening the AVD Manager via Tools ▸ Android ▸ AVD Manager. Afterwards press the Create Virtual Device…​ button.

Create a new AVD

Select values similar to the following screenshots.

Settings for a new AVD

On the next screen select the latest API level for your AVD. You may need to select the option for additional images as highlighted in the following screenshot.

Settings for a new AVD
Settings for a new AVD

Afterwards press the Finish button. This will create the AVD configuration and display it under the list of available virtual devices.

3.5. Start your virtual device

Select your new entry and press the Play button.

Settings for a new AVD

3.6. Start the application on your virtual device

Select Run ▸ Run 'app' to start your application. This opens a dialog in which you can select your device to deploy your application to.

Settings for a new AVD

After a while your application should start on the virtual device.

Settings for a new AVD

4. Android SDK Manager

4.1. Using the Android SDK manager

The Android SDK Manager allows you to install and delete Android packages for a specific Android version.

Select Tools ▸ Android ▸ SDK Manager or the SDK Manager icon in the toolbar of Android Studio to open the Android SDK manager.

Android SDK manager in Android Studio

4.2. Install selected Android version or library

In the Android SDK manager select the version of desired Android version the tree and press the Install button. The following screenshot shows the selection for the API 18 version of Android.

Install Android API

Press the OK button to start he installation.

The SDK Platforms tab is used to install API versions, which the SDK Tools is used to install the development tools.

4.3. Install support library

The support library allows you to use functionality provided by higher Android releases in lower Android versions. It also contains functionality that is unbundled from Android, for example the RecyclerView widget for efficient list display.

Android currently has several versions of the library, the v4, v7 and v13 version. These are valid as of the respective API level of Android. For example, the support library v7 works as of Android devices with version API 7. Higher versions of the support library require also the lower versions to work. For example, support the v7 library requires the v4 library.

5. Using Android Virtual Devices or real devices for testing

5.1. Android emulator and Android Virtual Device

The Android tooling contains an Android device emulator. This emulator can be used to run an Android Virtual Device (AVD), which emulates a real Android phone.

AVDs allow you to test your Android applications on different Android versions and configurations without access to the real hardware. Even if you have a real Android device available, you should get familiar with the creation and usage of AVDs. Virtual devices give you the possibility to test your application for selected Android versions and a specific configurations.

During the creation of your AVD you define the configuration for the virtual device. This includes, for example, the resolution, the Android API version and the density of your display.

You can define multiple AVDs with different configurations and start them in parallel. This allows you to test different device configurations at once.

If you stop and AVD during startup process the AVD might get corrupted. The first start may take up to 10 minutes on an older machine. On a modern machine it typically takes 1-3 minutes for a new AVD to start.

After the AVD has started, you can control the GUI with the mouse. The emulator also provides access to the phone buttons via a menu on the right side of the emulator.

Once started, don’t stop the AVD during your development. If you change your application and want to test a new version, you simply re-deploy your application on the AVD.

5.2. Debug certificate and expire date

Android applications must be signed before they can get installed on an Android device. During development Eclipse signs your application automatically with a self-signed certificate called the debug key.

This debug certificate has an expiration date of 365 days from its creation date. When the certificate expires, you will get a build error that the certificate has been expired.

To fix this problem, delete the debug.keystore file. The default storage location is in ~/.android/ on OS X and Linux, in C:\Documents andSettings\[username]\.android\ on Windows XP, and in C:\Users\[username]]\.android\ on Windows Vista and Windows 7.

The next time you build, the build tools will regenerate a new keystore and debug key.

5.3. Google vs. Android AVD

During the creation of an AVD you decide if you want to create an Android device or a Google device.

An AVD created for Android contains the programs from the Android Open Source Project . An AVD created for the Google API’s contains additional Google specific code.

AVDs created for the Google API allow you to test applications which use Google Play services, e.g., the new Google maps API or the new location services.

5.4. Speed optimization with GPU rendering

During the creation of an emulator you can choose if you either want Snapshot or Use Host GPU enabled.

The dialog implies that you can select both options, but if you do, you get an error message that these options can not be selected together.

If you select the Snapshot option, the second time you start the device it is started very fast, because the AVD stores its state if you close it. If you select Use Host GPU the AVD uses the graphics card of your host computer directly which makes the rendering on the emulated device much faster.

Startup options of the emulator

5.5. Speed optimization with the Intel system image

It is possible to run an AVD with an image based on the ARM CPU architecture or based on the Intel CPI architecture.

An Android virtual device which uses the Intel system image is much faster in execution on Intel / AMD hardware compared to the ARM based system image. This is because the emulator does not need to translate the ARM CPU instructions to the Intel / AMD CPU on your computer.

The Intel image for an API can be installed via the Android SDK Manager. In Android Studio this happens automatically if you create an device. If is possible to configure this via the package details.

Intel emulator
An Intel image is not available for all API levels.

At the time of this writing your also need to download and install extra drivers for MS windows.

Intel emulator

After the download you find the driver in your Android installation directory in the extras/intel folder. You need to install the drivers by running starting the .exe file. This additional installation step is required on Window to accelerate the Intel emulator. Only downloading the driver via the Android does not make a difference.

After the download you can create a new AVD based on the Intel emulator. The emulator does not start faster but is way faster during the execution of your Android application.

Linux requires a more complex setup. For a detailed installation description see the Intel emulator installation guide (https://software.intel.com/en-us/android/articles/intel-hardware-accelerated-execution-manager) which also includes detailed instructions for Windows.

5.6. Using a real Android device for testing

Turn on USB Debugging on your device in the settings. Select Settings ▸ Development Options, then enable the USB-Debugging option.

You may also need to install the driver for your mobile phone. Linux and Mac OS usually work out of the box while Windows typically requires the installation of a driver.

For details on the driver installation on Windows please see http://developer.android.com/guide/developing/device.html.

The minimum Android version of your Android application needs to fit to the Android version on your device.

If you have several devices connected to your computer, you can select which one should be used. If only one device is connected, the application is automatically deployed on this device.

6. Software components of an Android application

6.1. Android application

An Android application (short: Android app) is a single installable unit which can be started and used independently of other Android applications. Android application components can connect to components of other Android applications based on a task description represented by an Intent object. This way they can create cross-application tasks.

An Android application consists of Android components, Java source and resource files. The existing Android components are described in the following table.

Table 3. Android application components
Component Description

Application

An Android application can have one Application class which is instantiated before any other Android component. It is the last component which is stopped during application shutdown.

If not explicitly defined, Android creates a default application object for your application.

Activity

An activity is the visual representation of an Android application. An Android application can have several activities.

Activities use views and fragments to create their user interface and to interact with the user.

Service

A service performs tasks without providing an user interface. They can communicate with other Android components. For example, a broadcast receiver can notify the user via the notification framework in Android.

Broadcast receiver (short: receiver)

A broadcast receiver (receiver) can be registered to listen to system messages and intents. A receiver gets notified by the Android system if the specified event occurs.

For example, you can register a receiver for the event that the Android system finished the boot process. Or you can register for the event that the state of the phone changes, e.g., someone is calling.

Content provider (short: provider)

A content provider (provider) defines a structured interface to application data. A provider can be used for accessing data within one application, but can also be used to share data with other applications.

Android contains an SQLite database which is frequently used in conjunction with a content provider. The SQLite database would store the data, which would be accessed via the provider.

6.2. Defining the user interface with fragments, views and layout managers

Fragments are components which run in the context of an activity. A fragment encapsulates application code so that it is easier to reuse them and to support devices of different size.

The following picture shows an activity called MainActivity. On a smaller screen it shows only one fragment and allows the user to navigate to another fragment. On a wide screen it shows those two fragments immediately.

Shows only one Fragment at a time
Two Fragments side by side

Views are user interface widgets, e.g., buttons or text fields. Views have attributes which can be used to configure their appearance and behavior.

A ViewGroup is responsible for arranging other views. It is also known as layout manager.

The base class for these layout managers is the android.view.ViewGroup class which extends the android.view.View class which is the base class for views.

Layout managers can be nested to create complex layouts.

6.3. Home screen widgets

Home screen widgets are broadcast receivers which provide interactive components which are primarily used on the Android home screen. They typically display some kind of data and allow the user to perform actions with them. For example, a widget can display a short summary of new emails and if the user selects an email, it could start the email application with the selected email.

To avoid confusion with views (which are also called widgets), this text uses the term home screen widgets, if it speaks about widgets.

Live wallpapers allow you to create animated backgrounds for the Android home screen.

6.4. Context

Instances of the class android.content.Context provide the connection to the Android system and device the application is running on. It gives access to the system and application resources and services

For example, you can check the size of the current device display via the Context.

Activities and services extend the Context class. Therefore, they can be directly used to access the Context.

7. The Android manifest

7.1. Configuration of your Android application

The components, settings and metadata of an Android application are described in the AndroidManifest.xml file. This file is known as the manifest file or the manifest.

All activities, services and content provider components of the application must be statically declared in this file. Broadcast receiver can be defined statically in the manifest file or dynamically at runtime in the application. This file is read by the Android system during installation of the application. The Android system evaluates this configuration file and determines the capabilities of the application.

The Gradle build system for building and packaging Android application can modify the manifest file. For example, the application version is typically supplied by the Gradle build file.

7.2. Android manifest example

The following listing shows an example for a simple Android manifest file.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.rssreader"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="19" />

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:name="RssApplication"
        android:allowBackup="false"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="RssfeedActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".DetailActivity"
            android:label="Details" >
        </activity>
        <activity android:name="MyPreferenceActivity" >
        </activity>

        <service android:name="RssDownloadService" >
        </service>
    </application>

</manifest>

7.3. Version and package

The package attribute defines the base package for the Java objects referred to in this file. If a Java object lies within a different package, it must be declared with the full qualified package name.

Google Play requires that every Android application uses its own unique package name. Therefore it is a good habit to use your reverse domain name here. This will avoid collisions with other Android applications.

android:versionName and android:versionCode specify the version of your application. versionName is what the user sees and can be any string.

versionCode must be an integer. The Android Market determines whether it should perform an update of the applications for the existing installation based on that versionCode. You typically start with "1" and increase this value by one if you roll-out a new version of your application.

7.4. Application and components

The <application> section allows to define metadata for your application and optionally define an explicit application class. It is also a container for declaring other Android components.

The <activity> tag defines an activity. The name attribute points to class, which (if not fully qualified) is relative to the package defined in the`package` attribute.

The intent filter part in the Android manifest file, tells the Android runtime that this activity should be registered as a possible entry point into the application and made available in the launcher of the Android system.

The action defines that it ( android:name="android.intent.action.MAIN" ` ) can be started. The `category android:name="android.intent.category.LAUNCHER" parameter tells the Android system to add the activity to the launcher.

The <@string/app_name> value refers to resource files which contain the actual value of the application name. The usage of a resource file makes it easy to provide different resources (e.g., strings, colors, icons) for different devices and makes it easy to translate applications.

Similar to the <activity> tag, you can use the service, receiver and provider to declare other Android components.

7.5. Minimum and target SDK

The uses-sdk section in the manifest allows you to specify the minSdkVersion and targetSdkVersion version of your application.

Table 4. Minimum and target version
Value Description

minSdkVersion

Define the minimum version of Android your application works on. This attribute is used as a filter in applications stores Play. A user cannot install your application on a device with a lower API level than specified in this attribute.

targetSdkVersion

Specifies the version on which you tested and developed. If it is not equal to the API version of the Android device, the Android system might apply forward- or backward-compatibility changes. It is good practice to always set this to the latest Android API version to take advantages of changes in the latest Android improvements.

7.6. Permissions

The Android manifest file must also contain the required permissions for the application. For example, if the application requires network access, it must be specified here.

Your application can declare permissions with the <permission> tag and declare that it required a permission with the <uses-permission> tag.

Certain permissions, like network access, are granted automatically on Android 6.0 or higher systems. Other permissions must be confirmed by the users to become active.

7.7. Required device configuration

The uses-configuration section in the manifest allows you to specify required input methods for your device. For example, the following snippet would require that the device has a hardware keyboard.

<uses-configuration android:reqHardKeyboard="true"/>

The uses-feature section allows you to specify the required hardware configuration for your device. For example, the following snippet would require that the device has a camera.

<uses-feature android:name="android.hardware.camera" />

7.8. Installation location

Via the installLocation attribute of your application you can specify if your application can be installed on the external storage of the device. Use auto or preferExternal to permit this.

In reality this option is rarely used, as an application installed on the external storage is stopped once the device is connected to a computer and mounted as USB storage.

7.9. More info

You find more information about the attributes and sections of the manifest see http://developer.android.com/guide/topics/manifest/manifest-intro.html.

8. Resources

8.1. Resource files

Android allows you to create static resources like images and XML configuration files. This allows you to keep these resources separate from the source code of your Android application.

Resource files must be placed in the /res directory of your application in a predefined sub-folder. The specific sub-folder depends on type of resource which is stored. You can also append additional qualifiers to the folder name to indicate that the related resources should be used for special configurations. This are called resource qualifiers . For example, you can specify that layout file is only valid for a certain screen size.

The following table gives an overview of the supported resources and their standard folder prefixes.

Table 5. Resources
Resource Folder Description

Drawables

/res/drawables

Images (e.g., png or jpeg files)or vector drawables or XML files which scale automatically with the density of the Android device

Simple Values

/res/values

Used to define strings, colors, dimensions, styles and static arrays of strings or integers via XML files. By convention each type is stored in a separate file, e.g., strings are defined in the res/values/strings.xml file.

Layouts

/res/layout

XML files with layout descriptions are used to define the user interface for activities and fragments.

Styles and themes

/res/values

Files which define the appearance of your Android application.

Animations

/res/animator

Defines animations in XML for the animation API which allows to animate arbitrary properties of objects over time.

Raw data

/res/raw

Arbitrary files saved in their raw form. You access them via an InputStream object.

Menus

/res/menu

Defines the actions which can be used in the toolbar of the application.

8.2. Example: Defining strings, string arrays, colors and dimensions

For example, the following values.xml file in the /res/values folder defines a few String constants, a String array, a color and a dimension.

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Test</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>

    <string-array name="operationsystems">
        <item>Ubuntu</item>
        <item>Android</item>
        <item>Microsoft Windows</item>
    </string-array>

    <color name="red">#ffff0000</color>

    <dimen name="mymargin">10dp</dimen>

</resources>

8.3. Resource files and R.java

Every relevant resource in the res folder, gets an ID assigned by the Android build system. Android generates gen a R.java file which contains the generated values. These references are static integer values.

If you add a new resource file, the corresponding reference is automatically created in a R.java file. Manual changes in the R.java file are not necessary and will be overwritten by the tooling. The Android system provides methods to access the corresponding resource files via these IDs.

For example, to access a String with the R.string.yourString ID in your source code, you would use the getString(R.string.yourString) method defined on the Context class.

8.4. Layout files

Android activities define their user interface with views (widgets) and fragments. This user interface can be defined via XML layout resource files in the <filename class="filename">/res/layout_ folder or via Java code. You can also mix both approaches.

Defining layouts via XML layout files is the preferred way. This separates the programming logic from the layout definition. It also allows the definition of different layouts for different devices.

A layout resource file is referred to as layout . A layout specifies the ViewGroups , Views , their relationship and their attributes via an XML representation.

The following code is an example for a simple layout file.

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/mytext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

A layout is assigned to an activity via the setContentView() method calls, as demonstrated in the following example code.

package com.vogella.android.first;

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

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

}

8.5. Performance considerations with layouts

Calculating the layout and drawing the views is a resource intensive operation. You should use the simplest layout possible to achieve good performance. For example, you should avoid nesting layout managers too deeply or avoid using complex layout managers in case a simple layout manager is sufficient.

8.6. Good practices for resources IDs

If a view needs to be accessed via Java or XML code, you have to give the view a unique ID via the android:id attribute. To assign a new ID to a view use the android:id attribute of the corresponding element in the layout file.

The Android SDK uses the camelCase notation for most of its IDs, e.g., buttonRefresh . It is good practice to follow this approach.

The following shows an example in which a button gets the button1 ID assigned via the android:id="@+id/button1" parameter. By conversion this statement creates a new ID if necessary in the R.java file and assigns the defined ID to the corresponding view.

<Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Show Preferences" >
</Button>

It is good practice to define IDs in one central configuration file. This is typically called ids.xml and placed in the /res/values folder. This allows you to use the predefined ID in your layout file. If you want to define the id in a separate file, you first need to remove the @+id entries in your layout files, otherwise you get an error messages that these files have already been created. The following listing shows an example for such a file.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="button1" type="id"/>
</resources>
<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"
    tools:context=".MainActivity" >

    <Button
        android:id="@id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_marginRight="27dp"
        android:text="Button" />

</RelativeLayout>

While the above is good practice for real projects, the tutorials of this $book avoid the usage of a separate id file as this setup is time consuming.

8.7. System resources

Android also provides resources. These are called system resources. System resources are distinguished from local resources by the android namespace prefix. For example, android.R.string.cancel defines the platform string for a cancel operation.

9. Android views - UI Widgets

A view in Android represents a widget, e.g., a button, or a layout manager. The Android SDK provides standard views (widgets), e.g., via the Button, TextView, EditText classes. It also includes complex widgets, for example, ListView .

All views in Android extend the android.view.View class. This class is relatively large (more than 18 000 lines of code) and provides a lot of base functionality for subclasses.

The main packages for views are part of the android.view namespace for all the base classes and android.widget for the default widgets of the Android platform.

10. Layout manager and ViewGroups

10.1. Using a layout manager

A layout manager is responsible for layouting itself and its child Views It is a subclass of ViewGroup.

Android supports different default layout managers.

The most relevant layout managers in Android are:

  • ConstraintLayout - provided by an extra library

  • LinearLayout

  • FrameLayout

  • RelativeLayout

  • GridLayout

10.2. Layout attributes

All layout manager can be configured via attributes. Children can also define attributes which may be evaluated by their parent layout.

Children can specify their desired width and height via the following attributes.

  • android:layout_width - Defines the width of the widget.

  • android:layout_height - Defines the height of the widget.

Views can define their size. This can be done in units of measurement or via pre-defined layout values. For example, as 100dp.

The match_parent value tells the application to maximize the widget in its parent. The wrap_content value tells the layout to allocate the minimum amount so that the widget is rendered correctly. The effect of these elements is demonstrated in the following graphics.

Layout with wrap_content
Layout with match_parent

10.3. Constraint layout

Constraint layout is provided by an external library. It allows you to use a flat view hierarchy and has great performance. Also the design tools support constraint layout very well. New projects should prefer the usage of constraint layout.

10.4. FrameLayout

FrameLayout is a layout manager which draws all child elements on top of each other. This allows to create nice visual effects.

The following screenshot shows the Gmail application which uses FrameLayout to display several button on top of another layout.

FrameLayout

10.5. LinearLayout

LinearLayout puts all its child elements into a single column or row depending on the android:orientation attribute. Possible values for this attribute are horizontal and vertical. horizontal is the default value.

If horizontal is used, the child elements are layouted as indicated by the following picture.

linearlayout20

Vertical would result in a layout as depicted in the following picture.

linearlayout10

LinearLayout can be nested to achieve more complex layouts.

LinearLayout supports assigning a weight to individual children via the android:layout_weight layout parameter. This value specifies how much of the extra space in the layout is allocated to the corresponding view. If, for example, you have two widgets and the first one defines a layout_weight of 1 and the second of 2, the first will get 1/3 of the available space and the other one 2/3. You can also set the layout_width to zero to always have a certain ratio.

10.6. RelativeLayout

RelativeLayout allows positioning the widget relative to each other. This can be used for complex layouts. RelativeLayout is a complex layout manager and should only be used if such a complex layout is required, as it performs a resource intensive calculation to layout its children.

A simple usage for RelativeLayout is if you want to center a single component. Just add one component to the RelativeLayout and set the android:layout_centerInParent attribute to true.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
         />

</RelativeLayout>

10.7. GridLayout

GridLayout was introduced with Android 4.0. This layout allows you to organize a view into a Grid. GridLayout separates its drawing area into: rows, columns, and cells.

You can specify how many columns you want to define for each View , in which row and column it should be placed as well as how many columns and rows it should use. If not specified, GridLayout uses defaults, e.g., one column, one row and the position of a view depends on the order of the declaration.

The following layout file defines a layout using GridLayout .

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/GridLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="4"
    android:useDefaultMargins="true" >

    <TextView
        android:layout_column="0"
        android:layout_columnSpan="3"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="40dp"
        android:layout_row="0"
        android:text="User Credentials"
        android:textSize="32dip" />

    <TextView
        android:layout_column="0"
        android:layout_gravity="right"
        android:layout_row="1"
        android:text="User Name: " >
    </TextView>

    <EditText
        android:id="@+id/input1"
        android:layout_column="1"
        android:layout_columnSpan="2"
        android:layout_row="1"
        android:ems="10" />

    <TextView
        android:layout_column="0"
        android:layout_gravity="right"
        android:layout_row="2"
        android:text="Password: " >
    </TextView>

    <EditText
        android:id="@+id/input2"
        android:layout_column="1"
        android:layout_columnSpan="2"
        android:layout_row="2"
        android:inputType="textPassword"
        android:ems="8" />

    <Button
        android:id="@+id/button1"
        android:layout_column="2"
        android:layout_row="3"
        android:text="Login" />

</GridLayout>

This creates a user interface similar to the following screenshot.

GridLayout Activity result

10.8. ScrollView

The ScrollView or the HorizontalScrollView class is not a layout manager. It is useful to make views available, even if they do not fit onto the screen. A scroll view can contain one view, e.g., a layout manager containing more views. If the child view is too large, scroll view allows scrolling the content.

Scroll view

The following code shows an example layout file which uses a ScrollView.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/TextView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingLeft="8dip"
        android:paddingRight="8dip"
        android:paddingTop="8dip"
        android:text="This is a header"
        android:textAppearance="?android:attr/textAppearanceLarge" >
    </TextView>

</ScrollView>

The android:fillViewport="true" attribute ensures that the scrollview is set to the full screen even if the elements are smaller than one screen.

11. Exercise: Influence view layout at runtime

11.1. Target of this exercise

In this exercise you add radio buttons the layout of the application you created in Exercise: Getting started with Android Studio. Depending on the user selection the radio button arrangement changes from horizontal to vertical.

11.2. Add radio group and radio buttons to your layout

Open your layout file and add a radio group with two radio buttons to your layout.

Assign them based on the following table.

Table 6. ID Assignment
ID View

orientation

Radio Group

horizontal

First radio button

vertical

Second radio button

The resulting layout file should be similar to the following listing. Note: Only the RadioGroup part is new.

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >


    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/main_input"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentEnd="true" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start"
        android:id="@+id/button"
        android:layout_below="@id/main_input"
        android:layout_alignParentStart="true"
        android:onClick="onClick"/>


    <RadioGroup
        android:id="@+id/orientation"
        android:layout_below="@id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp">

        <RadioButton
            android:id="@+id/horizontal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Horizontal" >
        </RadioButton>

        <RadioButton
            android:id="@+id/vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="Vertical" >
        </RadioButton>
    </RadioGroup>


</RelativeLayout>

The resulting layout should look like the following screenshot.

Show the layout

11.3. Change radio group orientation dynamically

Change the onCreate() method in your activity. Use the findViewById() method to find the RadioGroup in your layout.

Implement a listener on the radio group which changes the orientation of the radio buttons based on the current selection of the buttons. Which button is selected, can be identified by the ID parameter.

RadioGroup allows you to add a RadioGroup.OnCheckedChangeListener from the android.widget.RadioGroup package via the setOnCheckedChangeListener()` method. This listener is notified if the selection of the radio group changes.

You can use the following code as template to implement the listener.

final RadioGroup group1 = (RadioGroup) findViewById(R.id.orientation);
group1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                        case R.id.horizontal:
                                group.setOrientation(LinearLayout.HORIZONTAL);
                                break;
                        case R.id.vertical:
                                group.setOrientation(LinearLayout.VERTICAL);
                                break;
                }
        }
});

11.4. Validating

Run your application and select the different radio button. Ensure that the orientation of the buttons is changed based on your selection.

12. Using and accessing static resources

12.1. References to resources in code

The Resources class allows to access individual resources. An instance of the Resources class can be retrieved via the getResources() method of the Context class. As activities and services extend the Context class, you can directly use this method in implementations of these components.

An instance of the Resources class is also required by other Android framework classes. For example, the following code shows how to create a Bitmap file from a reference ID.

// BitmapFactory requires an instance of the Resource class
BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_search);

12.2. Accessing views from the layout in an activity

In your activity (and fragment) code you frequently need to access the views to access and modify their properties.

In an activity you can use the findViewById(id) method call to search for a view in the current layout. The id is the ID attribute of the view in the layout. The usage of this method is demonstrated by the following code.

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView textView = (TextView) findViewById(R.id.mytext);

    // TODO do something with the TextView
}

It is also possible to search in a view hierarchy with the findViewById(id) method, as demonstrated in the following code snippet.

// search in the layout of the activity
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.mylayout);

// afterwards search in linearLayout for another view
TextView textView = (TextView) linearLayout.findViewById(R.id.mytext);

// note, you could have directly searched for R.id.mytext, the above coding
// is just for demonstration purposes

You could also build a utility method which makes access to views easier.

package com.example.android.test;

import android.app.Activity;
import android.view.View;

public class UiUtils {
   public static <T extends View> T findView(View root, int id)      {
      return (T) root.findViewById(id); }

   public static <T extends View> T findView(Activity activity, int id)      {
      return (T) activity.getWindow().getDecorView().getRootView().findViewById(id); }
}

This would allow you to find the view without explicit cast in your view hierarchy.

Button button = UiUtils.findView(this, R.id.button);

12.3. Reference to resources in XML files

In your XML files, for example, your layout files, you can refer to other resources via the @ sign.

For example, if you want to refer to a color, which is defined in an XML resource, you can refer to it via @color/your_id. Or if you defined a String with the "titlepage" key in an XML resource, you could access it via @string/titlepage

To use an Android system resource, include the android namespace into the references, e.g., android.R.string.cancel.

12.4. Using assets?

The res directory contains structured values which predefined semantics for the Android platform. The assets directory can be used to store any kind of data. You can access files stored in this folder based on their path. The assets directory also allows you to have sub-folders.

You could also store unstructured data in the /res/raw folder. But it is considered good practice to use the assets directory for such data.

You access this data via the AssetsManager which you can access via the getAssets() method from an instance of the Context class.

The AssetsManager class allows you to read a file in the assets folder as InputStream with the open() method. The following code shows an example for this.

// get the AssetManager
AssetManager manager = getAssets();

// read the "logo.png" bitmap from the assets folder
InputStream open = null;
try {
        open = manager.open("logo.png");
        Bitmap bitmap = BitmapFactory.decodeStream(open);
        // assign the bitmap to an ImageView in this layout
        ImageView view = (ImageView) findViewById(R.id.imageView1);
        view.setImageBitmap(bitmap);
        } catch (IOException e) {
                e.printStackTrace();
        } finally {
                if (open != null) {
                        try {
                                open.close();
                        } catch (IOException e) {
                                e.printStackTrace();
                        }
                }
}

13. Exercise: Using resources in XML files and in code

13.1. Add images to your application

In this exercise you continue to use the existing application. Create two new images to your project called ic_tethering and ic_offline.

13.2. Add views to your project

Open your layout file and add a new Button and an ImageView to it. Assign the ic_offline file to your ImageView , via your layout file as demonstrated in the following XML snippet.

 <!--
        NOTE: More attributes are required
        for the correct layout of the ImageView. These are left
        out for brevity
    -->

<ImageView
  android:id="@+id/myicon"
  .... more attributes
  android:src="@drawable/ic_offline" />

13.3. Replace images via button click

If the button is clicked, use the findViewById() to search for the ImageView. Use its setImageResource() method to assign the png file (which is represented at runtime via a Drawable object) to your ImageView . The parameter of the setImageResource() method is the R reference to your file, e.g., R.drawable.your_png_file .

13.4. Validating

Ensure that if you press your new button, the displayed image is replaced.

14. Exercise: Using ScrollView

This exercise demonstrates the usage of the ScrollView view to provide a scrollable user interface component. Create an android project de.vogella.android.scrollview with an activity called ScrollViewActivity.

Use activity_main.xml as layout file.

Change the layout file used in the activity to the following.

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true"
    android:orientation="vertical" >

    <LinearLayout
        android:id="@+id/LinearLayout01"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/TextView01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="8dip"
            android:paddingRight="8dip"
            android:paddingTop="8dip"
            android:text="This is a header"
            android:textAppearance="?android:attr/textAppearanceLarge" >
        </TextView>

        <TextView
            android:id="@+id/TextView02"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:text="@+id/TextView02" >
        </TextView>

        <LinearLayout
            android:id="@+id/LinearLayout02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >

            <Button
                android:id="@+id/Button01"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:text="Submit" >
            </Button>

            <Button
                android:id="@+id/Button02"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:text="Cancel" >
            </Button>
        </LinearLayout>
    </LinearLayout>

</ScrollView>

Change your ScrollViewActivity class to the following code.

package de.vogella.android.scrollview;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class ScrollViewActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView view =        (TextView) findViewById(R.id.TextView02);
        String s="";
        for (int i=0; i < 500; i++) {
                s += "vogella.com ";
        }
        view.setText(s);
    }
}

Start your application and ensure that you can scroll down to the buttons.

Showing the running application with the ScrollView in action

15. Exercise: Create a temperature converter

15.1. Target of this exercise

In this exercise you learn how to create and consume Android resources.

This application is available on Google Play under the following URL: http://play.google.com/store/apps/details?id=de.vogella.android.temperature

You can also scan the following barcode with your Android phone to install it via the Google Play application.

QR Code to install the Android Temperature converter

15.2. Create Project

Create a new Android project with the following data.

Table 7. New Android project
Property Value

Application Name

Temperature Converter

Package name

com.vogella.android.temperatureconverter

API (Minimum, Target, Compile with)

Latest

Template

Empty Activity

Activity

MainActivity

Layout

activity_main

15.3. Create attributes

Select the res/values/strings.xml file to open the editor for this file. Add the Color and String definitions to the file as described by the following table.

Table 8. New attributes to add

Type

Name

Value

Color

myColor

#F5F5F5

String

celsius

to Celsius

String

fahrenheit

to Fahrenheit

String

calc

Calculate

The entered values should be similar to the following listing.

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Temperature Converter</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <color name="myColor">#F5F5F5</color>
    <string name="celsius">to Celsius</string>
    <string name="fahrenheit">to Fahrenheit</string>
    <string name="calc">Calculate</string>

</resources>

15.4. Creating the layout

Select the res/layout/activity_main.xml file and open the associated Android editor via a double-click on the file.

Remove any existing view from your layout, either directly from the XML source or via the graphical editor.

Afterwards add an LinearLayout, another LinearLayout with one ViewText, EditText as children. Afterwards add a RadioGroup with two radio buttons and a Button to your layout. Do this either directly in the XML file or via the graphical editor. A simple way of organizing the components is to drag and drop them onto the Component Tree view.

The result should look like the following screenshots. The first one shows the component view the second one the preview.

Component view
Current layout of activity_main.xml

Switch to the XML tab of your layout file and verify that the file looks similar to the following listing.

The Android tools team changes the generated code from time to time, so your XML might look slightly different.

<LinearLayout 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"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:background="@color/myColor">


    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editText1" />

    <RadioGroup
        android:id="@+id/radioGroup1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@+id/editText1"
        android:layout_below="@+id/editText1">

        <RadioButton
            android:id="@+id/radio0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="RadioButton" />

        <RadioButton
            android:id="@+id/radio1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="RadioButton" />
    </RadioGroup>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@+id/radioGroup1"
        android:layout_below="@+id/radioGroup1"
        android:layout_marginTop="22dp"
        android:text="Button" />

</LinearLayout>

You see some warning messages. You fix these in the following section of this exercise.

15.5. Edit view properties

Switch to the XML representation of the file and assign the @string/celsius value to the android:text property of the first radio button. Assign the fahrenheit string attribute to the text property of the second radio button.

Change the text property of the radio button

Ensure that the Checked property is set to true for the first RadioButton.

Assign @string/calc to the text property of your button and assign the value onClick to the OnClick property.

Set the inputType property to numberSigned and numberDecimal on the EditText . As an example you can use the last line in the following XML snippet. Also change its ID to "inputValue".

<EditText
  android:id="@+id/inputValue"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_alignParentEnd="true"
  android:layout_below="@+id/textView"
  android:ems="10"
  android:inputType="numberSigned|numberDecimal" />

All your user interface components are contained in a layout. Assign the background color to this Layout.

Select Color and then select myColor in the dialog. As an example, you can use the last line in the following XML snippet.

<LinearLayout 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"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:background="@color/myColor">

Afterwards the background should change to the whitesmoke color. It might be difficult to see the difference.

Switch to the activity_main.xml tab and verify that the XML is correct.

<LinearLayout 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"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:background="@color/myColor">


    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/inputValue"
        android:inputType="numberSigned|numberDecimal"/>

    <RadioGroup
        android:id="@+id/radioGroup1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@+id/editText1"
        android:layout_below="@+id/editText1">

        <RadioButton
            android:id="@+id/radio0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="@string/celsius" />

        <RadioButton
            android:id="@+id/radio1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/fahrenheit" />
    </RadioGroup>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@+id/radioGroup1"
        android:layout_below="@+id/radioGroup1"
        android:layout_marginTop="22dp"
        android:text="@string/calc"
        android:onClick="onClick"/>

</LinearLayout>

15.6. Create utiliy class

Create the following utility class to convert from celsius to fahrenheit and vice versa.

package com.vogella.android.temperatureconverter;

public class ConverterUtil {
        // converts to celsius
        public static float convertFahrenheitToCelsius(float fahrenheit) {
                return ((fahrenheit - 32) * 5 / 9);
        }

        // converts to fahrenheit
        public static float convertCelsiusToFahrenheit(float celsius) {
                return ((celsius * 9) / 5) + 32;
        }
}

15.7. Change the activity code

Change the MainActivity to the following

package com.vogella.android.temperatureconverter;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.Toast;

public class MainActivity extends Activity {
  private EditText text;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    text = (EditText) findViewById(R.id.inputValue);

  }

  // this method is called at button click because we assigned the name to the
  // "OnClick" property of the button
  public void onClick(View view) {
    switch (view.getId()) {
    case R.id.button1:
      RadioButton celsiusButton = (RadioButton) findViewById(R.id.radio0);
      RadioButton fahrenheitButton = (RadioButton) findViewById(R.id.radio1);
      if (text.getText().length() == 0) {
        Toast.makeText(this, "Please enter a valid number",
            Toast.LENGTH_LONG).show();
        return;
      }

      float inputValue = Float.parseFloat(text.getText().toString());
      if (celsiusButton.isChecked()) {
        text.setText(String
            .valueOf(ConverterUtil.convertFahrenheitToCelsius(inputValue)));
        celsiusButton.setChecked(false);
        fahrenheitButton.setChecked(true);
      } else {
        text.setText(String
            .valueOf(ConverterUtil.convertCelsiusToFahrenheit(inputValue)));
        fahrenheitButton.setChecked(false);
        celsiusButton.setChecked(true);
      }
      break;
    }
  }

}

15.8. Start the application

Start your Android application and type in a number, select your conversion and press the button. The result should be displayed and the other option should get selected.

Change the text property of the radio button

16. Deployment

16.1. How to deploy

In general there are restrictions how to deploy an Android application to your device. You can deploy the application via USB in test mode onto your device , email yourself the application or use one of the many Android markets to install the application. The following description highlights the most common ones.

16.2. Defining software and hardware requirements for the application

The application can define via a <uses-feature> declaration in the manifest file define which hardware of software features is requires. Via the android:required property the application can define if such a feature is required for the application to work correctly (true) or if application prefers to use the feature if present on the device, but that it is designed to function without the specified feature, if necessary.

Examples for such definitions are the presence of a certain hardware sensor or the availability of a camera.

For an overview of the available restrictions see http://developer.android.com/guide/topics/manifest/uses-feature-element.html.

16.3. Signing your application for the release

Android applications must be signed before they can get installed on an Android device. During development the build process signs the application automatically with a debug key.

To install the Android application via another channel you need to sign the Android apk with a self-created signature key.

Please note that you need to use the same signature key in Google Play (Google Market) to update your application. If you lose the key, you will NOT be able to update your application ever again.

Make sure to backup your key.

16.4. Export your application via Android Studio

Use the Build ▸ Generate Signed APK…​ menu entry to start the export from Android Studio.

16.5. Export your application via the Eclipse IDE

If you want to export your production application via the Eclipse IDE, you can right-click on it and select Android Tools ▸ Export Signed Application Package.

This wizard allows to use an existing key or to create a new one.

16.6. Via external sources

Android also allows to install applications directly. Just click on a link which points to an .apk file, e.g., in an email attachment or on a webpage. Android will prompt you if you want to install this application.

This requires a setting on the Android device which allows the installation of non-market application. Typically this setting can be found under the "Security" settings.

16.7. Google Play (Market)

Google Play requires a one time fee, currently 25 Dollar. After that the developer can directly upload his application and the required icons, under Google Play Publishing .

Google performs some automatic scanning of applications, but no approval process is in place. All application, which do not contain malware, will be published. Usually a few minutes after upload, the application is available.

17. About this website

18. Android online resources

18.1. Android core resources

http://developer.android.com - Android Developer Homepage

http://www.vogella.com/android.html - vogella Android online tutorials

https://github.com/googlesamples/android-RuntimePermissions - Code example for demonstrating runtime permissions

https://possiblemobile.com/2013/06/context/ Overview of the Eclipse contenxt

18.2. Android learning resources

http://androidbackstage.blogspot.de/ - Podcast from the Google developers about Android

http://fragmentedpodcast.com/ - Fragmented - An Android Developer Podcast

18.3. Android tools

http://tools.android.com/recent - Recent changes in the Android tooling

https://github.com/skylot/jadx - Command line and GUI tools for produce Java source code from Android Dex and Apk files

18.4. vogella GmbH training and consulting support

TRAINING SERVICE & SUPPORT

The vogella company provides comprehensive training and education services from experts in the areas of Eclipse RCP, Android, Git, Java, Gradle and Spring. We offer both public and inhouse training. Whichever course you decide to take, you are guaranteed to experience what many before you refer to as “The best IT class I have ever attended”.

The vogella company offers expert consulting services, development support and coaching. Our customers range from Fortune 100 corporations to individual developers.

Copyright © 2012-2016 vogella GmbH. Free use of the software examples is granted under the terms of the EPL License. This tutorial is published under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany license.

See Licence.