Saturday, July 28, 2012

Android LinkedIn connections implementation

For purpose of this article it is assumed that the LinkedIn OAuth flow is complete as described in this article Android LinkedIn OAuth implementation. The idea of Android LinkedIn connections implementation is to get all the first degree connections of the logged in LinkedIn user and display in a list view.

For displaying the connections we have 2 simple layouts.

The basic list view which represents the entire connection list.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/linkedInList"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
    </ListView>

</RelativeLayout>

The basic list view item which represents displaying one connection in the list.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="5dp">

    <TextView
        android:id="@+id/feedItemText"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:paddingTop="5dp"
        android:paddingLeft="5dp"
        android:autoLink="web"
        android:textSize="12dp"/>

</RelativeLayout>

We use an ArrayAdapter to provide and hold the connections data to list.
// List adapter
private static class LinkedInAdapter extends ArrayAdapter<String> {

     private LinkedInListActivity mActivity = null;
     private LayoutInflater mInflater = null;

     static class ViewHolder {
     TextView feedItemText;      
     }         

     public LinkedInAdapter(LinkedInListActivity activity, Context context,
                     ArrayList<String> values) {
        super(context, R.layout.linkedin_list_item, values);
        this.mActivity = activity;

         // Cache the LayoutInflate to avoid asking for a new one each time.
         mInflater = LayoutInflater.from(context);
     }  

     @Override
     public View getView(int position, View convertView, ViewGroup parent) {
         View v = convertView;
         ViewHolder holder;

         if ( v == null ) {
             v = mInflater.inflate(R.layout.linkedin_list_item, null);
             holder = new ViewHolder();
             holder.feedItemText = (TextView) v.findViewById(R.id.feedItemText);
             v.setTag(holder);
         }
         else {
             holder = (ViewHolder) convertView.getTag();
         }

         if ( holder.feedItemText != null ) {      
             holder.feedItemText.setText(mActivity.mConnections.get(position).toString());
         } 

         return v;
     }     

     public void add(String s) {
         mActivity.mConnections.add(s);
     }
}

We use a AsyncTask to request the connections data from LinkedIn and parse and populate the connections data to the list adapter. REST API interface is used to request the connections. The output data format used is JSON here.

private String LINKED_IN_CONNECTIONS_API = "http://api.linkedin.com/v1/people/~/connections";
String urlStr = LINKED_IN_CONNECTIONS_API;
urlStr += "?format=json";

We create a scribe service instance for LinkedIn. We make a GET request on the connections URL. Also the access token and secret received in the OAUth flow is used to sign the request.
  
OAuthService linkedInService = new ServiceBuilder()
  .provider(LinkedInApi.class)
  .apiSecret( LinkedInOAuthActivity.APISECRET )
  .callback( LinkedInOAuthActivity.CALLBACK )
  .build();

OAuthRequest request = new OAuthRequest(Verb.GET, urlStr); 

Token t = new Token(access_token, access_secret);
linkedInService.signRequest(t, request);

Response response = null;
try {
  response = request.send();
 if ( response.isSuccessful() )
  return response.getBody();
 else
  return null;
}
catch ( Exception e ) {
 e.printStackTrace();
 return null;
}

Once the response is received we parse the body which has the JSON data corresponding to all the connections. We extract the first name and last name and populate in the list.
for ( int i = 0; i < arr.length(); i++) {
   try {
       jsonObject = arr.getJSONObject(i);
   } catch (JSONException e1) {
       e1.printStackTrace();
   }

   try {  
       String fn = jsonObject.getString("firstName");
       String ln = jsonObject.getString("lastName");
       mLinkedInListAdapter.add(fn + " " + ln);
   }
   catch (JSONException e1) {
       e1.printStackTrace();
   }
}

Finally we notify that data in list adapter has changed to render in the list view.
mLinkedInListAdapter.notifyDataSetChanged();

2 comments :

  1. I got this example running, but if I change out the API key and API secret to my own, it instantly stops working, I'm not sure why, as it doesn't seem like settings in the LinkedIn developer App settings, any help you can give to clarify this issue, would be greatly appreciated.

    ReplyDelete
  2. Is there a way authenticate the user seemly, without getting the LinkedIn "Are you Human" check

    ReplyDelete

Contact Form

Name

Email *

Message *

Back to Top