最新版本(0.0.7) Easier 、Lighter 、 More Business-Orientedjava
以更簡單、更輕量、更加面向業務需求爲設計目標,提供 微博、微信、QQ、Tim、QQ 輕聊版、釘釘 的登錄分享功能支持;android
項目地址 : GitHub - SocialSdkLibrarygit
博客地址 :快速接入微信微博QQ釘釘原生登陸分享github
🎉 2018.12.27 完成 gradle
插件,拆分平臺,自動化依賴,一個新臺階 🐶web
🎉 2018.12.21 已經225顆 🌟,着手準備拆分紅不一樣平臺庫,方便靈活接入 ⛽️json
🎉 2018.9.26 項目得到了第202顆 🌟,感謝新同事補星 2 個 😄小程序
🎉 2018.6.7 項目得到了第100顆 🌟,最後一顆是我問同事要的 🤦緩存
🎉 2018.5.12 修復內存問題、功能擴展 穩定版本 1.1.0 ❤️bash
🎉 2018.2.12 支持釘釘分享 🆕微信
🎉 2017.12.12 對代碼進行簡單重構並測試 穩定版本 1.0.0 ❤️
🔥 開源:沒有彩蛋,沒有彩蛋,沒有彩蛋;
🔥 簡單:只須要關注登陸、分享管理類和一個數據結構對象便可,不須要再關注平臺之間的差別;
🔥 輕量:僅包含三方 SDK
和一個簡單的異步框架(38k),網絡請求、JSON
解析從外部注入,減小多餘的依賴,保證與宿主項目高度統一;
🔥 面向需求設計:
web
分享兼容;Intent
喚醒分享,如支持本地視頻分享,qq
的純文字分享等等;token
避免屢次受權,可選擇有效時長;STEP1: 添加插件依賴路徑
project / build.gradle
buildscript {
repositories {
maven { url "https://dl.bintray.com/zfy/maven" }
}
dependencies {
// 請查看文初最新版本,這邊可能忘記更新!!!
classpath 'com.zfy.social:social-sdk-plugin:0.0.7'
}
}
allprojects {
repositories {
maven { url "https://dl.bintray.com/zfy/maven" }
}
}
複製代碼
STEP2: 配置參數,注意與 android
同級
app / build.gralde
// 引用插件
apply plugin: 'socialsdk'
// android 配置模塊
android {
...
}
// socialsdk 配置模塊
socialsdk {
wx {
appId = 'wx4b8db***5b195c3'
appSecret = '0a3cb007291d0e5***3654f499171'
onlyAuthCode = false // 微信受權僅返回 code
}
qq {
appId = '1104***200'
appSecret = 'A6AqtY***g59yQ4N'
}
wb {
appId = '218***998'
url = 'http://open.manfenmm.com/***/***'
}
dd {
appId = 'dingo***wrefwjeumuof'
}
local false // 使用本地依賴
}
複製代碼
STEP3:初始化
SocialOptions options = new SocialOptions.Builder(this)
// 調試模式,開啓 log 輸出
.debug(true)
// 加載縮略圖失敗時,降級使用資源圖
.failImgRes(R.mipmap.ic_launcher_new)
// token 保留時間,單位小時,默認不保留
.tokenExpiresHours(24)
// 分享若是停留在第三放將會返回成功,默認返回失敗
.shareSuccessIfStay(true)
// 微博 loading 窗顏色
.wbProgressColor(Color.YELLOW)
// 添加自定義的 json 解析
.jsonAdapter(new GsonJsonAdapter())
// 請求處理類,若是使用了微博的 openApi 分享,這個是必須的
.requestAdapter(new OkHttpRequestAdapter())
// 構建
.build();
複製代碼
說一下 Adapter
,項目內使用了 JSON
解析,網絡請求等功能,可是又不想引入多餘的框架,因此才用了宿主項目注入的方式,保證和宿主項目統一。
IJsonAdapter
,必須 !負責完成 Json
解析和序列化,提供一個 Gson
下的實現僅供參考 - GsonJsonAdapter.java;
IRequestAdapter
,非必須!內部使用 UrlConnection
作了一個默認的實現,負責完成網絡請求,也可使用 OkHttp
從新實現,能夠參考 - OkHttpRequestAdapter.java,目前微信的 OAuth2
受權和圖片下載的相關請求都是使用 IRequestAdapter
代理;
登錄功能支持三個平臺,qq,微信,微博;
// 3個平臺
Target.LOGIN_QQ;
Target.LOGIN_WX;
Target.LOGIN_WB;
複製代碼
登陸將會返回 LoginResult
, 其中主要包括登陸類型,基本用戶信息,令牌信息 3 部分;
public class LoginResult {
// 登錄的類型,對應 Target.LOGIN_QQ 等。。。
private int target;
// 返回的基本用戶信息
// 針對登陸類型可強轉爲 WbUser,WxUser,QQUser 來獲取更加豐富的信息
private SocialUser socialUser;
// 本次登錄的 token 信息,openId, unionId,token,expires_in
private AccessToken accessToken;
// 受權碼,若是 onlyAuthCode 爲 true, 將會返回它
private String wxAuthCode;
}
複製代碼
登陸時須要設置登陸回調:
OnLoginListener listener = new OnLoginListener() {
@Override
public void onStart() {
// 當登陸開始時觸發
}
@Override
public void onSuccess(LoginResult result) {
// 登陸成功,獲取用戶信息
SocialUser socialUser = result.getSocialUser();
}
@Override
public void onCancel() {
// 登陸取消
}
@Override
public void onFailure(SocialError e) {
// 登陸失敗
}
};
複製代碼
獲取更多用戶信息:
SocialUser socialUser = loginResult.getSocialUser();
// 基本信息能夠從 SocialUser 在獲取到
String userNickName = socialUser.getUserNickName();
// 獲取 openId
String openId = socialUser.getOpenId();
// 微信獲取 unionId,其餘平臺仍舊返回 openId
String unionId = socialUser.getUnionId();
// 獲取 userId,微信返回 unionId, 其餘平臺返回 openId
String userId = socialUser.getUserId();
// 強轉爲平臺用戶,能夠拿到更多信息
int target = result.getTarget();
switch (target) {
case Target.LOGIN_QQ:
QQUser qqUser = (QQUser) socialUser;
break;
case Target.LOGIN_WB:
WbUser wbUser = (WbUser) socialUser;
break;
case Target.LOGIN_WX:
WxUser wxUser = (WxUser) socialUser;
break;
}
複製代碼
發起登陸:
LoginManager.login(mActivity, Target.LOGIN_QQ, listener);
複製代碼
關於 token
時效,能夠在初始化時設置 tokenExpiresHours
來控制,也一樣提供清除受權 token
的方法。
// 清除所有平臺的 token
LoginManager.clearAllToken(context);
// 清除指定平臺的 token
LoginManager.clearToken(context, Target.LOGIN_QQ);
複製代碼
重要:請仔細查看平臺和數據類型中間的支持能力
當 微博 使用 openApi
形式去分享時,可能有較長的延時,建議在生命週期中增長進度條顯示,避免用戶等待好久沒有響應。
針對業務邏輯和 SDK
設計,將分享數據類型劃分爲 7 種類型,他們能涵蓋大多數業務場景,分別是:
開啓 App 類型,打開渠道應用;
文字類型,純文本分享;
圖片類型(jpg, png, gif(要求能動));
App 推廣類型;
網頁連接類型;
音頻分享類型;
視頻分享類型;
複製代碼
爲了保證每一個平臺都有封閉且統一的外觀,若是某個平臺不兼容某種類型的分享,將會使用 web
分享的方式代替;好比微信不支持 app
分享,分享出去以後時 web
分享的模式。
// 支持的分享渠道
Target.SHARE_DD; // 釘釘好友
Target.SHARE_QQ_FRIENDS; // qq好友
Target.SHARE_QQ_ZONE; // qq空間
Target.SHARE_WX_FRIENDS; // 微信好友
Target.SHARE_WX_ZONE; // 微信朋友圈
Target.SHARE_WX_FAVORITE; // 微信收藏
Target.SHARE_WB; // 新浪微博
Target.SHARE_SMS; // 短信分享
Target.SHARE_EMAIL; // 郵件分享
Target.SHARE_CLIPBOARD; // 粘貼板分享
複製代碼
分享時,咱們首先要構造分享用的數據,ShareObj
對象提供了多種靜態方法用來快速建立對應分享的類型的對象;
// 測試用的路徑
localImagePath = new File(Environment.getExternalStorageDirectory(), "1.jpg").getAbsolutePath();
localVideoPath = new File(Environment.getExternalStorageDirectory(), "video.mp4").getAbsolutePath();
localGifPath = new File(Environment.getExternalStorageDirectory(), "3.gif").getAbsolutePath();
netVideoPath = "http://7xtjec.com1.z0.glb.clouddn.com/export.mp4";
netImagePath = "http://7xtjec.com1.z0.glb.clouddn.com/token.png";
netMusicPath = "http://7xtjec.com1.z0.glb.clouddn.com/test_music.mp3";
netMusicPath = "http://mp3.haoduoge.com/test/2017-05-19/1495207225.mp3";
targetUrl = "http://bbs.csdn.net/topics/391545021";
// 打開渠道對應app
ShareObj shareMediaObj = ShareObj.buildOpenAppObj();
// 分享文字
ShareObj textObj = ShareObj.buildTextObj("分享文字", "summary");
// 分享圖片
ShareObj imageObj = ShareObj.buildImageObj("分享圖片", "summary", localImagePath);
// 分享gif
ShareObj imageGifObj = ShareObj.buildImageObj("分享圖片", "summary", localGifPath);
// 分享app
ShareObj appObj = ShareObj.buildAppObj("分享app", "summary", localImagePath, targetUrl);
// 分享web
ShareObj webObj = ShareObj.buildWebObj("分享web", "summary", localImagePath, targetUrl);
// 分享視頻
ShareObj videoObj = ShareObj.buildVideoObj("分享視頻", "summary", localImagePath, targetUrl, localVideoPath, 10);
// 本地視頻分享、部分平臺支持
ShareObj videoLocalObj = ShareObj.buildVideoObj("分享本地視頻", "summary", localImagePath, targetUrl, localVideoPath, 0);
// 分享音樂
ShareObj musicObj = ShareObj.buildMusicObj("分享音樂", "summary", localImagePath, targetUrl, netMusicPath, 10);
複製代碼
針對一些不能被統一的參數使用擴展的參數支持:
// 使 ShareObj 支持短信分享
webObj.setSmsParams("13611301719", "說啥呢");
// 使 ShareObj 支持粘貼板分享
webObj.setClipboardParams("複製的內容");
// 使 ShareObj 支持郵件分享
webObj.setEMailParams("1101873740@qq.com", "主題", "內容");
// 使 ShareObj 在微信平臺優先使用小程序分享
webObj.setWxMiniParams("51299u9**q31",SocialValues.WX_MINI_TYPE_RELEASE,"/page/path");
複製代碼
使用 OnShareListener
做爲監聽分享回調;
OnShareListener listener = new OnShareListener() {
@Override
public void onStart(int shareTarget, ShareObj obj) {
// 分享開始
}
@Override
public ShareObj onPrepareInBackground(int shareTarget, ShareObj obj) throws Except
// 重寫分享對象,例如給分享出去的圖片加水印等
return null;
}
@Override
public void onSuccess(int target) {
// 分享成功
}
@Override
public void onFailure(SocialError e) {
// 分享失敗
}
@Override
public void onCancel() {
// 分享被取消
}
};
複製代碼
// 喚醒分享
ShareManager.share(mActivity, Target.SHARE_QQ_FRIENDS, imageObj, mOnShareListener);
複製代碼
關於重寫分享對象,其實提供一種能在分享以前對須要分享的 ShareObj
進行統一處理的機會,相似分享功能的一個切面,好比能夠用來解決網絡圖片沒法分享,咱們須要將它下載到本地,在進行分享,又好比圖片分享出去以前加上 app 水印等操做。
主要是重寫 OnShareListener
的 onPrepareInBackground
方法,這個方法會在分享以前首先執行,若是返回不是 null
,將會使用新建立的 ShareObj
進行分享,另外因爲考慮到可能進行耗時操做,這個方法是在子線程執行的。
@Override
public ShareObj onPrepareInBackground(int shareTarget,ShareObj obj) {
// 重構分享對象,不須要時返回 null 便可
obj.setTitle(obj.getTitle() + "/哈哈哈");
return obj;
}
複製代碼
爲了更好的統一分享失敗時返回的異常,返回的全部異常都會有一個 code
,能夠根據不一樣的 code
定位問題和給出更友好的提示。
int CODE_COMMON_ERROR = 101; // 通用錯誤,未歸類
int CODE_NOT_INSTALL = 102; // 沒有安裝應用
int CODE_VERSION_LOW = 103; // 版本太低,不支持
int CODE_SHARE_BY_INTENT_FAIL = 105; // 使用 Intent 分享失敗
int CODE_STORAGE_READ_ERROR = 106; // 沒有讀存儲的權限,獲取分享縮略圖將會失敗
int CODE_STORAGE_WRITE_ERROR = 107; // 沒有寫存儲的權限,微博分享視頻copy操做將會失敗
int CODE_FILE_NOT_FOUND = 108; // 文件不存在
int CODE_SDK_ERROR = 109; // sdk 返回錯誤
int CODE_REQUEST_ERROR = 110; // 網絡請求發生錯誤
int CODE_CANNOT_OPEN_ERROR = 111; // 沒法啓動 app
int CODE_PARSE_ERROR = 112; // 數據解析錯誤
int CODE_IMAGE_COMPRESS_ERROR = 113; // 圖片壓縮失敗
int CODE_PARAM_ERROR = 114; // 參數錯誤
int CODE_SDK_INIT_ERROR = 115; // SocialSdk 初始化錯誤
int CODE_PREPARE_BG_ERROR = 116; // 執行 prepareOnBackground 時錯誤
int CODE_NOT_SUPPORT = 117; // 不支持
複製代碼
例如你能夠這麼作:
listener = new OnShareListener() {
...
@Override
public void onFailure(SocialError e) {
showMsg("分享失敗 " + e.toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (e.getCode() == SocialError.CODE_STORAGE_READ_ERROR) {
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 100);
} else if (e.getCode() == SocialError.CODE_STORAGE_WRITE_ERROR) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}
}
}
};
複製代碼
參考這裏 HuaweiPlatform.java
向 SocialSdk
註冊構建工廠:
SocialSdk.addPlatform(new HuaweiPlatform.Factory());
複製代碼