Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / Apache

Easiest Way to Call a RESTful Method from Android

5.00/5 (5 votes)
4 Apr 2014CPOL4 min read 16.4K  
Call a RESTful method from Android without breaking, or in any wise damaging, a sweat

On Steve Martin and a Word to the Wise

There's an old Steve Martin joke where he portrays an over-exuberant shyster who claims to be able to divulge how one can "get a million dollars and never pay taxes." Of course, everybody and his grandmother's cat would like to know that trick, but the ebullient Martin then lets the wind out of the audience's sails when the first pointer to accomplish said feat is: "First, get a million dollars!"

There is a bit of a parallel between that shtick and this tip in that, in order to call a RESTful method from Android, you must first have a RESTful method to call, as this tip does not show you how to do that; that is "an exercise left to the reader" (which hopefully will not lead you to look up an exorcist).

So, a word to the wise (as a word to the wise is sufficient, and others won't listen, anyway): If you don't have an existing RESTful method to call, this tip will do you about as much good as an umbrella would keep you dry while sitting on the ocean floor.

Droidio

You can use Eclipse if you want, but I prefer and recommend Droidio (Android Studio) which, although still in "Preview" mode, works well and is obviously targeted specifically towards Android development (unlike Eclipse, which is sort of a "one IDE fits all" environment). And, being a product of the Googleplex, it is bound to be well-funded and continue to be improved. IOW, get in on the ground floor with Drodio - I don't think you'll be "disc-appointed."

You can download Droidio here.

Note: If you are interested in some books on Droidio, there is a list within this reference (scroll down or search for "Android Studio").

Dreaming of Electronic Sheep

The code I will show you simply calls a (Web API) RESTful method that returns an integer value.

Before we get to the actual code, though, we will first need to add a Button and an EditText to the design surface. In a typical simple Android app, this would be in activity_main.xml. In Droidio, you can simply drag and drop these widgets to the design surface (a la Borland Delphi, Visual Studio, etc.):

Image 1

A Patchy Regression

As you will see in the Java code below, the overridden doInBackground() method uses the Apache IOUtils code; in the screenshot above, you can see that the corresponding .jar file needed to call that (commons-io-2.4.jar) has been copied to the \app\libs folder. Once you do that (download it from here first), right-click the .jar file and select "Add as Library." This updates the build.gradle file with the necessary entry so that the Dependencies section now looks like this (I also added the gson jar that way):

XML
dependencies {
    compile 'com.android.support:appcompat-v7:+'
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile files('libs/commons-io-2.4.jar')
    compile files('libs/gson-2.2.4.jar')
}

This (updating of the build.gradle file) is something Droidio does for you that other environments don't, forcing you to jump through hoops like a captive tiger at the circus.

Meanwhile, Back at the Droid Ranch

To play along with the code below, add at least a button named DeptsCountBtn and an EditText named dynamicCountEdit.

Next, in MainActivity.java (the default main code file you will have in the default Android project), add a class that extends

AsyncTask 
(so that the instance of the class will run on a thread other than the UI thread) and which overrides the operation to be performed on that thread in its doInBackground() method and which also implements the onPostExecute() callback method, which will handle the results of the doInBackground() method like so:

Java
private class GetDepartmentsCount extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... params) {

        String urlString = params[0]; // URL to call
        String result = "";

        // HTTP Get
        try {
            URL url = new URL(urlString);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            InputStream inputStream = urlConnection.getInputStream();
            if (null != inputStream)
                result = IOUtils.toString(inputStream);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return e.getMessage();
        }
        return result;
    }

    @Override
    protected void onPostExecute(String result) {
        EditText dynCount = (EditText)findViewById(R.id.dynamicCountEdit);
        dynCount.setText(result + " records were found");
        Log.i("FromOnPostExecute", result);
    }
}

As you can probably tell, the OnPostExecute() code shows you the results of the call in the EditText and also writes it to Logcat.

Now, add the URL you will call and a reference to the method you just added in your Activity:

Java
private static final String getDeptCountsUrl =
"http://10.0.2.2:28642/api/Departments/GetCount?serialNum=4242";
private GetDepartmentsCount _getDeptsCount;

Note: Of course, you will have to replace the value assigned to getDeptCountsUrl to one of your own that returns an integer value. The "10.0.2.2" part, though, is necessary to retain when communicating with an emulator (when debugging from within Droidio and attaching to an emulator rather than directly accessing an Android device).

Add to the Activity's onCreate() event handler code to hook up a button you have added to the corresponding .xml (named "activity_main" in the example here) and then hook up an OnClickListener for that button like this:

Java
Button getDeptsCountBtn = (Button)findViewById(R.id.DeptsCountBtn);
getDeptsCountBtn.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        _getDeptsCount = new GetDepartmentsCount();
        _getDeptsCount.execute("http://10.0.2.2:28642/api/Departments/GetCount?serialNum=4242");
    }

Now to show the code in context, here is the entire thing:

Java
public class MainActivity extends ActionBarActivity {

    private GetDepartmentsCount _getDeptsCount;

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

        Button getDeptsCountBtn = (Button)findViewById(R.id.DeptsCountBtn);
        getDeptsCountBtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                _getDeptsCount = new GetDepartmentsCount();
                _getDeptsCount.execute("http://10.0.2.2:28642/api/Departments/GetCount?serialNum=4242");
            }
        });
    }

    @Override
    public void onStop() {
        super.onStop();
        _getDeptsCount.cancel(true);
    }

    private class GetDepartmentsCount extends AsyncTask<String, String, String> {

        @Override
        protected String doInBackground(String... params) {

            String urlString = params[0]; // URL to call
            String result = "";

            // HTTP Get
            try {
                URL url = new URL(urlString);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = urlConnection.getInputStream();
                if (null != inputStream)
                    result = IOUtils.toString(inputStream);
            } catch (Exception e) {
                System.out.println(e.getMessage());
                return e.getMessage();
            }
            return result;
        }

        @Override
        protected void onPostExecute(String result) {
            EditText dynCount = (EditText)findViewById(R.id.dynamicCountEdit);
            dynCount.setText(result + " records were found");
            Log.i("FromOnPostExecute", result);
        }
    } 
}

When you run the app from Droidio and mash the "Get Dept Count" button, you will soon (the definition of "soon" depends on how many gerbils are currently rowing the bark, I mean Internet, etc.) see the result:

Image 2

Not so fast there, Pard!

If you find this of benefit, please make use of Droidio's Help > Submit Feedback menu item so that the Googlers can make Droidio as good as possible as soon as possible. As the Jackson 5 said (paraphrasing), the bug you help squash may be your own.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)