Orkut Application Platform

Orkut API Adapter for Android: accessing Orkut from an Android application

Bruno Oliveira, Developer Relations
January 2011

Contents:

What is the Orkut API Adapter for Android?

The Orkut API Adapter for Android is an experimental extension to the Orkut Client Library that allows you to make calls to Orkut from an Android application.

In this article, we will assume that you are familiar with the Client Library, version 2.0 or above. If this is not the case, then we recommend that you read the Client Library's Developer Guide first, as that will help you better understand the material we will present here. Also, if you are familiar with the 1.1 version of the client library but not the recently released 2.0, it might be worth taking a look at the guide as well, since there were significant changes.

We will also presume, naturally, that you are familiar with the basics of developing Android applications. If you have little experience with Android, we recommend that you take a look at the documentation and tutorials available at the developer.android.com site before proceeding. However, you don't need to be an expert in Android to use the Orkut API Adapter for Android: we will only employ very basic concepts like activities, intents, the AndroidManifest.xml file, shared preferences, etc.

Where can I download the Orkut API Adapter for Android?

You can download the latest version of the Orkut API Adapter for Android directly from http://code.google.com/p/orkroid. Please bear in mind that it's a very simple library, so, in order to achieve the maximum possible environment compatibility, it is supplied directly as source files rather than a compiled format like a .jar.

How do I include the Orkut API Adapter for Android in my Android project?

Including the library in your Android project is probably much simpler than you imagined: simply copy all the project's source files into your project's source tree. In Linux or Mac, you could use these commands, supposing that your project is in ~/MyProject and that you downloaded and unpacked the Orkut API Adapter for Android library to /tmp/orkroid:

$ cd ~/MyProject
$ mkdir -p src/com/google/orkut/orkroid $ cd src/com/google/orkut/orkroid $ cp /tmp/orkroid/src/com/google/orkut/orkroid/* .

Or, if you are using another operating system or a specific development platform, perform the necessary steps as appropriate for your environment. But keep in mind that, as with any Java project, the path of the .java files must correspond to their fully qualified package name. Since the fully qualified package name for all Orkut API Adapter for Android classes is com.google.orkut.orkroid, that means that the files must be installed in the path com/google/orkut/orkroid relative to your project's base source path.

Please notice that you will also need to include the Orkut Client Library (version 2.0 or above), in your project, since the Orkut API Adapter for Android depends on it.

A note about omissions

In this article, we may sometimes omit the import statements in our explanation for brevity, but they are very easy to obtain. If your development environment doesn't generate them automatically (or at the press of a button), entering them manually is straightforward: you can find most of the classes we will use under the com.google.orkut.client.api namespace, or the com.google.orkut.orkroid namespace (the latter contains the classes that are specific to the Orkut API Adapter for Android).

We will also use common Android classes like Activity, Intent, widget classes, etc. These are found in the android namespace hierarchy. If you have any doubt about these classes, please refer to the documentation available at developer.android.com.

We will also omit a lot of error handling in this article, but please be aware that many of the functions in the Orkut Client Library and in the Orkut API Adapter for Android may throw exceptions, and your code should be ready to deal with them.

Initialization

When using the Client Library, the starting step in any project is to initialize it with your consumer key and consumer secret. It's the same with the Orkut API Adapter for Android:

import com.google.orkut.client.api.OrkutAdapter;
import com.google.orkut.client.api.DefaultOrkutAdapter;

(...)

OrkutAdapter orkad = new DefaultOrkutAdapter(
   "your.consumer.key.here",
   "YourConsumerSecretHere",
   "about:blank",  // redirect page -- use about:blank
   false,          // false for sandbox, true for production
   null            // debug listener (attach one if you want)
);

After you initialize your OrkutAdapter object, you have to initialize the Orkut API Adapter for Android. To do that, call Orkroid.init:

Orkroid.init(orkad);

You can put this initialization code wherever it makes sense in your application. For example, you could run this in an initial "welcome screen" Activity. The only requirement is that, naturally, this initialization must happen before you use anything else on the Orkut API Adapter for Android or the Client Library.

Authentication

As you know, you have to ways to authenticate an OrkutAdapter: you can provide an existing "access pass" (that you saved from another session) through the setAccessPass() function, or you can perform the "OAuth dance", that is, direct the user to the orkut login page to have him log in and authorize your application.

One of the major features of the Orkut API Adapter for Android is that it encapsulates the whole "OAuth Dance" for you (including the whole process of embedding a web browser in the application, redirecting it to the authentication URL, obtaining the verifier token, etc). You only have to write few lines of integration code. The Orkut API Adapter for Android comes with a ready-made Activity (as in, an Android Activity) that performs the whole OAuth workflow with the user, exchaning all the necessary tokens, and then automatically prepares the OrkutAdapter object for you.

To launch this activity, you have to do two things: firstly, you have to include that activity in your application's AndroidManifest.xml file:

<activity android:name="com.google.orkut.orkroid.OrkroidAuthActivity"
              android:label="@string/app_name"
              android:theme="@android:style/Theme.NoTitleBar" />

And then, launch it when you are ready. This is done exactly as you expect, that is, in the same way as you would launch any other activity:

Intent intent = new Intent(this, OrkroidAuthActivity.class);
startActivityForResult(intent, 0);

Here, we are using startActivityForResult rather than startActivity, because we want to be notified when the activity returns. When it does, we will know whether the login process succeeded or failed, and, if it succeeded, the OrkutAdapter object will be ready for our use.

So, for reference, here is snippet of code of the whole process:

// Initialize an Orkut Adapter (Client Library)
OrkutAdapter orkad = new DefaultOrkutAdapter(
   "your.consumer.key.here",
   "YourConsumerSecretHere",
   "about:blank",  // redirect page -- use about:blank
   false,          // false for sandbox, true for production
   null            // debug listener (attach one if you want)
);

// Initialize Orkut API Adapter for Android
Orkroid.init(orkad);

// Do we have an access pass stored from last time?
SharedPreferences sp = getPreferences(MODE_PRIVATE);
String accessPass = sp.getString("accesspass", "");

if (accessPass.equals("")) {
   // nope, no access pass -- start OAuth Dance:
   Intent intent = new Intent(this, OrkroidAuthActivity.class);
   startActivityForResult(intent, 0);
}
else {
   // we already have an access pass -- use it.
   Orkroid.getOA().setAccessPass(accessPass);

   // launch our main manu activity:
   Intent intent = new Intent(this, MainMenuActivity.class);
   startActivity(intent);
   finish();  // we are done
}

So, now we need to receive the notification from the OrkroidAuthActivity. How do we do this? Well, we must override the onActivityResult method in our activity. This is the method that the framework will call when the OrkroidAuthActivity that we launched returns with its result.

So without further delay, let's implement that in our activity:

public void onActivityResult(int requestCode, int resultCode, Intent data) {
   super.onActivityResult(requestCode, resultCode, data);

   if (resultCode == RESULT_OK) {
      // success -- save the access pass for future use!
      SharedPreferences.Editor spe = getPreferences(MODE_PRIVATE).edit();
      spe.putString("accesspass", Orkroid.getOA().getAccessPass());
      spe.commit();

      // go to our main menu
      Intent intent = new Intent(this, MainMenuActivity.class);
      startActivity(intent);
      finish();  // we are done
   }
   else {
      // failed. handle error somehow. Here, we'll be simple:
      Exception ex = (Exception) data.getSerializableExtra("exception");
      Toast.makeText(this, "Authentication failed: " +
                ex.getMessage(), Toast.LENGTH_LONG).show();
   }
}

So, as we said before, onActivityResult is a member function that the framework calls when an activity that you launched finishes (actually, not any activity, but only the ones you launched with startActivityForResult() -- but not the ones you launch with a plain startActivity()).

The requestCode will be the same as the second parameter you passed to startActivityForResult. In our example, we passed 0 to it, so 0 is what we would receive in requestCode. Why is this useful? Because if you are launching two or more activities with startActivityForResult(), you can give them different codes and then you can use the requestCode parameter to tell them apart in the onActivityResult method. Otherwise you won't know which one has finished.

The resultCode parameter tells us whether the authentication was successful or not. If it's RESULT_OK, then the authentication was successful and we can proceed to our application's main menu, as illustrated in the code. If resultCode is any other value, it means that our authentication failed. You can get the exception that caused the failure by calling the getSerializableExtra() method of the returned Intent, as illustrated in the code.

Notice that when we authenticate successfully, we are saving the access pass into the application's SharedPreferences. Naturally, this step is optional: you can choose any other method to store the access pass or not do it at all. However, if you don't store the access pass for later use, the user will have to log in again every time he launches your application, which may be very inconvenient. Also, remember that only saving it to the SharedPreferences doesn't do anything -- the Orkut API Adapter for Android doesn't know anything about SharedPreferences. You have to load them too, when your app is initializing, like we did (to recapitulate, take another look at the beginning of this section, where we load the access pass from the SharedPreferences).

Making Requests

Now that we know how to initialize the OrkutAdapter object and authenticate, we can move on to our main objective: making requests to orkut. This is actually very simple, but there is a slight "catch" in Android: you cannot block for a long time on the UI thread. This is a common demand made by several user interface toolkits: the code that responds to a UI event should be very, very fast. Remember that users are less sensitive about actual speed than about responsiveness, so hanging for 5 seconds with the user interface completely frozen will probably cause a much worse impression than making the user wait for 10 seconds with a responsive interface that lets the user continue to work while the computation goes on in the background (or, at the very least, displays an animation and a progress bar).

Because of this principle, when you have to run code that may take a long time to complete (and when we are talking about interface responsiveness, anything longer than half a second is a long time), the typical pattern in Android is making the UI event code fire an AsyncTask (or, more precisely, your subclass of AsyncTask), and return from the event handler immediately after. The actual processing happens in the AsyncTask's doInBackground method. When it is finished, it schedules the onPostExecute method to run in the UI thread to show the results of the computation to the user.

To spare you the need to write your own subclass of AsyncTask and deal with the administrative tasks involved in setting it up, the Orkut API Adapter for Android provides you with a very simple method: OrkroidTask.execute(). You simply supply it the batch transaction that you want to execute in the background and a reference to a callback listener (typically the activity itself), and it will handle all the work of making the request to orkut's servers and calling your callback on the UI thread when it's done.

Here is how you use it:

public class MyActivity extends Activity implements OrkroidTask.Listener {
   (...)

   public void onClick(View target) { // or any other event handler
      try {
         BatchTransaction btx;

         // (create and populate BatchTransaction here)

         OrkroidTask.execute("", btx, this);
      }
      catch (Exception ex) {
         // (handle error here)
      }
   }

   public void onOrkroidTaskFinished(String tag, BatchTransaction btx,
                Exception exc) {
      if (exc != null) {
         // handle exception (exc)
      }
      else {
         // handle success
      }
   }
}

The tag parameter is just an arbitrary string that you can pass to OrkroidTask.execute, and it will give you back the same string in onOrkroidTaskFinished. This is useful if you are making several requests in parallel and you want a way to tell which one has finished when onOrkroidTaskFinished is called. If you are only doing one request at a time, you can ignore the tag parameter and just feed the empty string to it like we did above.

So, to give a real example, let's write the full code for an activity that allows the user to update his orkut status. Our activity has a TextView whose resource ID is statustext, and a button whose ID is submitbutton. So, let's first add the boilerplate code that creates the activity initializes our member variables:

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.orkut.client.api.BatchTransaction;
import com.google.orkut.client.api.UpdateProfileTx;
import com.google.orkut.orkroid.Orkroid;
import com.google.orkut.orkroid.OrkroidTask;

public class SetStatusActivity extends Activity implements
                        OrkroidTask.Listener, View.OnClickListener {
   protected Button submitButton;
   protected EditText statusText;
   protected ProgressDialog progressDialog = null;

   public void onCreate(Bundle savedInstanceBundle) {
      super.onCreate(savedInstanceBundle);
      setContentView(R.layout.setstatusactivity);
      submitButton = (Button) findViewById(R.id.submitbutton);
      statusText = (EditText) findViewById(R.id.statustext);

      submitButton.setOnClickListener(this);
   }

   public void onClick(View target) {
      if (target == submitButton) {
         // TODO 1: (we'll add the update code here)
      }
   }

   public void showToast(String errmsg) {
      Toast.makeText(this, errmsg, Toast.LENGTH_LONG).show();
   }

   public void onOrkroidTaskFinished(String tag, BatchTransaction btx,
         Exception exc) {
      // TODO 2: (we'll add our callback code here)
   }
}

As you can see, we are simply doing standard Android setup: assigning references to our widgets of interest to protected variables and connecting event handlers.

Let's focus on the TODO 1 part above. That's where we have to fill in the code that will run when the user clicks the "Submit" button after entering his new status text in statusText. Like we said before, this event handler should not make the request but instead fire off a background task via OrkroidTask.execute. But before that, we have to prepare the batch transaction with a request to update the status:

try {
   // This code goes in the TODO 1 section in the code skeleton above

   // Show a progress dialog to keep the user happy
   progressDialog = ProgressDialog.show(this, "Updating...",
                   "Updating your status...");

   // Create the batch transaction and set it up with the request
   // to change user status:
   UpdateProfileTx tx = Orkroid.getOA().getProfileTF().updateSelfProfile();
   tx.setStatus(statusText.getText().toString());
   btx.add(tx);

   // Now that the batch is done, feed it to OrkroidTask.execute():
   OrkroidTask.execute("", btx, this);
}
catch (Exception ex) {
   showToast("Error submitting transaction: " + ex.toString());
}

Well, the next thing is implementing TODO 2, which is the code that executes when the batch finishes running. There are two possible results: not surprisingly, the two possible results are that the batch succeeded or it failed. If it failed, the onOrkroidTaskFinished method will receive a null value in its btx parameter, and possibly the exception that caused the problem in its exc parameter.

So here is an example of how we could implement onOrkroidTaskFinished:

public void onOrkroidTaskFinished(String tag,
                BatchTransaction btx, Exception exc) {

   if (progressDialog != null) progressDialog.dismiss();
   progressDialog = null;

   if (btx == null) {
      // an error occurred
      if (exc != null) showToast("Error: " + exc.getMessage());
      else             showToast("Unknown error while accessing orkut.");
   }
   else {
      // success!
      showToast("Status updated!");
   }
}

As you can see, all it really does is dismiss the progress dialog and inform the user of the success or failure of that request. Your application can be more elaborate than that, of course. Particularly, if you made a request that expects to read data back from the server (listing friends, for example), the onOrkroidTaskFinished method is the right place to retrieve the data, since it will all be there in the BatchTransaction. All you have to do is query the individual transactions and get your data (remember that you can get the individual transactions from a BatchTransaction via the getTransaction(index) method).

Finishing Remarks

We hope this quick introduction has been helpful. If you have any feedback or questions, please visit the Orkut Developer Forum.

Happy coding!

Bruno Oliveira

Authentication required

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

Signing you in...

Google Developers needs your permission to do that.