Please note that the contents of this offline web site may be out of date. To access the most recent documentation visit the online version .
Note that links that point to online resources are green in color and will open in a new window.
We would love it if you could give us feedback about this material by filling this form (You have to be online to fill it)



Creating a Simple Android App

The sample backend API we are using stores two Greetings. So, for our simple app, we'll create a UI that lets you do the following interactions with that backend data in this order:

  • Sign into your Google account.
  • Specify which of the two greetings to display.
  • List all of the greetings.
  • Supply your own custom greeting and an integer count with the backend returning that greeting multiplied count times.
  • Get a greeting personalized with your account email.

The complete UI will look something like this:

the_UI

Add the UI

To add the UI to support interactions with the backend API:

  1. Open the Hello World project file src/main/res/layout/activity_main.xml in Android Studio, and replace all of the contents with the following layout and views:

    <ScrollView 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">
    
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin"
        tools:context=".MainActivity">
    
     <LinearLayout android:orientation="horizontal"
                   android:layout_height="wrap_content"
                   android:layout_width="fill_parent">
     <TextView
              android:id="@+id/email_address_tv"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:layout_weight="1"
              android:text="Not signed in" />
    
     <Button android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:id="@+id/sign_in_button"
             android:text="Sign in"
             android:onClick="onClickSignIn"/>
     </LinearLayout>
    
        <View
            android:layout_width="match_parent"
            android:layout_height="5dip"
            android:background="#000000"/>
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Get Greeting" />
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <EditText
                android:id="@+id/greeting_id_edit_text"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="right"
                android:inputType="number"
                android:hint="Greeting ID to GET"/>
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:text="GET Greeting"
                android:onClick="onClickGetGreeting" />
        </LinearLayout>
        <View
            android:layout_width="match_parent"
            android:layout_height="5dip"
            android:background="#000000"/>
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Multiply Greetings" />
    
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
          <EditText
              android:id="@+id/greeting_text_edit_text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="right"
              android:gravity="right"
              android:inputType="textAutoCorrect"
              android:hint="Greeting to send"/>
          <EditText
              android:id="@+id/greeting_count_edit_text"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="right"
              android:gravity="right"
              android:inputType="number"
              android:hint="Greeting count to send"/>
          <Button
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="right"
              android:onClick="onClickSendGreetings"
              android:text="Send Greetings"/>
        </LinearLayout>
        <View
            android:layout_width="match_parent"
            android:layout_height="5dip"
            android:background="#000000"/>
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Authenticated Greeting" />
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:text="Get Authenticated Greeting"
            android:onClick="onClickGetAuthenticatedGreeting"/>
        <View
            android:layout_width="match_parent"
            android:layout_height="30sp" />
    
        <ListView
            android:id="@+id/greetings_list_view"
            android:layout_height="500sp"
            android:layout_width="fill_parent"
            android:layout_marginLeft="30sp"
            android:layout_marginRight="30sp"
            android:scrollbarAlwaysDrawVerticalTrack="true"
            tools:listitem="@android:layout/simple_list_item_1"
            android:text="No Messages retrieved yet"/>
    
    </LinearLayout>
    </ScrollView>
    

Modify main.xml

Locate the file src/main/res/menu/main.xml and replace the contents with the following:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/action_settings"
        android:title="@string/action_settings"
        android:orderInCategory="100"
        android:showAsAction="never" />
</menu>

Modify styles.xml

Locate the file src/main/res/values/styles.xml and replace all of the contents with the following:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

</resources>

Modify strings.xml

We'll need to add some message strings expected by our error handlers. Locate the file src/main/res/values/strings.xml and replace the contents with the following:

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

    <string name="app_name">Hello Endpoints</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="toast_no_google_account_selected">No Google Account Selected</string>
    <string name="toast_exception_checking_authorization">Exception checking authorization</string>
    <string name="toast_no_google_accounts_registered">No Google Accounts Registered</string>
    <string name="toast_only_one_google_account_registered">Your only registered Google account was
    selected
  </string>
</resources>

Add an Application class for local data storage

We need to add a class for local storage. To add the class:

  1. Select src/main/java/com.google.devrel.samples.helloendpoints in the Android Studio left pane and right-click.
  2. Select New > Java Class .
  3. Supply the name Application for the class.
  4. Replace the contents of Application.java with the following:

    package com.google.devrel.samples.helloendpoints;
    
    import com.appspot.<your_project_id>.helloworld.model.HelloGreeting;
    import com.google.api.client.util.Lists;
    
    import java.util.ArrayList;
    
    /**
     * Dummy Application class that can hold static data for use only in sample applications.
     *
     * TODO(developer): Implement a proper data storage technique for your application.
     */
    public class Application extends android.app.Application {
        ArrayList<HelloGreeting> greetings = Lists.newArrayList();
    }
    

Update the Android Manifest

To update the manifest:

Locate the file src/main/res/AndroidManifest.xml and replace the contents of the file with the following:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.devrel.samples.helloendpoints"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="9"
        android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name="com.google.devrel.samples.helloendpoints.Application">
        <meta-data android:name="com.google.android.gms.version"
                   android:value="@integer/google_play_services_version" />
        <activity
            android:name="com.google.devrel.samples.helloendpoints.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

This change adds the Internet permission and adds the name attribute android:name="com.google.devrel.samples.helloendpoints.Application" to the <application> tag.

Add an empty AppConstants class for later use

We'll need a constants and utility class to hold information needed by the app so it can connect to the backend API. In the next part of the tutorial, Connecting the App to the Backend , we'll fill this in, but for now, we'll leave this class empty.

To create a new constants/utility method class:

  1. Select src/main/java/com.google.devrel.samples.helloendpoints and right-click.
  2. Select New > Java Class .
  3. Supply the name AppConstants for the class.

At this point, we are finished with the basic layout and controls. In the next part of the tutorial, we'll add the click handlers for the buttons.

Replace code in MainActivity

We'll need to replace the autogenerated code in MainActivity.java :

  1. Open the file src/main/java/com.google.devrel.samples.helloendpoints/MainActivity.java .

  2. Delete the contents of MainActivity.java .

  3. Add the following code:

    package com.google.devrel.samples.helloendpoints;
    
    import android.graphics.Color;
    import android.os.Bundle;
    import android.support.v7.app.ActionBarActivity;
    import android.view.LayoutInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.WindowManager;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.TextView;
    
    import com.appspot.<your_project_id>.helloworld.Helloworld;
    import com.appspot.<your_project_id>.helloworld.Helloworld.Greetings.GetGreeting;
    import com.appspot.<your_project_id>.helloworld.Helloworld.Greetings.Multiply;
    import com.appspot.<your_project_id>.helloworld.model.HelloGreeting;
    import com.google.common.base.Strings;
    
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.List;
    import java.util.Set;
    
    public class MainActivity extends ActionBarActivity {
        private static final String LOG_TAG = "MainActivity";
        private GreetingsDataAdapter mListAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // Prevent the keyboard from being visible upon startup.
            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
    
            ListView listView = (ListView) findViewById(R.id.greetings_list_view);
            mListAdapter = new GreetingsDataAdapter((Application) getApplication());
            listView.setAdapter(mListAdapter);
        }
    
        /**
         * Simple use of an ArrayAdapter but we're using a static class to ensure no references to the
         * Activity exists.
         */
        static class GreetingsDataAdapter extends ArrayAdapter {
            GreetingsDataAdapter(Application application) {
                super(application.getApplicationContext(), android.R.layout.simple_list_item_1,
                        application.greetings);
            }
    
            void replaceData(HelloGreeting[] greetings) {
                clear();
                for (HelloGreeting greeting : greetings) {
                    add(greeting);
                }
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                TextView view = (TextView) super.getView(position, convertView, parent);
    
                HelloGreeting greeting = (HelloGreeting)this.getItem(position);
    
                StringBuilder sb = new StringBuilder();
    
                Set<String> fields = greeting.keySet();
                boolean firstLoop = true;
                for (String fieldName : fields) {
                    // Append next line chars to 2.. loop runs.
                    if (firstLoop) {
                        firstLoop = false;
                    } else {
                        sb.append("\n");
                    }
    
                    sb.append(fieldName)
                            .append(": ")
                            .append(greeting.get(fieldName));
                }
    
                view.setText(sb.toString());
                return view;
            }
        }
    
    }
    
  4. Replace the value <your_project_id> in the imports listed above with the actual project ID for the backend API, using Android studio's code completion. Alternatively, you can copy the actual project ID listed in the project navigator line /libs/helloworld-v1-1.17.0-rc-SNAPSHOT.jar/com.appspot.the_actual_project_id.helloworld .

    Notice the LOG_TAG defined up at the top. This tag allows us to filter error messages by the Activty tag name while running in debug mode in Android Studio.

    Notice also that the code snippet includes an ArrayAdapter class to handle the display.

  5. Click File > Save All and Build > Rebuild Project to make sure the project compiles.

  6. Next, we'll add the code required for interactions with the backend API.

Next...

Continue to Connecting the App to the Backend .

Authentication required

You need to be signed in with Google+ to do that.

Signing you in...

Google Developers needs your permission to do that.