android

Tutorial – Developing your first Android app

This week I ran a training course to show the development team how to create an app in Android, how to create an AVD etc. It covered areas such as layouts, code structure, creating an Activity, calling one activity from another. It was to an audience containing some non Java developers and some with no development experience at all so it is very light on code and focussed only on creating a very simple calculator. Along with it were some slides produced in a very cool presentation tool called emaze. My slides can be found here, please use and share if you want. If you do all I ask is you let me know so I can see that people are benefiting from them.

You can find a word document of the tutorial available here: Creating a simple calculator.

The code for this session was based on this blog post.

Creating a simple calculator

System Requirements

• Intel Core i5 or better if you want to run the emulator. Core 2 Duos are fine at running Android Studio though.
• JDK 1.7 or higher
• Android Studio (This tutorial was based on version 0.8.6)
• Android SDK 4.4.2 (Although we aren’t using any of the specific 4.4.2 functionality)

Practical 1 – Create a new project
1. In Android Studio click File>New Project
Practical2-Step1a
2. Set Application Name to “Simple Calculator”. This will be the name displayed under the icon when installed on the device.
3. Set Company Domain to “example.com”. This will then become the package structure that the source code is stored under.
4. Keep the default project path and click Next.
Practical2-Step2
5. Notice that Android Studio helps with the SDK version to pick based on the percentage of devices running that version. Enabling the developer to support as many devices as possible if this is the priority.

Note from Google: The minimum SDK version determines the lowest level of Android device the app will run on.
You typically want to target as many users as possible, so you ideally want to support everyone. However, it has some disadvantages around new features that are available in the new versions.

6. There are other options available that won’t be covered around wearables, project glass and TV based applications.
7. Select the minimum SDK that you’ll application will support (4.0). Click Next.
Practical2-Step3
8. There are a number of options on this screen enabling you to create your first activity tailored to what you want to do. However, it doesn’t tie you to only be able to do that single thing in the activity. For example, there is a navigation drawer and a Google Maps activity. These can be merged together after choosing one of these from the wizard. They are just a starting point.
9. Select Blank Activity and click Next.
Practical2-Step4
10. Change the Activity Name to CalculatorActivity just to make this activity name suit what we are going to be doing with it.
11. You can change the title to something like Simple Calculator. This will be displayed at the top of the activity.
12. Click Finish.
Practical2-NewProjectCompleted
13. You’ll now have a basic application that you can run.
14. If you have a device connected to your machine, you can run it by clicking on the Debug App toolbar icon (One that looks like an insect) and select your device, otherwise you will need to go through practical 2 first to create an emulator before you can run it. (There is another way of launching the AVD Manager when running the application but I’ll go with the instructions below for now)

Practical 2 – Creating your Android Virtual Device

An Android Virtual Device or AVD is essentially Android running on an Emulator on your desktop. It does have its limitations in that it’s not mobile, doesn’t have a SIM card, access to a GPS, Accelerometers, and other sensors. However, for some apps it is perfectly fine to use. That said you can mock locations and get the emulator to use your laptops camera for its camera but nothing beats just developing on a real device. Since we don’t have that many real devices kicking around we’ll be using the emulator.

Quick note: Connecting and debugging apps on a real device is pretty much just plugging in the device via USB. The only additional step you may need to do is to enable the developer menu in the settings.

1. Start Android Studio.
2. Click on the AVD Manager toolbar button at the top near the right.
3. Click on the Device Definitions tab.
Practical1-AVD
4. Select Nexus 4 from the list and click Create AVD.
Practical1-CreateAVD
5. Give you AVD a name or keep the existing name.
6. Set Target to “Select API Level 17”
7. CPU “Intel Atom” or “ARM” (Doesn’t really matter for this tutorial)
8. Set Skin to “No Skin”
9. Tick Use Host GPU in Emulator Options.
10. Click OK
11. You should now see it in your list in the Android Virtual Devices tab.
12. Select it and click the Start button & you should now have a working Nexus 4 emulator! (Might take a while though depending on your hardware)

Practical 3 – Adding controls to the layout

In this session you will be creating a new layout (the view that is displayed in the calculator activity). We’ll be adding a couple of EditText controls, 4 buttons and a TextView.

We could do this in a couple of ways using either LinearLayout or RelativeLayout, for now we’ll go with LinearLayout.

1. Find your Activities layout file, it should be called activity_calculator.xml which will be located in app->src->main->res->layout. Double click on it to open it.
2. You have two ways of editing the layouts, using either the GUI builder or XML. Sometimes the GUI builder throws errors so for this tutorial we’ll use XML I’m afraid.
3. Click on the Text tab at the bottom of the preview window for the layout to view the XML.
4. Select all of the text and replace it with

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

</LinearLayout>

5. This provides the initial layout structure for the whole screen. The android:orientation=”vertical” tells the system that the controls will be laid out on beneath the previous one, i.e. in rows. If you want the controls in columns then change the value to horizontal.
6. The next step is to add two text fields that will take the two numbers that the calculator will operate on. To add these we need to insert an additional linear layout. For clarity I have included android:orientation=”horizontal” that adds the included controls in columns. This isn’t necessary by default because if there is no orientation it is horizontal.
7. The mark up below should be inserted as the content of the LinearLayout markup added above. To ensure you’ve done it right your file should end with two closing tags </LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/linearLayout1"
android:orientation="horizontal"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginTop="3dp">
<EditText
android:id="@+id/etNumber1"
android:layout_weight="1"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_width="match_parent"
android:inputType="numberDecimal">
</EditText>
<EditText
android:id="@+id/etNumber2"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:layout_width="match_parent"
android:inputType="numberDecimal">
</EditText>
</LinearLayout>

The other fields of interest are android:id which is just a unique id that allows the Java code to get hold of the control to get, set values and manipulate the control.
android:inputType allows the developer to restrict the values that are entered or displayed. There are about 30 different options available from phone numbers, email addresses passwords etc.



Pixels and Screen issues Other attributes like heights, widths etc. use sizes that have different dimensions available shown below. The two important dimensions are dp (density independent pixels) and sp (scale independent pixels). The dp allows the developer to specify sizes as if they were pixels, however, it handles issues around screen densities so the developer doesn’t have to be as concerned around handling differently a cheap screen with a low pixel density and a better device with a higher pixel density. (Like Non-retina and retina to you Apple folk out there ) DP – Abstract unit based on the physical density of the screen. SP – Like DP but the font is resized also based on the users font size preference. PT – 1/72 inch of the physical screen size. PX – Based on the actual pixels on the screen (This isn’t a recommended) IN – Size in inches based on the physical screen size of the device. MM - Size in mm based on the physical screen size of the device.
8. With these controls added you should see in the preview two text fields side by side. (You can run this in the emulator if you want but all you’ll see is an app with two text fields that you can enter only decimals into or if running on a real device will bring the numeric keyboard up when you tap on the control) 9. Next we want to add the buttons to perform the operations on the two numbers. This should go below the XML you pasted in the previous step. This will create a new row of controls below the text fields and are laid out in columns. <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/linearLayout2" android:orientation="horizontal" android:layout_marginTop="3dp" android:layout_marginLeft="5dp" android:layout_marginRight="5dp"> <Button android:id="@+id/btnAdd" android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_weight="1" android:text="+" android:textSize="8sp"> </Button> <Button android:id="@+id/btnSubtract" android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_weight="1" android:text="-" android:textSize="8sp"> </Button> <Button android:id="@+id/btnMultiply" android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_weight="1" android:text="*" android:textSize="8sp"> </Button> <Button android:id="@+id/btnDivide" android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_weight="1" android:text="/" android:textSize="8sp"> </Button> </LinearLayout> 10. The code above introduces a new control (Button) with the android:text tag containing the text displayed in the button. There is also a tag android:layout_weight which is uses to determine how much space it should consume in the layout compared to it’s siblings. In this case they are all 1 so they are evenly spaced. 11. The final bit to add is a TextView control to display the answer in. Add this in between the two </LinearLayout> tags at the end of the file. <TextView android:id="@+id/tvResult" android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:textSize="12sp" android:layout_marginTop="3dp" android:gravity="center_horizontal"> </TextView>

12. Some points of interest for this control are android:width and android:gravity. The width attribute is in this case is set to match_parent which means that it’s width will be the same size as the parent container. In this situation it will be the width of the screen (minus any padding).
The android:gravity attribute specifies where the control should sit in it’s container, e.g. left, right, center-horizontal, center-vertical, top, bottom etc.
13. Running the app now in your simulator you should see the following:
Practical2-RunningSimulator

Practical 4 – Adding the code to support the front end
So we’ve build the UI for our calculator activity the next step is to add some code to the Java Activity that will get hold of the controls, setup listeners for events fired by the buttons and perform the required operation to then present the result back to the user.

1. First let’s find your Activity file, double click on your Java file called CalculatorActivity. This can be found in app->src->main->java->com.example.simplecalculator.
2. We will now add member variables to the class that are Java representations of the controls that you have added in the layout file in the previous practical. At the top of the file on a new line after extends Activity {

private EditText etNumber1;
private EditText etNumber2;

private Button btnAdd;
private Button btnSubtract;
private Button btnMultply;
private Button btnDivide;

private TextView tvResult;

3. When you copy this text into the class the IDE will (hopefully) prompt you to import the classes into the file. All this is, is just a declaration to say that you want to use another class in this class. To import the class when it highlights the issue you’ll need to click on the red underlined name and click on the red lightbulb and select import class or use Alt-Enter (Option-Enter on Macs). (You can configure the IDE to auto-import which helps speed up development).

4. Next we will add code to the onCreate method. This is the method that is called by Android whenever the activity is first created. We will use it to initialise the controls specified above using the findViewById method.

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_calculator);

  // Find the elements and assign them to the member variables
  etNumber1 = (EditText) findViewById(R.id.etNumber1);
  etNumber2 = (EditText) findViewById(R.id.etNumber2);

  btnAdd = (Button) findViewById(R.id.btnAdd);
  btnSubtract = (Button) findViewById(R.id.btnSubtract);
  btnMultply = (Button) findViewById(R.id.btnMultiply);
  btnDivide = (Button) findViewById(R.id.btnDivide);

  tvResult = (TextView) findViewById(R.id.tvResult);

  // Configure this class to be the listener for all the buttons
  btnAdd.setOnClickListener(this);
  btnSubtract.setOnClickListener(this);
  btnMultply.setOnClickListener(this);
  btnDivide.setOnClickListener(this);
}

The setContentView is used to connect this activity with the layout file that you updated earlier. The R class is a special auto-generated class that contains constants of resources in the application, from images, layouts to strings and custom dimensions.
For each control we setup we need to make sure that we cast the object returned by findViewById to the correct type.
The final lines are to set the onclick event listener for the buttons to be this class. This will highlight an error in the editor, to fix this complete the next step.

5. Near the top of the file after the words extends Activity copy implements View.OnClickListener
6. This will result in another error/warning because a new method needs to be added that implements the OnClickListener interface.
Practical4-ImplementMethod
7. Click on the red underlined text and you should get a red light bulb, click on that and select Implement Methods. Click OK in the dialog that then pops up.
8. Now we need to fill in the behaviour for the onClick handler. Copy the code below into the public void onClick(View v) method.

String operation = "";
float number1;
float number2;
float result = 0;

// check if the fields are empty
if (TextUtils.isEmpty(etNumber1.getText().toString())
  || TextUtils.isEmpty(etNumber2.getText().toString())) {
  return;
}

// read EditText and fill variables with numbers
number1 = Float.parseFloat(etNumber1.getText().toString());
number2 = Float.parseFloat(etNumber2.getText().toString());

// defines the button that has been clicked and performs the corresponding operation
// write operation into operation, we will use it later for output
switch (v.getId()) {
  case R.id.btnAdd:
    operation = "+";
    result = number1 + number2;
  break;
  case R.id.btnSubtract:
    operation = "-";
    result = number1 - number2;
    break;
  case R.id.btnMultiply:
    operation = "*";
    result = number1 * number2;
    break;
  case R.id.btnDivide:
    operation = "/";
    result = number1 / number2;
    break;
  default:
    break;
}

// form the output line
tvResult.setText(number1 + " " + operation + " " + number2 + " = " + result);

9. You’ll need to import TextView by clicking on the red underlined name and click on the red lightbulb and select import class or use Alt-Enter (Option-Enter on Macs)
10. You should now be ready to run the code and have a play. Click on the play button or the bug button to debug. Practical4-Play-Debug

Practical 5 – Add Permission and show a video

In this practical we will take the existing app that we have produced and tag on a random feature but it is really just to show the ease in which a video could be displayed using an existing Intent in the system.

1. First we need to open AndroidManifest.xml and add the new permission to use the Internet.
Copy
<uses-permission android:name=”android.permission.INTERNET” />
and paste it in the bottom of the AndroidManifest.xml file just before the </manifest> tag.
2. Right Click on java in the project structure panel and select New->Activity->Blank Activity
3. Change the Activity Name to “Video Activity”
4. Update it’s hierarchical parent activity to be the CalculatorActivity. This will ensure that if using the back button or the navigation menu functionality that it knows where the activity needs to go back to.
5. Next we need to add a new button to the new layout file. Find your activity_video.xml file in app->src->main->res->layout.
6. Add the following code to the layout before the </RelativeLayout> tag.

<Button
android:id="@+id/btnVideo"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Launch Video"
android:textSize="12sp"
android:onClick="launchVideo">
</Button>

7. Note this time we have specified the attribute android:onClick the value is “launchVideo” this is the name of the method in the Java Activity that needs to be created that will handle the onClick event.
8. You should now see the preview of the button on the right hand side of the IDE.
9. Find and open your VideoActivity.java file and add the following new method:

public void launchVideo(View view) {
Toast.makeText(this, "Launch Video", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("http://techslides.com/demos/sample-videos/small.mp4"), "video/mp4");
startActivity(intent);
}

10. There are a couple of things worth talking about here: The Toast method call is what is used in Android for on screen notifications. All you need to do to add a notification is provide the context in the first paramter which is the current activity, the text you want to display and how long you want to display it for.
The rest of the code is there to launch an Activity available in the system that is capable of displaying the data provided. This code will end up launching a video player on the device to play the video from this site. (The success of this demo is entirely based on our Internet connection speed!)
You can have multiple apps on your device that support these Intents and that is why on Android if you request a particular Intent Android sometimes prompts the user asking which app they want to use to handle it.
11. The part that we are still missing is to connect the CalculatorActivity to the VideoActivity. We will do this by hijacking the existing Settings menu. (Rather than do this properly as I think we’ll be short on time we will just rename the text for now but keep the settings ID)
12. Open strings.xml in app->src->main->res->values. This is where internationalise text is kept (Could have a whole lesson on this but for now I’ll just say this is the default language and to create other translations we need to create new string.xml files with the locale appended)
13. Find the word Settings and replace it with Video. This will replace the text that is defined in the menu file calculator.xml so when the menu button is pressed we should see the menu item “Video”
14. Now go to CalculatorActivity.java so that we can launch our new activity from the selected menu item. Find the method onOptionsItemSelected and in the if block where id == R.id.action_settings add the following code:

Intent video = new Intent(this, VideoActivity.class);
startActivity(video);

15. You are now ready to start your app. Click on the play or debug button.
Practical5-Menu
16. When it is started you can click on the menu button (on a phone it could be hardware or 3 dots on the screen) and select Video. This will launch the new activity and you should see the button “Launch Video”.
Practical5-LaunchVideo Screen
17. Note that the action bar at the top of the application has changed slightly and there is an < arrow allowing you to go back. Because you selected the parent hierarchy earlier this functionality comes for free, you can tap this or the back button to go back to the calculator activity, if you want.

18. When you do tap on the Launch Video button you should see eventually the video player display and play the video click that is streaming from the Internet.

Google MapView not appearing in my app when using a debug build from two different sources

Today I got to the bottom of an issue that I’d semi been looking into for a week or so. I am doing some development using Google Map v2 and I noticed that it was working fine when I ran the debug build direct from Android Studio, the map displayed perfectly. However, when I deployed the debug apk created from either Jenkins or another development machine the maps didn’t appear at all. I had the Google logo in the bottom left corner and that was it.

It felt like a map api key issue but I couldn’t quite work out what. It was only when I noticed that I was getting a warning when deploying the app from another development machine saying “re-installation failed due to different application signature” that I put two and two together.

The issue was my original machine had the debug.keystore file in .android however, on the other machine the debug.keystore would be different. So the fix was to take my debug.keystore and put it into source control along with my release.keystore file and update the app gradle build config to use the one from source control with the following configuration.

signingConfigs {
  debug {
    storeFile file(“keystore/debug.keystore”)
  }

release {
    storeFile file(“keystore/release-key.keystore”)
    storePassword “*********”
    keyAlias “my_alias_name”
    keyPassword “******”
  }
}

Adding Jenkins build number into your Android application

Today I was trying to get the Jenkins build number into my Android app for display, however, I couldn’t find any tutorials on how to do this. I have pieced together a few things and put them together below.

Getting the Jenkins build number into Gradle build system

So, Android uses two fields for versioning, these appear in the app’s build.gradle file.

versionCode – The unique version that android uses to distinguish between versions of an app.

versionName – This is more of a human readable and flexible build number that is what I’d like to display. By default this is hard coded to “1.0” and I’d like to make it “1.0.” + JENKINS_BUILD_NUMBER.

Jenkins exposes the current build number as a system environment variable so we need to access this in the build script using the following code. Put this in the defaultConfig section for now (I’m sure there might be a better place but this works for me):

ext.buildNumber = System.getenv("BUILD_NUMBER") ?: "dev"

This code above sets the buildNumber variable to the jenkins build number if it is not null, otherwise it sets it to “dev”. I did this so that we can distinguish between development builds and continuous integration builds.

I then updated versionNumber with the following code:

versionName "0.1.$buildNumber"

This now makes the Jenkins build number and our application version accessible to our application.

Getting the version name from the build system into my app
If you are using the Gradle build system there is an addition class available to your application that allows you to get the configured version number.

Add BuildConfig.VERSION_NAME to where ever you need to retrieve the current version name from. For example, I have a TextView in the settings screen of my application and I set the version name with the code below.


final TextView versionName = (TextView) findViewById(R.id.versionNameText);
versionName.setText(BuildConfig.VERSION_NAME);

That’s it.

Installing Gradle on Ubuntu 14

Today I tried to install gradle using apt-get and it failed with the message

Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies.
gradle : Depends: libgradle-plugins-java (= 1.4-2ubuntu1) but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

Being a bit of a novice I had no idea how to resolve this. I tried sudo apt-get install libgradle-plugins-java but that couldn’t be resolved either.

After a bit of digging I needed to do the following to add a repository to apt-get so it could get all the dependencies.

sudo add-apt-repository ppa:cwchien/gradle
sudo apt-get update
sudo apt-get install gradle