diff --git a/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java b/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java
index 9618e11..ebcfdda 100644
--- a/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java
+++ b/app/src/main/java/com/AbdAllahAbdElFattah13/linkedin/login/MainActivity.java
@@ -1,8 +1,5 @@
package com.AbdAllahAbdElFattah13.linkedin.login;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
-
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -15,17 +12,13 @@
import android.widget.TextView;
import android.widget.Toast;
-import com.AbdAllahAbdElFattah13.linkedin.login.R;
-import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.LinkedInUser;
-import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener;
-import com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder.LinkedInFromActivityBuilder;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
-import org.json.JSONException;
-import org.json.JSONObject;
+import com.AbdAllahAbdElFattah13.linkedinsdk.ui.LinkedInUser;
+import com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder.LinkedInFromActivityBuilder;
-import java.io.IOException;
import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
@@ -38,12 +31,8 @@ public class MainActivity extends AppCompatActivity {
private ImageView ivUserPic;
private Button btnLogin;
- private Button btnGetUpdatedInfo;
private TextView tvFName, tvLName, tvEmail;
- private String accessToken;
- private long accessTokenExpiry;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -51,7 +40,6 @@ protected void onCreate(Bundle savedInstanceState) {
getCredentials();
-
ivUserPic = findViewById(R.id.iv_user_pic);
btnLogin = findViewById(R.id.btn_login);
tvFName = findViewById(R.id.tv_first_name);
@@ -70,41 +58,12 @@ public void onClick(View v) {
}
});
-
- btnGetUpdatedInfo = findViewById(R.id.btn_get_update);
- btnGetUpdatedInfo.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
-
- LinkedInFromActivityBuilder.retrieveBasicProfile(accessToken, accessTokenExpiry, new OnBasicProfileListener() {
- @Override
- public void onDataRetrievalStart() {
-
- }
-
- @Override
- public void onDataSuccess(LinkedInUser user) {
- setUserData(user);
- }
-
- @Override
- public void onDataFailed(int errCode, String errMessage) {
-
- Toast.makeText(MainActivity.this, "Failed", Toast.LENGTH_SHORT).show();
- }
- });
-
- }
- });
-
}
/**
* Sets data to UI
*/
private void setUserData(LinkedInUser user) {
- accessToken = user.getAccessToken();
- accessTokenExpiry = user.getAccessTokenExpiry();
Log.wtf("LINKEDIN ID", user.getId());
@@ -112,18 +71,14 @@ private void setUserData(LinkedInUser user) {
tvLName.setText(user.getLastName());
tvEmail.setText(user.getEmail());
- btnGetUpdatedInfo.setVisibility(View.VISIBLE);
-
- if(user.getProfileUrl()!= null && !user.getProfileUrl().isEmpty()){
- new ImageLoadTask(user.getProfileUrl(), ivUserPic).execute();
+ if (user.getProfilePictureUrl() != null && !user.getProfilePictureUrl().isEmpty()) {
+ new ImageLoadTask(user.getProfilePictureUrl(), ivUserPic).execute();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
-
-
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == LINKEDIN_REQUEST && data != null) {
@@ -134,8 +89,6 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten
setUserData(user);
} else {
-
-
//print the error
Log.wtf("LINKEDIN ERR", data.getStringExtra("err_message"));
@@ -146,11 +99,8 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten
//some error occured
Toast.makeText(this, "Failed", Toast.LENGTH_SHORT).show();
}
-
-
}
}
-
}
@@ -188,7 +138,6 @@ protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
imageView.setImageBitmap(result);
}
-
}
@@ -199,25 +148,38 @@ protected void onPostExecute(Bitmap result) {
* Make sure to update your linkedin credentials in the said file
*/
private void getCredentials() {
- try {
-
- InputStream is = getAssets().open("linkedin-credentials.json");
- int size = is.available();
- byte[] buffer = new byte[size];
- is.read(buffer);
- is.close();
- String json = new String(buffer, "UTF-8");
- JSONObject linkedinCred = new JSONObject(json);
- clientID = linkedinCred.getString("client_id");
- clientSecret = linkedinCred.getString("client_secret");
- redirectUrl = linkedinCred.getString("redirect_url");
-
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } catch (JSONException e) {
- e.printStackTrace();
- }
+
+ // 77uzd83rv05qdd
+// 11jwfr3Jh1g6Vldb
+// private const val REDIRECT_URI = "https://www.cuju.io/android"
+
+ clientID = "77uzd83rv05qdd";
+ clientSecret = "11jwfr3Jh1g6Vldb";
+ redirectUrl = "https://www.cuju.io/android";
+
+// try {
+//
+// InputStream is = getAssets().open("linkedin-credentials.json");
+// int size = is.available();
+// byte[] buffer = new byte[size];
+// is.read(buffer);
+// is.close();
+// String json = new String(buffer, "UTF-8");
+// JSONObject linkedinCred = new JSONObject(json);
+//// 77uzd83rv05qdd
+//// 11jwfr3Jh1g6Vldb
+//// private const val REDIRECT_URI = "https://www.cuju.io/android"
+//
+// clientID = "77uzd83rv05qdd";
+// clientSecret = "11jwfr3Jh1g6Vldb";
+// redirectUrl = "https://www.cuju.io/android";
+//
+// } catch (UnsupportedEncodingException e) {
+// e.printStackTrace();
+// } catch (IOException e) {
+// e.printStackTrace();
+// } catch (JSONException e) {
+// e.printStackTrace();
+// }
}
}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 04a989b..d659d34 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -37,8 +37,6 @@
android:layout_height="wrap_content" />
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 236a7f9..36e6ea2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
+ ext.kotlin_version = '1.3.71'
repositories {
google()
jcenter()
@@ -12,6 +13,7 @@ buildscript {
// Required plugins added to classpath to facilitate pushing to JCenter/Bintray
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -29,6 +31,10 @@ ext {
testRunnerVersion = "1.2.0"
espressoCoreVersion = "3.2.0"
+ //arch components
+ lifecycle_version = "2.2.0"
+ arch_version = "2.1.0"
+
// LinkedIn SDK Library Info
libVersionCode = 1
libVersionName = '1.0.0'
diff --git a/linkedinsdk/build.gradle b/linkedinsdk/build.gradle
index 35271ca..bfe05ea 100644
--- a/linkedinsdk/build.gradle
+++ b/linkedinsdk/build.gradle
@@ -1,4 +1,10 @@
apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+repositories {
+ mavenCentral()
+}
android {
@@ -29,9 +35,17 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "androidx.appcompat:appcompat:$rootProject.ext.androidxVersion"
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation "androidx.core:core-ktx:1.2.0"
+
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$rootProject.ext.lifecycle_version"
+ implementation "androidx.lifecycle:lifecycle-livedata-ktx:$rootProject.ext.lifecycle_version"
+
testImplementation "junit:junit:$rootProject.ext.junitVersion"
+ testImplementation "androidx.arch.core:core-testing:$rootProject.ext.arch_version"
+
androidTestImplementation "androidx.test:runner:$rootProject.ext.testRunnerVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$rootProject.ext.espressoCoreVersion"
}
diff --git a/linkedinsdk/src/main/AndroidManifest.xml b/linkedinsdk/src/main/AndroidManifest.xml
index edf24ee..e9511ae 100644
--- a/linkedinsdk/src/main/AndroidManifest.xml
+++ b/linkedinsdk/src/main/AndroidManifest.xml
@@ -3,7 +3,7 @@
package="com.AbdAllahAbdElFattah13.linkedinsdk">
-
+
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java
deleted file mode 100644
index 962be7d..0000000
--- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/LinkedInAuthenticationActivity.java
+++ /dev/null
@@ -1,283 +0,0 @@
-package com.AbdAllahAbdElFattah13.linkedinsdk;
-
-import android.annotation.SuppressLint;
-import android.app.Activity;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.view.WindowManager;
-import android.webkit.WebView;
-import android.webkit.WebViewClient;
-
-import androidx.appcompat.app.AlertDialog;
-import androidx.appcompat.app.AppCompatActivity;
-
-import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.LinkedInUser;
-import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener;
-import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.RequestHandler;
-import com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder.LinkedInFromActivityBuilder;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.IOException;
-import java.util.Calendar;
-
-public class LinkedInAuthenticationActivity extends AppCompatActivity {
-
- private static String CLIENT_ID;
- private static String CLIENT_SECRET_KEY;
- private static String STATE; //for security
- private static String REDIRECT_URI;
-
- private static final String AUTHORIZATION_URL = "https://www.linkedin.com/uas/oauth2/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 AlertDialog progressDialog;
-
- private LinkedInUser linkedInUser = new LinkedInUser();
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.linkedin_activity_linkedin_authentication);
-
- //enable fullscreen mode
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
- if (getSupportActionBar() != null) {
- getSupportActionBar().hide();
- }
-
- CLIENT_ID = getIntent().getStringExtra(LinkedInFromActivityBuilder.CLIENT_ID);
- CLIENT_SECRET_KEY = getIntent().getStringExtra(LinkedInFromActivityBuilder.CLIENT_SECRET_KEY);
- REDIRECT_URI = getIntent().getStringExtra(LinkedInFromActivityBuilder.REDIRECT_URI);
- STATE = getIntent().getStringExtra(LinkedInFromActivityBuilder.STATE);
-
- webView = findViewById(R.id.web_view_linkedin_login);
- webView.requestFocus(View.FOCUS_DOWN);
- webView.clearHistory();
- webView.clearCache(true);
-
- showProgressDialog();
-
- webView.setWebViewClient(new WebViewClient() {
- @Override
- public void onPageFinished(WebView view, String url) {
- hideProgressDialog();
- }
-
- //to support below Android N we need to use the deprecated method only
- @Override
- public boolean shouldOverrideUrlLoading(WebView view, String authorizationUrl) {
-
- showProgressDialog();
-
- if (authorizationUrl.startsWith(REDIRECT_URI)) {
-
- Uri uri = Uri.parse(authorizationUrl);
- String stateToken = uri.getQueryParameter(STATE_PARAM);
- if (stateToken == null || !stateToken.equals(STATE)) {
- Log.e(LinkedInFromActivityBuilder.TAG, "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) {
- Intent intent = new Intent();
- intent.putExtra("err_code", LinkedInFromActivityBuilder.ERROR_USER_DENIED);
- intent.putExtra("err_message", "Authorization not received. User didn't allow access to account.");
- setResult(Activity.RESULT_CANCELED, intent);
- finish();
- }
-
-
- new RetrieveDataAsyncTask().execute(authorizationToken);
-
-
- } else {
- //Default behaviour
- webView.loadUrl(authorizationUrl);
- }
- return true;
- }
- });
-
- String authUrl = getAuthorizationUrl();
- webView.loadUrl(authUrl);
- }
-
-
- @SuppressLint("StaticFieldLeak")
- private class RetrieveDataAsyncTask extends AsyncTask {
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- showProgressDialog();
- }
-
- @Override
- protected Boolean doInBackground(String... tokens) {
- if (tokens.length > 0) {
- String authorizationToken = tokens[0];
-
- try {
-
- retrieveAccessTokenFromAPI(authorizationToken);
-
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- } catch (JSONException e) {
- e.printStackTrace();
- return false;
- }
-
- }
-
- return false;
- }
-
- @Override
- protected void onPostExecute(Boolean didSuccess) {
- super.onPostExecute(didSuccess);
-
-
- if (linkedInUser.getAccessToken() != null) {
-
- LinkedInFromActivityBuilder.retrieveBasicProfile(linkedInUser.getAccessToken(), linkedInUser.getAccessTokenExpiry(), new OnBasicProfileListener() {
- @Override
- public void onDataRetrievalStart() {
- }
-
- @Override
- public void onDataSuccess(LinkedInUser linkedInUser) {
- hideProgressDialog();
- Intent intent = new Intent();
- intent.putExtra("social_login", linkedInUser);
- setResult(Activity.RESULT_OK, intent);
- finish();
- }
-
- @Override
- public void onDataFailed(int errCode, String errMessage) {
- hideProgressDialog();
- Intent intent = new Intent();
- intent.putExtra("err_code", errCode);
- intent.putExtra("err_message", errMessage);
- setResult(Activity.RESULT_CANCELED, intent);
- finish();
- }
- });
-
- } else {
-
- hideProgressDialog();
- Intent intent = new Intent();
- intent.putExtra("err_code", LinkedInFromActivityBuilder.ERROR_FAILED);
- intent.putExtra("err_message", "AUTHORIZATION FAILED");
- setResult(Activity.RESULT_CANCELED, intent);
- finish();
-
- }
-
- }
- }
-
-
- /**
- * Method that retrieves authentication token using authorization token
- */
- private void retrieveAccessTokenFromAPI(String authorizationToken) throws IOException, JSONException {
- String accessTokenUrl = getAccessTokenUrl(authorizationToken);
- String result = RequestHandler.sendPost(accessTokenUrl, new JSONObject());
- if (result != null) {
- JSONObject resultJson = new JSONObject(result);
- int expiresIn = resultJson.has("expires_in") ? resultJson.getInt("expires_in") : 0;
- String accessToken1 = resultJson.has("access_token") ? resultJson.getString("access_token") : null;
-
- if (expiresIn > 0 && accessToken1 != null) {
- Calendar calendar = Calendar.getInstance();
- calendar.add(Calendar.SECOND, expiresIn);
- long expireDate = calendar.getTimeInMillis();
- linkedInUser.setAccessToken(accessToken1);
- linkedInUser.setAccessTokenExpiry(expireDate);
- } else {
- Log.e(LinkedInFromActivityBuilder.TAG, "Access Token Expired or Doesn't exist");
- }
- } else {
- Log.e(LinkedInFromActivityBuilder.TAG, "Failed To Retrieve Access Token");
- }
- }
-
-
- /**
- * Method that generates the url for get the access token from the Service
- *
- * @return String - access token url
- */
- 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 + CLIENT_ID
- + AMPERSAND
- + REDIRECT_URI_PARAM + EQUALS + REDIRECT_URI
- + AMPERSAND
- + SECRET_KEY_PARAM + EQUALS + CLIENT_SECRET_KEY;
- }
-
-
- /**
- * Method that generates the url for get the authorization token from the Service
- *
- * @return String - authorization url
- */
- private static String getAuthorizationUrl() {
- return AUTHORIZATION_URL
- + QUESTION_MARK + RESPONSE_TYPE_PARAM + EQUALS + RESPONSE_TYPE_VALUE
- + AMPERSAND + CLIENT_ID_PARAM + EQUALS + CLIENT_ID
- + AMPERSAND + STATE_PARAM + EQUALS + STATE
- + AMPERSAND + REDIRECT_URI_PARAM + EQUALS + REDIRECT_URI
- + AMPERSAND + "scope=r_liteprofile%20r_emailaddress";
- }
-
- private void showProgressDialog() {
- if (!LinkedInAuthenticationActivity.this.isFinishing()) {
- if (progressDialog == null) {
- AlertDialog.Builder builder = new AlertDialog.Builder(LinkedInAuthenticationActivity.this);
- builder.setCancelable(false); // if you want user to wait for some process to finish,
- builder.setView(R.layout.linkedin_layout_progress_dialog);
- progressDialog = builder.create();
- }
- progressDialog.show();
- }
- }
-
- private void hideProgressDialog() {
- if (!LinkedInAuthenticationActivity.this.isFinishing() && progressDialog != null) {
- progressDialog.dismiss();
- }
- }
-}
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java
deleted file mode 100644
index cef8c5a..0000000
--- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/RetrieveBasicProfileAsyncTask.java
+++ /dev/null
@@ -1,117 +0,0 @@
-package com.AbdAllahAbdElFattah13.linkedinsdk;
-
-import android.os.AsyncTask;
-import android.util.Log;
-
-import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.LinkedInUser;
-import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener;
-import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.RequestHandler;
-import com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder.LinkedInFromActivityBuilder;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.IOException;
-
-public class RetrieveBasicProfileAsyncTask extends AsyncTask {
-
- private static final String TAG = "LinkedInAuth";
- private OnBasicProfileListener basicProfileListener;
- private LinkedInUser linkedInUser = new LinkedInUser();
-
- public RetrieveBasicProfileAsyncTask(String accessToken, long accessTokenExpiry, OnBasicProfileListener basicProfileListener) {
- this.basicProfileListener = basicProfileListener;
- this.linkedInUser.setAccessToken(accessToken);
- this.linkedInUser.setAccessTokenExpiry(accessTokenExpiry);
- }
-
- @Override
- protected void onPreExecute() {
- super.onPreExecute();
- basicProfileListener.onDataRetrievalStart();
- }
-
- @Override
- protected Boolean doInBackground(String... tokens) {
-
-
- if (linkedInUser.getAccessToken() != null) {
-
- try {
-
- retrieveBasicProfile();
-
- retrieveEmailFromAPI();
-
- return linkedInUser.getId() != null;
-
- } catch (IOException e) {
- e.printStackTrace();
- return false;
- } catch (JSONException e) {
- e.printStackTrace();
- return false;
- }
-
- }
-
- return false;
- }
-
- @Override
- protected void onPostExecute(Boolean didSuccess) {
- super.onPostExecute(didSuccess);
-
- if (didSuccess) {
- basicProfileListener.onDataSuccess(linkedInUser);
- } else {
- basicProfileListener.onDataFailed(LinkedInFromActivityBuilder.ERROR_FAILED, "AUTHORIZATION FAILED");
- }
- }
-
-
- /**
- * Method that retrieves user basic info from LinkedIn API
- */
- private void retrieveBasicProfile() throws IOException, JSONException {
-
- String profileUrl = "https://api.linkedin.com/v2/me?projection=(id,firstName,lastName,profilePicture(displayImage~:playableStreams))";
- String result = RequestHandler.sendGet(profileUrl, linkedInUser.getAccessToken());
- if (result != null) {
-
- JSONObject jsonObject = new JSONObject(result);
-
- String linkedInUserId = jsonObject.getString("id");
- String country = jsonObject.getJSONObject("firstName").getJSONObject("preferredLocale").getString("country");
- String language = jsonObject.getJSONObject("firstName").getJSONObject("preferredLocale").getString("language");
- String firstNameKey = language + "_" + country;
- String linkedInUserFirstName = jsonObject.getJSONObject("firstName").getJSONObject("localized").getString(firstNameKey);
- String linkedInUserLastName = jsonObject.getJSONObject("lastName").getJSONObject("localized").getString(firstNameKey);
- String linkedInUserProfile = jsonObject.getJSONObject("profilePicture").getJSONObject("displayImage~").getJSONArray("elements").getJSONObject(0).getJSONArray("identifiers").getJSONObject(0).getString("identifier");
-
- linkedInUser.setId(linkedInUserId);
- linkedInUser.setFirstName(linkedInUserFirstName);
- linkedInUser.setLastName(linkedInUserLastName);
- linkedInUser.setProfileUrl(linkedInUserProfile);
-
- } else {
- Log.e(TAG, "Failed To Retrieve Basic Profile");
- }
- }
-
- /**
- * Method that retrieves user email from LinkedIn emailAddress API
- */
- private void retrieveEmailFromAPI() throws IOException, JSONException {
- String emailUrl = "https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))";
- String result = RequestHandler.sendGet(emailUrl, linkedInUser.getAccessToken());
- if (result != null) {
- JSONObject jsonObject = new JSONObject(result);
- String email = jsonObject.getJSONArray("elements").getJSONObject(0).getJSONObject("handle~").getString("emailAddress");
- linkedInUser.setEmail(email);
- } else {
- Log.e(TAG, "Failed To Retrieve Email from LinkedIn API");
- }
- }
-
-}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/di/DependencyGraph.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/di/DependencyGraph.kt
new file mode 100644
index 0000000..96d4ada
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/di/DependencyGraph.kt
@@ -0,0 +1,23 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.di
+
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.usecases.RetrieveAccessTokenUseCase
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.usecase.RetrieveBasicProfileInfoUseCase
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.Executors
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler
+import com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models.LinkedInInitializationInfo
+import com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.viewmodel.LinkedInAuthenticationViewModelFactory
+
+class DependencyGraph(
+ private val initializationInfo: LinkedInInitializationInfo,
+ private val requestHandler: RequestHandler,
+ private val executors: Executors
+) {
+ fun providesRetrieveAccessTokenUseCase() = RetrieveAccessTokenUseCase(requestHandler)
+ fun providesRetrieveBasicProfileInfoUseCase() = RetrieveBasicProfileInfoUseCase(requestHandler)
+ fun providesLinkedInAuthenticationViewModelFactory() = LinkedInAuthenticationViewModelFactory(
+ initializationInfo,
+ providesRetrieveAccessTokenUseCase(),
+ providesRetrieveBasicProfileInfoUseCase(),
+ executors
+ )
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/abstracts/UseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/abstracts/UseCase.kt
new file mode 100644
index 0000000..618b4ad
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/abstracts/UseCase.kt
@@ -0,0 +1,6 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.domain.abstracts
+
+abstract class UseCase {
+
+ abstract fun run(input: Input?): Output
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt
new file mode 100644
index 0000000..6ee9441
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/RetrieveAuthorizationTokenFromUriUseCase.kt
@@ -0,0 +1,11 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases
+
+import android.net.Uri
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.abstracts.UseCase
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.LinkedInConst
+
+class RetrieveAuthorizationTokenFromUriUseCase : UseCase() {
+ override fun run(input: Uri?): String? {
+ return input?.getQueryParameter(LinkedInConst.RESPONSE_TYPE_VALUE)
+ }
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt
new file mode 100644
index 0000000..253c4b7
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/LinkedInAccessTokenInfo.kt
@@ -0,0 +1,3 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models
+
+data class LinkedInAccessTokenInfo(val accessToken: String, val accessTokenExpiry: Long)
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt
new file mode 100644
index 0000000..10df57b
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/models/errors/RetrieveAccessTokenError.kt
@@ -0,0 +1,8 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.errors
+
+sealed class RetrieveAccessTokenError(msg: String) : RuntimeException("RetrieveAccessTokenError: $msg") {
+
+ class NullInput(msg: String) : RetrieveAccessTokenError(msg)
+ class AccessTokenRequestFailed(msg: String) : RetrieveAccessTokenError(msg)
+
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt
new file mode 100644
index 0000000..f8ae3d6
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_access_token/usecases/RetrieveAccessTokenUseCase.kt
@@ -0,0 +1,54 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.usecases
+
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.abstracts.UseCase
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.LinkedInAccessTokenInfo
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.errors.RetrieveAccessTokenError
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.LinkedInConst
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler
+import org.json.JSONObject
+import java.util.*
+
+class RetrieveAccessTokenUseCase(private val requestHandler: RequestHandler) : UseCase() {
+
+ private fun getAccessTokenEndpoint(inputs: RetrieveAccessTokenInputs): String {
+ return (LinkedInConst.ACCESS_TOKEN_URL
+ + LinkedInConst.QUESTION_MARK
+ + LinkedInConst.GRANT_TYPE_PARAM + LinkedInConst.EQUALS + LinkedInConst.GRANT_TYPE
+ + LinkedInConst.AMPERSAND
+ + LinkedInConst.RESPONSE_TYPE_VALUE + LinkedInConst.EQUALS + inputs.authorizationToken
+ + LinkedInConst.AMPERSAND
+ + LinkedInConst.CLIENT_ID_PARAM + LinkedInConst.EQUALS + inputs.clientId
+ + LinkedInConst.AMPERSAND
+ + LinkedInConst.REDIRECT_URI_PARAM + LinkedInConst.EQUALS + inputs.redirectUri
+ + LinkedInConst.AMPERSAND
+ + LinkedInConst.SECRET_KEY_PARAM + LinkedInConst.EQUALS + inputs.clientSecretKey)
+ }
+
+ @Throws(RetrieveAccessTokenError::class)
+ override fun run(input: RetrieveAccessTokenInputs?): LinkedInAccessTokenInfo {
+ if (input == null) throw RetrieveAccessTokenError.NullInput("RetrieveAccessTokenUseCase inputs can't be null!")
+
+ val accessTokenEndpoint = getAccessTokenEndpoint(input)
+ val resultString = requestHandler.sendPost(accessTokenEndpoint, JSONObject())
+ if (resultString != null) {
+ val resultJson = JSONObject(resultString)
+ val expiresIn = if (resultJson.has("expires_in")) resultJson.getInt("expires_in") else 0
+ val accessToken = if (resultJson.has("access_token")) resultJson.getString("access_token") else null
+
+ if (expiresIn > 0 && accessToken != null) {
+ val calendar = Calendar.getInstance()
+ calendar.add(Calendar.SECOND, expiresIn)
+ val expireDate = calendar.timeInMillis
+
+ val linkedInAccessTokenInfo = LinkedInAccessTokenInfo(accessToken, expireDate)
+ return linkedInAccessTokenInfo
+ } else {
+ throw RetrieveAccessTokenError.AccessTokenRequestFailed("API call returned null access token!")
+ }
+ } else {
+ throw RetrieveAccessTokenError.AccessTokenRequestFailed("Access token API failed!")
+ }
+ }
+
+ data class RetrieveAccessTokenInputs(val authorizationToken: String, val clientId: String, val redirectUri: String, val clientSecretKey: String)
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt
new file mode 100644
index 0000000..8180a9d
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/LinkedInBasicProfileInfo.kt
@@ -0,0 +1,3 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models
+
+data class LinkedInBasicProfileInfo(val id: String, val email: String, val firstName: String, val lastName: String, val profilePictureUrl: String?, val accessToken: String, val accessTokenExpiry: Long)
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt
new file mode 100644
index 0000000..74a0ee1
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/models/error/RetrieveBasicProfileInfoError.kt
@@ -0,0 +1,6 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.error
+
+sealed class RetrieveBasicProfileInfoError(msg: String) : RuntimeException(msg) {
+ class NullInput(msg: String) : RetrieveBasicProfileInfoError(msg)
+ class FailedToRetrieveBasicProfileInfo(msg: String) : RetrieveBasicProfileInfoError(msg)
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfoUseCase.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfoUseCase.kt
new file mode 100644
index 0000000..670ec12
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/usecases/retrieve_basic_profile/usecase/RetrieveBasicProfileInfoUseCase.kt
@@ -0,0 +1,98 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.usecase
+
+import android.util.Log
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.abstracts.UseCase
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.LinkedInAccessTokenInfo
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.LinkedInBasicProfileInfo
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.error.RetrieveBasicProfileInfoError
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler.sendGet
+import org.json.JSONException
+import org.json.JSONObject
+import java.io.IOException
+
+class RetrieveBasicProfileInfoUseCase(private val requestHandler: RequestHandler) : UseCase() {
+
+ private val TAG = "RetrieveBasicProfileInf"
+
+ override fun run(input: LinkedInAccessTokenInfo?): LinkedInBasicProfileInfo {
+ if (input == null) throw RetrieveBasicProfileInfoError.NullInput("Input can't be null for RetrieveBasicProfileInfo")
+
+ try {
+ val email = retrieveEmailFromAPI(input)
+ val profileInfo = retrieveBasicProfile(input, email)
+
+ return profileInfo
+ } catch (e: Exception) {
+ throw RetrieveBasicProfileInfoError.FailedToRetrieveBasicProfileInfo(e.localizedMessage)
+ }
+ }
+
+ /**
+ * Method that retrieves user email from LinkedIn emailAddress API
+ */
+ @Throws(IOException::class, JSONException::class)
+ private fun retrieveEmailFromAPI(accessTokenInfo: LinkedInAccessTokenInfo): String {
+ val emailUrl = "https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))"
+ val result = sendGet(emailUrl, accessTokenInfo.accessToken)
+ if (result != null) {
+ val jsonObject = JSONObject(result)
+ val email = jsonObject.getJSONArray("elements").getJSONObject(0).getJSONObject("handle~").getString("emailAddress")
+ return email
+ } else {
+ Log.e(TAG, "Failed To Retrieve Email from LinkedIn API")
+ throw RetrieveBasicProfileInfoError.FailedToRetrieveBasicProfileInfo("Failed To Retrieve Basic Profile")
+ }
+ }
+
+ /**
+ * Method that retrieves user basic info from LinkedIn API
+ */
+ @Throws(IOException::class, JSONException::class)
+ private fun retrieveBasicProfile(accessTokenInfo: LinkedInAccessTokenInfo, email: String): LinkedInBasicProfileInfo {
+ val profileEndpoint = "https://api.linkedin.com/v2/me?projection=(id,firstName,lastName,profilePicture(displayImage~:playableStreams))"
+ val result = requestHandler.sendGet(profileEndpoint, accessTokenInfo.accessToken)
+ if (result != null) {
+ val jsonObject = JSONObject(result)
+ val linkedInUserId = jsonObject.getString("id")
+
+ val country = jsonObject
+ .getJSONObject("firstName")
+ .getJSONObject("preferredLocale")
+ .getString("country")
+ val language = jsonObject
+ .getJSONObject("firstName")
+ .getJSONObject("preferredLocale")
+ .getString("language")
+ val firstNameKey = language + "_" + country
+ val linkedInUserFirstName = jsonObject.getJSONObject("firstName")
+ .getJSONObject("localized")
+ .getString(firstNameKey)
+
+ val linkedInUserLastName = jsonObject.getJSONObject("lastName")
+ .getJSONObject("localized")
+ .getString(firstNameKey)
+
+ //to take care of users without pp
+ val linkedInUserProfile = try {
+ jsonObject
+ .getJSONObject("profilePicture")
+ .getJSONObject("displayImage~")
+ .getJSONArray("elements")
+ .getJSONObject(0)
+ .getJSONArray("identifiers")
+ .getJSONObject(0)
+ .getString("identifier")
+ } catch (e: Exception) {
+ null
+ }
+
+ return LinkedInBasicProfileInfo(linkedInUserId, email, linkedInUserFirstName, linkedInUserLastName, linkedInUserProfile, accessTokenInfo.accessToken, accessTokenInfo.accessTokenExpiry)
+
+ } else {
+ Log.e(TAG, "Failed To Retrieve Basic Profile")
+ throw RetrieveBasicProfileInfoError.FailedToRetrieveBasicProfileInfo("Failed To Retrieve Basic Profile")
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/Executors.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/Executors.kt
new file mode 100644
index 0000000..1b46e21
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/Executors.kt
@@ -0,0 +1,45 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils
+
+import android.os.Handler
+import android.os.Looper
+
+import java.util.concurrent.Executor
+import java.util.concurrent.Executors
+
+/**
+ * Global executor pools for the sdk.
+ *
+ * Grouping tasks like this avoids the effects of task starvation (e.g. disk reads don't wait behind
+ * webservice requests).
+ */
+open class Executors(
+ private val diskIO: Executor,
+ private val networkIO: Executor,
+ private val mainThread: Executor
+) {
+
+ constructor() : this(
+ Executors.newSingleThreadExecutor(),
+ Executors.newFixedThreadPool(3),
+ MainThreadExecutor()
+ )
+
+ fun diskIO(): Executor {
+ return diskIO
+ }
+
+ fun networkIO(): Executor {
+ return networkIO
+ }
+
+ fun mainThread(): Executor {
+ return mainThread
+ }
+
+ private class MainThreadExecutor : Executor {
+ private val mainThreadHandler = Handler(Looper.getMainLooper())
+ override fun execute(command: Runnable) {
+ mainThreadHandler.post(command)
+ }
+ }
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/LinkedInConst.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/LinkedInConst.kt
new file mode 100644
index 0000000..f8ae660
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/LinkedInConst.kt
@@ -0,0 +1,24 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils
+
+object LinkedInConst {
+ const val AUTHORIZATION_URL = "https://www.linkedin.com/uas/oauth2/authorization"
+ const val ACCESS_TOKEN_URL = "https://www.linkedin.com/uas/oauth2/accessToken"
+ const val SECRET_KEY_PARAM = "client_secret"
+ const val RESPONSE_TYPE_PARAM = "response_type"
+ const val GRANT_TYPE_PARAM = "grant_type"
+ const val GRANT_TYPE = "authorization_code"
+ const val RESPONSE_TYPE_VALUE = "code"
+ const val CLIENT_ID_PARAM = "client_id"
+ const val STATE_PARAM = "state"
+ const val REDIRECT_URI_PARAM = "redirect_uri"
+ const val QUESTION_MARK = "?"
+ const val AMPERSAND = "&"
+ const val EQUALS = "="
+
+ fun getAuthorizationUrl(clientId: String, redirectUri: String, state: String): String = (AUTHORIZATION_URL
+ + QUESTION_MARK + RESPONSE_TYPE_PARAM + EQUALS + RESPONSE_TYPE_VALUE
+ + AMPERSAND + CLIENT_ID_PARAM + EQUALS + clientId
+ + AMPERSAND + STATE_PARAM + EQUALS + state
+ + AMPERSAND + REDIRECT_URI_PARAM + EQUALS + redirectUri
+ + AMPERSAND + "scope=r_liteprofile%20r_emailaddress")
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/RequestHandler.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/RequestHandler.kt
new file mode 100644
index 0000000..2a136b6
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/domain/utils/RequestHandler.kt
@@ -0,0 +1,122 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils
+
+import android.util.Log
+import org.json.JSONException
+import org.json.JSONObject
+import java.io.*
+import java.net.HttpURLConnection
+import java.net.URL
+import java.net.URLEncoder
+import javax.net.ssl.HttpsURLConnection
+
+object RequestHandler {
+ private const val TAG = "RequestHandler"
+
+ /**
+ * Method that handles Post request
+ *
+ * @return String - response from API, null if failed
+ */
+ @JvmStatic
+ @Throws(IOException::class, JSONException::class)
+ fun sendPost(urlStr: String, postDataParams: JSONObject): String? {
+ val url = URL(urlStr)
+ val conn = url.openConnection() as HttpURLConnection
+ conn.readTimeout = 20000
+ conn.connectTimeout = 20000
+ conn.requestMethod = "POST"
+ conn.doInput = true
+ conn.doOutput = true
+ val os = conn.outputStream
+ val writer = BufferedWriter(OutputStreamWriter(os, "UTF-8"))
+ writer.write(encodeParams(postDataParams))
+ writer.flush()
+ writer.close()
+ os.close()
+ val responseCode = conn.responseCode // To Check for 200
+ if (responseCode == HttpsURLConnection.HTTP_OK) {
+ val bufferedReader = BufferedReader(InputStreamReader(conn.inputStream))
+ val sb = StringBuilder()
+ var line: String
+ while (bufferedReader.readLine().also { line = it } != null) {
+ sb.append(line)
+ break
+ }
+ bufferedReader.close()
+ return sb.toString()
+ } else {
+ val err = BufferedReader(InputStreamReader(conn.errorStream))
+ val sb = StringBuilder()
+ var line: String
+ while (err.readLine().also { line = it } != null) {
+ sb.append(line)
+ break
+ }
+ err.close()
+ Log.e(TAG, "Error Code " + conn.responseCode)
+ Log.e(TAG, "Error Message $sb")
+ }
+ return null
+ }
+
+ /**
+ * Method that handles Get request
+ *
+ * @return String - response from API, null if failed
+ */
+ @JvmStatic
+ @Throws(IOException::class)
+ fun sendGet(url: String?, accessToken: String): String? {
+ val obj = URL(url)
+ val con = obj.openConnection() as HttpURLConnection
+ con.requestMethod = "GET"
+ con.setRequestProperty("Authorization", "Bearer $accessToken")
+ con.setRequestProperty("cache-control", "no-cache")
+ con.setRequestProperty("X-Restli-Protocol-Version", "2.0.0")
+ val responseCode = con.responseCode
+ Log.d(TAG, "Response Code :: $responseCode")
+ return if (responseCode == HttpURLConnection.HTTP_OK) { // connection ok
+ val bufferedReader = BufferedReader(InputStreamReader(con.inputStream))
+ var inputLine: String?
+ val response = StringBuilder()
+ while (bufferedReader.readLine().also { inputLine = it } != null) {
+ response.append(inputLine)
+ }
+ bufferedReader.close()
+ response.toString()
+ } else {
+ val err = BufferedReader(InputStreamReader(con.errorStream))
+ val sb = StringBuilder()
+ var line: String
+ while (err.readLine().also { line = it } != null) {
+ sb.append(line)
+ break
+ }
+ err.close()
+ Log.e(TAG, "Error Code " + con.responseCode)
+ Log.e(TAG, "Error Message $sb")
+ null
+ }
+ }
+
+ /**
+ * Method that encodes parameters
+ *
+ * @return String - url encoded string
+ */
+ @Throws(UnsupportedEncodingException::class, JSONException::class)
+ private fun encodeParams(params: JSONObject): String {
+ val result = StringBuilder()
+ var first = true
+ val itr = params.keys()
+ while (itr.hasNext()) {
+ val key = itr.next()
+ val value = params[key]
+ if (first) first = false else result.append("&")
+ result.append(URLEncoder.encode(key, "UTF-8"))
+ result.append("=")
+ result.append(URLEncoder.encode(value.toString(), "UTF-8"))
+ }
+ return result.toString()
+ }
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/OnBasicProfileListener.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/OnBasicProfileListener.java
deleted file mode 100644
index 0d11cce..0000000
--- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/OnBasicProfileListener.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.AbdAllahAbdElFattah13.linkedinsdk.helpers;
-
-public interface OnBasicProfileListener {
- void onDataRetrievalStart();
-
- void onDataSuccess(LinkedInUser linkedInUser);
-
- void onDataFailed(int errCode, String errMessage);
-
-}
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/RequestHandler.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/RequestHandler.java
deleted file mode 100644
index e264605..0000000
--- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/RequestHandler.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package com.AbdAllahAbdElFattah13.linkedinsdk.helpers;
-
-import android.util.Log;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.util.Iterator;
-
-import javax.net.ssl.HttpsURLConnection;
-
-public class RequestHandler {
-
- private static final String TAG = "LinkedInAuth";
-
- /**
- * Method that handles Post request
- *
- * @return String - response from API, null if failed
- */
- public static String sendPost(String r_url , JSONObject postDataParams) throws IOException, JSONException {
- URL url = new URL(r_url);
-
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- conn.setReadTimeout(20000);
- conn.setConnectTimeout(20000);
- conn.setRequestMethod("POST");
- conn.setDoInput(true);
- conn.setDoOutput(true);
-
- OutputStream os = conn.getOutputStream();
- BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(os, "UTF-8"));
- writer.write(encodeParams(postDataParams));
- writer.flush();
- writer.close();
- os.close();
-
- int responseCode=conn.getResponseCode(); // To Check for 200
- if (responseCode == HttpsURLConnection.HTTP_OK) {
-
- BufferedReader in=new BufferedReader( new InputStreamReader(conn.getInputStream()));
- StringBuilder sb = new StringBuilder();
- String line="";
- while((line = in.readLine()) != null) {
- sb.append(line);
- break;
- }
- in.close();
- return sb.toString();
- }else{
-
- BufferedReader err=new BufferedReader( new InputStreamReader(conn.getErrorStream()));
- StringBuilder sb = new StringBuilder();
- String line="";
- while((line = err.readLine()) != null) {
- sb.append(line);
- break;
- }
- err.close();
- Log.e(TAG, "Error Code "+conn.getResponseCode());
- Log.e(TAG, "Error Message "+sb.toString());
- }
- return null;
- }
-
-
- /**
- * Method that handles Get request
- *
- * @return String - response from API, null if failed
- */
- public static String sendGet(String url, String accessToken) throws IOException {
- URL obj = new URL(url);
- HttpURLConnection con = (HttpURLConnection) obj.openConnection();
- con.setRequestMethod("GET");
- con.setRequestProperty("Authorization", "Bearer " + accessToken);
- con.setRequestProperty("cache-control", "no-cache");
- con.setRequestProperty("X-Restli-Protocol-Version", "2.0.0");
- int responseCode = con.getResponseCode();
- System.out.println("Response Code :: " + responseCode);
- if (responseCode == HttpURLConnection.HTTP_OK) { // connection ok
- BufferedReader in = new BufferedReader(new InputStreamReader( con.getInputStream()));
- String inputLine;
- StringBuilder response = new StringBuilder();
-
- while ((inputLine = in.readLine()) != null) {
- response.append(inputLine);
- }
- in.close();
- return response.toString();
- } else {
-
- BufferedReader err=new BufferedReader( new InputStreamReader(con.getErrorStream()));
- StringBuilder sb = new StringBuilder();
- String line="";
- while((line = err.readLine()) != null) {
- sb.append(line);
- break;
- }
- err.close();
- Log.e(TAG, "Error Code "+con.getResponseCode());
- Log.e(TAG, "Error Message "+sb.toString());
-
- return null;
- }
- }
-
-
- /**
- * Method that encodes parameters
- *
- * @return String - url encoded string
- */
- private static String encodeParams(JSONObject params) throws UnsupportedEncodingException, JSONException {
- StringBuilder result = new StringBuilder();
- boolean first = true;
- Iterator itr = params.keys();
- while(itr.hasNext()){
- String key= itr.next();
- Object value = params.get(key);
- if (first)
- first = false;
- else
- result.append("&");
-
- result.append(URLEncoder.encode(key, "UTF-8"));
- result.append("=");
- result.append(URLEncoder.encode(value.toString(), "UTF-8"));
- }
- return result.toString();
- }
-}
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInAuthenticationState.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInAuthenticationState.kt
new file mode 100644
index 0000000..4c9499c
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInAuthenticationState.kt
@@ -0,0 +1,14 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models
+
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.LinkedInAccessTokenInfo
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.errors.RetrieveAccessTokenError
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.LinkedInBasicProfileInfo
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.error.RetrieveBasicProfileInfoError
+
+sealed class LinkedInAuthenticationState {
+ object Loading : LinkedInAuthenticationState()
+ class AccessTokenRetrievedSuccessfully(val accessTokenInfo: LinkedInAccessTokenInfo) : LinkedInAuthenticationState()
+ class FailedToRetrieveAccessToken(val accessTokenRetrievalError: RetrieveAccessTokenError) : LinkedInAuthenticationState()
+ class BasicProfileRetrievedSuccessfully(val profileInfo: LinkedInBasicProfileInfo) : LinkedInAuthenticationState()
+ class FailedToRetrieveProfile(val accessTokenRetrievalError: RetrieveBasicProfileInfoError) : LinkedInAuthenticationState()
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInInitializationInfo.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInInitializationInfo.kt
new file mode 100644
index 0000000..f1c4e44
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/models/LinkedInInitializationInfo.kt
@@ -0,0 +1,3 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models
+
+data class LinkedInInitializationInfo(val clientId: String, val clientSecretKey: String, val redirectUri: String)
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/viewmodel/LinkedInAuthenticationViewModel.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/viewmodel/LinkedInAuthenticationViewModel.kt
new file mode 100644
index 0000000..bd0f29a
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/presentation/linkedin_authentication/viewmodel/LinkedInAuthenticationViewModel.kt
@@ -0,0 +1,79 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.viewmodel
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.models.errors.RetrieveAccessTokenError
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_access_token.usecases.RetrieveAccessTokenUseCase
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.models.error.RetrieveBasicProfileInfoError
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.usecases.retrieve_basic_profile.usecase.RetrieveBasicProfileInfoUseCase
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.Executors
+import com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models.LinkedInAuthenticationState
+import com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models.LinkedInInitializationInfo
+
+class LinkedInAuthenticationViewModel(
+ private val initializationInfo: LinkedInInitializationInfo,
+ private val retrieveAccessTokenUseCase: RetrieveAccessTokenUseCase,
+ private val retrieveBasicProfileInfoUseCase: RetrieveBasicProfileInfoUseCase,
+ private val executors: Executors
+) : ViewModel() {
+
+ private val _state = MutableLiveData()
+ val state: LiveData = _state
+
+ fun onAuthorizationTokenGranted(authorizationToken: String) {
+ _state.value = LinkedInAuthenticationState.Loading
+
+ executors.networkIO().execute {
+ val accessTokenInfo = try {
+ retrieveAccessTokenUseCase.run(RetrieveAccessTokenUseCase.RetrieveAccessTokenInputs(
+ authorizationToken = authorizationToken,
+ clientId = initializationInfo.clientId,
+ clientSecretKey = initializationInfo.clientSecretKey,
+ redirectUri = initializationInfo.redirectUri
+ ))
+ } catch (e: RetrieveAccessTokenError) {
+ executors.mainThread().execute {
+ _state.value = LinkedInAuthenticationState.FailedToRetrieveAccessToken(e)
+ }
+ return@execute
+ }
+ executors.mainThread().execute {
+ _state.value = LinkedInAuthenticationState.AccessTokenRetrievedSuccessfully(accessTokenInfo)
+ }
+
+ val profileInfo = try {
+ retrieveBasicProfileInfoUseCase.run(accessTokenInfo)
+ } catch (e: RetrieveBasicProfileInfoError) {
+ executors.mainThread().execute {
+ _state.value = LinkedInAuthenticationState.FailedToRetrieveProfile(e)
+ }
+ return@execute
+ }
+ executors.mainThread().execute {
+ _state.value = LinkedInAuthenticationState.BasicProfileRetrievedSuccessfully(profileInfo)
+ }
+ }
+ }
+}
+
+@Suppress("UNCHECKED_CAST")
+class LinkedInAuthenticationViewModelFactory constructor(
+ private val initializationInfo: LinkedInInitializationInfo,
+ private val retrieveAccessTokenUseCase: RetrieveAccessTokenUseCase,
+ private val retrieveBasicProfileInfoUseCase: RetrieveBasicProfileInfoUseCase,
+ private val executors: Executors
+) : ViewModelProvider.Factory {
+ override fun create(modelClass: Class): T {
+ if (modelClass.isAssignableFrom(LinkedInAuthenticationViewModel::class.java)) {
+ return (LinkedInAuthenticationViewModel(
+ initializationInfo,
+ retrieveAccessTokenUseCase,
+ retrieveBasicProfileInfoUseCase,
+ executors
+ )) as T
+ }
+ throw IllegalArgumentException("Unknown ViewModel class!")
+ }
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInAuthenticationActivity.kt b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInAuthenticationActivity.kt
new file mode 100644
index 0000000..786c210
--- /dev/null
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInAuthenticationActivity.kt
@@ -0,0 +1,173 @@
+package com.AbdAllahAbdElFattah13.linkedinsdk.ui
+
+import android.app.Activity
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.util.Log
+import android.view.View
+import android.view.WindowManager
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import androidx.appcompat.app.AlertDialog
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.Observer
+import com.AbdAllahAbdElFattah13.linkedinsdk.R
+import com.AbdAllahAbdElFattah13.linkedinsdk.di.DependencyGraph
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.Executors
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.LinkedInConst.RESPONSE_TYPE_VALUE
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.LinkedInConst.getAuthorizationUrl
+import com.AbdAllahAbdElFattah13.linkedinsdk.domain.utils.RequestHandler
+import com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models.LinkedInAuthenticationState
+import com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.models.LinkedInInitializationInfo
+import com.AbdAllahAbdElFattah13.linkedinsdk.presentation.linkedin_authentication.viewmodel.LinkedInAuthenticationViewModel
+import com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder.LinkedInFromActivityBuilder
+import kotlinx.android.synthetic.main.linkedin_activity_linkedin_authentication.*
+
+class LinkedInAuthenticationActivity : AppCompatActivity() {
+
+ private var progressDialog: AlertDialog? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.linkedin_activity_linkedin_authentication)
+
+ //enable fullscreen mode
+ window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
+ WindowManager.LayoutParams.FLAG_FULLSCREEN)
+ if (supportActionBar != null) {
+ supportActionBar!!.hide()
+ }
+ CLIENT_ID = intent.getStringExtra(LinkedInFromActivityBuilder.CLIENT_ID)
+ CLIENT_SECRET_KEY = intent.getStringExtra(LinkedInFromActivityBuilder.CLIENT_SECRET_KEY)
+ REDIRECT_URI = intent.getStringExtra(LinkedInFromActivityBuilder.REDIRECT_URI)
+ STATE = intent.getStringExtra(LinkedInFromActivityBuilder.STATE)
+
+ val dependencyGraph = createDependencyGraph(CLIENT_ID, CLIENT_SECRET_KEY, REDIRECT_URI)
+ val vm = dependencyGraph
+ .providesLinkedInAuthenticationViewModelFactory().create(LinkedInAuthenticationViewModel::class.java)
+
+ web_view_linkedin_login.requestFocus(View.FOCUS_DOWN)
+ web_view_linkedin_login.clearHistory()
+ web_view_linkedin_login.clearCache(true)
+
+ setProgressDialogVisibility(true)
+
+ vm.state.observe(this, Observer { state ->
+ when (state) {
+ LinkedInAuthenticationState.Loading -> {
+ setProgressDialogVisibility(true)
+ }
+ is LinkedInAuthenticationState.AccessTokenRetrievedSuccessfully -> {
+ setProgressDialogVisibility(false)
+ }
+ is LinkedInAuthenticationState.FailedToRetrieveAccessToken -> {
+ setProgressDialogVisibility(false)
+ }
+ is LinkedInAuthenticationState.BasicProfileRetrievedSuccessfully -> {
+ setProgressDialogVisibility(false)
+
+ val linkedinUser = LinkedInUser()
+ state.profileInfo.apply {
+ linkedinUser.id = id
+ linkedinUser.email = email
+ linkedinUser.firstName = firstName
+ linkedinUser.lastName = lastName
+ linkedinUser.profilePictureUrl = profilePictureUrl
+ linkedinUser.accessToken = accessToken
+ linkedinUser.accessTokenExpiry = accessTokenExpiry
+ }
+
+ val outputIntent = Intent().apply {
+ putExtra("social_login", linkedinUser)
+ }
+ setResult(Activity.RESULT_OK, outputIntent)
+ finish()
+ }
+ is LinkedInAuthenticationState.FailedToRetrieveProfile -> {
+ setProgressDialogVisibility(false)
+
+ val err = state.accessTokenRetrievalError
+ val outputIntent = Intent().apply {
+ putExtra("error_code", 1019)
+ putExtra("error_msg", err.localizedMessage)
+ }
+
+ setResult(Activity.RESULT_CANCELED, outputIntent)
+ finish()
+ }
+ }
+ })
+
+ web_view_linkedin_login.webViewClient = object : WebViewClient() {
+ override fun onPageFinished(view: WebView, url: String) {
+ setProgressDialogVisibility(false)
+ }
+
+ //to support below Android N we need to use the deprecated method only
+ override fun shouldOverrideUrlLoading(view: WebView, authorizationUrl: String): Boolean {
+ setProgressDialogVisibility(true)
+ if (authorizationUrl.startsWith(REDIRECT_URI)) {
+ val uri = Uri.parse(authorizationUrl)
+ //vm.onRedirect(uri);
+ val stateToken = uri.getQueryParameter(STATE_PARAM)
+ if (stateToken == null || stateToken != STATE) {
+ Log.e(LinkedInFromActivityBuilder.TAG, "State token doesn't match")
+ return true
+ }
+
+ //If the user doesn't allow authorization to our application, the authorizationToken Will be null.
+ val authorizationToken = uri.getQueryParameter(RESPONSE_TYPE_VALUE)
+ if (authorizationToken == null) {
+ val intent = Intent()
+ intent.putExtra("err_code", LinkedInFromActivityBuilder.ERROR_USER_DENIED)
+ intent.putExtra("err_message", "Authorization not received. User didn't allow access to account.")
+ setResult(Activity.RESULT_CANCELED, intent)
+ finish()
+ } else {
+ vm.onAuthorizationTokenGranted(authorizationToken)
+ }
+ } else {
+ //Default behaviour
+ web_view_linkedin_login.loadUrl(authorizationUrl)
+ }
+ return true
+ }
+ }
+ val authUrl = getAuthorizationUrl(CLIENT_ID, REDIRECT_URI, STATE)
+ web_view_linkedin_login.loadUrl(authUrl)
+ }
+
+ private fun createDependencyGraph(clientId: String, clientSecret: String, redirectUri: String): DependencyGraph {
+ val linkedInInitializationInfo = LinkedInInitializationInfo(clientId, clientSecret, redirectUri)
+ return DependencyGraph(linkedInInitializationInfo, RequestHandler, Executors())
+ }
+
+ private fun setProgressDialogVisibility(show: Boolean) {
+ if (!this@LinkedInAuthenticationActivity.isFinishing) {
+ if (show) {
+ if (progressDialog == null) {
+ val builder = AlertDialog.Builder(this@LinkedInAuthenticationActivity)
+ builder.setCancelable(false) // if you want user to wait for some process to finish,
+ builder.setView(R.layout.linkedin_layout_progress_dialog)
+ progressDialog = builder.create()
+ }
+ progressDialog!!.show()
+ } else {
+ if (progressDialog != null) {
+ progressDialog!!.dismiss()
+ }
+ }
+ }
+ }
+
+ companion object {
+ private var CLIENT_ID: String = ""
+ private var CLIENT_SECRET_KEY = ""
+ private var REDIRECT_URI: String = ""
+
+ //for security
+ private var STATE: String = ""
+ private const val STATE_PARAM = "state"
+ }
+}
\ No newline at end of file
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/LinkedInUser.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInUser.java
similarity index 85%
rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/LinkedInUser.java
rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInUser.java
index 9010ab9..9df7044 100644
--- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/helpers/LinkedInUser.java
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/LinkedInUser.java
@@ -1,4 +1,4 @@
-package com.AbdAllahAbdElFattah13.linkedinsdk.helpers;
+package com.AbdAllahAbdElFattah13.linkedinsdk.ui;
import android.os.Parcel;
import android.os.Parcelable;
@@ -8,7 +8,7 @@ public class LinkedInUser implements Parcelable {
private String email;
private String firstName;
private String lastName;
- private String profileUrl;
+ private String profilePictureUrl;
private String accessToken;
private long accessTokenExpiry;
@@ -22,7 +22,7 @@ protected LinkedInUser(Parcel in) {
email = in.readString();
firstName = in.readString();
lastName = in.readString();
- profileUrl = in.readString();
+ profilePictureUrl = in.readString();
accessToken = in.readString();
accessTokenExpiry = in.readLong();
}
@@ -33,7 +33,7 @@ public void writeToParcel(Parcel dest, int flags) {
dest.writeString(email);
dest.writeString(firstName);
dest.writeString(lastName);
- dest.writeString(profileUrl);
+ dest.writeString(profilePictureUrl);
dest.writeString(accessToken);
dest.writeLong(accessTokenExpiry);
}
@@ -88,12 +88,12 @@ public void setLastName(String lastName) {
this.lastName = lastName;
}
- public String getProfileUrl() {
- return profileUrl;
+ public String getProfilePictureUrl() {
+ return profilePictureUrl;
}
- public void setProfileUrl(String profileUrl) {
- this.profileUrl = profileUrl;
+ public void setProfilePictureUrl(String profilePictureUrl) {
+ this.profilePictureUrl = profilePictureUrl;
}
public String getAccessToken() {
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInBuilder.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInBuilder.java
similarity index 82%
rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInBuilder.java
rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInBuilder.java
index dcea7f8..5310d37 100644
--- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInBuilder.java
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInBuilder.java
@@ -1,14 +1,10 @@
-package com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder;
+package com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
-import androidx.annotation.NonNull;
-
-import com.AbdAllahAbdElFattah13.linkedinsdk.LinkedInAuthenticationActivity;
-import com.AbdAllahAbdElFattah13.linkedinsdk.RetrieveBasicProfileAsyncTask;
-import com.AbdAllahAbdElFattah13.linkedinsdk.helpers.OnBasicProfileListener;
+import com.AbdAllahAbdElFattah13.linkedinsdk.ui.LinkedInAuthenticationActivity;
import java.util.Random;
@@ -104,9 +100,4 @@ private void generateState() {
this.state = sb.toString();
intent.putExtra(STATE, state);
}
-
- public static void retrieveBasicProfile(@NonNull String accessToken, long accessTokenExpiry, @NonNull OnBasicProfileListener onBasicProfileListener) {
- new RetrieveBasicProfileAsyncTask(accessToken, accessTokenExpiry, onBasicProfileListener).execute();
- }
-
}
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromActivityBuilder.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromActivityBuilder.java
similarity index 86%
rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromActivityBuilder.java
rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromActivityBuilder.java
index 06ed007..cf27718 100644
--- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromActivityBuilder.java
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromActivityBuilder.java
@@ -1,7 +1,6 @@
-package com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder;
+package com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder;
import android.app.Activity;
-import android.content.Context;
import android.content.Intent;
public final class LinkedInFromActivityBuilder extends LinkedInBuilder {
diff --git a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromFragmentBuilder.java b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromFragmentBuilder.java
similarity index 91%
rename from linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromFragmentBuilder.java
rename to linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromFragmentBuilder.java
index 556943b..6375cc7 100644
--- a/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/linkedin_builder/LinkedInFromFragmentBuilder.java
+++ b/linkedinsdk/src/main/java/com/AbdAllahAbdElFattah13/linkedinsdk/ui/linkedin_builder/LinkedInFromFragmentBuilder.java
@@ -1,4 +1,4 @@
-package com.AbdAllahAbdElFattah13.linkedinsdk.linkedin_builder;
+package com.AbdAllahAbdElFattah13.linkedinsdk.ui.linkedin_builder;
import android.content.Intent;