8 | * 自定义Application 9 | */ 10 | public class SocialSDKApplication extends Application { 11 | 12 | @Override 13 | public void onCreate() { 14 | 15 | initBugHD(); 16 | super.onCreate(); 17 | } 18 | 19 | /** 20 | * 初始化BugHD,实时监控APP的崩溃 21 | */ 22 | private void initBugHD() { 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /socialsdk/src/main/java/com/elbbbird/android/socialsdk/sso/wechat/IWXCallback.java: -------------------------------------------------------------------------------- 1 | package com.elbbbird.android.socialsdk.sso.wechat; 2 | 3 | import com.elbbbird.android.socialsdk.model.SocialToken; 4 | import com.elbbbird.android.socialsdk.model.SocialUser; 5 | 6 | /** 7 | * 微信授权回调接口 8 | *
9 | * Created by zhanghailong-ms on 2015/7/11.
10 | */
11 | public interface IWXCallback {
12 | void onGetCodeSuccess(String code);
13 |
14 | void onGetTokenSuccess(SocialToken token);
15 |
16 | void onGetUserInfoSuccess(SocialUser user);
17 |
18 | void onFailure(Exception e);
19 |
20 | void onCancel();
21 | }
22 |
--------------------------------------------------------------------------------
/sample-app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 |
4 |
5 | android {
6 |
7 | compileSdkVersion 23
8 | buildToolsVersion "23.0.1"
9 | defaultConfig {
10 | applicationId "com.encore.actionnow"
11 | minSdkVersion 15
12 | targetSdkVersion 23
13 | versionCode 1
14 | versionName VERSION_NAME
15 | }
16 |
17 |
18 | }
19 |
20 | dependencies {
21 | compile fileTree(include: ['*.jar'], dir: 'libs')
22 | testCompile 'junit:junit:4.12'
23 | compile 'com.android.support:appcompat-v7:23.1.1'
24 | compile 'com.android.support:design:23.1.1'
25 | compile 'com.jakewharton:butterknife:7.0.1'
26 | compile project(':socialsdk')
27 | }
28 |
--------------------------------------------------------------------------------
/socialsdk/src/main/res/values/es_strings.xml:
--------------------------------------------------------------------------------
1 |
6 | * Created by zhanghailong-ms on 2015/11/16.
7 | */
8 | public class SocialToken {
9 |
10 | private String openId;
11 | private String token;
12 | private String refreshToken;
13 | private long expiresTime;
14 |
15 | public SocialToken() {
16 | }
17 |
18 | public SocialToken(String openId, String token, String refreshToken, long expiresTime) {
19 | this.openId = openId;
20 | this.token = token;
21 | this.refreshToken = refreshToken;
22 | this.expiresTime = System.currentTimeMillis() + expiresTime * 1000L;
23 | }
24 |
25 | public String getOpenId() {
26 | return openId;
27 | }
28 |
29 | public void setOpenId(String openId) {
30 | this.openId = openId;
31 | }
32 |
33 | public String getToken() {
34 | return token;
35 | }
36 |
37 | public void setToken(String token) {
38 | this.token = token;
39 | }
40 |
41 | public String getRefreshToken() {
42 | return refreshToken;
43 | }
44 |
45 | public void setRefreshToken(String refreshToken) {
46 | this.refreshToken = refreshToken;
47 | }
48 |
49 | public long getExpiresTime() {
50 | return expiresTime;
51 | }
52 |
53 | public void setExpiresTime(long expiresTime) {
54 | this.expiresTime = expiresTime;
55 | }
56 |
57 | @Override
58 | public String toString() {
59 | return "SocialToken# openId=" + openId + ", token=" + token + ", refreshToken=" + refreshToken + ", expiresTime=" + expiresTime;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/sample-app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 | * Created by zhanghailong-ms on 2015/11/17.
17 | */
18 | public class QQSSOProxy {
19 |
20 | private static Tencent tencent;
21 |
22 | public static Tencent getTencentInstance(Context context, String appId) {
23 | if (tencent == null) {
24 | tencent = Tencent.createInstance(appId, context);
25 | }
26 |
27 | return tencent;
28 | }
29 |
30 | public static void login(Context context, String appId, String scope, IUiListener listener) {
31 | Tencent tencent = getTencentInstance(context, appId);
32 | if (!SocialSSOProxy.isTokenValid(context)) {
33 | tencent.login((Activity) context, scope, listener);
34 | }
35 | }
36 |
37 | public static void logout(Context context, String appId) {
38 | Tencent tencent = getTencentInstance(context, appId);
39 | if (SocialSSOProxy.isTokenValid(context)) {
40 | tencent.logout(context);
41 | }
42 |
43 | QQSSOProxy.tencent = null;
44 | }
45 |
46 | public static void getUserInfo(Context context, String appId, SocialToken token, IUiListener listener) {
47 | //这里只是为了在刷新用户信息的时候,设置一下全局变量。场景:APP升级安装,没有重新登录过程,调用该接口刷新用户信息,
48 | //如果没有该过程刷新Global.getContext()等常量,会出现空指针
49 | getTencentInstance(context, appId);
50 |
51 | if (SocialSSOProxy.isTokenValid(context)) {
52 | UserInfo info = new UserInfo(context, parseToken(appId, token));
53 | info.getUserInfo(listener);
54 | }
55 | }
56 |
57 | private static QQToken parseToken(String appId, SocialToken socialToken) {
58 | QQToken token = new QQToken(appId);
59 | //3600是随意定义的,不影响token的使用
60 | token.setAccessToken(socialToken.getToken(), "3600");
61 | token.setOpenId(socialToken.getOpenId());
62 |
63 | return token;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/otto/SSOBusEvent.java:
--------------------------------------------------------------------------------
1 | package com.elbbbird.android.socialsdk.otto;
2 |
3 | import com.elbbbird.android.socialsdk.model.SocialToken;
4 | import com.elbbbird.android.socialsdk.model.SocialUser;
5 |
6 | /**
7 | * Otto Bus Event
8 | * Created by zhanghailong-ms on 2015/11/20.
9 | */
10 | public class SSOBusEvent {
11 |
12 | public static final int PLATFORM_DEFAULT = 0;
13 | public static final int PLATFORM_WEIBO = 1;
14 | public static final int PLATFORM_WECHAT = 2;
15 | public static final int PLATFORM_QQ = 3;
16 |
17 | public static final int TYPE_GET_TOKEN = 0;
18 | public static final int TYPE_GET_USER = 1;
19 | public static final int TYPE_FAILURE = 2;
20 | public static final int TYPE_CANCEL = 3;
21 |
22 | private int type;
23 | private int platform;
24 | private SocialUser user;
25 | private SocialToken token;
26 | private Exception exception;
27 |
28 | public SSOBusEvent(int type, int platform) {
29 | this.type = type;
30 | this.platform = platform;
31 | }
32 |
33 | public SSOBusEvent(int type, int platform, SocialUser user) {
34 | this.type = type;
35 | this.platform = platform;
36 | this.user = user;
37 | }
38 |
39 | public SSOBusEvent(int type, int platform, SocialToken token) {
40 | this.type = type;
41 | this.platform = platform;
42 | this.token = token;
43 | }
44 |
45 | public SSOBusEvent(int type, int platform, Exception exception) {
46 | this.type = type;
47 | this.platform = platform;
48 | this.exception = exception;
49 | }
50 |
51 | public int getType() {
52 | return type;
53 | }
54 |
55 | public void setType(int type) {
56 | this.type = type;
57 | }
58 |
59 | public SocialUser getUser() {
60 | return user;
61 | }
62 |
63 | public void setUser(SocialUser user) {
64 | this.user = user;
65 | }
66 |
67 | public SocialToken getToken() {
68 | return token;
69 | }
70 |
71 | public void setToken(SocialToken token) {
72 | this.token = token;
73 | }
74 |
75 | public Exception getException() {
76 | return exception;
77 | }
78 |
79 | public void setException(Exception exception) {
80 | this.exception = exception;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/share/qq/QQShareProxy.java:
--------------------------------------------------------------------------------
1 | package com.elbbbird.android.socialsdk.share.qq;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.os.Bundle;
6 |
7 | import com.tencent.connect.share.QQShare;
8 | import com.tencent.connect.share.QzoneShare;
9 | import com.tencent.tauth.IUiListener;
10 | import com.tencent.tauth.Tencent;
11 |
12 | import java.util.ArrayList;
13 |
14 | /**
15 | * QQ分享Proxy
16 | * Created by zhanghailong-ms on 2015/11/24.
17 | */
18 | public class QQShareProxy {
19 |
20 | private static Tencent tencent;
21 |
22 | private static Tencent getInstance(Context context, String appId) {
23 | if (tencent == null)
24 | tencent = Tencent.createInstance(appId, context);
25 |
26 | return tencent;
27 | }
28 |
29 | public static void shareToQQ(Context context, String appId, String title, String summary, String url,
30 | String imageUrl, String appName, IUiListener listener) {
31 | Bundle params = new Bundle();
32 | params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
33 | params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
34 | params.putString(QQShare.SHARE_TO_QQ_SUMMARY, summary);
35 | params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, url);
36 | params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, imageUrl);
37 | params.putString(QQShare.SHARE_TO_QQ_APP_NAME, appName);
38 | Tencent tencent = getInstance(context, appId);
39 | tencent.shareToQQ((Activity) context, params, listener);
40 | }
41 |
42 | public static void shareToQZone(Context context, String appId, String title, String summary, String url,
43 | String imageUrl, IUiListener listener) {
44 | Bundle params = new Bundle();
45 | params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE, QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT);
46 | params.putString(QzoneShare.SHARE_TO_QQ_TITLE, title);
47 | params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, summary);
48 | params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, url);
49 | ArrayList
6 | * Created by zhanghailong-ms on 2015/11/16.
7 | */
8 | public class SocialUser {
9 |
10 | public static final int TYPE_DEFAULT = 0;
11 | public static final int TYPE_WEIBO = 1;
12 | public static final int TYPE_WECHAT = 2;
13 | public static final int TYPE_QQ = 3;
14 |
15 | public static final int GENDER_UNKNOWN = 0;
16 | public static final int GENDER_MALE = 1;
17 | public static final int GENDER_FEMALE = 2;
18 |
19 | private int type;
20 | private String name;
21 | private String avatar;
22 | private int gender;
23 | private String desc;
24 | private SocialToken token;
25 |
26 | public SocialUser() {
27 | }
28 |
29 | public SocialUser(int type, String name, String avatar, int gender, SocialToken token) {
30 | this.type = type;
31 | this.name = name;
32 | this.avatar = avatar;
33 | this.gender = gender;
34 | this.token = token;
35 | }
36 |
37 | public SocialUser(int type, String name, String avatar, int gender, String desc, SocialToken token) {
38 | this.type = type;
39 | this.name = name;
40 | this.avatar = avatar;
41 | this.gender = gender;
42 | this.desc = desc;
43 | this.token = token;
44 | }
45 |
46 | public int getType() {
47 | return type;
48 | }
49 |
50 | public void setType(int type) {
51 | this.type = type;
52 | }
53 |
54 | public String getName() {
55 | return name;
56 | }
57 |
58 | public void setName(String name) {
59 | this.name = name;
60 | }
61 |
62 | public String getAvatar() {
63 | return avatar;
64 | }
65 |
66 | public void setAvatar(String avatar) {
67 | this.avatar = avatar;
68 | }
69 |
70 | public int getGender() {
71 | return gender;
72 | }
73 |
74 | public void setGender(int gender) {
75 | this.gender = gender;
76 | }
77 |
78 | public String getDesc() {
79 | return desc;
80 | }
81 |
82 | public void setDesc(String desc) {
83 | this.desc = desc;
84 | }
85 |
86 | public SocialToken getToken() {
87 | return token;
88 | }
89 |
90 | public void setToken(SocialToken token) {
91 | this.token = token;
92 | }
93 |
94 | public boolean isTokenValid() {
95 | return getToken().getToken() != null && System.currentTimeMillis() < getToken().getExpiresTime();
96 | }
97 |
98 | @Override
99 | public String toString() {
100 | return "SocialUser: type=" + type + ", name=" + name + ", avatar=" + avatar + ", gender=" + gender + ", desc=" + desc
101 | + ", token=" + token.getToken();
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/model/SocialShareScene.java:
--------------------------------------------------------------------------------
1 | package com.elbbbird.android.socialsdk.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 社会化分享数据类
7 | * Created by zhanghailong-ms on 2015/11/23.
8 | */
9 | public class SocialShareScene implements Serializable {
10 |
11 | public static final int SHARE_TYPE_DEFAULT = 0;
12 | public static final int SHARE_TYPE_WEIBO = 1;
13 | public static final int SHARE_TYPE_WECHAT = 2;
14 | public static final int SHARE_TYPE_WECHAT_TIMELINE = 3;
15 | public static final int SHARE_TYPE_QQ = 4;
16 | public static final int SHARE_TYPE_QZONE = 5;
17 |
18 | private int id;
19 | private int type;
20 | private String appName;
21 | private String title;
22 | private String desc;
23 | private String thumbnail;
24 | private String url;
25 |
26 | /**
27 | * @param id 分享唯一标识符,可随意指定,会在分享结果ShareBusEvent中返回
28 | * @param appName 分享到QQ时需要指定,会在分享弹窗中显示该字段
29 | * @param type 分享类型,会在分享结果ShareBusEvent中作为platform返回
30 | * @param title 标题
31 | * @param desc 简短描述
32 | * @param thumbnail 缩略图网址
33 | * @param url WEB网址
34 | */
35 | public SocialShareScene(int id, String appName, int type, String title, String desc, String thumbnail, String url) {
36 | this.id = id;
37 | this.appName = appName;
38 | this.type = type;
39 | this.title = title;
40 | this.desc = desc;
41 | this.thumbnail = thumbnail;
42 | this.url = url;
43 | }
44 |
45 | public SocialShareScene(int id, String appName, String title, String desc, String thumbnail, String url) {
46 | this.id = id;
47 | this.appName = appName;
48 | this.title = title;
49 | this.desc = desc;
50 | this.thumbnail = thumbnail;
51 | this.url = url;
52 | }
53 |
54 | public String getAppName() {
55 | return appName;
56 | }
57 |
58 | public void setAppName(String appName) {
59 | this.appName = appName;
60 | }
61 |
62 | public int getId() {
63 | return id;
64 | }
65 |
66 | public void setId(int id) {
67 | this.id = id;
68 | }
69 |
70 | public int getType() {
71 | return type;
72 | }
73 |
74 | public void setType(int type) {
75 | this.type = type;
76 | }
77 |
78 | public String getTitle() {
79 | return title;
80 | }
81 |
82 | public void setTitle(String title) {
83 | this.title = title;
84 | }
85 |
86 | public String getDesc() {
87 | return desc;
88 | }
89 |
90 | public void setDesc(String desc) {
91 | this.desc = desc;
92 | }
93 |
94 | public String getThumbnail() {
95 | return thumbnail;
96 | }
97 |
98 | public void setThumbnail(String thumbnail) {
99 | this.thumbnail = thumbnail;
100 | }
101 |
102 | public String getUrl() {
103 | return url;
104 | }
105 |
106 | public void setUrl(String url) {
107 | this.url = url;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/sso/SocialOauthActivity.java:
--------------------------------------------------------------------------------
1 | package com.elbbbird.android.socialsdk.sso;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 |
8 | import com.elbbbird.android.socialsdk.R;
9 | import com.elbbbird.android.socialsdk.SocialSDK;
10 | import com.elbbbird.android.socialsdk.model.SocialInfo;
11 | import com.elbbbird.android.socialsdk.view.ShareButton;
12 | import com.tencent.connect.common.Constants;
13 |
14 | /**
15 | * 社交授权activity
16 | * Created by zhanghailong-ms on 2015/11/20.
17 | */
18 | public class SocialOauthActivity extends Activity {
19 |
20 | private static final String TAG = "SocialOauthActivity";
21 | private static boolean DEBUG = SocialSDK.isDebugModel();
22 |
23 | private SocialInfo info;
24 | private ShareButton llWeibo;
25 | private ShareButton llWeChat;
26 | private ShareButton llQQ;
27 |
28 | /**
29 | * type=0, 用户选择QQ或者微博登录
30 | * type=1,用户选择微信登录
31 | */
32 | private int type = 0;
33 |
34 | @Override
35 | protected void onCreate(Bundle savedInstanceState) {
36 | super.onCreate(savedInstanceState);
37 |
38 | setContentView(R.layout.es_activity_social_oauth);
39 |
40 | info = (SocialInfo) getIntent().getExtras().getSerializable("info");
41 |
42 | llWeibo = (ShareButton) findViewById(R.id.social_oauth_sb_weibo);
43 | llWeibo.setOnClickListener(new View.OnClickListener() {
44 | @Override
45 | public void onClick(View v) {
46 | SocialSSOProxy.loginWeibo(SocialOauthActivity.this, info);
47 | }
48 | });
49 | llWeChat = (ShareButton) findViewById(R.id.social_oauth_sb_wechat);
50 | llWeChat.setOnClickListener(new View.OnClickListener() {
51 | @Override
52 | public void onClick(View v) {
53 | SocialSSOProxy.loginWeChat(SocialOauthActivity.this, info);
54 | type = 1;
55 | }
56 | });
57 | llQQ = (ShareButton) findViewById(R.id.social_oauth_sb_qq);
58 | llQQ.setOnClickListener(new View.OnClickListener() {
59 | @Override
60 | public void onClick(View v) {
61 | SocialSSOProxy.loginQQ(SocialOauthActivity.this, info);
62 | }
63 | });
64 |
65 | }
66 |
67 | @Override
68 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
69 | super.onActivityResult(requestCode, resultCode, data);
70 | SocialSDK.oauthWeiboCallback(SocialOauthActivity.this, requestCode, resultCode, data);
71 | if (requestCode == Constants.REQUEST_LOGIN || requestCode == Constants.REQUEST_APPBAR) {
72 | SocialSDK.oauthQQCallback(requestCode, resultCode, data);
73 | }
74 |
75 | if (type == 0) {
76 | finish();
77 | }
78 | }
79 |
80 | @Override
81 | protected void onRestart() {
82 | super.onRestart();
83 |
84 | if (type == 1) {
85 | finish();
86 | }
87 | }
88 |
89 | @Override
90 | public void finish() {
91 | super.finish();
92 | overridePendingTransition(0, R.anim.es_snack_out);
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/sso/weibo/AbsOpenAPI.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010-2013 The SINA WEIBO Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.elbbbird.android.socialsdk.sso.weibo;
18 |
19 | import android.content.Context;
20 | import android.text.TextUtils;
21 |
22 | import com.sina.weibo.sdk.auth.Oauth2AccessToken;
23 | import com.sina.weibo.sdk.net.AsyncWeiboRunner;
24 | import com.sina.weibo.sdk.net.RequestListener;
25 | import com.sina.weibo.sdk.net.WeiboParameters;
26 | import com.sina.weibo.sdk.utils.LogUtil;
27 |
28 | /**
29 | *
30 | * @author SINA
31 | * @since 2013-11-05
32 | */
33 | public abstract class AbsOpenAPI {
34 | private static final String TAG = AbsOpenAPI.class.getName();
35 |
36 | /**
37 | */
38 | protected static final String API_SERVER = "https://api.weibo.com/2";
39 | /**
40 | */
41 | protected static final String HTTPMETHOD_POST = "POST";
42 | /**
43 | */
44 | protected static final String HTTPMETHOD_GET = "GET";
45 | /**
46 | */
47 | protected static final String KEY_ACCESS_TOKEN = "access_token";
48 |
49 | /**
50 | */
51 | protected Oauth2AccessToken mAccessToken;
52 | protected Context mContext;
53 | protected String mAppKey;
54 |
55 | /**
56 | */
57 | public AbsOpenAPI(Context context, String appKey, Oauth2AccessToken accessToken) {
58 | mContext = context;
59 | mAppKey = appKey;
60 | mAccessToken = accessToken;
61 | }
62 |
63 | /**
64 | */
65 | protected void requestAsync(String url, WeiboParameters params, String httpMethod, RequestListener listener) {
66 | if (null == mAccessToken
67 | || TextUtils.isEmpty(url)
68 | || null == params
69 | || TextUtils.isEmpty(httpMethod)
70 | || null == listener) {
71 | LogUtil.e(TAG, "Argument error!");
72 | return;
73 | }
74 |
75 | params.put(KEY_ACCESS_TOKEN, mAccessToken.getToken());
76 | new AsyncWeiboRunner(mContext).requestAsync(url, params, httpMethod, listener);
77 | }
78 |
79 | /**
80 | */
81 | protected String requestSync(String url, WeiboParameters params, String httpMethod) {
82 | if (null == mAccessToken
83 | || TextUtils.isEmpty(url)
84 | || null == params
85 | || TextUtils.isEmpty(httpMethod)) {
86 | LogUtil.e(TAG, "Argument error!");
87 | return "";
88 | }
89 |
90 | params.put(KEY_ACCESS_TOKEN, mAccessToken.getToken());
91 | return new AsyncWeiboRunner(mContext).request(url, params, httpMethod);
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/sso/weibo/WeiboSSOProxy.java:
--------------------------------------------------------------------------------
1 | package com.elbbbird.android.socialsdk.sso.weibo;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.util.Log;
6 |
7 | import com.elbbbird.android.socialsdk.SocialSDK;
8 | import com.elbbbird.android.socialsdk.model.SocialInfo;
9 | import com.elbbbird.android.socialsdk.model.SocialToken;
10 | import com.elbbbird.android.socialsdk.sso.SocialSSOProxy;
11 | import com.sina.weibo.sdk.auth.AuthInfo;
12 | import com.sina.weibo.sdk.auth.Oauth2AccessToken;
13 | import com.sina.weibo.sdk.auth.WeiboAuthListener;
14 | import com.sina.weibo.sdk.auth.sso.SsoHandler;
15 | import com.sina.weibo.sdk.net.RequestListener;
16 |
17 | /**
18 | * 微博授权proxy
19 | * Created by zhanghailong-ms on 2015/11/16.
20 | */
21 | public class WeiboSSOProxy {
22 |
23 | private static final boolean DEBUG = SocialSDK.isDebugModel();
24 | private static final String TAG = "WeiboSSOProxy";
25 |
26 | private static SsoHandler ssoHandler;
27 | private static AuthInfo authInfo;
28 |
29 | public static SsoHandler getSsoHandler(Context context, SocialInfo info) {
30 | if (ssoHandler == null)
31 | ssoHandler = new SsoHandler((Activity) context, getAuthInfo(context, info.getWeiboAppKey(), info.getWeiboRedirectrUrl(), info.getWeiboScope()));
32 |
33 | return ssoHandler;
34 | }
35 |
36 | private static AuthInfo getAuthInfo(Context context, String key, String redirectUrl, String scope) {
37 | if (authInfo == null || !key.equals(authInfo.getAppKey()))
38 | authInfo = new AuthInfo(context, key, redirectUrl, scope);
39 |
40 | return authInfo;
41 | }
42 |
43 | public static void login(Context context, SocialInfo info, WeiboAuthListener listener) {
44 | if (!SocialSSOProxy.isTokenValid(context)) {
45 | getSsoHandler(context, info).authorize(listener);
46 | }
47 | }
48 |
49 | public static void logout(Context context, SocialInfo info, SocialToken token, RequestListener listener) {
50 | if (SocialSSOProxy.isTokenValid(context)) {
51 | LogoutAPI logout = new LogoutAPI(context, info.getWeiboAppKey(), parseToken(token));
52 | logout.logout(listener);
53 | }
54 |
55 | ssoHandler = null;
56 | authInfo = null;
57 | }
58 |
59 | public static void getUserInfo(Context context, SocialInfo info, SocialToken token, RequestListener listener) {
60 | if (DEBUG)
61 | Log.i(TAG, "getUserInfo");
62 | if (SocialSSOProxy.isTokenValid(context)) {
63 | if (DEBUG)
64 | Log.i(TAG, "getUserInfo#isTokenValid true");
65 | UsersAPI usersAPI = new UsersAPI(context, info.getWeiboAppKey(), parseToken(token));
66 | usersAPI.show(Long.parseLong(token.getOpenId()), listener);
67 | } else {
68 | if (DEBUG)
69 | Log.i(TAG, "getUserInfo#isTokenValid false");
70 | }
71 | }
72 |
73 | private static Oauth2AccessToken parseToken(SocialToken socialToken) {
74 | Oauth2AccessToken token = new Oauth2AccessToken();
75 | token.setUid(socialToken.getOpenId());
76 | token.setExpiresTime(socialToken.getExpiresTime());
77 | token.setToken(socialToken.getToken());
78 |
79 | return token;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/share/weibo/AccessTokenKeeper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010-2013 The SINA WEIBO Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.elbbbird.android.socialsdk.share.weibo;
18 |
19 | import android.content.Context;
20 | import android.content.SharedPreferences;
21 | import android.content.SharedPreferences.Editor;
22 |
23 | import com.sina.weibo.sdk.auth.Oauth2AccessToken;
24 |
25 | /**
26 | * 该类定义了微博授权时所需要的参数。
27 | *
28 | * @author SINA
29 | * @since 2013-10-07
30 | */
31 | public class AccessTokenKeeper {
32 | private static final String PREFERENCES_NAME = "com_weibo_sdk_android";
33 |
34 | private static final String KEY_UID = "uid";
35 | private static final String KEY_ACCESS_TOKEN = "access_token";
36 | private static final String KEY_EXPIRES_IN = "expires_in";
37 | private static final String KEY_REFRESH_TOKEN = "refresh_token";
38 |
39 | /**
40 | * 保存 Token 对象到 SharedPreferences。
41 | *
42 | * @param context 应用程序上下文环境
43 | * @param token Token 对象
44 | */
45 | public static void writeAccessToken(Context context, Oauth2AccessToken token) {
46 | if (null == context || null == token) {
47 | return;
48 | }
49 |
50 | SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
51 | Editor editor = pref.edit();
52 | editor.putString(KEY_UID, token.getUid());
53 | editor.putString(KEY_ACCESS_TOKEN, token.getToken());
54 | editor.putString(KEY_REFRESH_TOKEN, token.getRefreshToken());
55 | editor.putLong(KEY_EXPIRES_IN, token.getExpiresTime());
56 | editor.commit();
57 | }
58 |
59 | /**
60 | * 从 SharedPreferences 读取 Token 信息。
61 | *
62 | * @param context 应用程序上下文环境
63 | * @return 返回 Token 对象
64 | */
65 | public static Oauth2AccessToken readAccessToken(Context context) {
66 | if (null == context) {
67 | return null;
68 | }
69 |
70 | Oauth2AccessToken token = new Oauth2AccessToken();
71 | SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
72 | token.setUid(pref.getString(KEY_UID, ""));
73 | token.setToken(pref.getString(KEY_ACCESS_TOKEN, ""));
74 | token.setRefreshToken(pref.getString(KEY_REFRESH_TOKEN, ""));
75 | token.setExpiresTime(pref.getLong(KEY_EXPIRES_IN, 0));
76 |
77 | return token;
78 | }
79 |
80 | /**
81 | * 清空 SharedPreferences 中 Token信息。
82 | *
83 | * @param context 应用程序上下文环境
84 | */
85 | public static void clear(Context context) {
86 | if (null == context) {
87 | return;
88 | }
89 |
90 | SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
91 | Editor editor = pref.edit();
92 | editor.clear();
93 | editor.commit();
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/model/SocialInfo.java:
--------------------------------------------------------------------------------
1 | package com.elbbbird.android.socialsdk.model;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * 社交平台信息
7 | * Created by zhanghailong-ms on 2015/11/13.
8 | */
9 | public class SocialInfo implements Serializable {
10 |
11 | private boolean debugMode = false;
12 | private String wechatAppId = "";
13 | private String weChatAppSecret = "";
14 | private String weChatScope = "snsapi_userinfo";
15 | private String weiboAppKey = "";
16 | private String weiboRedirectrUrl = "http://www.sina.com";
17 | private String weiboScope = "email,direct_messages_read,direct_messages_write,"
18 | + "friendships_groups_read,friendships_groups_write,statuses_to_me_read,"
19 | + "follow_app_official_microblog," + "invitation_write";
20 | private String qqAppId = "";
21 | private String qqScope = "all";
22 |
23 | public boolean isDebugMode() {
24 | return debugMode;
25 | }
26 |
27 | public void setDebugMode(boolean debugMode) {
28 | this.debugMode = debugMode;
29 | }
30 |
31 | public String getWechatAppId() {
32 | return wechatAppId;
33 | }
34 |
35 | public void setWechatAppId(String wechatAppId) {
36 | this.wechatAppId = wechatAppId;
37 | }
38 |
39 | public String getWeChatAppSecret() {
40 | return weChatAppSecret;
41 | }
42 |
43 | public void setWeChatAppSecret(String weChatAppSecret) {
44 | this.weChatAppSecret = weChatAppSecret;
45 | }
46 |
47 | public String getWeChatScope() {
48 | return weChatScope;
49 | }
50 |
51 | public void setWeChatScope(String weChatScope) {
52 | this.weChatScope = weChatScope;
53 | }
54 |
55 | public String getWeiboAppKey() {
56 | return weiboAppKey;
57 | }
58 |
59 | public void setWeiboAppKey(String weiboAppKey) {
60 | this.weiboAppKey = weiboAppKey;
61 | }
62 |
63 | public String getWeiboRedirectrUrl() {
64 | return weiboRedirectrUrl;
65 | }
66 |
67 | public void setWeiboRedirectrUrl(String weiboRedirectrUrl) {
68 | this.weiboRedirectrUrl = weiboRedirectrUrl;
69 | }
70 |
71 | public String getWeiboScope() {
72 | return weiboScope;
73 | }
74 |
75 | public void setWeiboScope(String weiboScope) {
76 | this.weiboScope = weiboScope;
77 | }
78 |
79 | public String getQqAppId() {
80 | return qqAppId;
81 | }
82 |
83 | public void setQqAppId(String qqAppId) {
84 | this.qqAppId = qqAppId;
85 | }
86 |
87 | public String getQqScope() {
88 | return qqScope;
89 | }
90 |
91 | public void setQqScope(String qqScope) {
92 | this.qqScope = qqScope;
93 | }
94 |
95 | public String getUrlForWeChatToken() {
96 | return "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
97 | + getWechatAppId()
98 | + "&secret="
99 | + getWeChatAppSecret()
100 | + "&code=%s&grant_type=authorization_code";
101 | }
102 |
103 | public String getUrlForWeChatUserInfo() {
104 | return "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s";
105 | }
106 |
107 | public String getUrlForWeChatRefreshToken() {
108 | return "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid="
109 | + getWechatAppId()
110 | + "&grant_type=refresh_token&refresh_token=%s";
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/sso/SocialUserKeeper.java:
--------------------------------------------------------------------------------
1 | package com.elbbbird.android.socialsdk.sso;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | import com.elbbbird.android.socialsdk.model.SocialToken;
7 | import com.elbbbird.android.socialsdk.model.SocialUser;
8 |
9 | /**
10 | * 用户信息持久化
11 | *
12 | * Created by zhanghailong-ms on 2015/11/16.
13 | */
14 | public class SocialUserKeeper {
15 |
16 | private static final String PREFERENCE_NAME = "es_social_user";
17 |
18 | private static final String KEY_TYPE = "type";
19 | private static final String KEY_OPENID = "open_id";
20 | private static final String KEY_NAME = "name";
21 | private static final String KEY_AVATAR = "avatar";
22 | private static final String KEY_GENDER = "gender";
23 | private static final String KEY_TOKEN = "token";
24 | private static final String KEY_EXPIRES_TIME = "expires_time";
25 | private static final String KEY_REFRESH_TOKEN = "refresh_token";
26 | private static final String KEY_SIGNATURE = "signature";
27 |
28 | /**
29 | * 持久化用户信息
30 | *
31 | * @param context context
32 | * @param user 用户信息
33 | */
34 | protected static void writeSocialUser(Context context, SocialUser user) {
35 | if (user == null || context == null)
36 | return;
37 |
38 | SharedPreferences.Editor editor = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE).edit();
39 | editor.putInt(KEY_TYPE, user.getType());
40 | editor.putString(KEY_OPENID, user.getToken().getOpenId());
41 | editor.putString(KEY_NAME, user.getName());
42 | editor.putString(KEY_AVATAR, user.getAvatar());
43 | editor.putInt(KEY_GENDER, user.getGender());
44 | editor.putString(KEY_TOKEN, user.getToken().getToken());
45 | editor.putString(KEY_REFRESH_TOKEN, user.getToken().getRefreshToken());
46 | editor.putLong(KEY_EXPIRES_TIME, user.getToken().getExpiresTime());
47 | editor.putString(KEY_SIGNATURE, user.getDesc());
48 | editor.commit();
49 | }
50 |
51 | /**
52 | * 读取用户信息
53 | *
54 | * @param context context
55 | * @return 用户信息
56 | */
57 | protected static SocialUser readSocialUser(Context context) {
58 | if (context == null)
59 | return null;
60 |
61 | SocialUser user = new SocialUser();
62 | SocialToken token = new SocialToken();
63 | SharedPreferences preferences = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
64 | user.setType(preferences.getInt(KEY_TYPE, 0));
65 | user.setName(preferences.getString(KEY_NAME, ""));
66 | user.setAvatar(preferences.getString(KEY_AVATAR, ""));
67 | user.setGender(preferences.getInt(KEY_GENDER, 0));
68 | user.setDesc(preferences.getString(KEY_SIGNATURE, ""));
69 | token.setOpenId(preferences.getString(KEY_OPENID, ""));
70 | token.setToken(preferences.getString(KEY_TOKEN, ""));
71 | token.setRefreshToken(preferences.getString(KEY_REFRESH_TOKEN, ""));
72 | token.setExpiresTime(preferences.getLong(KEY_EXPIRES_TIME, 0));
73 | user.setToken(token);
74 |
75 | return user;
76 | }
77 |
78 | /**
79 | * 清除用户信息
80 | *
81 | * @param context context
82 | */
83 | protected static void clear(Context context) {
84 | if (null == context)
85 | return;
86 |
87 | SharedPreferences.Editor editor = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE).edit();
88 | editor.clear();
89 | editor.commit();
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/sso/SocialInfoKeeper.java:
--------------------------------------------------------------------------------
1 | package com.elbbbird.android.socialsdk.sso;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 |
6 | import com.elbbbird.android.socialsdk.model.SocialInfo;
7 |
8 | /**
9 | * 社交平台信息持久化
10 | * Created by zhanghailong-ms on 2015/11/20.
11 | */
12 | public class SocialInfoKeeper {
13 |
14 | private static final String PREFERENCE_NAME = "es_social_info";
15 |
16 | private static final String KEY_DEBUG = "debug";
17 | private static final String KEY_WECHAT_APP_ID = "wechat_app_id";
18 | private static final String KEY_WECHAT_APP_SECRET = "wechat_app_secret";
19 | private static final String KEY_WECHAT_SCOPE = "wechat_scope";
20 | private static final String KEY_WEIBO_APP_KEY = "weibo_app_key";
21 | private static final String KEY_WEIBO_REDIRECT_URL = "weibo_redirect_url";
22 | private static final String KEY_WEIBO_SCOPE = "weibo_scope";
23 | private static final String KEY_QQ_APP_ID = "qq_app_id";
24 | private static final String KEY_QQ_SCOPE = "qq_scope";
25 |
26 | /**
27 | * 持久化社交平台信息
28 | *
29 | * @param context context
30 | * @param info 社交平台信息
31 | */
32 | public static void writeSocialInfo(Context context, SocialInfo info) {
33 | if (info == null || context == null)
34 | return;
35 |
36 | SharedPreferences.Editor editor = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE).edit();
37 | editor.putBoolean(KEY_DEBUG, info.isDebugMode());
38 | editor.putString(KEY_WECHAT_APP_ID, info.getWechatAppId());
39 | editor.putString(KEY_WECHAT_APP_SECRET, info.getWeChatAppSecret());
40 | editor.putString(KEY_WECHAT_SCOPE, info.getWeChatScope());
41 | editor.putString(KEY_WEIBO_APP_KEY, info.getWeiboAppKey());
42 | editor.putString(KEY_WEIBO_REDIRECT_URL, info.getWeiboRedirectrUrl());
43 | editor.putString(KEY_WEIBO_SCOPE, info.getWeiboScope());
44 | editor.putString(KEY_QQ_SCOPE, info.getQqScope());
45 | editor.putString(KEY_QQ_APP_ID, info.getQqAppId());
46 | editor.commit();
47 | }
48 |
49 | /**
50 | * 读取社交平台信息
51 | *
52 | * @param context context
53 | * @return 社交平台信息
54 | */
55 | public static SocialInfo readSocialInfo(Context context) {
56 | if (context == null)
57 | return null;
58 |
59 | SocialInfo info = new SocialInfo();
60 | SharedPreferences preferences = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE);
61 | info.setDebugMode(preferences.getBoolean(KEY_DEBUG, false));
62 | info.setWechatAppId(preferences.getString(KEY_WECHAT_APP_ID, ""));
63 | info.setWeChatAppSecret(preferences.getString(KEY_WECHAT_APP_SECRET, ""));
64 | info.setWeChatScope(preferences.getString(KEY_WECHAT_SCOPE, "snsapi_userinfo"));
65 | info.setWeiboAppKey(preferences.getString(KEY_WEIBO_APP_KEY, ""));
66 | info.setWeiboRedirectrUrl(preferences.getString(KEY_WEIBO_REDIRECT_URL, "http://www.sina.com"));
67 | info.setWeiboScope(preferences.getString(KEY_WEIBO_SCOPE, "email,direct_messages_read,direct_messages_write,"
68 | + "friendships_groups_read,friendships_groups_write,statuses_to_me_read,"
69 | + "follow_app_official_microblog," + "invitation_write"));
70 | info.setQqAppId(preferences.getString(KEY_QQ_APP_ID, ""));
71 | info.setQqScope(preferences.getString(KEY_QQ_SCOPE, "all"));
72 |
73 | return info;
74 | }
75 |
76 | /**
77 | * 清除社交平台信息
78 | *
79 | * @param context context
80 | */
81 | public static void clear(Context context) {
82 | if (null == context)
83 | return;
84 |
85 | SharedPreferences.Editor editor = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE).edit();
86 | editor.clear();
87 | editor.commit();
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/sample-app/src/main/java/com/encore/actionnow/SsoAllActivity.java:
--------------------------------------------------------------------------------
1 | package com.encore.actionnow;
2 |
3 | import android.os.Bundle;
4 | import android.support.design.widget.FloatingActionButton;
5 | import android.support.design.widget.Snackbar;
6 | import android.support.v7.widget.Toolbar;
7 | import android.util.Log;
8 | import android.view.View;
9 | import android.widget.Button;
10 | import android.widget.Toast;
11 |
12 | import com.elbbbird.android.socialsdk.SocialSDK;
13 | import com.elbbbird.android.socialsdk.model.SocialToken;
14 | import com.elbbbird.android.socialsdk.model.SocialUser;
15 | import com.elbbbird.android.socialsdk.otto.BusProvider;
16 | import com.elbbbird.android.socialsdk.otto.SSOBusEvent;
17 | import com.encore.actionnow.app.BaseActivity;
18 | import com.squareup.otto.Subscribe;
19 |
20 | import butterknife.Bind;
21 | import butterknife.ButterKnife;
22 | import butterknife.OnClick;
23 |
24 | public class SsoAllActivity extends BaseActivity {
25 |
26 | private static final String TAG = "SsoAllActivity";
27 |
28 | @Bind(R.id.sso_all_btn_login_all)
29 | Button btnLoginAll;
30 | @Bind(R.id.sso_all_btn_logout_all)
31 | Button btnLogoutAll;
32 |
33 | @OnClick(R.id.sso_all_btn_login_all)
34 | public void login(View view) {
35 | SocialSDK.setDebugMode(true);
36 | SocialSDK.init("wx3ecc7ffe590fd845", "1b3f07fa99d82232d360c359f6504980", "1633462674", "1104664609");
37 | SocialSDK.oauth(SsoAllActivity.this);
38 | }
39 |
40 | @OnClick(R.id.sso_all_btn_logout_all)
41 | public void logout(View view) {
42 | SocialSDK.revoke(SsoAllActivity.this);
43 | }
44 |
45 | @Override
46 | protected void onCreate(Bundle savedInstanceState) {
47 | super.onCreate(savedInstanceState);
48 | setContentView(R.layout.activity_sso_all);
49 | ButterKnife.bind(this);
50 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
51 | setSupportActionBar(toolbar);
52 |
53 | FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
54 | fab.setOnClickListener(new View.OnClickListener() {
55 | @Override
56 | public void onClick(View view) {
57 | Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
58 | .setAction("Action", null).show();
59 | }
60 | });
61 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
62 |
63 | /**************************************************/
64 | BusProvider.getInstance().register(this);
65 | /**************************************************/
66 | }
67 |
68 | @Subscribe
69 | public void onOauthResult(SSOBusEvent event) {
70 | switch (event.getType()) {
71 | case SSOBusEvent.TYPE_GET_TOKEN:
72 | SocialToken token = event.getToken();
73 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_GET_TOKEN " + token.toString());
74 | break;
75 | case SSOBusEvent.TYPE_GET_USER:
76 | SocialUser user = event.getUser();
77 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_GET_USER " + user.toString());
78 | Toast.makeText(SsoAllActivity.this, "ShareBusEvent.TYPE_GET_USER \n\r" + user.toString(), Toast.LENGTH_SHORT).show();
79 | break;
80 | case SSOBusEvent.TYPE_FAILURE:
81 | Exception e = event.getException();
82 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_FAILURE " + e.toString());
83 | break;
84 | case SSOBusEvent.TYPE_CANCEL:
85 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_CANCEL");
86 | break;
87 | }
88 | }
89 |
90 |
91 | @Override
92 | protected void onDestroy() {
93 | /*********************************************/
94 | BusProvider.getInstance().unregister(this);
95 | /*********************************************/
96 | super.onDestroy();
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/sample-app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
26 | * Created by zhanghailong-ms on 2015/11/17.
27 | */
28 | public class WeChatSSOProxy {
29 |
30 | private static IWXCallback callback;
31 |
32 | public static void login(Context context, IWXCallback callback, SocialInfo info) {
33 | if (!SocialSSOProxy.isTokenValid(context)) {
34 | WeChatSSOProxy.callback = callback;
35 | SendAuth.Req req = new SendAuth.Req();
36 | req.scope = info.getWeChatScope();
37 | WeChat.getIWXAPIInstance(context, info.getWechatAppId()).sendReq(req);
38 | }
39 | }
40 |
41 | public static void authComplete(SendAuth.Resp resp) {
42 |
43 | switch (resp.errCode) {
44 | case BaseResp.ErrCode.ERR_OK:
45 | callback.onGetCodeSuccess(resp.code);
46 | break;
47 | case BaseResp.ErrCode.ERR_USER_CANCEL:
48 | callback.onCancel();
49 | break;
50 | case BaseResp.ErrCode.ERR_AUTH_DENIED:
51 | callback.onFailure(new Exception("BaseResp.ErrCode.ERR_AUTH_DENIED"));
52 | break;
53 | }
54 | }
55 |
56 | public static void getToken(final String code, final String getTokenUrl) {
57 | new Thread(new Runnable() {
58 | @Override
59 | public void run() {
60 | try {
61 | URL url = new URL(String.format(getTokenUrl, code));
62 | HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
63 | InputStream in = new BufferedInputStream(urlConn.getInputStream());
64 |
65 | String result = inputStream2String(in);
66 | try {
67 | JSONObject info = new JSONObject(result);
68 | //当前token的有效市场只有7200s,需要利用refresh_token去获取新token,考虑当前需要利用token的只有获取用户信息,手动设置token超时为30天
69 | SocialToken token = new SocialToken(info.getString("openid"), info.getString("access_token"), info.getString("refresh_token"), /*info.getLong("expires_in")*/ 30 * 24 * 60 * 60);
70 | callback.onGetTokenSuccess(token);
71 | } catch (JSONException e) {
72 | callback.onFailure(e);
73 | }
74 | } catch (Exception e) {
75 | callback.onFailure(e);
76 | }
77 | }
78 | }).start();
79 |
80 | }
81 |
82 | public static void getUserInfo(final Context context, final String getUserInfoUrl, final SocialToken token) {
83 | if (SocialSSOProxy.isTokenValid(context)) {
84 | new Thread(new Runnable() {
85 | @Override
86 | public void run() {
87 | try {
88 | URL url = new URL(String.format(getUserInfoUrl, token.getToken(), token.getOpenId()));
89 | HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
90 | InputStream in = new BufferedInputStream(urlConn.getInputStream());
91 |
92 | String result = inputStream2String(in);
93 | try {
94 | JSONObject info = new JSONObject(result);
95 | String name = info.getString("nickname");
96 | int gender = info.getInt("sex");
97 | String icon = info.getString("headimgurl");
98 |
99 | SocialUser user = new SocialUser(SocialUser.TYPE_WECHAT,
100 | name, icon, gender, token);
101 |
102 | callback.onGetUserInfoSuccess(user);
103 | } catch (JSONException e) {
104 | callback.onFailure(e);
105 | }
106 | } catch (Exception e) {
107 | callback.onFailure(e);
108 | }
109 | }
110 | }).start();
111 | }
112 | }
113 |
114 | private static String inputStream2String(InputStream is) throws IOException {
115 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
116 | int i;
117 | while ((i = is.read()) != -1) {
118 | baos.write(i);
119 | }
120 | return baos.toString();
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/sso/weibo/User.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2010-2013 The SINA WEIBO Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.elbbbird.android.socialsdk.sso.weibo;
18 |
19 | import org.json.JSONException;
20 | import org.json.JSONObject;
21 |
22 | /**
23 | *
24 | * @author SINA
25 | * @since 2013-11-24
26 | */
27 | public class User {
28 |
29 | public String id;
30 | public String idstr;
31 | public String screen_name;
32 | public String name;
33 | public int province;
34 | public int city;
35 | public String location;
36 | public String description;
37 | public String url;
38 | public String profile_image_url;
39 | public String profile_url;
40 | public String domain;
41 | public String weihao;
42 | public String gender;
43 | public int followers_count;
44 | public int friends_count;
45 | public int statuses_count;
46 | public int favourites_count;
47 | public String created_at;
48 | public boolean following;
49 | public boolean allow_all_act_msg;
50 | public boolean geo_enabled;
51 | public boolean verified;
52 | public int verified_type;
53 | public String remark;
54 | public Status status;
55 | public boolean allow_all_comment;
56 | public String avatar_large;
57 | public String avatar_hd;
58 | public String verified_reason;
59 | public boolean follow_me;
60 | public int online_status;
61 | public int bi_followers_count;
62 | public String lang;
63 |
64 | public String star;
65 | public String mbtype;
66 | public String mbrank;
67 | public String block_word;
68 |
69 | public static User parse(String jsonString) {
70 | try {
71 | JSONObject jsonObject = new JSONObject(jsonString);
72 | return User.parse(jsonObject);
73 | } catch (JSONException e) {
74 | e.printStackTrace();
75 | }
76 |
77 | return null;
78 | }
79 |
80 | public static User parse(JSONObject jsonObject) {
81 | if (null == jsonObject) {
82 | return null;
83 | }
84 |
85 | User user = new User();
86 | user.id = jsonObject.optString("id", "");
87 | user.idstr = jsonObject.optString("idstr", "");
88 | user.screen_name = jsonObject.optString("screen_name", "");
89 | user.name = jsonObject.optString("name", "");
90 | user.province = jsonObject.optInt("province", -1);
91 | user.city = jsonObject.optInt("city", -1);
92 | user.location = jsonObject.optString("location", "");
93 | user.description = jsonObject.optString("description", "");
94 | user.url = jsonObject.optString("url", "");
95 | user.profile_image_url = jsonObject.optString("avatar_hd", "");
96 | user.profile_url = jsonObject.optString("profile_url", "");
97 | user.domain = jsonObject.optString("domain", "");
98 | user.weihao = jsonObject.optString("weihao", "");
99 | user.gender = jsonObject.optString("gender", "");
100 | user.followers_count = jsonObject.optInt("followers_count", 0);
101 | user.friends_count = jsonObject.optInt("friends_count", 0);
102 | user.statuses_count = jsonObject.optInt("statuses_count", 0);
103 | user.favourites_count = jsonObject.optInt("favourites_count", 0);
104 | user.created_at = jsonObject.optString("created_at", "");
105 | user.following = jsonObject.optBoolean("following", false);
106 | user.allow_all_act_msg = jsonObject.optBoolean("allow_all_act_msg", false);
107 | user.geo_enabled = jsonObject.optBoolean("geo_enabled", false);
108 | user.verified = jsonObject.optBoolean("verified", false);
109 | user.verified_type = jsonObject.optInt("verified_type", -1);
110 | user.remark = jsonObject.optString("remark", "");
111 | //user.status = jsonObject.optString("status", ""); // XXX: NO Need ?
112 | user.allow_all_comment = jsonObject.optBoolean("allow_all_comment", true);
113 | user.avatar_large = jsonObject.optString("avatar_large", "");
114 | user.avatar_hd = jsonObject.optString("avatar_hd", "");
115 | user.verified_reason = jsonObject.optString("verified_reason", "");
116 | user.follow_me = jsonObject.optBoolean("follow_me", false);
117 | user.online_status = jsonObject.optInt("online_status", 0);
118 | user.bi_followers_count = jsonObject.optInt("bi_followers_count", 0);
119 | user.lang = jsonObject.optString("lang", "");
120 |
121 | user.star = jsonObject.optString("star", "");
122 | user.mbtype = jsonObject.optString("mbtype", "");
123 | user.mbrank = jsonObject.optString("mbrank", "");
124 | user.block_word = jsonObject.optString("block_word", "");
125 |
126 | return user;
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/sample-app/src/main/java/com/encore/actionnow/SsoActivity.java:
--------------------------------------------------------------------------------
1 | package com.encore.actionnow;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.design.widget.FloatingActionButton;
6 | import android.support.design.widget.Snackbar;
7 | import android.support.v7.widget.Toolbar;
8 | import android.util.Log;
9 | import android.view.View;
10 | import android.widget.Button;
11 |
12 | import com.elbbbird.android.socialsdk.SocialSDK;
13 | import com.elbbbird.android.socialsdk.model.SocialToken;
14 | import com.elbbbird.android.socialsdk.model.SocialUser;
15 | import com.elbbbird.android.socialsdk.otto.BusProvider;
16 | import com.elbbbird.android.socialsdk.otto.SSOBusEvent;
17 | import com.encore.actionnow.app.BaseActivity;
18 | import com.squareup.otto.Subscribe;
19 | import com.tencent.connect.common.Constants;
20 |
21 | import butterknife.Bind;
22 | import butterknife.ButterKnife;
23 | import butterknife.OnClick;
24 |
25 | public class SsoActivity extends BaseActivity {
26 |
27 | private static final String TAG = "SsoActivity";
28 |
29 | @Bind(R.id.sso_btn_login_qq)
30 | Button btnLoginQQ;
31 | @Bind(R.id.sso_btn_logout_qq)
32 | Button btnLogoutQQ;
33 | @Bind(R.id.sso_btn_login_wechat)
34 | Button btnLoginWeChat;
35 | @Bind(R.id.sso_btn_logout_wechat)
36 | Button btnLogoutWeChat;
37 | @Bind(R.id.sso_btn_login_weibo)
38 | Button btnLoginWeibo;
39 | @Bind(R.id.sso_btn_logout_weibo)
40 | Button btnLogoutWeibo;
41 |
42 | @OnClick({R.id.sso_btn_login_qq, R.id.sso_btn_login_wechat, R.id.sso_btn_login_weibo})
43 | public void login(View view) {
44 | switch (view.getId()) {
45 | case R.id.sso_btn_login_weibo:
46 | SocialSDK.setDebugMode(true);
47 | SocialSDK.initWeibo("1633462674");
48 | SocialSDK.oauthWeibo(SsoActivity.this);
49 | break;
50 |
51 | case R.id.sso_btn_login_wechat:
52 | SocialSDK.setDebugMode(true);
53 | SocialSDK.initWeChat("wx3ecc7ffe590fd845", "1b3f07fa99d82232d360c359f6504980");
54 | SocialSDK.oauthWeChat(SsoActivity.this);
55 | break;
56 |
57 | case R.id.sso_btn_login_qq:
58 | SocialSDK.setDebugMode(true);
59 | SocialSDK.initQQ("1104664609");
60 | SocialSDK.oauthQQ(SsoActivity.this);
61 | break;
62 |
63 | }
64 | }
65 |
66 | @OnClick({R.id.sso_btn_logout_qq, R.id.sso_btn_logout_wechat, R.id.sso_btn_logout_weibo})
67 | public void logout(View view) {
68 | switch (view.getId()) {
69 | case R.id.sso_btn_logout_weibo:
70 | SocialSDK.revokeWeibo(SsoActivity.this);
71 | break;
72 |
73 | case R.id.sso_btn_logout_wechat:
74 | SocialSDK.revokeWeChat(SsoActivity.this);
75 | break;
76 |
77 | case R.id.sso_btn_logout_qq:
78 | SocialSDK.revokeQQ(SsoActivity.this);
79 | break;
80 | }
81 | }
82 |
83 |
84 | @Override
85 | protected void onCreate(Bundle savedInstanceState) {
86 | super.onCreate(savedInstanceState);
87 | setContentView(R.layout.activity_sso);
88 | ButterKnife.bind(this);
89 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
90 | setSupportActionBar(toolbar);
91 |
92 | FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
93 | fab.setOnClickListener(new View.OnClickListener() {
94 | @Override
95 | public void onClick(View view) {
96 | Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
97 | .setAction("Action", null).show();
98 | }
99 | });
100 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
101 |
102 | /**************************************************/
103 | BusProvider.getInstance().register(this);
104 | /**************************************************/
105 | }
106 |
107 | @Subscribe
108 | public void onOauthResult(SSOBusEvent event) {
109 | switch (event.getType()) {
110 | case SSOBusEvent.TYPE_GET_TOKEN:
111 | SocialToken token = event.getToken();
112 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_GET_TOKEN " + token.toString());
113 | break;
114 | case SSOBusEvent.TYPE_GET_USER:
115 | SocialUser user = event.getUser();
116 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_GET_USER " + user.toString());
117 | break;
118 | case SSOBusEvent.TYPE_FAILURE:
119 | Exception e = event.getException();
120 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_FAILURE " + e.toString());
121 | break;
122 | case SSOBusEvent.TYPE_CANCEL:
123 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_CANCEL");
124 | break;
125 | }
126 | }
127 |
128 | @Override
129 | protected void onDestroy() {
130 | /*********************************************/
131 | BusProvider.getInstance().unregister(this);
132 | /*********************************************/
133 | super.onDestroy();
134 | }
135 |
136 | @Override
137 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
138 | super.onActivityResult(requestCode, resultCode, data);
139 | SocialSDK.oauthWeiboCallback(SsoActivity.this, requestCode, resultCode, data);
140 | if (requestCode == Constants.REQUEST_LOGIN || requestCode == Constants.REQUEST_APPBAR) {
141 | SocialSDK.oauthQQCallback(requestCode, resultCode, data);
142 | }
143 |
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/SocialUtils.java:
--------------------------------------------------------------------------------
1 | package com.elbbbird.android.socialsdk;
2 |
3 | import android.content.Context;
4 | import android.content.pm.PackageInfo;
5 | import android.content.pm.PackageManager;
6 | import android.graphics.Bitmap;
7 | import android.graphics.BitmapFactory;
8 |
9 | import java.io.ByteArrayOutputStream;
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 | import java.net.HttpURLConnection;
13 | import java.net.MalformedURLException;
14 | import java.net.URL;
15 | import java.net.URLConnection;
16 |
17 | /**
18 | * Created by zhanghailong-ms on 2015/4/7.
19 | */
20 | public class SocialUtils {
21 |
22 | /**
23 | * 从网络获取图片数据
24 | *
25 | * @param url 地址
26 | * @return 图片数据
27 | */
28 | public static byte[] getHtmlByteArray(final String url) {
29 | URL htmlUrl = null;
30 | InputStream inStream = null;
31 | try {
32 | htmlUrl = new URL(url);
33 | URLConnection connection = htmlUrl.openConnection();
34 | HttpURLConnection httpConnection = (HttpURLConnection) connection;
35 | int responseCode = httpConnection.getResponseCode();
36 | if (responseCode == HttpURLConnection.HTTP_OK) {
37 | inStream = httpConnection.getInputStream();
38 | }
39 | } catch (MalformedURLException e) {
40 | e.printStackTrace();
41 | } catch (IOException e) {
42 | e.printStackTrace();
43 | }
44 | byte[] data = inputStreamToByte(inStream);
45 |
46 | return data;
47 | }
48 |
49 | /**
50 | * 从输入流获取数据
51 | *
52 | * @param is 输入流
53 | * @return 数据
54 | */
55 | public static byte[] inputStreamToByte(InputStream is) {
56 | try {
57 | ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
58 | int ch;
59 | while ((ch = is.read()) != -1) {
60 | bytestream.write(ch);
61 | }
62 | byte imgdata[] = bytestream.toByteArray();
63 | bytestream.close();
64 | return imgdata;
65 | } catch (Exception e) {
66 | e.printStackTrace();
67 | }
68 |
69 | return null;
70 | }
71 |
72 | /**
73 | * 生成时间戳
74 | *
75 | * @param type 类型
76 | * @return 时间戳
77 | */
78 | public static String buildTransaction(final String type) {
79 | return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
80 | }
81 |
82 | /**
83 | * 压缩数据
84 | *
85 | * @param data 数据
86 | * @param size 最大值
87 | * @return 压缩后数据
88 | */
89 | public static byte[] compressBitmap(byte[] data, float size) {
90 | Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
91 | if (bitmap == null || getSizeOfBitmap(bitmap) <= size) {
92 | return data;
93 | }
94 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
95 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
96 | int quality = 100;
97 | while ((baos.toByteArray().length / 1024f) > size) {
98 | quality -= 5;
99 | baos.reset();
100 | if (quality <= 0) {
101 | break;
102 | }
103 | bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
104 | }
105 | byte[] byteData = baos.toByteArray();
106 | return byteData;
107 | }
108 |
109 | /**
110 | * 获取bitmap长度
111 | *
112 | * @param bitmap bitmap
113 | * @return 长度
114 | */
115 | private static long getSizeOfBitmap(Bitmap bitmap) {
116 |
117 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
118 | bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
119 | long length = baos.toByteArray().length / 1024;
120 | return length;
121 | }
122 |
123 | /**
124 | * 是否安装微信
125 | *
126 | * @param context context
127 | * @return 是否安装
128 | */
129 | public static boolean isInstalledWeChat(Context context) {
130 | return isPackageInstalled(context, "com.tencent.mm");
131 | }
132 |
133 | /**
134 | * 是否安装QQ
135 | *
136 | * @param context context
137 | * @return 是否安装
138 | */
139 | public static boolean isInstalledQQ(Context context) {
140 | return isPackageInstalled(context, "com.tencent.mobileqq");
141 | }
142 |
143 | /**
144 | * 是否安装了该包名的app
145 | *
146 | * @param context context
147 | * @param pkgName 包名
148 | * @return 是否安装
149 | */
150 | private static boolean isPackageInstalled(Context context, String pkgName) {
151 | PackageManager pm = context.getPackageManager();
152 | try {
153 | PackageInfo pkgInfo = pm.getPackageInfo(pkgName, 0);
154 | return pkgInfo != null && pkgInfo.applicationInfo.enabled;
155 | } catch (PackageManager.NameNotFoundException e) {
156 | }
157 | return false;
158 | }
159 |
160 | private static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
161 | ByteArrayOutputStream output = new ByteArrayOutputStream();
162 | bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
163 | if (needRecycle) {
164 | bmp.recycle();
165 | }
166 |
167 | byte[] result = output.toByteArray();
168 | try {
169 | output.close();
170 | } catch (Exception e) {
171 | }
172 |
173 | return result;
174 | }
175 |
176 | /**
177 | * 获取微信,朋友圈分享默认icon
178 | *
179 | * @param context context
180 | * @return 数据
181 | */
182 | public static byte[] getDefaultShareImage(Context context) {
183 |
184 | return bmpToByteArray(BitmapFactory.decodeResource(context.getResources(), R.drawable.es_icon_default), true);
185 | }
186 | }
187 |
--------------------------------------------------------------------------------
/sample-app/src/main/java/com/encore/actionnow/ShareActivity.java:
--------------------------------------------------------------------------------
1 | package com.encore.actionnow;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.design.widget.FloatingActionButton;
6 | import android.support.design.widget.Snackbar;
7 | import android.support.v7.widget.Toolbar;
8 | import android.util.Log;
9 | import android.view.View;
10 | import android.widget.Button;
11 |
12 | import com.elbbbird.android.socialsdk.SocialSDK;
13 | import com.elbbbird.android.socialsdk.model.SocialShareScene;
14 | import com.elbbbird.android.socialsdk.otto.BusProvider;
15 | import com.elbbbird.android.socialsdk.otto.ShareBusEvent;
16 | import com.encore.actionnow.app.BaseActivity;
17 | import com.sina.weibo.sdk.api.share.BaseResponse;
18 | import com.sina.weibo.sdk.api.share.IWeiboHandler;
19 | import com.sina.weibo.sdk.constant.WBConstants;
20 | import com.squareup.otto.Subscribe;
21 | import com.tencent.connect.common.Constants;
22 |
23 | import butterknife.Bind;
24 | import butterknife.ButterKnife;
25 | import butterknife.OnClick;
26 |
27 | public class ShareActivity extends BaseActivity implements IWeiboHandler.Response {
28 |
29 | private static final String TAG = "ShareActivity";
30 |
31 | private SocialShareScene scene = new SocialShareScene(0, "演技派", SocialShareScene.SHARE_TYPE_WECHAT, "Android 开源社会化登录 SDK,支持微信,微博, QQ",
32 | "像友盟, ShareSDK 等平台也提供类似的 SDK ,之所以造轮子是因为这些平台的 SDK 内部肯定会带有数据统计功能,不想给他们共享数据。",
33 | "http://cdn.v2ex.co/gravatar/becb0d5c59469a34a54156caef738e90?s=73&d=retro", "http://www.v2ex.com/t/238165");
34 |
35 | @Bind(R.id.share_btn_share_qq)
36 | Button btnShareQQ;
37 | @Bind(R.id.share_btn_share_qzone)
38 | Button btnShareQZone;
39 | @Bind(R.id.share_btn_share_wechat)
40 | Button btnShareWeChat;
41 | @Bind(R.id.share_btn_share_wechat_timeline)
42 | Button btnShareWeChatTimeline;
43 | //disable,与SDK内部SocialShareActivity intent-filter冲突
44 | @Bind(R.id.share_btn_share_weibo)
45 | Button btnShareWeibo;
46 |
47 | @OnClick({R.id.share_btn_share_qq, R.id.share_btn_share_qzone, R.id.share_btn_share_wechat, R.id.share_btn_share_wechat_timeline, R.id.share_btn_share_weibo})
48 | public void share(View view) {
49 | switch (view.getId()) {
50 | case R.id.share_btn_share_qq:
51 | SocialSDK.setDebugMode(true);
52 | SocialSDK.shareToQQ(ShareActivity.this, "1104664609", scene);
53 | break;
54 | case R.id.share_btn_share_qzone:
55 | SocialSDK.setDebugMode(true);
56 | SocialSDK.shareToQZone(ShareActivity.this, "1104664609", scene);
57 | break;
58 | case R.id.share_btn_share_wechat:
59 | SocialSDK.setDebugMode(true);
60 | SocialSDK.shareToWeChat(ShareActivity.this, "wx3ecc7ffe590fd845", scene);
61 | break;
62 | case R.id.share_btn_share_wechat_timeline:
63 | SocialSDK.setDebugMode(true);
64 | SocialSDK.shareToWeChatTimeline(ShareActivity.this, "wx3ecc7ffe590fd845", scene);
65 | break;
66 | case R.id.share_btn_share_weibo:
67 | SocialSDK.setDebugMode(true);
68 | SocialSDK.shareToWeibo(ShareActivity.this, "1633462674", scene);
69 | break;
70 | }
71 | }
72 |
73 | @Override
74 | protected void onCreate(Bundle savedInstanceState) {
75 | super.onCreate(savedInstanceState);
76 | setContentView(R.layout.activity_share);
77 | ButterKnife.bind(this);
78 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
79 | setSupportActionBar(toolbar);
80 |
81 | FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
82 | fab.setOnClickListener(new View.OnClickListener() {
83 | @Override
84 | public void onClick(View view) {
85 | Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
86 | .setAction("Action", null).show();
87 | }
88 | });
89 | getSupportActionBar().setDisplayHomeAsUpEnabled(true);
90 |
91 |
92 | /*********************************************/
93 | BusProvider.getInstance().register(this);
94 | /*********************************************/
95 | }
96 |
97 | @Subscribe
98 | public void onShareResult(ShareBusEvent event) {
99 | switch (event.getType()) {
100 | case ShareBusEvent.TYPE_SUCCESS:
101 | Log.i(TAG, "onShareResult#ShareBusEvent.TYPE_SUCCESS " + event.getId());
102 | break;
103 | case ShareBusEvent.TYPE_FAILURE:
104 | Exception e = event.getException();
105 | Log.i(TAG, "onShareResult#ShareBusEvent.TYPE_FAILURE " + e.toString());
106 | break;
107 | case ShareBusEvent.TYPE_CANCEL:
108 | Log.i(TAG, "onShareResult#ShareBusEvent.TYPE_CANCEL");
109 | break;
110 | }
111 | }
112 |
113 | @Override
114 | protected void onDestroy() {
115 | /*********************************************/
116 | BusProvider.getInstance().unregister(this);
117 | /*********************************************/
118 | super.onDestroy();
119 | }
120 |
121 | @Override
122 | protected void onNewIntent(Intent intent) {
123 | super.onNewIntent(intent);
124 |
125 | SocialSDK.shareToWeiboCallback(intent, this);
126 | }
127 |
128 | @Override
129 | public void onResponse(BaseResponse baseResponse) {
130 | switch (baseResponse.errCode) {
131 | case WBConstants.ErrorCode.ERR_OK:
132 | BusProvider.getInstance().post(new ShareBusEvent(ShareBusEvent.TYPE_SUCCESS, scene.getType(), scene.getId()));
133 | break;
134 | case WBConstants.ErrorCode.ERR_CANCEL:
135 | BusProvider.getInstance().post(new ShareBusEvent(ShareBusEvent.TYPE_CANCEL, scene.getType()));
136 | break;
137 | case WBConstants.ErrorCode.ERR_FAIL:
138 | BusProvider.getInstance().post(new ShareBusEvent(ShareBusEvent.TYPE_FAILURE, scene.getType(), new Exception("WBConstants.ErrorCode.ERR_FAIL")));
139 | break;
140 | }
141 | }
142 |
143 | @Override
144 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
145 | super.onActivityResult(requestCode, resultCode, data);
146 |
147 | if (requestCode == Constants.REQUEST_QZONE_SHARE || requestCode == Constants.REQUEST_QQ_SHARE) {
148 | SocialSDK.shareToQCallback(requestCode, resultCode, data);
149 | }
150 |
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/socialsdk/src/main/java/com/elbbbird/android/socialsdk/share/SocialShareActivity.java:
--------------------------------------------------------------------------------
1 | package com.elbbbird.android.socialsdk.share;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.Gravity;
7 | import android.view.View;
8 |
9 | import com.elbbbird.android.socialsdk.R;
10 | import com.elbbbird.android.socialsdk.SocialSDK;
11 | import com.elbbbird.android.socialsdk.model.SocialInfo;
12 | import com.elbbbird.android.socialsdk.model.SocialShareScene;
13 | import com.elbbbird.android.socialsdk.otto.BusProvider;
14 | import com.elbbbird.android.socialsdk.otto.ShareBusEvent;
15 | import com.elbbbird.android.socialsdk.view.ShareButton;
16 | import com.sina.weibo.sdk.api.share.BaseResponse;
17 | import com.sina.weibo.sdk.api.share.IWeiboHandler;
18 | import com.sina.weibo.sdk.constant.WBConstants;
19 | import com.tencent.connect.common.Constants;
20 |
21 | /**
22 | * 一键社会化分享
23 | * Created by zhanghailong-ms on 2015/11/23.
24 | */
25 | public class SocialShareActivity extends Activity implements IWeiboHandler.Response {
26 |
27 | private SocialInfo info;
28 | private SocialShareScene scene;
29 |
30 | private ShareButton sbWechat;
31 | private ShareButton sbWeChatTimeline;
32 | private ShareButton sbWeibo;
33 | private ShareButton sbQQ;
34 | private ShareButton sbQZone;
35 | private ShareButton sbMore;
36 |
37 | @Override
38 | protected void onCreate(Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 |
41 | setContentView(R.layout.es_activity_social_share);
42 |
43 | getWindow().setGravity(Gravity.BOTTOM);
44 |
45 | info = (SocialInfo) getIntent().getExtras().getSerializable("info");
46 | scene = (SocialShareScene) getIntent().getExtras().getSerializable("scene");
47 |
48 | initViews();
49 | }
50 |
51 | private void initViews() {
52 | sbWechat = (ShareButton) findViewById(R.id.social_share_sb_wechat);
53 | sbWechat.setOnClickListener(new View.OnClickListener() {
54 | @Override
55 | public void onClick(View v) {
56 | scene.setType(SocialShareScene.SHARE_TYPE_WECHAT);
57 | SocialSDK.shareToWeChat(SocialShareActivity.this, info.getWechatAppId(), scene);
58 | }
59 | });
60 | sbWeChatTimeline = (ShareButton) findViewById(R.id.social_share_sb_wechat_timeline);
61 | sbWeChatTimeline.setOnClickListener(new View.OnClickListener() {
62 | @Override
63 | public void onClick(View v) {
64 | SocialSDK.shareToWeChatTimeline(SocialShareActivity.this, info.getWechatAppId(), scene);
65 | scene.setType(SocialShareScene.SHARE_TYPE_WECHAT_TIMELINE);
66 | }
67 | });
68 | sbWeibo = (ShareButton) findViewById(R.id.social_share_sb_weibo);
69 | sbWeibo.setOnClickListener(new View.OnClickListener() {
70 | @Override
71 | public void onClick(View v) {
72 | scene.setType(SocialShareScene.SHARE_TYPE_WEIBO);
73 | SocialSDK.shareToWeibo(SocialShareActivity.this, info.getWeiboAppKey(), scene);
74 | }
75 | });
76 | sbQQ = (ShareButton) findViewById(R.id.social_share_sb_qq);
77 | sbQQ.setOnClickListener(new View.OnClickListener() {
78 | @Override
79 | public void onClick(View v) {
80 | scene.setType(SocialShareScene.SHARE_TYPE_QQ);
81 | SocialSDK.shareToQQ(SocialShareActivity.this, info.getQqAppId(), scene);
82 | }
83 | });
84 | sbQZone = (ShareButton) findViewById(R.id.social_share_sb_qzone);
85 | sbQZone.setOnClickListener(new View.OnClickListener() {
86 | @Override
87 | public void onClick(View v) {
88 | scene.setType(SocialShareScene.SHARE_TYPE_QZONE);
89 | SocialSDK.shareToQZone(SocialShareActivity.this, info.getQqAppId(), scene);
90 | }
91 | });
92 | sbMore = (ShareButton) findViewById(R.id.social_share_sb_more);
93 | sbMore.setOnClickListener(new View.OnClickListener() {
94 | @Override
95 | public void onClick(View v) {
96 | scene.setType(SocialShareScene.SHARE_TYPE_DEFAULT);
97 | Intent share = new Intent(android.content.Intent.ACTION_SEND);
98 | share.setType("text/plain");
99 | share.putExtra(Intent.EXTRA_TEXT, scene.getTitle() + "\n\r" + scene.getUrl());
100 | share.putExtra(Intent.EXTRA_TITLE, scene.getTitle());
101 | share.putExtra(Intent.EXTRA_SUBJECT, scene.getDesc());
102 | startActivity(share);
103 | }
104 | });
105 | }
106 |
107 | @Override
108 | public void finish() {
109 | super.finish();
110 | overridePendingTransition(0, R.anim.es_snack_out);
111 | }
112 |
113 | @Override
114 | protected void onNewIntent(Intent intent) {
115 | super.onNewIntent(intent);
116 | if (scene.getType() == SocialShareScene.SHARE_TYPE_WEIBO) {
117 | SocialSDK.shareToWeiboCallback(intent, this);
118 | finish();
119 | }
120 | }
121 |
122 | @Override
123 | public void onResponse(BaseResponse baseResponse) {
124 | switch (baseResponse.errCode) {
125 | case WBConstants.ErrorCode.ERR_OK:
126 | BusProvider.getInstance().post(new ShareBusEvent(ShareBusEvent.TYPE_SUCCESS, scene.getType(), scene.getId()));
127 | break;
128 | case WBConstants.ErrorCode.ERR_CANCEL:
129 | BusProvider.getInstance().post(new ShareBusEvent(ShareBusEvent.TYPE_CANCEL, scene.getType()));
130 | break;
131 | case WBConstants.ErrorCode.ERR_FAIL:
132 | BusProvider.getInstance().post(new ShareBusEvent(ShareBusEvent.TYPE_FAILURE, scene.getType(), new Exception("WBConstants.ErrorCode.ERR_FAIL: "
133 | + baseResponse.errMsg)));
134 | break;
135 | }
136 | }
137 |
138 | @Override
139 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
140 | super.onActivityResult(requestCode, resultCode, data);
141 |
142 | if (requestCode == Constants.REQUEST_QZONE_SHARE || requestCode == Constants.REQUEST_QQ_SHARE) {
143 | SocialSDK.shareToQCallback(requestCode, resultCode, data);
144 | finish();
145 | }
146 |
147 | }
148 |
149 | @Override
150 | protected void onRestart() {
151 | super.onRestart();
152 | if (scene.getType() == SocialShareScene.SHARE_TYPE_WECHAT || scene.getType() == SocialShareScene.SHARE_TYPE_WECHAT_TIMELINE) {
153 | finish();
154 | }
155 | }
156 |
157 | }
158 |
--------------------------------------------------------------------------------
/README_Detail.md:
--------------------------------------------------------------------------------
1 | # ESSocialSDK [](https://travis-ci.org/ElbbbirdStudio/ESSocialSDK)
2 | 社交登录授权,分享SDK
3 | 支持微信、微博、QQ登录授权
4 | 微信好友、微信朋友圈、微博、QQ好友、QQ空间分享以及系统默认分享
5 |
6 | ## Gradle
7 |
8 | ```groovy
9 | compile 'com.elbbbird.android:socialsdk:0.2.0@aar'
10 | ```
11 |
12 | ## Debug模式
13 | ```java
14 | SocialSDK.setDebugMode(true); //默认false
15 | ```
16 |
17 | ## 社交平台SSO授权功能
18 |
19 | ### 授权结果回调
20 | SDK使用了[Otto](http://square.github.io/otto/)作为事件库,用以组件通信。
21 | 在调用`SocialSDK.oauth()`接口`Activity`的`onCreate()`方法内添加
22 | ```java
23 | BusProvider.getInstance().register(this);
24 | ```
25 | 在该`Activity`的`onDestroy()`方法添加
26 | ```java
27 | @Override
28 | protected void onDestroy() {
29 | BusProvider.getInstance().unregister(this);
30 | super.onDestroy();
31 | }
32 | ```
33 | 添加回调接口
34 | ```java
35 | @Subscribe
36 | public void onOauthResult(BusEvent event) {
37 | switch (event.getType()) {
38 | case BusEvent.TYPE_GET_TOKEN:
39 | SocialToken token = event.getToken();
40 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_GET_TOKEN " + token.toString());
41 | break;
42 | case BusEvent.TYPE_GET_USER:
43 | SocialUser user = event.getUser();
44 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_GET_USER " + user.toString());
45 | break;
46 | case BusEvent.TYPE_FAILURE:
47 | Exception e = event.getException();
48 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_FAILURE " + e.toString());
49 | break;
50 | case BusEvent.TYPE_CANCEL:
51 | Log.i(TAG, "onOauthResult#BusEvent.TYPE_CANCEL");
52 | break;
53 | }
54 | }
55 | ```
56 |
57 | ### 微博授权
58 | - 配置微博后台回调地址
59 | SDK的默认回调地址为`http://www.sina.com`,需要在微博后台配置,否则会提示回调地址错误。
60 | 如果在`SocialSDK.initWeibo()`方法自定义了回调地址,需要在后台配置为相应地址。
61 | - oauth
62 | ```java
63 | SocialSDK.initWeibo("app_key");
64 | SocialSDK.oauthWeibo(context);
65 | ```
66 | - onActivityResult
67 | ```java
68 | SocialSDK.oauthWeiboCallback(context, requestCode, resultCode, data);
69 | ```
70 |
71 | - revoke
72 | ```java
73 | SocialSDK.revokeWeibo(context);
74 | ```
75 |
76 | ### 微信授权
77 |
78 | - WXEntryActivity
79 | 创建包名:`package_name.wxapi`
80 | 在该包名下创建类`WXEntryActivity`继承自`WXCallbackActivity`
81 |
82 | ```java
83 | package com.encore.actionnow.wxapi;
84 | public class WXEntryActivity extends WXCallbackActivity {
85 |
86 | }
87 | ```
88 |
89 | - AndroidManifest.xml
90 | ```xml
91 |