Skip to content Skip to sidebar Skip to footer

How To Implement "login With Linkedin" With "oauth 2.0" In Android

In OAuth1.0 'Login with Linkedin' Working fine but before few days Linkedin make some changes in their policy, please refer below link for more detail, https://engineering.linkedin

Solution 1:

After a little effort I got it working, but implementing it every time you start a new project will waste a lot of time.

So I created a light weight library for the same.

Just add the dependency to your app level build.gradle file

dependencies {
    implementation 'com.shantanudeshmukh:linkedinsdk:1.0.0'
}

Initiate Login Request.

LinkedInBuilder.getInstance(MainActivity.this)
        .setClientID("<YOUR_CLIENT_ID_HERE>")
        .setClientSecret("<YOUR_CLIENT_SECRET_HERE>")
        .setRedirectURI("<YOUR_REDIRECT_URL_HERE>")
        .authenticate(LINKEDIN_REQUEST_CODE);

Handle the response:

@OverrideprotectedvoidonActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == LINKEDIN_REQUEST_CODE && data != null) {
        if (resultCode == RESULT_OK) {
            //Successfully signed inLinkedInUseruser= data.getParcelableExtra("social_login");

            //acessing user info
            Log.i("LinkedInLogin", user.getFirstName());

        } else {

            if (data.getIntExtra("err_code", 0) == LinkedInBuilder.ERROR_USER_DENIED) {
                //Handle : user denied access to account

            } elseif (data.getIntExtra("err_code", 0) == LinkedInBuilder.ERROR_FAILED) {
                    
                //Handle : Error in API : see logcat output for details
                Log.e("LINKEDIN ERROR", data.getStringExtra("err_message"));
            }
        }
    }
}

I'm using this library in multiple production apps, so I'll try to keep it as updated as possible. You can find other details here.

Solution 2:

I created a small library to implement LinkedIn Authentication via OAuth2

Library - https://github.com/Sumudu-Sahan/LinkedInManager

Steps

  1. Add the below maven dependency to your project level build.gradle file

    allprojects { repositories { ... maven { url 'https://jitpack.io' } } }

  2. add the below maven dependency to your app level build.gradle file

    dependencies { implementation 'com.github.Sumudu-Sahan:LinkedInManager:1.00.02' }

  3. Inherit your activity, fragment from LinkedInManagerResponse

    public class MainActivity extends AppCompatActivity implements LinkedInManagerResponse

  4. Initiate the LinkedInRequestManager object instance for login process

    LinkedInRequestManager linkedInRequestManager = new LinkedInRequestManager(Activity, LinkedInManagerResponse, "CLIENT ID", "CLIENT SECRET", "REDIRECTION URL");

  5. Start Authenticate with below statement

linkedInRequestManager.showAuthenticateView(LinkedInRequestManager.MODE_BOTH_OPTIONS);

Available Modes

LinkedInRequestManager.MODE_EMAIL_ADDRESS_ONLY
LinkedInRequestManager.MODE_LITE_PROFILE_ONLY
LinkedInRequestManager.MODE_BOTH_OPTIONS

Solution 3:

Here is my code, to implement sign in with "0Auth2.0"

classNewLinkedInIntegrationextendsActivity {

    privatestaticfinalStringAPI_KEY="your client id";
    privatestaticfinalStringSECRET_KEY="your secret key";
    privatestaticfinalStringSTATE="DCEeFWf45A53sdfKef424";

    privatestaticfinalStringREDIRECT_URI="your url";
    privatestaticfinalStringAUTHORIZATION_URL="https://www.linkedin.com/uas/oauth2/authorization";

    privatestaticfinalStringACCESS_TOKEN_URL="https://www.linkedin.com/uas/oauth2/accessToken";

    privatestaticfinalStringSECRET_KEY_PARAM="client_secret";

    privatestaticfinalStringRESPONSE_TYPE_PARAM="response_type";

    privatestaticfinalStringGRANT_TYPE_PARAM="grant_type";

    privatestaticfinalStringGRANT_TYPE="authorization_code";

    privatestaticfinalStringRESPONSE_TYPE_VALUE="code";

    privatestaticfinalStringCLIENT_ID_PARAM="client_id";

    privatestaticfinalStringSTATE_PARAM="state";
    privatestaticfinalStringREDIRECT_URI_PARAM="redirect_uri";
    privatestaticfinalStringQUESTION_MARK="?";
    privatestaticfinalStringAMPERSAND="&";
    privatestaticfinalStringEQUALS="=";

    StringprofileUrl="https://api.linkedin.com/v2/me?projection=(id,firstName,lastName,profilePicture(displayImage~:playableStreams))";
    String accessToken;
    String linkedInUserEmailAddress;
    SharedPreferences sharedPreferences;
    StringemailAddress="https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))";
    private WebView webView;
    TransparentDialog mProgressBarHandler;
    private ProgressDialog pd;
    String deviceId, location, country;
    String linkedInUserId, linkedInUserFirstName, linkedInUserLastName, linkedInUserProfile;

    @OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_linked);
        //get the webView from the layout
        webView = (WebView) findViewById(R.id.main_activity_web_view);
        deviceId = getIntent().getStringExtra("deviceId");
        location = getIntent().getStringExtra("location");
        country = getIntent().getStringExtra("country");
        //Request focus for the webview
        webView.requestFocus(View.FOCUS_DOWN);
        webView.clearHistory();
        webView.clearCache(true);
        sharedPreferences = MyApplication.preference;
        pd = ProgressDialog.show(this, "", "Loadingg...", true);
        webView.setWebViewClient(newWebViewClient() {
            @OverridepublicvoidonPageFinished(WebView view, String url) {
                //This method will be executed each time a page finished loading.//The only we do is dismiss the progressDialog, in case we are showing any.if (pd != null && pd.isShowing()) {
                    pd.dismiss();
                }
            }

            @OverridepublicbooleanshouldOverrideUrlLoading(WebView view, String authorizationUrl) {
                //This method will be called when the Auth proccess redirect to our RedirectUri.//We will check the url looking for our RedirectUri.if (authorizationUrl.startsWith(REDIRECT_URI)) {
                    Log.i("Authorize", "");
                    Uriuri= Uri.parse(authorizationUrl);
                    //We take from the url the authorizationToken and the state token. We have to check that the state token returned by the Service is the same we sent.//If not, that means the request may be a result of CSRF and must be rejected.StringstateToken= uri.getQueryParameter(STATE_PARAM);
                    if (stateToken == null || !stateToken.equals(STATE)) {
                        Log.e("Authorize", "State token doesn't match");
                        returntrue;
                    }

                    //If the user doesn't allow authorization to our application, the authorizationToken Will be null.StringauthorizationToken= uri.getQueryParameter(RESPONSE_TYPE_VALUE);
                    if (authorizationToken == null) {
                        Log.i("Authorize", "The user doesn't allow authorization.");
                        returntrue;
                    }
                    Log.i("Authorize", "Auth token received: " + authorizationToken);

                    //Generate URL for requesting Access TokenStringaccessTokenUrl= getAccessTokenUrl(authorizationToken);
                    //We make the request in a AsyncTasknewPostRequestAsyncTask().execute(accessTokenUrl);

                } else {
                    //Default behaviour
                    Log.i("Authorize", "Redirecting to: " + authorizationUrl);
                    webView.loadUrl(authorizationUrl);
                }
                returntrue;
            }
        });
        StringauthUrl= getAuthorizationUrl();
        Log.i("Authorize", "Loading Auth Url: " + authUrl);
        webView.loadUrl(authUrl);
    }

    /**
     * Method that generates the url for get the access token from the Service
     *
     * @return Url
     */privatestatic String getAccessTokenUrl(String authorizationToken) {
        return ACCESS_TOKEN_URL
                + QUESTION_MARK
                + GRANT_TYPE_PARAM + EQUALS + GRANT_TYPE
                + AMPERSAND
                + RESPONSE_TYPE_VALUE + EQUALS + authorizationToken
                + AMPERSAND
                + CLIENT_ID_PARAM + EQUALS + API_KEY
                + AMPERSAND
                + REDIRECT_URI_PARAM + EQUALS + REDIRECT_URI
                + AMPERSAND
                + SECRET_KEY_PARAM + EQUALS + SECRET_KEY;
    }

    /**
     * Method that generates the url for get the authorization token from the Service
     *
     * @return Url
     */privatestatic String getAuthorizationUrl() {
        return AUTHORIZATION_URL
                + QUESTION_MARK + RESPONSE_TYPE_PARAM + EQUALS + RESPONSE_TYPE_VALUE
                + AMPERSAND + CLIENT_ID_PARAM + EQUALS + API_KEY
                + AMPERSAND + STATE_PARAM + EQUALS + STATE
                + AMPERSAND + REDIRECT_URI_PARAM + EQUALS + REDIRECT_URI + "&scope=r_liteprofile%20r_emailaddress%20w_member_social";
    }


    privateclassPostRequestAsyncTaskextendsAsyncTask<String, Void, Boolean> {

        @OverrideprotectedvoidonPreExecute() {
            pd = ProgressDialog.show(NewLinkedInIntegration.this, "", "Loading", true);
        }

        @Overrideprotected Boolean doInBackground(String... urls) {
            if (urls.length > 0) {
                Stringurl= urls[0];
                HttpClienthttpClient=newDefaultHttpClient();
                HttpPosthttpost=newHttpPost(url);
                try {
                    HttpResponseresponse= httpClient.execute(httpost);
                    if (response != null) {
                        //If status is OK 200if (response.getStatusLine().getStatusCode() == 200) {
                            Stringresult= EntityUtils.toString(response.getEntity());
                            JSONObjectresultJson=newJSONObject(result);
                            intexpiresIn= resultJson.has("expires_in") ? resultJson.getInt("expires_in") : 0;
                            StringaccessToken= resultJson.has("access_token") ? resultJson.getString("access_token") : null;
                            Log.e("Tokenm", "" + accessToken);
                            if (expiresIn > 0 && accessToken != null) {
                                Log.i("Authorize", "This is the access Token: " + accessToken + ". It will expires in " + expiresIn + " secs");
                                Calendarcalendar= Calendar.getInstance();
                                calendar.add(Calendar.SECOND, expiresIn);
                                longexpireDate= calendar.getTimeInMillis();
                                SharedPreferencespreferences= NewLinkedInIntegration.this.getSharedPreferences("user_info", 0);
                                SharedPreferences.Editoreditor= preferences.edit();
                                editor.putLong("expires", expireDate);
                                editor.putString("accessToken", accessToken);
                                editor.commit();

                                returntrue;
                            }
                        }
                    }
                } catch (IOException e) {
                    Log.e("Authorize", "Error Http response " + e.getLocalizedMessage());
                } catch (ParseException e) {
                    Log.e("Authorize", "Error Parsing Http response " + e.getLocalizedMessage());
                } catch (JSONException e) {
                    Log.e("Authorize", "Error Parsing Http response " + e.getLocalizedMessage());
                }
            }
            returnfalse;
        }

        @OverrideprotectedvoidonPostExecute(Boolean status) {
            if (pd != null && pd.isShowing()) {
                pd.dismiss();
            }
            if (status) {
                SharedPreferencespreferences= NewLinkedInIntegration.this.getSharedPreferences("user_info", 0);
                accessToken = preferences.getString("accessToken", null);
                try {
                    if (accessToken != null) {
                        newGetProfileRequestAsyncTask().execute(profileUrl);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }

    publicvoidsendGetRequest(String urlString, String accessToken)throws Exception {
        URLurl=newURL(urlString);
        HttpsURLConnectioncon= (HttpsURLConnection) url.openConnection();
        con.setRequestMethod("GET");
        con.setRequestProperty("Authorization", "Bearer " + accessToken);
        con.setRequestProperty("cache-control", "no-cache");
        con.setRequestProperty("X-Restli-Protocol-Version", "2.0.0");
        BufferedReaderbr=newBufferedReader(newInputStreamReader(con.getInputStream()));
        StringBuilderjsonString=newStringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            jsonString.append(line);
        }
        JSONObjectjsonObject=newJSONObject(jsonString.toString());
        Log.d("Complete json object", jsonObject.toString());
        try {
            linkedInUserId = jsonObject.getString("id");
            Stringcountry= jsonObject.getJSONObject("firstName").getJSONObject("preferredLocale").getString("country");
            Stringlanguage= jsonObject.getJSONObject("firstName").getJSONObject("preferredLocale").getString("language");
            StringgetFirstnameKey= language + "_" + country;
            linkedInUserFirstName = jsonObject.getJSONObject("firstName").getJSONObject("localized").getString(getFirstnameKey);
            linkedInUserLastName = jsonObject.getJSONObject("firstName").getJSONObject("localized").getString(getFirstnameKey);
            linkedInUserProfile = jsonObject.getJSONObject("profilePicture").getJSONObject("displayImage~").getJSONArray("elements").getJSONObject(0).getJSONArray("identifiers").getJSONObject(0).getString("identifier");

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    privatevoidsendGetRequestForEmail(String urlString, String accessToken)throws Exception {
        URLurl=newURL(urlString);
        HttpsURLConnectioncon= (HttpsURLConnection) url.openConnection();
        con.setRequestMethod("GET");
        con.setRequestProperty("Authorization", "Bearer " + accessToken);
        con.setRequestProperty("cache-control", "no-cache");
        con.setRequestProperty("X-Restli-Protocol-Version", "2.0.0");
        BufferedReaderbr=newBufferedReader(newInputStreamReader(con.getInputStream()));
        StringBuilderjsonString=newStringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            jsonString.append(line);
        }
        JSONObjectjsonObject=newJSONObject(jsonString.toString());
        linkedInUserEmailAddress = jsonObject.getJSONArray("elements").getJSONObject(0).getJSONObject("handle~").getString("emailAddress");
        Log.d("email json object", jsonObject.toString());
        sendRequestToServerForLinkwedInIntegration();


    }

    publicvoidsendRequestToServerForLinkwedInIntegration() {

        if (AppUtils.isInternetOn(NewLinkedInIntegration.this)) {

            JSONObjectuserJsonObject=newJSONObject();
            try {
                userJsonObject.put(NetworkKeys.EMAIL, linkedInUserEmailAddress);
                userJsonObject.put(NetworkKeys.USERNAME, linkedInUserFirstName + " " + linkedInUserLastName);
                userJsonObject.put(NetworkKeys.CONTACTNO, "");
                userJsonObject.put(NetworkKeys.UID, linkedInUserId);
                userJsonObject.put(NetworkKeys.PROVIDER, "LinkedIn");
                userJsonObject.put(NetworkKeys.IMAGE, linkedInUserProfile);
                userJsonObject.put(NetworkKeys.DEVICE_TOKEN, deviceId);
                userJsonObject.put(NetworkKeys.LOCATION, location);
                userJsonObject.put(NetworkKeys.COUNTRY, country);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            Stringurl= Constants.WebServices.SOCIAL_MEDIA_LOGIN;
            CallWebService.getInstance(NewLinkedInIntegration.this, true).hitJSONObjectVolleyWebServicemanageclubdetailsWithoutAccessToken(Request.Method.POST, url, deviceId, userJsonObject, newCallBackInterfaceVolley() {
                @OverridepublicvoidonJsonObjectSuccess(JSONObject object) {
                    pd.dismiss();
                    try {
                        booleansuccess= object.getBoolean(NetworkKeys.SUCCESS);

                        if (success) {
                            JSONObjectuserInfoJsonObject= object.getJSONObject(NetworkKeys.USERJSONOBJECT);
                            StringuserId= userInfoJsonObject.getString(NetworkKeys.SIGN_IN_USERID);
                            StringuserEmail= userInfoJsonObject.getString(NetworkKeys.SIGN_IN_USER_EMAIL);
                            StringuserImage= userInfoJsonObject.getString(NetworkKeys.SIGN_IN_USER_IMAGE);
                            StringuserName= userInfoJsonObject.getString(NetworkKeys.SIGN_IN_USER_NAME);
                            StringuserCity= userInfoJsonObject.getString(NetworkKeys.USER_CITY);
                            StringcontactNo= userInfoJsonObject.getString(NetworkKeys.CONTACT_NO);
                            StringuserCountry= userInfoJsonObject.getString(NetworkKeys.USER_COUNTRY);
                            StringisNotificationOn= userInfoJsonObject.getString(NetworkKeys.ISNOTIFICATION);
                            StringuserLocation= userInfoJsonObject.getString(NetworkKeys.SIGN_IN_USER_LOCATION);
                            StringsignInUserType= userInfoJsonObject.getString(NetworkKeys.SIGN_IN_USER_PROVIDER);
                            StringuserAuthToken= userInfoJsonObject.getString(NetworkKeys.SIGN_IN_USER_AUTHTOKEN);
                            SharedPreferences.Editoreditor= sharedPreferences.edit();
                            editor.putString(NetworkKeys.SIGN_IN_USERID, userId);
                            editor.putString(NetworkKeys.SIGN_IN_USER_EMAIL, userEmail);
                            editor.putString(NetworkKeys.SIGN_IN_USER_IMAGE, userImage);
                            editor.putString(NetworkKeys.SIGN_IN_USER_NAME, userName);
                            editor.putString(NetworkKeys.USER_CITY, userCity);
                            editor.putString(NetworkKeys.USER_COUNTRY, userCountry);
                            editor.putString(NetworkKeys.SIGN_IN_USER_MOBILE, contactNo);
                            editor.putString(NetworkKeys.SIGN_IN_USER_LOCATION, userLocation);
                            editor.putString(NetworkKeys.SIGN_IN_USER_PROVIDER, signInUserType);
                            editor.putString(NetworkKeys.ISNOTIFICATION, isNotificationOn);
                            editor.putString(NetworkKeys.SIGN_IN_USER_AUTHTOKEN, userAuthToken);
                            editor.putBoolean(NetworkKeys.IS_USER_LOGIN_FROM_SOCIAL_MEDIA, true);
                            editor.putBoolean(NetworkKeys.SIGN_IN_USER_SUCCESSFULLY, true);
                            editor.apply();
                            Intentintent=newIntent(NewLinkedInIntegration.this, CardSelctionActivity.class);
                            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                            startActivity(intent);
                            finish();
                        } else {
                            pd.dismiss();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                @OverridepublicvoidonJsonArrarSuccess(JSONArray array) {

                }

                @OverridepublicvoidonFailure(String str) {
                    pd.dismiss();
                }
            });
        } else {
            AppUtils.showToast(NewLinkedInIntegration.this, getResources().getString(R.string.internet_connection));
        }
    }


    privateclassGetProfileRequestAsyncTaskextendsAsyncTask<String, Void, JSONObject> {

        @OverrideprotectedvoidonPreExecute() {
            pd = ProgressDialog.show(NewLinkedInIntegration.this, "", "Loading..", true);
        }

        @Overrideprotected JSONObject doInBackground(String... urls) {
            if (urls.length > 0) {
                try {
                    sendGetRequest(profileUrl, accessToken);
                    sendGetRequestForEmail(emailAddress, accessToken);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            returnnull;
        }

        @OverrideprotectedvoidonPostExecute(JSONObject data) {
            if (pd != null && pd.isShowing()) {
                pd.dismiss();
            }
            if (data != null) {

                try {
                    StringwelcomeTextString= String.format("Welcome %1$s %2$s, You are a %3$s", data.getString("firstName"), data.getString("lastName"), data.getString("headline"));

                } catch (JSONException e) {
                    Log.e("Authorize", "Error Parsing json " + e.getLocalizedMessage());
                }
            }
        }

    }
}

If you want further assistance go to below link explained how to sign in with Linkedin with auth 2.0. Have a look

linkedin integration with oauth20 -v2-in-complete implementation ain android

Solution 4:

Inspired by @Shantanu, I've restructured/updated his "unofficial" SDK for Android, you can use it from [this GitHub repo](https://github.com/AbdAllahAbdElFattah13/LinkedIn-SDK-Android.

It's now Kotlin based and follows clean architecture principles for better understanding and modifications.

We also use it in our production apps, so it should be working fine. :)

Post a Comment for "How To Implement "login With Linkedin" With "oauth 2.0" In Android"