在 Android 应用中集成 LinkedIn API
在本教程中,我们将在我们的 Android 应用中集成 LinkedIn 登录 功能。在 Android app 中实现 LinkedIn API 可以帮助用户使用 LinkedIn 账号登录、分享动态等。
要在我们的 Android 应用中集成 LinkedIn API ,我们需要 LinkedIn 的 认证密钥 (客户端 ID 和客户端密钥)以及应用程序的 哈希密钥 。
生成 LinkedIn 认证密钥和应用程序哈希密钥的步骤
1. 在 https://www.linkedin.com/developer/apps 上创建 LinkedIn 开发者账号,并点击”创建应用”。
2. 在“创建新应用程序”表中填写Android应用程序的所有必填详细信息,并接受LinkedIn API使用条款,然后点击“提交”。
3.提交应用程序详细信息后,它会生成LinkedIn身份验证密钥。现在我们将选择 “默认应用程序权限” 。此权限授权访问用户帐户的特权。在这里,我们选择 r_basicprofile 和 “r_emailaddress” ,然后点击 “更新” 。
4. 现在,我们需要我们的应用程序的 ‘Hash Key’ 。它可以通过两种不同的方式生成。
- 使用命令提示符上的命令。
Windows:
keytool -exportcert -keystore %HOMEPATH%\.android\debug.keystore -alias androiddebugkey | openssl sha1 -binary | openssl base64
Mac/Unix
keytool -exportcert -keystore ~/.android/debug.keystore -alias androiddebugkey | openssl sha1 -binary | openssl base64
通过命令提示符生成哈希键需要在我们的操作系统中安装OpenSSL。我们可以从www.slproweb.com/products/Win32OpenSSL.html下载用于Windows的OpenSSL,而对于Mac/Unix系统则可以从http://www.openssl.org/source/下载。
- 在Activity.java类中使用编程代码。
PackageInfo info = getPackageManager().getPackageInfo(
"Your Package Nane",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
对于这个应用程序,我们将使用编程代码为我们的应用程序生成“哈希键”。
现在创建我们的应用程序,并简单地编写以下代码并运行以生成我们的“哈希键”。它将在Logcat中显示应用程序的“哈希键”。
MainActivity.java
package example.com.linkedinlogindemo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import java.security.MessageDigest;
public class MainActivity extends AppCompatActivity {
public static final String PACKAGE = "example.com.linkedinlogindemo";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
computePakageHash();
}
private void computePakageHash() {
try {
PackageInfo info = getPackageManager().getPackageInfo(
"example.com.linkedinlogindemo",
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(signature.toByteArray());
Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
}
} catch (Exception e) {
Log.e("TAG",e.getMessage());
}
}
}
5. 从Logcat复制“哈希键”,然后将其粘贴到LinkedIn应用程序的Mobile选项卡中。然后点击“添加”和“更新”。这将使我们的应用程序的“哈希键”被注册到LinkedIn API。
在Android应用中集成LinkedIn登录的示例
让我们创建一个集成LinkedIn登录功能的Android应用示例。在用户成功登录后,它会将用户重定向到另一个活动(ProfileActivity)并显示用户信息。
我们需要在项目中添加LinkedIn SDK for Android。可以从这里下载 https://developer.linkedin.com/downloads#androidsdk.
必填的权限
在 AndroidManifest.xml 文件中添加 Internet 权限。
<uses-permission android:name="android.permission.INTERNET" />
settings.gradle
在 settings.gradle 文件中添加 linkedin-sdk
include ':app', ':linkedin-sdk'
build.gradle(模块)
在build.gradle文件中添加 compile project(path: ‘:linkedin-sdk’) 。
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
compile project(path: ':linkedin-sdk')
}
activity_main.xml
在activity_main.xml文件中添加以下代码。从LinkedIn开发者网站 https://developer.linkedin.com/downloads 下载推荐的LinkedIn按钮,并将其作为按钮的背景添加进去。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="example.com.linkedinlogindemo.MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:textSize="20dp"
android:layout_centerHorizontal="true"
android:text="This is Login Page" />
<Button
android:id="@+id/login_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="17dp"
android:background="@drawable/loginbutton"
tools:layout_editor_absoluteX="58dp"
tools:layout_editor_absoluteY="437dp" />
</RelativeLayout>
MainActivity.java
在MainActivity.java类中,我们使用LISessionManager类,该类提供了创建和管理LISession对象(LinkedIn会话对象)的所有功能。在build方法中,scope添加’Scope.R_BASICPROFILE’和’Scope.R_EMAILADDRESS’以访问LinkedIn用户的基本个人资料信息和电子邮件地址。
package example.com.linkedinlogindemo;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.linkedin.platform.LISessionManager;
import com.linkedin.platform.errors.LIAuthError;
import com.linkedin.platform.listeners.AuthListener;
import com.linkedin.platform.utils.Scope;
public class MainActivity extends AppCompatActivity {
Button loginBtn;
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loginBtn = (Button) findViewById(R.id.login_button);
textView=(TextView)findViewById(R.id.textView);
loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
loginHandle();
}
});
}
public void loginHandle() {
LISessionManager.getInstance(getApplicationContext()).init(MainActivity.this, buildScope(), new AuthListener() {
@Override
public void onAuthSuccess() {
// Authentication was successful. You can now do other calls with the SDK.
Intent intent=new Intent(MainActivity.this,ProfileActivity.class);
startActivity(intent);
}
@Override
public void onAuthError(LIAuthError error) {
// Handle authentication errors
Toast.makeText(getApplicationContext(),"Login Error "+error.toString(),Toast.LENGTH_LONG).show();
}
}, true);
}
private static Scope buildScope() {
return Scope.build(Scope.R_BASICPROFILE, Scope.R_EMAILADDRESS);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Add this line to your existing onActivityResult() method
LISessionManager.getInstance(getApplicationContext()).onActivityResult(this, requestCode, resultCode, data);
}
}
activity_profile.xml
现在,在 activity_profile.xml 文件中添加以下代码。在这个活动中,我们将在成功登录后显示用户信息。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
tools:context="example.com.linkedinlogindemo.ProfileActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Welcome to profile" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/userDetail"
android:text="userdetail"
android:layout_marginTop="20dp"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:textColor="#FFF"
android:text="logout"
android:id="@+id/logout_button"
android:background="#022885"
/>
</LinearLayout>
ProfileActivity.java
在APIHelper类的getRequest()方法中添加LinkedIn API URL https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address) 它将在成功调用LinkedIn API时检索用户信息。
package example.com.linkedinlogindemo;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.linkedin.platform.APIHelper;
import com.linkedin.platform.LISession;
import com.linkedin.platform.LISessionManager;
import com.linkedin.platform.errors.LIApiError;
import com.linkedin.platform.listeners.ApiListener;
import com.linkedin.platform.listeners.ApiResponse;
import org.json.JSONException;
import org.json.JSONObject;
public class ProfileActivity extends AppCompatActivity {
TextView user_detail;
String firstName,lastName,userEmail;
Button logout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
user_detail=(TextView)findViewById(R.id.userDetail);
logout=(Button)findViewById(R.id.logout_button);
fetchuserData();
logout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
LISessionManager.getInstance(getApplicationContext()).clearSession();
Toast.makeText(getApplicationContext(),"Logout Successfully",Toast.LENGTH_LONG).show();
Intent intent = new Intent(ProfileActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
private void fetchuserData() {
String url = "https://api.linkedin.com/v1/people/~:(id,first-name,last-name,email-address)";
APIHelper apiHelper = APIHelper.getInstance(getApplicationContext());
apiHelper.getRequest(this, url, new ApiListener() {
@Override
public void onApiSuccess(ApiResponse apiResponse) {
// Success!
try {
JSONObject jsonObject = apiResponse.getResponseDataAsJson();
firstName = jsonObject.getString("firstName");
lastName = jsonObject.getString("lastName");
userEmail = jsonObject.getString("emailAddress");
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("First Name " + firstName + "\n\n");
stringBuilder.append("Last Name " + lastName + "\n\n");
stringBuilder.append("Email " + userEmail);
user_detail.setText(stringBuilder);
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onApiError(LIApiError liApiError) {
// Error making GET request!
Toast.makeText(getApplicationContext(),"API Error"+liApiError.toString(),Toast.LENGTH_LONG).show();
}
});
}
}
输出: