Integrating LinkedIn API in Android App

To integrate the LinkedIn Sign-In functionality in an Android application, the LinkedIn API is implemented in the Android app. It thus provides the functionality to login using the LinkedIn account, shares post, etc. The LinkedIn Authentication Key (Client ID and Client Secret) and app Hash Key are a must for integrating the LinkedIn API in an Android app.

To generate LinkedIn Authentication Key and APP Hash Key:

  • In the ‘Create a New Application’ form, fill all the required details of the Android application.
  • Accept the LinkedIn API Terms of Use.
  • Click ‘Submit’.
  • The LinkedIn Authentication Key is generated, after submitting the application details.

  • Select the ‘Default Application Permissions’ which will authorize the access privilege of the user account.
  • Select r_basicprofile, and ‘r_emailaddress’.
  • Click ‘Update’.
  • The ‘Hash Key’ for the app can be generated by either of the two ways.
    • Using command on command prompt.
    • Using the programming code in Activity.java class.
  • Using command on command prompt:
    • Windows:
      keytool -exportcert -keystore %HOMEPATH%\.android\debug.keystore -alias androiddebugkey | openssl sha1 -binary | openssl base64

 

    • Mac/Unix:
      keytool -exportcert -keystore ~/.android/debug.keystore -alias androiddebugkey | openssl sha1 -binary | openssl base64

 

The OpenSSL needs to be installed in the operating system, to generate the Hash Key through command prompt. The OpenSSL can be downloaded from

  • Using the programming code in Activity.java class:
    PackageInfo info = getPackageManager().getPackageInfo(  
                        "Package Name",  
                        PackageManager.GET_SIGNATURES);  
                for (Signature signature : info.signatures) {  
                    MessageDigest md = MessageDigest.getInstance("SHA");  
                    md.update(signature.toByteArray());  
                    Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));

 

To generate ‘Hash Key’ for this application, we are using the programming code. To do this, write the below code in the application and run it. The application ‘Hash Key’ will be displayed in the Logcat.

MainActivity.java:

package com.example.radioapp;  
 
import android.content.pm.PackageInfo;  
import android.content.pm.PackageManager;  
import android.content.pm.Signature;  
import android.support.v7.app.AppCompatActivity;  
import android.os.Bundle;  
import android.util.Base64;  
import android.util.Log;  
 
import java.security.MessageDigest;  
 
 
public class MainActivity extends AppCompatActivity {  
    public static final String PACKAGE = "example.com.linkedinlogindemo";  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        computePakageHash();  
    }  
 
    private void computePakageHash() {  
        try {  
            PackageInfo info = getPackageManager().getPackageInfo(  
                    "example.com.linkedinlogindemo",  
                    PackageManager.GET_SIGNATURES);  
            for (Signature signature : info.signatures) {  
                MessageDigest md = MessageDigest.getInstance("SHA");  
                md.update(signature.toByteArray());  
                Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));  
            }  
        } catch (Exception e) {  
            Log.e("TAG",e.getMessage());  
        }  
    }  
}
  • Copy and Paste the ‘Hash Key’ from the Logcat to the Mobile tab of the application.
  • Click on ‘Add’ and ‘Update’ buttons.
  • Thus the application ‘Hash Key’ will be registered with the LinkedIn API.

Example:

In the below example, we are integrating the LinkedIn log-in functionality in our Android application. The user will be redirected to another activity i.e., ProfileActivity, after a successful user log-in. The user information will thus be displayed. To add the LinkedIn SDK for Android in a project, download it from https://developer.linkedin.com/downloads#androidsdk.

AndroidManifest.xml:

In the AndroidManifest.xml file, we will write the code to add the Internet permission.

Required Permission:

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

Code:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.radioapp">
 
    <uses-permission android:name="android.permission.INTERNET" />
 
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
 
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
 
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
 
        </activity>
        <activity
            android:name=".ProfileActivity" />
    </application>
</manifest>

settings.gradle:

In the settings.gradle file, we will write the code to add the linkedin-sdk.

include ':app', ':linkedin-sdk'

build.gradle (Module):

In the build.gradle file, we will write the code to add the compile project(path: ‘:linkedin-sdk’).

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support:support-annotations:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:design:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation project(path: ':linkedin-sdk')
 
    android {
        useLibrary 'org.apache.http.legacy'
    }
 
Code:
apply plugin: 'com.android.application'
 
android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.radioapp"
        minSdkVersion 23
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets {
        main {
            assets {
                srcDirs 'src/main/assets', 'src/main/res/assets/'
            }
        }
    }
}
 
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support:support-annotations:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:design:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.google.zxing:core:3.2.1'
    implementation project(path: ':linkedin-sdk')
 
    android {
        useLibrary 'org.apache.http.legacy'
    }
}

activity_main.xml:

In the activity_main.xml file, we will write the below code. The LinkedIn button can be downloaded from the LinkedIn developer site https://developer.linkedin.com/downloads. We will add the button as the background of the button.

Code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
 
    <Button
        android:id="@+id/login_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="50dp"
        android:background="@drawable/loginbutton"
        tools:layout_editor_absoluteX="100dp"
        tools:layout_editor_absoluteY="800dp" />
 
</RelativeLayout>

MainActivity.java:

In the MainActivity.java file, we will write the code to add the LISessionManager class. This class provides the functionalities to create and manage the LISession object i.e., LinkedIn session object. To access the basic profile information of the user and the email address of LinkedIn, scope adds the ‘Scope.R_BASICPROFILE’ and ‘Scope.R_EMAILADDRESS’, in the build.

Code:

package com.example.radioapp;
 
 
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.linkedin.platform.LISessionManager;
import com.linkedin.platform.errors.LIAuthError;
import com.linkedin.platform.listeners.AuthListener;
import com.linkedin.platform.utils.Scope;
 
 
public class MainActivity extends AppCompatActivity {
    Button loginBtn;
    TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        loginBtn = (Button) findViewById(R.id.login_button);
        loginBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loginHandle();
            }
        });
    }
    public void loginHandle() {
        LISessionManager.getInstance(getApplicationContext()).init(MainActivity.this, buildScope(), new AuthListener() {
            @Override
            public void onAuthSuccess() {
                // Authentication was successful.  You can now do other calls with the SDK.
 
                Intent intent=new Intent(MainActivity.this,ProfileActivity.class);
                startActivity(intent);
            }
 
            @Override
            public void onAuthError(LIAuthError error) {
                // Handle authentication errors
                Toast.makeText(getApplicationContext(),"Login Error "+error.toString(),Toast.LENGTH_LONG).show();
            }
        }, true);
    }
 
    private static Scope buildScope() {
        return Scope.build(Scope.R_BASICPROFILE, Scope.R_EMAILADDRESS);
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // Add this line to your existing onActivityResult() method
        LISessionManager.getInstance(getApplicationContext()).onActivityResult(this, requestCode, resultCode, data);
    }
 
 
}

activity_profile.xml:

In the activity_profile.xml file, we will write the code to display the user information after a successful login.

Code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    tools:context=".ProfileActivity">
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Welcome to profile" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/userDetail"
        android:text="userdetail"
        android:layout_marginTop="20dp"
        />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:textColor="#FFF"
        android:text="logout"
        android:id="@+id/logout_button"
        android:background="#022885"
        />
</LinearLayout>

ProfileActivity.java:

In the ProfileActivity.java file, we will write the code to add the LinkedIn API URL https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address) in getRequest() method of APIHelper class. The user information will thus be retrieved on the success of the LinkedIn API.

Code:

package com.example.radioapp;
 
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
 
import com.linkedin.platform.APIHelper;
import com.linkedin.platform.LISession;
import com.linkedin.platform.LISessionManager;
import com.linkedin.platform.errors.LIApiError;
import com.linkedin.platform.listeners.ApiListener;
import com.linkedin.platform.listeners.ApiResponse;
 
import org.json.JSONException;
import org.json.JSONObject;
 
public class ProfileActivity extends AppCompatActivity {
    TextView user_detail;
    String firstName,lastName,userEmail;
    Button logout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_profile);
        user_detail=(TextView)findViewById(R.id.userDetail);
        logout=(Button)findViewById(R.id.logout_button);
 
        fetchuserData();
 
        logout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                LISessionManager.getInstance(getApplicationContext()).clearSession();
                Toast.makeText(getApplicationContext(),"Logout Successfully",Toast.LENGTH_LONG).show();
                Intent intent = new Intent(ProfileActivity.this, MainActivity.class);
                startActivity(intent);
            }
        });
    }
 
    private void fetchuserData() {
        String url = "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address)";
 
        APIHelper apiHelper = APIHelper.getInstance(getApplicationContext());
        apiHelper.getRequest(this, url, new ApiListener() {
            @Override
            public void onApiSuccess(ApiResponse apiResponse) {
                // Success!
                try {
                    JSONObject jsonObject = apiResponse.getResponseDataAsJson();
                    firstName = jsonObject.getString("firstName");
                    lastName = jsonObject.getString("lastName");
                    userEmail = jsonObject.getString("emailAddress");
 
                    StringBuilder stringBuilder = new StringBuilder();
                    stringBuilder.append("First Name " + firstName + "\n\n");
                    stringBuilder.append("Last Name " + lastName + "\n\n");
                    stringBuilder.append("Email " + userEmail);
 
                    user_detail.setText(stringBuilder);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
 
            }
 
            @Override
            public void onApiError(LIApiError liApiError) {
                // Error making GET request!
                Toast.makeText(getApplicationContext(),"API Error"+liApiError.toString(),Toast.LENGTH_LONG).show();
            }
        });
    }
}

Output 1:

Output 2: