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)



Connecting Your App to the Backend

Now that the UI is in place, we need to connect the app to the backend API. There are two separate parts to this:

  • Add code that gets the handle needed to access the backend API service. (All requests to the backend will use this handle.)
  • Add click handlers for the UI that respond to user actions by sending requests to the backend.

Adding code to get the backend service handle

Backend API requests are made through a service handle object. Let's add a utility method to obtain a handle to the backend service in our AppConstants.java .

To add code to get the backend service handle:

  1. Open the file AppConstants.java in Android Studio.

  2. Replace the contents of the file with the following code:

    package com.google.devrel.samples.helloendpoints;
    
    import android.app.Activity;
    import android.app.Dialog;
    import android.content.Context;
    
    import com.google.api.client.extensions.android.http.AndroidHttp;
    import com.google.api.client.extensions.android.json.AndroidJsonFactory;
    import com.google.api.client.http.HttpTransport;
    import com.google.api.client.json.JsonFactory;
    import com.appspot.<your_project_id>.helloworld.Helloworld;
    
    import javax.annotation.Nullable;
    
    public class AppConstants {
    
        /**
         * Class instance of the JSON factory.
         */
        public static final JsonFactory JSON_FACTORY = new AndroidJsonFactory();
    
        /**
         * Class instance of the HTTP transport.
         */
        public static final HttpTransport HTTP_TRANSPORT = AndroidHttp.newCompatibleTransport();
    
    
        /**
         * Retrieve a Helloworld api service handle to access the API.
         */
        public static Helloworld getApiServiceHandle() {
            // Use a builder to help formulate the API request.
            Helloworld.Builder helloWorld = new Helloworld.Builder(AppConstants.HTTP_TRANSPORT,
                    AppConstants.JSON_FACTORY,null);
    
            return helloWorld.build();
        }
    
    }
    

    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 .

helloWorld.setRootUrl("http://192.168.1.100:8080/_ah/api/"); (We've used the IP address 192.168.1.100 , but you should use the real IP address of your development computer.)
  • Click File > Save All , then Build > Rebuild Project in Android Studio to make sure everything builds.

  • Now that we have the service handle code, let's add the click handlers for our UI.

    Adding click handlers to send backend requests

    Our UI needs click handlers that respond to user activity by sending the appropriate request to the backend. In this part of the tutorial, we are adding click handlers for Get Greeting , List Greetings , and Send Greetings .

    Adding a click handler for Get Greeting

    In this part of the UI, the user supplies the ID of the desired message in a textbox and then clicks Get Greeting to retrieve the message from the backend:

    the_UI

    Let's add a click handler called the onClickGetGreeting for the Get Greeting button. We'll also need a method for displaying results that can be used by all the other UI click handlers, which we will name displayGreetings .

    To do this:

    1. Add the following code to the MainActivity class:

      /**
       * This method is invoked when the "Get Greeting" button is clicked. See activity_main.xml for
       * the dynamic reference to this method.
       */
      public void onClickGetGreeting(View view) {
          View rootView = view.getRootView();
          TextView greetingIdInputTV = (TextView)rootView.findViewById(R.id.greeting_id_edit_text);
          if (greetingIdInputTV.getText()==null ||
                  Strings.isNullOrEmpty(greetingIdInputTV.getText().toString())) {
              Toast.makeText(this, "Input a Greeting ID", Toast.LENGTH_SHORT).show();
              return;
          };
      
          String greetingIdString = greetingIdInputTV.getText().toString();
          int greetingId = Integer.parseInt(greetingIdString);
      
          // Use of an anonymous class is done for sample code simplicity. {@code AsyncTasks} should be
          // static-inner or top-level classes to prevent memory leak issues.
          // @see http://goo.gl/fN1fuE @26:00 for a great explanation.
          AsyncTask<Integer, Void, HelloGreeting> getAndDisplayGreeting =
                  new AsyncTask<Integer, Void, HelloGreeting> () {
                      @Override
                      protected HelloGreeting doInBackground(Integer... integers) {
                          // Retrieve service handle.
                          Helloworld apiServiceHandle = AppConstants.getApiServiceHandle();
      
                          try {
                              GetGreeting getGreetingCommand = apiServiceHandle.greetings().getGreeting(integers[0]);
                              HelloGreeting greeting = getGreetingCommand.execute();
                              return greeting;
                          } catch (IOException e) {
                              Log.e(LOG_TAG, "Exception during API call", e);
                          }
                          return null;
                      }
      
                      @Override
                      protected void onPostExecute(HelloGreeting greeting) {
                          if (greeting!=null) {
                              displayGreetings(greeting);
                          } else {
                              Log.e(LOG_TAG, "No greetings were returned by the API.");
                          }
                      }
                  };
      
          getAndDisplayGreeting.execute(greetingId);
      }
      
      private void displayGreetings(HelloGreeting... greetings) {
          String msg;
          if (greetings==null || greetings.length < 1) {
              msg = "Greeting was not present";
              Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
          } else {
              Log.d(LOG_TAG, "Displaying " + greetings.length + " greetings.");
      
              List<HelloGreeting> greetingsList = Arrays.asList(greetings);
              mListAdapter.replaceData(greetings);
          }
      }
      

      This handler checks for some user input and prompts the user to supply an ID if the user hasn't supplied one. If there is input, the integer is handed off to an AsyncTask named getAndDisplayGreeting , which uses the backend API service handle to make the getGreeting request to the backend.

      The results returned are displayed via the displayGreetings method shown above.

    2. Click File > Save All , then Build > Rebuild Project in Android Studio to make sure everything builds.

    3. Test your app on Android by doing the following:

      1. Connect your Android device to your development system using a USB cable.
      2. Select Run > HelloWorld in Android Studio.
      3. Launch the app on your Android.
      4. Supply a value of 0 or 1 and click Get Greeting to get the Greeting corresponding to the supplied ID.

    Adding a click handler for Send Greetings

    In this part of the UI, the user supplies a text message in one textbox, and an integer N in the other textbox. Clicking Send Greetings POSTs these values to the backend where the greeting is repeated N times in the response and displayed in the ListView UI component:

    the_UI

    To add the onClickSendGreetings click handler for the Send Greetings button:

    1. Add the following code inside the MainActivity class:

      
      public void onClickSendGreetings(View view) {
        View rootView = view.getRootView();
      
        TextView greetingCountInputTV = (TextView)rootView.findViewById(R.id.greeting_count_edit_text);
        if (greetingCountInputTV.getText()==null ||
            Strings.isNullOrEmpty(greetingCountInputTV.getText().toString())) {
          Toast.makeText(this, "Input a Greeting Count", Toast.LENGTH_SHORT).show();
          return;
        };
      
        String greetingCountString = greetingCountInputTV.getText().toString();
        final int greetingCount = Integer.parseInt(greetingCountString);
      
        TextView greetingTextInputTV = (TextView)rootView.findViewById(R.id.greeting_text_edit_text);
        if (greetingTextInputTV.getText()==null ||
            Strings.isNullOrEmpty(greetingTextInputTV.getText().toString())) {
          Toast.makeText(this, "Input a Greeting Message", Toast.LENGTH_SHORT).show();
          return;
        };
      
        final String greetingMessageString = greetingTextInputTV.getText().toString();
      
      
        AsyncTask<Void, Void, HelloGreeting> sendGreetings = new AsyncTask<Void, Void, HelloGreeting> () {
          @Override
          protected HelloGreeting doInBackground(Void... unused) {
            // Retrieve service handle.
            Helloworld apiServiceHandle = AppConstants.getApiServiceHandle();
      
            try {
              HelloGreeting greeting = new HelloGreeting();
              greeting.setMessage(greetingMessageString);
      
              Multiply multiplyGreetingCommand = apiServiceHandle.greetings().multiply(greetingCount,
                  greeting);
              greeting = multiplyGreetingCommand.execute();
              return greeting;
            } catch (IOException e) {
              Log.e(LOG_TAG, "Exception during API call", e);
            }
            return null;
          }
      
          @Override
          protected void onPostExecute(HelloGreeting greeting) {
            if (greeting!=null) {
              displayGreetings(greeting);
            } else {
              Log.e(LOG_TAG, "No greetings were returned by the API.");
            }
          }
        };
      
        sendGreetings.execute((Void)null);
      }
      

      This handler invokes an AsyncTask to make the sendGreeting request to the backend API service.

    2. Click File > Save All , then Build > Rebuild Project in Android Studio to make sure everything builds.

    3. Test the app as you did previously, but this time enter a text greeting in in Greeting to send textbox and an integer in the Greeting count to send textbox, then click Send Greetings . Observe the greeting multiplied by the count in the response.

    At this point, your complete MainActivity code should look like this:

    package com.google.devrel.samples.helloendpoints;
    
    import android.content.Intent;
    import android.graphics.Color;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.support.v7.app.ActionBarActivity;
    import android.util.Log;
    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 android.widget.Toast;
    
    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;
    
    import com.google.devrel.samples.helloendpoints.R.id;
    
    import static com.google.devrel.samples.helloendpoints.BuildConfig.DEBUG;
    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)this.findViewById(R.id.greetings_list_view);
            mListAdapter = new GreetingsDataAdapter((Application)this.getApplication());
            listView.setAdapter(mListAdapter);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
    
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
        }
        /**
         * This method is invoked when the "Get Greeting" button is clicked. See activity_main.xml for
         * the dynamic reference to this method.
         */
        public void onClickGetGreeting(View view) {
            View rootView = view.getRootView();
            TextView greetingIdInputTV = (TextView)rootView.findViewById(R.id.greeting_id_edit_text);
            if (greetingIdInputTV.getText()==null ||
                    Strings.isNullOrEmpty(greetingIdInputTV.getText().toString())) {
                Toast.makeText(this, "Input a Greeting ID", Toast.LENGTH_SHORT).show();
                return;
            };
    
            String greetingIdString = greetingIdInputTV.getText().toString();
            int greetingId = Integer.parseInt(greetingIdString);
    
            // Use of an anonymous class is done for sample code simplicity. {@code AsyncTasks} should be
            // static-inner or top-level classes to prevent memory leak issues.
            // @see http://goo.gl/fN1fuE @26:00 for a great explanation.
            AsyncTask<Integer, Void, HelloGreeting> getAndDisplayGreeting =
                    new AsyncTask<Integer, Void, HelloGreeting> () {
                        @Override
                        protected HelloGreeting doInBackground(Integer... integers) {
                            // Retrieve service handle.
                            Helloworld apiServiceHandle = AppConstants.getApiServiceHandle();
    
                            try {
                                GetGreeting getGreetingCommand = apiServiceHandle.greetings().getGreeting(integers[0]);
                                HelloGreeting greeting = getGreetingCommand.execute();
                                return greeting;
                            } catch (IOException e) {
                                Log.e(LOG_TAG, "Exception during API call", e);
                            }
                            return null;
                        }
    
                        @Override
                        protected void onPostExecute(HelloGreeting greeting) {
                            if (greeting!=null) {
                                displayGreetings(greeting);
                            } else {
                                Log.e(LOG_TAG, "No greetings were returned by the API.");
                            }
                        }
                    };
    
            getAndDisplayGreeting.execute(greetingId);
        }
    
        private void displayGreetings(HelloGreeting... greetings) {
            String msg;
            if (greetings==null || greetings.length < 1) {
                msg = "Greeting was not present";
                Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
            } else {
                Log.d(LOG_TAG, "Displaying " + greetings.length + " greetings.");
    
                List<HelloGreeting> greetingsList = Arrays.asList(greetings);
                mListAdapter.replaceData(greetings);
            }
        }
    
    
        public void onClickSendGreetings(View view) {
          View rootView = view.getRootView();
    
          TextView greetingCountInputTV = (TextView)rootView.findViewById(R.id.greeting_count_edit_text);
          if (greetingCountInputTV.getText()==null ||
              Strings.isNullOrEmpty(greetingCountInputTV.getText().toString())) {
            Toast.makeText(this, "Input a Greeting Count", Toast.LENGTH_SHORT).show();
            return;
          };
    
          String greetingCountString = greetingCountInputTV.getText().toString();
          final int greetingCount = Integer.parseInt(greetingCountString);
    
          TextView greetingTextInputTV = (TextView)rootView.findViewById(R.id.greeting_text_edit_text);
          if (greetingTextInputTV.getText()==null ||
              Strings.isNullOrEmpty(greetingTextInputTV.getText().toString())) {
            Toast.makeText(this, "Input a Greeting Message", Toast.LENGTH_SHORT).show();
            return;
          };
    
          final String greetingMessageString = greetingTextInputTV.getText().toString();
    
    
          AsyncTask<Void, Void, HelloGreeting> sendGreetings = new AsyncTask<Void, Void, HelloGreeting> () {
            @Override
            protected HelloGreeting doInBackground(Void... unused) {
              // Retrieve service handle.
              Helloworld apiServiceHandle = AppConstants.getApiServiceHandle();
    
              try {
                HelloGreeting greeting = new HelloGreeting();
                greeting.setMessage(greetingMessageString);
    
                Multiply multiplyGreetingCommand = apiServiceHandle.greetings().multiply(greetingCount,
                    greeting);
                greeting = multiplyGreetingCommand.execute();
                return greeting;
              } catch (IOException e) {
                Log.e(LOG_TAG, "Exception during API call", e);
              }
              return null;
            }
    
            @Override
            protected void onPostExecute(HelloGreeting greeting) {
              if (greeting!=null) {
                displayGreetings(greeting);
              } else {
                Log.e(LOG_TAG, "No greetings were returned by the API.");
              }
            }
          };
    
          sendGreetings.execute((Void)null);
        }
    
        /**
         * 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;
            }
        }
    }
    

    Next...

    When you are finished with these tasks, continue on to Authentication: Adding Client IDs to Backend and Library .

    Authentication required

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

    Signing you in...

    Google Developers needs your permission to do that.