public void signInWithLinkedIn(View view) {
//First check if user is already authenticated or not and session is valid or not
if (!LISessionManager.getInstance(this).getSession().isValid()) {
//if not valid then start authentication
LISessionManager.getInstance(getApplicationContext()).init(LinkedInActivity.this, buildScope()//pass the build scope here
, new AuthListener() {
@Override
public void onAuthSuccess() {
// Authentication was successful. You can now do
// other calls with the SDK.
Toast.makeText(LinkedInActivity.this, "Successfully authenticated with LinkedIn.", Toast.LENGTH_SHORT).show();
//on successful authentication fetch basic profile data of user
//LISessionManager.getInstance(getApplicationContext()).clearSession();
fetchBasicProfileData();
}
@Override
public void onAuthError(LIAuthError error) {
// Handle authentication errors
//LISessionManager.getInstance(getApplicationContext()).clearSession();
Log.e("AUTH ERROR", "Auth Error :" + error.toString());
Toast.makeText(LinkedInActivity.this, "Failed to authenticate with LinkedIn. Please try again.", Toast.LENGTH_SHORT).show();
}
}, true);//if TRUE then it will show dialog if
// any device has no LinkedIn app installed to download app else won't show anything
} else {
//LISessionManager.getInstance(getApplicationContext()).clearSession();
Toast.makeText(this, "You have already been authenticated.", Toast.LENGTH_SHORT).show();
//if user is already authenticated fetch basic profile data for user
fetchBasicProfileData();
}
}
private static Scope buildScope() {
//Check Scopes in Application Settings before passing here else you won't able to read that data
// Scope.R_CONTACTINFO
return Scope.build(Scope.R_BASICPROFILE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
LISessionManager.getInstance(getApplicationContext()).onActivityResult(this, requestCode, resultCode, data);
Log.d("Access token->", LISessionManager.getInstance(getApplicationContext()).getSession().getAccessToken().getValue());
}
/**
* method to fetch basic profile data
*/
private void fetchBasicProfileData() {
//In URL pass whatever data from user you want for more values check below link
//LINK : https://developer.linkedin.com/docs/fields/basic-profile
String url = "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,headline,public-profile-url,picture-url,email-address,picture-urls::(original))";
APIHelper apiHelper = APIHelper.getInstance(getApplicationContext());
apiHelper.getRequest(this, url, new ApiListener() {
@Override
public void onApiSuccess(ApiResponse apiResponse) {
// Success!
JSONObject responseObject = apiResponse.getResponseDataAsJson();
try {
profileURL = responseObject.getString("publicProfileUrl");
imgURL = responseObject.getString("pictureUrl");
fetchConnectionsData();
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onApiError(LIApiError liApiError) {
// Error making GET request!
Log.e("FETCH PROFILE ERROR", "Fetch profile Error :" + liApiError.getLocalizedMessage());
Toast.makeText(LinkedInActivity.this, "Failed. Please try again.", Toast.LENGTH_SHORT).show();
}
});
}
Linkedin returns "No value for accessTokenValue" and "access toke is not set". It was working like last month but suddenly it does not work and I could not find anything wrong with the code. After much digging on Google, I am still unable to find a solution. Or am I using the v1 api which I should not? Any help will be greatly appreciated.
public class LinkedinActivity {
/****FILL THIS WITH YOUR INFORMATION*********/
//This is the public api key of our application
private static final String API_KEY = "apikey";
//This is the private api key of our application
private static final String SECRET_KEY = "secretcode";
//This is any string we want to use. This will be used for avoiding CSRF attacks. You can generate one here: http://strongpasswordgenerator.com/
private static final String STATE = "123456789";
//This is the url that LinkedIn Auth process will redirect to. We can put whatever we want that starts with http:// or https:// .
//We use a made up url that we will intercept when redirecting. Avoid Uppercases.
private static final String REDIRECT_URI = "https://example.com";
/*********************************************/
//These are constants used for build the urls
private static final String AUTHORIZATION_URL = "https://www.linkedin.com/oauth/v2/authorization";
private static final String ACCESS_TOKEN_URL = "https://www.linkedin.com/uas/oauth2/accessToken";
private static final String SECRET_KEY_PARAM = "client_secret";
private static final String RESPONSE_TYPE_PARAM = "response_type";
private static final String GRANT_TYPE_PARAM = "grant_type";
private static final String GRANT_TYPE = "authorization_code";
private static final String RESPONSE_TYPE_VALUE = "code";
private static final String CLIENT_ID_PARAM = "client_id";
private static final String STATE_PARAM = "state";
private static final String REDIRECT_URI_PARAM = "redirect_uri";
/*---------------------------------------*/
private static final String QUESTION_MARK = "?";
private static final String AMPERSAND = "&";
private static final String EQUALS = "=";
private WebView webView;
private ImageView close_icon;
private ProgressDialog pd;
//private OauthInterface oauthInterface;
String accessToken;
Context context;
Dialog dialog;
public LinkedinActivity(@NonNull Context context) {
this.context = context;
}
public void showLinkedin() {
dialog = new Dialog(context, R.style.AppTheme);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
dialog.setContentView(R.layout.linkedin_activity);
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
pd = ProgressDialog.show(context, "", "Loading...", true);
dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
LinkedinData linkedinData = (LinkedinData) context;
linkedinData.linkedCancel();
dialog.dismiss();
}
return true;
}
});
//oauthInterface = new OauthPresenter(this);
//get the webView from the layout
webView = (WebView) dialog.findViewById(R.id.activity_web_view);
close_icon = (ImageView) dialog.findViewById(R.id.close_icon);
close_icon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
LinkedinData linkedinData = (LinkedinData) context;
linkedinData.linkedCancel();
dialog.dismiss();
}
});
//Request focus for the webview
webView.requestFocus(View.FOCUS_DOWN);
//Show a progress dialog to the user
//Set a custom web view client
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(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();
}
}
@Override
public boolean shouldOverrideUrlLoading(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", "");
Uri uri = 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.
String stateToken = uri.getQueryParameter(STATE_PARAM);
if (stateToken == null || !stateToken.equals(STATE)) {
Log.e("Authorize", "State token doesn't match");
return true;
}
//If the user doesn't allow authorization to our application, the authorizationToken Will be null.
String authorizationToken = uri.getQueryParameter(RESPONSE_TYPE_VALUE);
if (authorizationToken == null) {
Log.i("Authorize", "The user doesn't allow authorization.");
return true;
}
Log.i("Authorize", "Auth token received: " + authorizationToken);
//Generate URL for requesting Access Token
String accessTokenUrl = getAccessTokenUrl(authorizationToken);
//We make the request in a AsyncTask
new PostRequestAsyncTask().execute(accessTokenUrl);
} else {
//Default behaviour
Log.i("Authorize", "Redirecting to: " + authorizationUrl);
webView.loadUrl(authorizationUrl);
}
return true;
}
});
//Get the authorization Url
String authUrl = getAuthorizationUrl();
Log.i("Authorize", "Loading Auth Url: " + authUrl);
//Load the authorization URL into the webView
webView.loadUrl(authUrl);
dialog.show();
}
private static 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
*/
private static String getAuthorizationUrl() {
return AUTHORIZATION_URL
+ QUESTION_MARK + RESPONSE_TYPE_PARAM + EQUALS + RESPONSE_TYPE_VALUE
+ AMPERSAND + CLIENT_ID_PARAM + EQUALS + API_KEY
+ AMPERSAND + REDIRECT_URI_PARAM + EQUALS + REDIRECT_URI
+ AMPERSAND + STATE_PARAM + EQUALS + STATE
+ AMPERSAND + "scope=r_emailaddress";
}
private class PostRequestAsyncTask extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
pd = ProgressDialog.show(context, "", "loading", true);
}
@Override
protected String doInBackground(String... urls) {
if (urls.length > 0) {
String url = urls[0];
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpost = new HttpPost(url);
try {
HttpResponse response = httpClient.execute(httpost);
if (response != null) {
//If status is OK 200
if (response.getStatusLine().getStatusCode() == 200) {
String result = EntityUtils.toString(response.getEntity());
//Convert the string result to a JSON Object
JSONObject resultJson = new JSONObject(result);
//Extract data from JSON Response
int expiresIn = resultJson.has("expires_in") ? resultJson.getInt("expires_in") : 0;
accessToken = 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");
//Calculate date of expiration
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, expiresIn);
long expireDate = calendar.getTimeInMillis();
////Store both expires in and access token in shared preferences
SharedPreferences preferences = context.getSharedPreferences("user_info", 0);
SharedPreferences.Editor editor = preferences.edit();
editor.putLong("expires", expireDate);
editor.putString("accessToken", accessToken);
//oauthInterface.oauthAuthentication(accessToken, "linkedin", new HackedPrefence(getApplicationContext()).getDevice_token());
editor.commit();
return accessToken;
}
}
}
} 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());
}
}
return accessToken;
}
@Override
protected void onPostExecute(String status) {
if (pd != null && pd.isShowing()) {
pd.dismiss();
}
LinkedinData linkedinData = (LinkedinData) context;
linkedinData.LinkedinSuccess(status);
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
interface LinkedinData {
void linkedCancel();
void LinkedinSuccess(String Token);
}
}
new LinkedinActivity(this).showLinkedin();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new LinkedinActivity(this).showLinkedin();
}
});
<?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">
<WebView
android:id="@+id/activity_web_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/close_icon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginRight="10dp"
android:layout_marginTop="22dp"
android:src="@drawable/ic_close_black"
android:layout_alignParentRight="true"/>
</RelativeLayout>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With