开发需要在国外上线的项目,集成了几种国外常用社交网站的授权登录(FaceBook,Twitter,Linkedin,Google+)。挖到的一些坑与解决办法。当然途中肯定都需要科学上网的方式进行...其实umeng集成了Twitter和FB,但是Twitter莫名不能成功,所以都自己搞一下。
Google+, Linkedin的集成来自同事
Google+授权三方登录
-
sdk 需要下载google_play_services,在as中按照下面的方式进行配置
- 获取google配置文件,需要在google增加个人应用,并且根据包名和sah1码生成配置文件
戳这里
获取配置文件后,将google-services.json放到app目录下 - 在项目给的gradle文件的dependncies节点下增加
classpath ‘com.google.gms:google-services:2.0.0-alpha6’
在app 的gradle中增加
apply plugin: ‘com.google.gms.google-services’
在app的gradle中增加
dependencies { compile ‘com.google.android.gms:play-services-auth:9.2.1’ } - 在google登录的onCreate的方法中增加
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
// Build a GoogleApiClient with access to the Google Sign-In API and the
// options specified by gso.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, this /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
- 在对应的xml文件中增加
- 在activity可以设置signinbutton的样式
// Customize sign-in button. The sign-in button can be displayed in
// multiple sizes and color schemes. It can also be contextually
// rendered based on the requested scopes. For example. a red button may
// be displayed when Google+ scopes are requested, but a white button
// may be displayed when only basic profile is requested. Try adding the
// Scopes.PLUS_LOGIN scope to the GoogleSignInOptions to see the
// difference.SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button);
signInButton.setSize(SignInButton.SIZE_STANDARD);
signInButton.setScopes(gso.getScopeArray());
signInButton.setOnClickListener(this);
- 在onClick方法中
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.sign_in_button:
Intent signInIntent = Auth.GoogleSignInApi.getSignInIntent(mGoogleApiClient);
startActivityForResult(signInIntent, RC_SIGN_IN);
break; // ...
}
}
- 在onActivityResult方法中设置如下
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
handleSignInResult(result);
}
}
private void handleSignInResult(GoogleSignInResult result) {
Log.d(TAG, "handleSignInResult:" + result.isSuccess());
if (result.isSuccess()) {
// Signed in successfully, show authenticated UI.
GoogleSignInAccount acct = result.getSignInAccount();
mStatusTextView.setText(getString(R.string.signed_in_fmt, acct.getDisplayName()));
updateUI(true);
} else {
// Signed out, show unauthenticated UI.
updateUI(false);
}
}
Google开发文档
注意google play服务 版本不兼容或者版本太低引起崩溃
Linkedin授权三方登录
- 需要在linkedin开发者那里注册应用。
戳这里
添加后,需要填写应用包名和package Hash码
具体方式可自行百度或者参考这个 - 下载linkedin的sdk并以module的方式集成到自己的项目中
- 获取手机端的授权 详情
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// Store a reference to the current activity
final Activity thisActivity = this;
LISessionManager.getInstance(getApplicationContext()).init(thisActivity, buildScope(), new AuthListener() {
@Override
public void onAuthSuccess() {
// Authentication was successful. You can now do
// other calls with the SDK.
}
@Override
public void onAuthError(LIAuthError error) {
// Handle authentication errors
}
}, true);
}
}
// Build the list of member permissions our LinkedIn session requires
private static Scope buildScope() {
return Scope.build(Scope.R_BASICPROFILE, Scope.W_SHARE);
}
@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);
}
}
- 获取授权成功后,获取用户信息 url:
获取全部信息https://api.linkedin.com/v1/people/~
获取指定信息https://api.linkedin.com/v1/people/~:(firstName,lastName,id,picture-url)?format=json
或者戳Linkedin开发文档
String url ="https://api.linkedin.com/v1/people/~:(firstName,lastName,id,picture-url)?format=json";
APIHelper apiHelper = APIHelper.getInstance(getApplicationContext()); apiHelper.getRequest(getApplicationContext(), url, new ApiListener() {
@Override
public void onApiSuccess(ApiResponse apiResponse) {
// Success!
LogUtils.e(TAG, "apiResponse" + apiResponse.toString());
}
@Override
public void onApiError(LIApiError liApiError) {
// Error making GET request!
LogUtils.e(TAG, " Error making GET request!");
}
Twitter授权三方登录
- 创建Twitter开发者账号
创建Twitter账号
Twitter开发者平台
这里的需要使用的美国的手机号请自行解决 0.0
记得设置app的callback url,不然无法调起网页版的授权界面 - 集成的准备工作
有两种集成方式,twitter4j或者官方的Fabric(可自行查看官方文档)
据说twitter4j有事不稳定?最后选了Fabric(要在AS中使用)
然后就注册登录,选择自己的项目,安装
它就会自动在你代码中加入必要代码
因为文档中没看到要安装插件的相关说明,所以按照文档进行集成,
运行后报找不到crashlytics的错时才将Fabric集成进来。
具体能帮助增加哪部分代码自行体会吧~
- 集成授权登录
自带的button按钮
设置callback以及回调
loginButton.setCallback(new Callback() {
@Override
public void success(Result result) {
String name = result.data.getUserName();
long userId = result.data.getUserId();
long id = result.data.getId();
TwitterAuthToken token = result.data.getAuthToken();
String secret = token.secret;
String strToken = token.token;
}
@Override
public void failure(TwitterException exception) {
Log.d("TwitterKit", "Login with Twitter failure", exception);
}
});
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
loginButton.onActivityResult(requestCode, resultCode, data);
}
这里基本就是结束了
- 遇到的一个坑
官方文档中
TwitterAuthConfig authConfig = new TwitterAuthConfig(TWITTER_KEY, TWITTER_SECRET);
Fabric.with(this, new Twitter(authConfig));
部分在Activity中进行的初始化。但是一直无法调起Twitter,放在application中初始化才可以。
FaceBook授权三方登录
-
添加FB授权应用
填写应用名称后就生成了App ID和App Secret
选settings,填写包名,Key Hashes(自行百度生成方式),打开Single Sign On,基本就完成准备工作了
添加配置
AndroidManifast.xml中
一定要注意,这个value="@string/application_id" 不要将id直接放进来,不然会出现id错误...
在build.gradle的dependencies引入facebook包
compile 'com.facebook.android:facebook-android-sdk:4.6.0'
- 代码加入,用的原生的按钮
初始化
FacebookSdk.sdkInitialize(activity.getApplicationContext());
CallbackManager callbackManager = CallbackManager.Factory.create();
必须放在setContentView前初始化,不然报错
List permissionNeeds = Arrays.asList("user_photos", "email", "user_birthday", "public_profile");
loginButton.setReadPermissions(permissionNeeds);
loginButton.registerCallback(callbackManager, new FacebookCallback() {
@Override
public void onSuccess(LoginResult loginResult) {
System.out.println("onSuccess");
GraphRequest request = GraphRequest.newMeRequest (loginResult.getAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
@Override
public void onCompleted(JSONObject object, GraphResponse response) {
LoginManager.getInstance().logOut();
// Application code
LogUtils.e(TAG, response.toString());
//System.out.println("Check: " + response.toString());
try {
String id = object.getString("id");
String name = object.getString("name");
String email = object.getString("email");
String gender = object.getString("gender");
String birthday = object.getString("birthday");
LogUtils.e(TAG, id + ", " + name + ", " + email + ", " + gender + ", " + birthday);
if (listener != null) {
listener.onSucceed(new SocialLoginBean(id, "", name, SocialLoginBean.TYPE_FACEBOOK));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,gender, birthday");
request.setParameters(parameters);
request.executeAsync();
}
@Override
public void onCancel() {
if (listener != null) {
listener.onError(UIUtils.getString(R.string.toast_login_cancel));
}
}
@Override
public void onError(FacebookException exception) {
if (listener != null) {
listener.onError(UIUtils.getString(R.string.toast_login_error));
}
}
});