Google Cloud Endpoints Tutorial – Part 3

Welcome to Part 3 of the Google Cloud Endpoints Tutorial.

The full series:

  • Part 1 : We looked at writing a Google Cloud Endpoints class manually by using the various annotations and Exception classes that are available. We create a Quotes API that provided a JSON + REST based interface to manage Quotes (add, modify, delete and retrieve quotes).
  • Part 2 : We generated the Google Cloud Endpoints class from a JDO Annotated Entity class by using the Code Generation tools provided in the library.
  • Part 3 : Generated the Cloud Endpoints Client Library for Android and wrote an Android application that invokes the Endpoints API.
  • Part 4: We wrote a JavaScript client for our Endpoints API.
  • Part 5: Securing our API
  • Part 6: Calling a Secured API from a JavaScript client.
  • Part 7 : Calling a Secured API from an Android client.

I have also published a list of Cloud Endpoints Tips:

  1. Check Endpoint Deployment Status
  2. Throw the Right Exception Classes
  3. Understand Injected Types
  4. Understand @API and @APIMethod Annotations
  5. Using Cursor and Limit parameters
  6. The @APIResourceProperty Annotation

In this episode

We have looked at generating the API implementation so far. You can pick and choose, whether you want to write it by hand or use the generated classes and tweak them to your liking. Whichever way you go, what we have now with us is an API backend that is hosted on the Google Cloud (App Engine) and we need to start consuming it via client applications.

In this part of the series, we are going to look at writing an Android client that consumes the Quotes API that we have ready and hosted. The tutorial will look at writing the application from scratch and demonstrating the List Quotes and Add New Quote function. Once you see that work, you can extend the Android application a bit further by incorporating the Edit Quote and Delete Quote as needed.

What do you need ?

  • Basic understanding of Android Application Development. Specifically, we will be looking at writing a few Activity classes, starting one Activity from another (via the Intent), using the Android AsyncTask to asynchronously invoke our API backend from the Android client. We shall be using Android stuff like ListActivity, Alert, Toast, Layouts, etc. If you are looking at brushing up on your Android fundamentals, look no further than this.
  • You have a working development environment for Google App Engine. This includes the Google Eclipse plugin.
  • You have a working development environment for Android. I have used Eclipse with the ADT Plug-in.

My Development Environment

This remains the same, no changes at all. My development environment is given below:

  • Eclipse Juno
  • Google Eclipse plugin with App Engine SDK 1.8.8
  • Android ADT Plugin with latest Android SDK installed.
  • Mac + Windows machine (I kept switching from one to another, to keep everyone happy ;-))

Attention-> Cloud Endpoints became GA (General Availability) in Release 1.8.7 of the App Engine SDK. The latest release as of App Engine at the time of writing is 1.8.9.

Revisiting the Quotes API

Let us recap quickly on what we have done so far. We have written a Quotes API hosted on Google App Engine that allows us to perform CRUD operations via a HTTP REST API. A Quote record contains a couple of attributes, the author and the famous quote that the author gave.

If you look at the API Methods, we had the following methods exposed:

Screen Shot 2014-01-12 at 4.21.42 PM

Additionally, we have the application live and available on App Engine. And we have some records added to it, so that in case we do a listQuote, a record or two is available.

In case you are planning to follow the rest of the article, it would help to have the Quotes API ready and available under your App Engine application id.

Generate Google Cloud Endpoints library

Google Cloud Endpoints provides a way for us to generate the client side libraries. This can be done via the command line but we will be using the Eclipse plugin to keep things the way it has been so far.

Assuming that you already have your Eclipse Project for Quotes API Project loaded in Eclipse, simply right click on the Project, go to Google and then Generate Cloud Endpoint Client Library as shown below:

Screen Shot 2014-01-12 at 11.38.43 AM

This will start generating Java classes that constitute the Client Library. It takes a while as shown by the dialog below:

Screen Shot 2014-01-12 at 11.37.58 AM

Once done, you can take a look at the various folders that have been generated for you. The folders include the sources that act as a stub for your Quotes API and also a set of dependent JAR files.

For the Quotes API project that I have, the Client library folders are shown below:

eclipse3

At the same level as your src folder, you will find the endpoint-libs folder in which the sources and JARs are present. 

The main points to take away is that:

  • You will need to take the classes that are generated in the quoteendpoint-v1-generated-source folder. These classes are client classes that act as a stub and which you can use in your Android application to invoke the CRUD operations in your hosted API.
  • More importantly, thats not all. You will need a bunch of dependent JAR files that are present in the dependencies folder and which you will need to carry along and link to in your Android project for everything to compile and eventually work.

We shall see that in a while.

Android Application Development

Before we dive into development of the Android client application, let us see it in action to better understand what we shall be building here.

When you launch the application, the first screen (Activity) is shown below:

androidapp1

The UI is simple and please do forgive me for my design skills :-) It has 3 buttons:

  • List Quotes : When clicked, it will start a new Activity that will Retrieve the current list of Quotes from the live App Engine application. A sample screen is shown below:androidapp2The List Activity is a simple ListActivity in Android. We use an Async Task to make the call via the Client library to get the Quotes and display them.
  • Add Quote : This Activity presents a simple form to the user to provide the Author name and the quote (message) as shown below:

androidapp3

When you click on Add, we will make a call to the Client library, which in turn will invoke the POST method to insertQuote in the live App. On successful addition, a message is shown to the user and when you go back to the List Quotes Activity, you see the newly added quote too, as given below:

androidapp5

Side Note: This is my only chance of being listed next to 2 great individuals. I stand no other chance. :-)

The 3rd button (About Appsimply shows a simple Alert box and displays the name and the version number.

Let’s get started with the Android Application Development now. All the steps now will happen inside the Android Development Environment. I am using the ADT plugin inside of Eclipse. If you are using Android Studio, steps should be more or less familiar.

Generate Skeleton App

The first step is to create a new Project. Simply go to File -> New -> Android Application Project

Screen Shot 2014-01-12 at 7.22.59 PM

Click on Next. In the screen below, we provide the name our App (FamousQuotesAndroid) along with package name. I have API 18 but you could have some other one too. 

Screen Shot 2014-01-12 at 7.23.43 PM

Click on Next. Deselect the Create custom launcher icon. Let the other values be as is and click on Next.

Screen Shot 2014-01-12 at 7.24.01 PM

Go with the default on this screen too as shown below and click on Next.

Screen Shot 2014-01-12 at 7.24.14 PM

The final screen is shown below. Simply click on Finish. 

Screen Shot 2014-01-12 at 7.24.34 PM

This will generate the Android Project. Ensure that it all compiles fine and verify that you are able to launch a AVD and run the basic application.

Add Google Client Library Classes and Dependencies (JARs)

The next step that we need to do is to add all the Cloud Endpoint classes and the Dependent JARs that were generated in the Quotes API Project.

You will need to add the JAR files shown below to the libs folder of your Android project. These JARs will be available in the dependencies folder of your Cloud Endpoint generated folder that we saw earlier.

The JAR files that you need to add are shown below:

eclipse1

The next thing to do is to add the Cloud Endpoint Java Source files that were generated in the quoteendpoint-v1-generated-source folder. Shown below is my Android Project Source structure:

eclipse4

As pointed out above, we have simply put the Cloud Endpoints generated Java files in the com.mindstorm package.

Similarly, the folder that you see below that i.e. Android Activities code is all the Android code that we shall see in a moment. It contains the Activity classes that compromise our Android application.

Understand Google Client Code and calling mechanism

It is important to understand to some extent what the Google Cloud Endpoints client classes look like.

  • The main class that you will deal with is the Quoteenpoint.java file. This is your starting point.
  • It contains the DEFAULT_ROOT_URL and the DEFAULT_SERVICE_PATH that you should modify if necessary so that the application points to your App Engine API which is hosted live at your application id.
  • It contains an inner class named Builder that you need to construct and get an instance of. The Builder constructor takes 3 parameters : Instance of the HTTP Connection Transport, an instance of GSONFactory for helping out in Java-JSON translations and an initializer.
  • Once the instance of a Builder is created, you will find that you can invoke all the API methods like listQuote, inserQuote, remoteQuote, getQuote and updateQuote, which you can then execute(). We shall see this in a while.

Android Activity Classes

Now let us go through the Android code. You do need to know a bit of basic Android Development over here, so most of the things should be straightforward. I have kept them deliberately simply and at a high level, you need to know the following things in Android:

  • Writing a basic Activity class and adding the entries in the AndroidManifest.xml file.
  • Invoking i.e. starting one Activity from the other. Basic Intent is used here.
  • Writing Event Handlers for button clicks. Knowledge of Linear Layout.
  • ListActivity
  • AsyncTask and why it is needed.

Android Main Activity class

This is the first screen that is shown in the Android application. There are 3 event handlers i.e. OnClick Listeners for the 3 buttons i.e. List Quotes, Add Quote and About App.

The List Quotes and Add Quote button click handlers simply start the respective Activities i.e. AddQuoteActivity and QuotesListActivity, that we shall see next.

Add Quote Activity

The code is given below but let us look at the main points:

  • The user enters the values for Author Name and Message and clicks on Add button.
  • The Add button click handler does some check for values and then invokes an Async Task: AddQuoteAsyncTask and passes the Strings i.e. Author Name and Message to it.
  • Pay attention to the AddQuoteAsyncTask class and the doInBackground method. Over here we construct the Quoteendpoint.Builder, create the Quote object and execute the insertQuote object. As simple as that.
Quoteendpoint.Builder builder = new Quoteendpoint.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), null);
Quoteendpoint service = builder.build();
Quote quote = new Quote();
quote.setAuthor(params[0]);
quote.setMessage(params[1]);
response = service.insertQuote(quote).execute();
  • In the postExecute method of the Async Task, we simply clear up the fields.

Quotes List Activity

This code should be straight forward now.

  • In the onCreate we invoke the QuotesListAsyncTask.
  • The QuotesListAsyncTask will create the builder, invoke the listQuote method and collect the responses into a collection.
  • Finally in the postExecute method, we add the data to the List Adapter and boom, it displays the stuff in the ListView Control.

This post talks about the list Quotes and Add Quote methods and has demonstrated that in the Android application. I hope that it is demonstrative of the fact that the update Quote, delete Quote and get Quote can also be executed accordingly and you can try it out.

Response Times

One of the important points to consider while using Google Cloud Endpoints is that your API is hosted on the App Engine platform. It is known that your application instance is not always running when for you. If it is idle for a while, your Application instance is removed and then on the next request, the instance is started up. The starting up (cold start) usually takes a while and anyone who has done work with App Engine is aware about this.

For e.g. look at the App Engine console log for the incoming requests below. I have highlighted in red, the abnormally high request processing time for particular API calls. 

logconsole1

This is not to alarm you but it is something that you should be aware of. Definitely an API request that takes 15+ seconds to complete is not what you want. But at the same time, if the instance is alive, you do see a fast response time.

Please note that Google App Engine addresses the issue of keeping the instance alive via Warmup requests. Please read up on that.

Full Project Download

You can download both the Projects from GitHub.

Hope you liked this episode of Google Cloud Endpoints in which we generated the Client Libraries for Android and also consumed it from an Android application.

Stay tuned for more episodes. Till the next one

About these ads

77 thoughts on “Google Cloud Endpoints Tutorial – Part 3

  1. Hi I am tryin to use your sample .. the endpoint working properly. the android addquote working properly but the listquote is not working i keep receiving this
    02-10 05:06:48.663: D/Could not retrieve Quotes(1288): java.lang.SecurityException: Permission denied (missing INTERNET permission?)

  2. Hi rominirani, it is really a great tutorial, but right now when I try to run my android app, the logcat says there is a 500 Internal Server Error, and it is an Unknown Error which gives me no clue of how to solve it. Do you have any idea about this? Thx!

  3. Sorry, I did not change the config of the URL, now it’s working. But I also want to know how I can integrate GCM into this Cloud Endpoint project? Thanks.

    1. Here are my thoughts on the same:

      1. If you are using Endpoints , then the idea is that you are regularly invoking / polling the API Endpoint in case you need to get data.
      2. If the above is inefficient due to which you are planning to use push notifications, then I believe you should look at the Mobile Backend Start project that provides a quick Backend project to deploy on App Engine along with Push Notification integration. Take a look at : https://developers.google.com/cloud/samples/mbs/

  4. hi
    Thanks for your tuto.
    But i am getting following error.
    “Conversion to Dalvik format failed with error 1″
    can you help me in this.

    1. I believe this could be related to your current Project Properties + Linked Library sources, etc. Maybe try removing all the libraries, check your build project and create your project again.

    1. What is the error that you are getting ? Are you trying to generate from command line or from Eclipse. Please give this information, so that I can try to help.

  5. Hello rominirani, first of all great tutorial!!

    I’m having troubles with the part:
    Quoteendpoint.Builder builder = new Quoteendpoint.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), null);

    I’m using Android Studio and I keep getting the error that can not resolve to AndroidHttp.

    The only option I have is AndroidHttpClient.

    Any ideas on what it can be?

    Marcus

    1. This is likely to happen if you have not linked the JAR files that are needed in the project. When you generate the Endpoint client library, there is also a dependencies folder that contains several JAR files and chief among them being the google-api-client-*.jar files. Please make sure that those JAR files are present and the class should get resolved.

  6. Hi Romin!

    your tutorial is awesome, thanks for it.
    I have a question, I imported your projects into Eclipse to testing.
    I change the “DEFAULT_ROOT_URL” in QuoteendPoint (Android project).
    I can see a field “USERINFO_EMAIL” in QuoteendpointScopes (Android project) but i don’t change it.
    My LogCat show this:
    401 Unauthorized
    {
    “code”: 401
    “errors”: [
    {
    "domain": "global",
    "location": "Authorization",
    "locationType": "header"
    "message": "User is Not Valid"
    "reason": "required"
    }
    ],
    “message”: “User is Not Valid”
    }

    How can i do to resolve this error?

    Thanks!

  7. Hi Rominirani,

    Thanks for the tutorial, very useful.

    Is there a method to find a specific quote, essentially querying for a specific quote instead of retrieving and listing all quotes.

    Chris

    1. Hi Chris,

      Thanks for the feedback. Yes – there is a getQuote method that requires you to pass in a long i.e. Quote Id. It should return you the particular Quote record.

      Does that work for you ?

  8. Hi.. I followed your steps, but I had one difference:
    The JAR files were not in the generated dependencies folder – they were in the lib folder. That dependencies folder was full of HTML files with the same names. Is this a difference in Eclipse versions? i have the ADT bundle.

    I am having an issue now though, were the android project is giving me an error, saying some of the fields in my api Model are duplicated. without going into further detail yet, have you ever seen it complain of the duplicate fields, after copying over the API files?
    I see the duplicated ones, but they also appear in the actual generated files from the GAE project… but it’s not highlighted as an error there.

    An example duplicate:
    @com.google.api.client.util.Key(“Members”)
    private java.util.List members;

    is listed as a duplicate with:
    @com.google.api.client.util.Key
    private java.util.List members;

    I don’t know why the generated code has both of these (my object only has 1) field named members.
    I’m wondering if there is something slightly wrong with the jar files I’m copying.. and the duplicate error is just a strange symptom of that?

    1. it seems like it may be where my object has a member that is a list of other objects. There are a couple other places this happens, and they get the same errors.. the field itself, as well as the getters and setters related to them, are all indicated as “duplicates”.

      1. I am not sure if this is due to objects containing other objects. Ideally it should be fine.

        You also mentioned about files going in some other folders. Not sure if newer versions are doing anything different. I might have to check it with the latest version of the App Engine and ADT Plugin and see if there is a difference.

        The typically flow that I was following in case I made any changes was that I always used to remove all the generated files from the Android project and copy over the newly generated files.

  9. Hi, thanks for the tutorial, I’m finding it easy to follow. However, I am getting an error that I have not been able to solve.
    I am using Eclipse Kepler Release 2
    Google SDK 1.9.4
    Android SDK 22.6.3

    When I right click on MyAPIProject or MyAPIProject2 and then Generate Cloud Endpoint Client Library I get the following error:

    An error occurred when attempting to generate the client libraries. See the error log for more details.

    When I go to the error log I see:

    eclipse.buildId=4.3.2.M20140221-1700
    java.version=1.7.0_55
    java.vendor=Oracle Corporation
    BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_US
    Framework arguments: -product org.eclipse.epp.package.standard.product
    Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.standard.product

    Error
    Sun May 04 11:57:31 EDT 2014
    Unexpected Exception

    java.lang.reflect.InvocationTargetException
    at com.google.gdt.eclipse.appengine.swarm.wizards.GenerateSwarmApiAction$1.run(GenerateSwarmApiAction.java:82)
    at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)
    Caused by: java.lang.ClassNotFoundException: com.google.api.server.spi.tools.ClientLibGenerator$Language
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmApiCreator.createClientLibFromApiConfig(SwarmApiCreator.java:113)
    at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmApiCreator.createSwarmApi(SwarmApiCreator.java:258)
    at com.google.gdt.eclipse.appengine.swarm.wizards.helpers.SwarmServiceCreator.create(SwarmServiceCreator.java:444)
    at com.google.gdt.eclipse.appengine.swarm.wizards.GenerateSwarmApiAction$1.run(GenerateSwarmApiAction.java:80)
    … 1 more

    I’ve been facing this error for the last two days (even before coming across your tutorial) and I’ve tried uninstalling and re-installing google plugins, eclipse, the ADT, and using another computer. I can’t get past this step

    1. I’m not sure why this occurred but I imagine it’s because of the SDK. I was using 1.9.4 but when I used 1.9.3 everything works. Two days to change an SDK. ugh!

      1. Thanks for the update. I have not tried with 1.9.4 but have got several other reports mentioning that code generation in 1.9.4 breaks things, so it is best to stick with 1.9.3 for now. Thanks for the information.

  10. Hi
    Thank you so much for this tutorial. It has helped me to learn
    Can you show me how to limit the number of quotes returned from the server?

    Quoteendpoint.Builder builder = new Quoteendpoint.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), null);
    Quoteendpoint service = builder.build();
    quotes = service.listQuote().execute()

    So how do i limit the quotes returned? how do i add the parameter limit used in the Api method list?

    1. Hi Ronald – Thank you for the feedback. Much appreciated.

      There are 2 parameters in the list() method that are important if you want to limit the number of quotes to be returned. They are

      1. Cursor
      2. Limit

      Let us say that there are 10 quotes and you want to fetch only 3 quotes at a time. So the limit is 3.

      Now, in your code, you are calling the `service.listQuote()`. This will create the ListQuote object. On this object, you can use the methods setCursor(…) and setLimit(…). So in the first call, you will do a setLimit(3) but the setCursor can be left as empty or null. Now, the response will only contain 3 items. But it will also have an additional attribute called nextPageToken. You will need to use that token value in the setCursor(nextPageToken) the next time you invoke the execute(). This way, it will be able to use the cursor only from the next result onwards and return you the next 3 items in the list.

      Hope this makes things clear. I suggest you try with the API Explorer first. You will find the Cursor and Limit parameter fields in the API explorer for the List method. So you can understand there first what is going on.

      1. Hi . Thank you so much. Got the first one of limiting the number returned to work. On the cursor part it means that i can create a kind of query string with say a custom sort order? and pass it as an argument?(tried using a sql string as a cursor and got illegalArgumentException! in the web interface-Google api explore.).

  11. No – you cannot pass what you want in the Cursor parameter. If you notice the response that you got from the web Google API Explorer when you use the limit, you will notice one extra attribute in the response called nextPageToken. Note down this value.

    Then, when you invoke the listMethod again, provide the above value in the cursor field. And notice the response : you will find that it retrieves the next number of records (based on limit), so it is just a pointer in the cursor to tell the JDO Cursor where to first seek and then get the next set of records from. Each time, it will return you the nextPageToken and you have to use it with each subsequent call as the value in the cursor parameter.

  12. Hello iRomin…
    Do you have any ideas on how google cloud endpoints handle relationships? Suppose i wish to keep Author and Quotes entities? an Author has many quotes . I can create the annotated classes using JPA.. and create the google endpoints(Using eclipse plugin) but iam surely puzzled on how to implement the say the insert APi method.
    Here my simple class

    Entity(name=”Author”)
    Public class Author
    {
    ///some data members here
    @OneToMany(cascade=CascadeType.All,mappedBy=”author”)
    private List quotes;
    // getters and setters…
    }

    Entity(name=”Quotes”)
    Public class Quotes
    {
    // some data members
    @ManyToOne()
    private Author author
    }

    After i create the classes and i click generate EndPoints, each class has a separate insert API method…and also the list method…

    What i have really failed to grasp is how to add data….the author class has a list of quotes as a data member..so what happens when i add an author? the quotes list will have null entries…and now if i am adding quotes…how do i relate them to authors?

    I have really failed to find some documentation on how cloud end points handle relationships btn entities. Do you know any link you can refer me to?

    Thank you so much!

    Ronald

    1. I believe you have to think a bit differently when it comes to an API.

      Here are some thoughts:
      1) Do not try to just do a one to one generation of Endpoints. If you want to, that is ok but keep things a bit separate.
      2) Now, you want to maintain Authors and you want to maintain Quotes for each Author.
      3) First, design your Endpoints API – think of what operations you want to expose and what the clients can do.
      4) You might want to give an API for managing Authors. So you can have an Endpoint class specifically only to manage Authors. Do not mix up the Quotes inside of this. Keep Quotes out of this entity.
      5) Now, provide a separate Endpoint for managing Quotes. Create your parameters expected i.e. Author name or Id, and the Quote ID , Message. That’s all. Then inside of the implementation, you will need to manage the JDO / JPA code accordingly.

      I think go this way – so that your backend code , entities and the relationships are not really exposed directly. Do all your jugglery inside of the Endpoint API, which then knows what objects to manage on the server.

      So, in other words, when you start getting to complex things, instead of just generating endpoints for each classes, think of API Design and methods first and then create your own Endpoint class. It will be easier to map things that way.

      Again, these are my thoughts and may not necessarily be the most optimized way. But I like to keep the layers independent of each other, so that it is easier to modify one without being tightly coupled to each other.

  13. found my issue btw.. the duplicates were created because my members were with a uppercase first letter.. so it made a duplicate with a lowercase. I renamed the members to be lowercase, and the duplicates went away.

  14. I want to create an Android (and later IOS app) app that can work with ‘existing App Engine Backend’.

    One of my friends has created App Engine Backend using python and the API’s and discovery documents are available online using https://xxx.appspot.com/_ah/api/explorer. My friend lives in a different state and he is just working on App Engine Backend. The APIs are deployed already & my friend has created End Point libraries for Android & iOS

    Now I want to create an Android App and link to this existing App Engine Back End. 1. Is it possible to connect these to project remotely? Since backend and front end developers are in different states, using different workspaces. 2. Is (a) adding ‘API key & project number’ from existing App Engine project to my new android project & (b) copying End Point libraries; sufficient for app to connect to back-end?

    I’m using Google’s ADT bundle for windows. ADT Package (22.6.2), Eclipse (4.3.1v), Java 7, Google Plugin for Eclipse 4.3(Kepler)

    1. It is possible to connect your Android application to the backend project. I am assuming that your friend has deployed the backend project in App Engine. So if it is a live instance running there, you should be able to connect to it.

      Alternately, if you import the backend project into your Eclipse, you can run the web application locally and try connecting to it also.

  15. Hi Rominirani,

    I cannot overstate how interesting and useful your tutorial is. I have encountered an issue. Even after :
    1) changing the DEFAULT_ROOT_URL to http://localhost:8888/_ah/api/
    2) Adding the internet permissions to the Manifest

    I get the following error when on “List Quotes”

    D/Could not retrieve Quotes(1983): failed to connect to localhost/127.0.0.1 (port 8888) after 20000ms: isConnected failed: ECONNREFUSED (Connection refused)
    D/Could not retrieve Quotes(1983): java.net.ConnectException: failed to connect to localhost/127.0.0.1 (port 8888) after 20000ms: isConnected failed: ECONNREFUSED (Connection refused)

    I am running through an emulator and I’ve also tried using http://10.0.2.2:8080/_ah/api/ as my DEFAULT_ROOT_URL.

    Is there anything else I may be getting wrong?

    Thanks,

    Ad

    1. 1. At a high level, things look good to me i.e. what you have tried.
      2. One question: If you deploy your application the google cloud i.e. actually put it on the .appspot.com, are you then able to connect from your Android client. Please verify that.

      1. Thank you for the Prompt reply Rominirani, I did think about deploying but I really wanted to debug locally and only deploy when I was happy with the results. I will give this a go but I think I’ll move on with your tutorial first as I want to learn more about the web clients and Authorisation as well.

        One more question though. Could this error be as a result of Authorisation?

      2. I think the best way to validate anything would be to look into the DDMS Perspective in the Eclipse IDE to determine what is going on. I think that could give you enough hints on what the exact exception is.

      3. The JavaScript client works so the issue is at least isolated to just the android client. I will take a better look at the log cat and the other tools in the DDMS perspective. If I still can’t solve the issue, I will deploy the application.

  16. I’ve found my error. I was using the wrong port (8080 instead of 8888). Silly me. This works well locally now. Thanks again!

  17. Hi rominirani, Thank you for your fantastic Tutorial! I love that! I found a “little” problem at the beginning of my project….When i click on “Generate Cloud Enpoint Client Library” i receive this message: “Error in Generating API this project does not have cloud endpoint classes”. What does it mean? I have a package ‘model’ and inside a PMF.java (Persistence Manager Factory class) and 2 class perfectly deployable on Datastore (as Persistence classes).

  18. Congrats for your post, it´s very useful. I have a problem, I can not generate the cloud endpoint client library and I don´t know why, I followed all the steps of the 3 tutorials. I´m getting an UnexpectedException. I have to change something of the project MyApiProject2 used in the tutorial 2 for generate the client library? Thanks a lot :)

    1. You will need to mention what the Unexpected Exception is. Check out the stack trace and let me know what is the exact error that you are getting. That will help me.

  19. Hi
    I was very pleased to find a tutorial which does a very good job of explaining in a clear and concise manner how to create google endpoints.
    Unfortunately I am having a great deal of difficulty getting the tutorial to work (Part 3).

    The add quote from the android app seems to work, we have a message to say the quote was updated but when I try to list it using the api explorer, it does not seem to have created a quote.

    When I try to list quotes from the android app the program crashes with the messages i have included at the end.

    I have made many attempts to get this tutorial to work I have now downloaded your version of the android app but it still will not work.

    I have modified your version of the Quoteendpoint
    to set public static final String DEFAULT_ROOT_URL = “http://localhost:8888/_ah/api/”; this is the only change i have made.
    I have tested the server app to insert and list quotes and it is working on the server side, but as I said quotes added from the android app are not being added.

    I would greatly appreciate you help to get this working because otherwise this seems to be an excellent tutorial.

    Thanks

    06-24 12:03:57.484: E/AndroidRuntime(4105): FATAL EXCEPTION: main
    06-24 12:03:57.484: E/AndroidRuntime(4105): Process: com.mindstorm.famousquotesandroid, PID: 4105
    06-24 12:03:57.484: E/AndroidRuntime(4105): java.lang.NullPointerException
    06-24 12:03:57.484: E/AndroidRuntime(4105): at com.mindstorm.famousquotesandroid.QuotesListActivity$QuotesListAsyncTask.onPostExecute(QuotesListActivity.java:81)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at com.mindstorm.famousquotesandroid.QuotesListActivity$QuotesListAsyncTask.onPostExecute(QuotesListActivity.java:1)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at android.os.AsyncTask.finish(AsyncTask.java:632)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at android.os.AsyncTask.access$600(AsyncTask.java:177)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at android.os.Handler.dispatchMessage(Handler.java:102)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at android.os.Looper.loop(Looper.java:136)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at android.app.ActivityThread.main(ActivityThread.java:5017)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at java.lang.reflect.Method.invokeNative(Native Method)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at java.lang.reflect.Method.invoke(Method.java:515)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
    06-24 12:03:57.484: E/AndroidRuntime(4105): at dalvik.system.NativeStart.main(Native Method)

  20. Hi

    I found the problem.
    I am not sure if you can test endpoints on localhost but I deployed the app to gae.
    I the noticed for DEFAULT_ROOT_URL i used http instead of https.
    I changed to https and it works.

    Thanks

  21. Hi, thanks again for your course
    I still have a problem..
    after adding the endpoints library to the android project (working on android studio)
    errors appear : cannot resolve symbol api (com.google.api)
    although I have been added all the libraries to /libs
    can you help me please??
    also I want to ask you if there is similar training resource for ios??
    thx

      1. I added dependencies for the libraries and it has been solved ..thanks
        I want to add custom queries …. How can I use endpoint classes instead of endpoint library?? since I couldn’t modify the endpoint library

      2. I am not sure what you mean by custom queries ? Does it mean you want to retrieve the entities based on your own queries/logic ? If yes, you can always enhance or add new find* or get* methods to the Endpoint classes. You can put your logic inside those method and as long as you expose them via the @APIMethod annotation and stuff, they should be available to your clients. Do generate the client libraries again in case you make changes to the Endpoint classes.

  22. I created new method annotated with @ApiMethod in my endpoint class …… and when generating the client library no changes have been made to the previous one
    So can I use my endpoint classes in my android project rather than the client libraries ???

    1. 1. Ideally the client libraries should have changed to take into effect the additional methods that you have created.

      2. You should use the Client Libraries since that will contain all the networking/marshalling code to make the request over the network to the Endpoint deployed application on App Engine.

      1. Thanks again for your answers

        The next problem I’m having :

        I have User.java entity class
        I made the attribute email as the Id
        the Get method in the Userendpoint class in the client library:
        public GetUser getUser(java.lang.String email) throws java.io.IOException {
        GetUser result = new GetUser(email);
        initialize(result);
        return result;
        }

        when calling in my android project:
        Userendpoint.Builder builder=new Userendpoint.Builder(AndroidHttp.newCompatibleTransport(), new GsonFactory(), null);
        Userendpoint service=builder.build();
        User u=service.getUser(“anEmail@hotmail.com”).execute();

        I got this error:
        Unable to resolve host “*********.appspot.com”: No address associated with hostname

  23. When Running the project …it can’t execute the getUser(“**”).execute() method
    and this error apear:
    com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found

    even I have one deployed version of my project on app engine

  24. Unable to resolve host “*********.appspot.com”: No address associated with hostname – this looks like there is some problem with the Endpoint hostname that you have specified. There is a DEFAULT_ROOT_URL that has the following format : “https://yourappid.appspot.com/_ah/api”. Please make sure that it is correct.

    1. the url problem has been solved …. However ,when running the project it can’t enter to the getUser(“**”).execute() method
      it stop execution at this method.

      1. When the project arrive to any .ecexute method ….. this error appear and the project stop execution after this method:

        07-14 12:19:00.380 30153-30180/com.emcloud.app W/System.err﹕ com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
        07-14 12:19:00.380 30153-30180/com.emcloud.app W/System.err﹕ Not Found
        07-14 12:19:00.380 30153-30180/com.emcloud.app W/System.err﹕ at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
        07-14 12:19:00.390 30153-30180/com.emcloud.app W/System.err﹕ at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
        07-14 12:19:00.390 30153-30180/com.emcloud.app W/System.err﹕ at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:312)
        07-14 12:19:00.390 30153-30180/com.emcloud.app W/System.err﹕ at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1045)
        07-14 12:19:00.390 30153-30180/com.emcloud.app W/System.err﹕ at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
        07-14 12:19:00.390 30153-30180/com.emcloud.app W/System.err﹕ at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
        07-14 12:19:00.390 30153-30180/com.emcloud.app W/System.err﹕ at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)

  25. Hi

    I already posted a comment saying I loved your tutorial and with a problem for which I already found the solution (after posting).
    I have another problem and I can’t find any useful information for the problem.
    I would like to use an end point to save a blob.
    I followed this tutorial but i created a blob field as well.
    When I generate the client endpoint the blob field has been changed to type string and there is a set method which only accepts a string, there is also an encode method which accepts a byte array.
    I have tested my client without updating the BLOB field , but when I try to update the blob it will not work.
    I have use the encode method to retrieve a string , I then update my blob (which has been transformed to a string for the clint) with this value returned by the encode method, but this will not insert a record.

    Can you help ? Can you recommend a site which tells you how to use endpoints to write blobs to the datastore.

    Thanks.

    1. Hi

      It seem like it helps to post a question, I found the solution to my problem.

      Basically my understanding was correct, I need to encode the byte array to a string
      and the save the the string returned by the encode function.
      The problem was he encode method automatically generated fort the entity.
      The solution is to use
      // where myimage is the image converted to a ByteArrayOutputStream
      String sa = Base64.encodeToString(myimage, Base64.DEFAULT);
      //
      and the save this string in the set method generated for the bitmap(String) , then it works fine.
      poi.setLocationImage(sa);

      Thanks

  26. Hello, first of all – great tutorial :)
    I’ve done everything in this tutorial (and part 1 and 2 as well) and I’m getting NullPointerException when I click List Quotes in android app. I tried to deploy MyAPIProject2 to AppEngine, it was successful but didn’t change anything. I’m a bit confused with all the things going on. Please help.

    NullPointerException points to :
    List _list = quotes.getItems();

    1. You will need to dig deeper to find out the root cause. For e.g.
      1) Does the request reach the Endpoints layer. Can you put in a few statements (log) to see what is happening ?

      2) If there is a Null Pointer Exception, do a stack trace and see what method is causing it.

      3) Does it run in the local development server ?

  27. Hello Thank you for this great tutorial.I My app engine back end is fine but when i run the android application , it does not add the quotes even though it says records are successfully added and also in getting a list quotes , it giving a errors. Could you help me please

    1. I will need to get some more debugging help from you if I am to pinpoint out the problem. Try the following:
      1) Does it run locally or you see the problem in the local dev server too ?
      2) Remember that the datastore is eventually consistent, so it would be a few moments before you see your data.
      3) Put a break point at the time of Datastore insert/update. Check closely if there are errors. Tune up the logging.
      4) Since you mentioned that there are errors while doing a list, what are the exceptions you are seeing.

  28. thank you very much i developp in python when i started developp my app in android i always got error because of androidJsonFactory not available for my sdk version phone. I found a solution during several days and i found it there thank very much again (excuse me for my english i generally speak french but i just want to thank you for this tuto)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s