Posting LinkedIn message from Android application

2020-01-29 07:36发布

问题:

I want to integrate my Android application with LinkedIn and post a message. Can anyone provide an example for how to do this?

回答1:

did you even try google it ? from http://developer.linkedin.com/docs/DOC-1255 we got http://code.google.com/p/linkedin-j/

EDIT: here is my sample project http://esilo.pl/LITest.zip

EDIT2: minimal sample, with tokens stored in SharedPreferences (so you don't need to do authorization every time(i'll update LITest.zip))

EDIT3: AsyncTask code added ... to avoid NetworkOnMainThreadException :)

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="pl.selvin.android.LinkedInTest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />

    <uses-permission android:name="android.permission.INTERNET" />

    <application android:label="LinkedInTest" >
        <activity
            android:name=".LITestActivity"
            android:label="LinkedIn Test"
            android:launchMode="singleInstance" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:host="litestcalback"
                    android:scheme="x-oauthflow-linkedin" />
            </intent-filter>
        </activity>
    </application>

</manifest>

LITestActivity.java:

package pl.selvin.android.LinkedInTest;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import com.google.code.linkedinapi.client.LinkedInApiClient;
import com.google.code.linkedinapi.client.LinkedInApiClientException;
import com.google.code.linkedinapi.client.LinkedInApiClientFactory;
import com.google.code.linkedinapi.client.oauth.LinkedInAccessToken;
import com.google.code.linkedinapi.client.oauth.LinkedInOAuthService;
import com.google.code.linkedinapi.client.oauth.LinkedInOAuthServiceFactory;
import com.google.code.linkedinapi.client.oauth.LinkedInRequestToken;
import com.google.code.linkedinapi.schema.Person;

public class LITestActivity extends Activity {

    // /change keysssssssssssssssssssssssssssss!!!!!!!!!!

    static final String CONSUMER_KEY = "keykeykeykey";
    static final String CONSUMER_SECRET = "secretsecret";

    static final String APP_NAME = "LITest";
    static final String OAUTH_CALLBACK_SCHEME = "x-oauthflow-linkedin";
    static final String OAUTH_CALLBACK_HOST = "litestcalback";
    static final String OAUTH_CALLBACK_URL = String.format("%s://%s",
            OAUTH_CALLBACK_SCHEME, OAUTH_CALLBACK_HOST);
    static final String OAUTH_QUERY_TOKEN = "oauth_token";
    static final String OAUTH_QUERY_VERIFIER = "oauth_verifier";
    static final String OAUTH_QUERY_PROBLEM = "oauth_problem";

    final LinkedInOAuthService oAuthService = LinkedInOAuthServiceFactory
            .getInstance().createLinkedInOAuthService(CONSUMER_KEY,
                    CONSUMER_SECRET);
    final LinkedInApiClientFactory factory = LinkedInApiClientFactory
            .newInstance(CONSUMER_KEY, CONSUMER_SECRET);

    static final String OAUTH_PREF = "LIKEDIN_OAUTH";
    static final String PREF_TOKEN = "token";
    static final String PREF_TOKENSECRET = "tokenSecret";
    static final String PREF_REQTOKENSECRET = "requestTokenSecret";

    TextView tv = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tv = new TextView(this);
        setContentView(tv);
        final SharedPreferences pref = getSharedPreferences(OAUTH_PREF,
                MODE_PRIVATE);
        final String token = pref.getString(PREF_TOKEN, null);
        final String tokenSecret = pref.getString(PREF_TOKENSECRET, null);
        if (token == null || tokenSecret == null) {
            startAutheniticate();
        } else {
            showCurrentUser(new LinkedInAccessToken(token, tokenSecret));
        }

    }

    void startAutheniticate() {
        new AsyncTask<Void, Void, LinkedInRequestToken>() {

            @Override
            protected LinkedInRequestToken doInBackground(Void... params) {
                return oAuthService.getOAuthRequestToken(OAUTH_CALLBACK_URL);
            }

            @Override
            protected void onPostExecute(LinkedInRequestToken liToken) {
                final String uri = liToken.getAuthorizationUrl();
                getSharedPreferences(OAUTH_PREF, MODE_PRIVATE)
                        .edit()
                        .putString(PREF_REQTOKENSECRET,
                                liToken.getTokenSecret()).commit();
                Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
                startActivity(i);
            }
        }.execute();
    }

    void finishAuthenticate(final Uri uri) {
        if (uri != null && uri.getScheme().equals(OAUTH_CALLBACK_SCHEME)) {
            final String problem = uri.getQueryParameter(OAUTH_QUERY_PROBLEM);
            if (problem == null) {

                new AsyncTask<Void, Void, LinkedInAccessToken>() {

                    @Override
                    protected LinkedInAccessToken doInBackground(Void... params) {
                        final SharedPreferences pref = getSharedPreferences(
                                OAUTH_PREF, MODE_PRIVATE);
                        final LinkedInAccessToken accessToken = oAuthService
                                .getOAuthAccessToken(
                                        new LinkedInRequestToken(
                                                uri.getQueryParameter(OAUTH_QUERY_TOKEN),
                                                pref.getString(
                                                        PREF_REQTOKENSECRET,
                                                        null)),
                                        uri.getQueryParameter(OAUTH_QUERY_VERIFIER));
                        pref.edit()
                                .putString(PREF_TOKEN, accessToken.getToken())
                                .putString(PREF_TOKENSECRET,
                                        accessToken.getTokenSecret())
                                .remove(PREF_REQTOKENSECRET).commit();
                        return accessToken;
                    }

                    @Override
                    protected void onPostExecute(LinkedInAccessToken accessToken) {
                        showCurrentUser(accessToken);
                    }
                }.execute();

            } else {
                Toast.makeText(this,
                        "Appliaction down due OAuth problem: " + problem,
                        Toast.LENGTH_LONG).show();
                finish();
            }

        }
    }

    void clearTokens() {
        getSharedPreferences(OAUTH_PREF, MODE_PRIVATE).edit()
                .remove(PREF_TOKEN).remove(PREF_TOKENSECRET)
                .remove(PREF_REQTOKENSECRET).commit();
    }

    void showCurrentUser(final LinkedInAccessToken accessToken) {
        final LinkedInApiClient client = factory
                .createLinkedInApiClient(accessToken);

        new AsyncTask<Void, Void, Object>() {

            @Override
            protected Object doInBackground(Void... params) {
                try {

                    final Person p = client.getProfileForCurrentUser();
                    // /////////////////////////////////////////////////////////
                    // here you can do client API calls ...
                    // client.postComment(arg0, arg1);
                    // client.updateCurrentStatus(arg0);
                    // or any other API call
                    // (this sample only check for current user
                    // and pass it to onPostExecute)
                    // /////////////////////////////////////////////////////////
                    return p;
                } catch (LinkedInApiClientException ex) {
                    return ex;
                }
            }

            @Override
            protected void onPostExecute(Object result) {
                if (result instanceof Exception) {
                    //result is an Exception :) 
                    final Exception ex = (Exception) result;
                    clearTokens();
                    Toast.makeText(
                            LITestActivity.this,
                            "Appliaction down due LinkedInApiClientException: "
                                    + ex.getMessage()
                                    + " Authokens cleared - try run application again.",
                            Toast.LENGTH_LONG).show();
                    finish();
                } else if (result instanceof Person) {
                    final Person p = (Person) result;
                    tv.setText(p.getLastName() + ", " + p.getFirstName());
                }
            }
        }.execute();

    }

    @Override
    protected void onNewIntent(Intent intent) {
        finishAuthenticate(intent.getData());
    }
}


回答2:

very helpful answer @Selvin!

this code should work fine on pre Honeycomb (API 11) targets, but it will fail with NetworkOnMainThreadException on (post) API 11. On pre IAPI 11 it's best avoided to run (possible long) network activity on the UI thread too, since it may lock it up.

I've updated Selvin's code to make it post API 10 compatible.

package com.package.my;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.google.code.linkedinapi.client.LinkedInApiClient;
import com.google.code.linkedinapi.client.LinkedInApiClientException;
import com.google.code.linkedinapi.client.LinkedInApiClientFactory;
import com.google.code.linkedinapi.client.oauth.LinkedInAccessToken;
import com.google.code.linkedinapi.client.oauth.LinkedInOAuthService;
import com.google.code.linkedinapi.client.oauth.LinkedInOAuthServiceFactory;
import com.google.code.linkedinapi.client.oauth.LinkedInRequestToken;
import com.google.code.linkedinapi.schema.Person;

public class your_class_name extends Activity {
    public static final String CONSUMER_KEY             = "your_app_key";
    public static final String CONSUMER_SECRET          = "your_app_secret";    
    public static final String APP_NAME                 = "your app name";
    public static final String OAUTH_CALLBACK_SCHEME    = "x-oauthflow-linkedin";
    public static final String OAUTH_CALLBACK_HOST      = "litestcalback";
    public static final String OAUTH_CALLBACK_URL       = OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST;
    static final String OAUTH_QUERY_TOKEN               = "oauth_token";
    static final String OAUTH_QUERY_VERIFIER            = "oauth_verifier";
    static final String OAUTH_QUERY_PROBLEM             = "oauth_problem";
    static final String OAUTH_PREF                      = "AppPreferences";
    static final String PREF_TOKEN                      = "linkedin_token";
    static final String PREF_TOKENSECRET                = "linkedin_token_secret";
    static final String PREF_REQTOKENSECRET             = "linkedin_request_token_secret";

    final LinkedInOAuthService oAuthService             = LinkedInOAuthServiceFactory.getInstance().createLinkedInOAuthService(CONSUMER_KEY, CONSUMER_SECRET);
    final LinkedInApiClientFactory factory              = LinkedInApiClientFactory.newInstance(CONSUMER_KEY, CONSUMER_SECRET);
    LinkedInRequestToken liToken;
    LinkedInApiClient client;

    TextView tv = null;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        tv = new TextView(this);
        setContentView(tv);
        final SharedPreferences pref    = getSharedPreferences(OAUTH_PREF, MODE_PRIVATE);
        final String token              = pref.getString(PREF_TOKEN, null);
        final String tokenSecret        = pref.getString(PREF_TOKENSECRET, null);
        if (token == null || tokenSecret == null) {
            startAutheniticate();
        } else {
            LinkedInAccessToken accessToken = new LinkedInAccessToken(token, tokenSecret);
            showCurrentUser(accessToken);
        }
    }//end method

    void startAutheniticate() {
        new Thread(){//added because this will make code work on post API 10 
            @Override
            public void run(){
                final LinkedInRequestToken liToken  = oAuthService.getOAuthRequestToken(OAUTH_CALLBACK_URL); 
                final String uri                    = liToken.getAuthorizationUrl();
                final SharedPreferences pref        = getSharedPreferences(OAUTH_PREF, MODE_PRIVATE);
                SharedPreferences.Editor editor     = pref.edit(); 
                editor.putString(PREF_REQTOKENSECRET, liToken.getTokenSecret());
                editor.commit();
                Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
                startActivity(i);
             }
        }.start();
    }//end method

    void finishAuthenticate(final Uri uri) {
        new Thread(){
            @Override
            public void run(){
                Looper.prepare();
                if (uri != null && uri.getScheme().equals(OAUTH_CALLBACK_SCHEME)) {
                    final String problem = uri.getQueryParameter(OAUTH_QUERY_PROBLEM);
                    if (problem == null) {
                        final SharedPreferences pref                = getSharedPreferences(OAUTH_PREF, MODE_PRIVATE);
                        final String request_token_secret           = pref.getString(PREF_REQTOKENSECRET, null);
                        final String query_token                    = uri.getQueryParameter(OAUTH_QUERY_TOKEN);
                        final LinkedInRequestToken request_token    = new LinkedInRequestToken(query_token, request_token_secret);
                        final LinkedInAccessToken accessToken       = oAuthService.getOAuthAccessToken(request_token, uri.getQueryParameter(OAUTH_QUERY_VERIFIER));
                        SharedPreferences.Editor editor = pref.edit(); 
                        editor.putString(PREF_TOKEN, accessToken.getToken());
                        editor.putString(PREF_TOKENSECRET, accessToken.getTokenSecret());
                        editor.remove(PREF_REQTOKENSECRET);
                        editor.commit();
                        showCurrentUser(accessToken);
                    } else {
                        Toast.makeText(getApplicationContext(), "Application down due OAuth problem: " + problem, Toast.LENGTH_LONG).show();
                        finish();
                    }
                }
                Looper.loop();
            }
        }.start();
    }//end method

    void clearTokens() {
        getSharedPreferences(OAUTH_PREF, MODE_PRIVATE).edit().remove(PREF_TOKEN).remove(PREF_TOKENSECRET).remove(PREF_REQTOKENSECRET).commit();
    }//end method

    void showCurrentUser(final LinkedInAccessToken accessToken) {
        new Thread(){
            @Override
            public void run(){
                Looper.prepare();
                final LinkedInApiClient client = factory.createLinkedInApiClient(accessToken);
                try {
                    final Person p = client.getProfileForCurrentUser();
                    // /////////////////////////////////////////////////////////
                    // here you can do client API calls ...
                    // client.postComment(arg0, arg1);
                    // client.updateCurrentStatus(arg0);
                    // or any other API call (this sample only check for current user
                    // and shows it in TextView)
                    // /////////////////////////////////////////////////////////             
                    runOnUiThread(new Runnable() {//updating UI thread from different thread not a good idea...
                        public void run() {
                            tv.setText(p.getLastName() + ", " + p.getFirstName());
                        }
                    });
                    //or use Toast
                    //Toast.makeText(getApplicationContext(), "Lastname:: "+p.getLastName() + ", First name: " + p.getFirstName(), 1).show();
                } catch (LinkedInApiClientException ex) {
                    clearTokens();
                    Toast.makeText(getApplicationContext(),
                        "Application down due LinkedInApiClientException: "+ ex.getMessage() + " Authokens cleared - try run application again.",
                        Toast.LENGTH_LONG).show();
                    finish();
                }
                Looper.loop();
            }
        }.start();
    }//end method

    @Override
    protected void onNewIntent(Intent intent) {
        finishAuthenticate(intent.getData());
    }//end method
}//end class

Hope someone finds this useful! Credits go to Selvin.