SocialSdk-快速接入登陸分享

最新版本(0.0.7) Easier 、Lighter 、 More Business-Orientedjava

以更簡單、更輕量、更加面向業務需求爲設計目標,提供 微博微信QQTimQQ 輕聊版釘釘 的登錄分享功能支持;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 水印等操做。

主要是重寫 OnShareListeneronPrepareInBackground 方法,這個方法會在分享以前首先執行,若是返回不是 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());
複製代碼
相關文章
相關標籤/搜索