【Unity】ShareSDK、SMSSDK的基本使用與常見問題

概要

測試使用ShareSDK的一些經常使用功能。包括:android

  • 用微博賬號作第三方登陸
  • 獲取用戶的賬號詳細信息
  • 獲取好友列表
  • 分享功能

測試使用SMSSDK插件,包括:git

  • 導入插件,解決包衝突
  • 短信登陸功能:發驗證碼,收驗證碼,比對驗證碼

學習資料:github

 


 

用微博賬號作第三方登陸

一、在mob.com上註冊賬號,添加一個應用,給該應用添加ShareSDK。
二、登陸微博開放平臺,填寫開發者信息。添加一個應用,肯定安卓包名,下載微博提供的簽名生成工具(md5簽名生成器apk),安裝到安卓手機上。打開工具輸入安卓包名,獲得簽名字符串。把包名和簽名填上。在OAuth2.0受權設置中輸入回調頁url。
三、打開Unity新建一個項目,Player Settings中填上上面的包名,本身的密鑰庫和密鑰。
四、下載ShareSDK for Unity,把包裏的ShareSDK.unitypackage導入到項目中。
五、新建一個場景取名Init,一個空物體(可取名ShareSDKManager),專門用於存放全遊戲中通用的(可跨場景長的、生命週期的)數據,開始遊戲時先進入該場景,執行ShareSDK初始化,而後再跳轉到其餘遊戲場景。該場景只會進入一次。
六、給ShareSDKManager物體掛上Share SDK腳本,填上在微博開放平臺中給的App Key,App Secret和回調頁路徑Redirect Url(默認填的是官方給的Debug賬號的信息)。
七、在腳本的Dev Info中打開本次測試id新浪微博Sinaweibo進行修改。其餘不用管,默認都填的官方給的Debug賬號信息。

 

八、新建一個ShareSDKManager腳本,掛載到 ShareSDKManager物體上。
using cn.sharesdk.unity3d; using UnityEngine; public class ShareSDKManager : MonoBehaviour { private static ShareSDKManager _instance; public static ShareSDKManager Instance { get { return _instance; } } 
  [HideInInspector]
    public PlatformType userPlatform = PlatformType.Unknown; // 用戶登陸的平臺(是微博登陸仍是短信登陸)
    [HideInInspector]
    public string userID = ""; [HideInInspector]
public ShareSDK ssdk; void Start () { _instance = this; DontDestroyOnLoad(gameObject); ssdk= gameObject.GetComponent<ShareSDK>(); // ShareSDK.Awake()中已經執行了shareSDKUtils.InitSDK(appKey,appSecret)初始化操做,這裏是否寫初始化可隨意 // 初始化完成後,跳轉場景 UnityEngine.SceneManagement.SceneManager.LoadScene(1); } }
九、新建一個場景取名Login,這是在Init場景以後進入的登陸頁面場景。新建腳本Login,掛到新建的LoginManager物體上。場景中的【用新浪微博登陸】按鈕觸發該物體中Login腳本對應的方法。登陸方法的流程參考下圖。這裏以應用沒有用戶系統的體系爲例。
using cn.sharesdk.unity3d; using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; public class Login : MonoBehaviour { ShareSDK ssdk; void Start () { ssdk= ShareSDKManager.Instance.shareSDK; ssdk.authHandler = OnAuthResultHandler; // 受權結果的回調函數
 } // 用新浪微博登陸
    public void OnSinaLoginButtonClick() { if (ssdk.IsAuthorized(PlatformType.SinaWeibo)) // 檢測指定的平臺是否已經受權過了
 {         // 寫入受權信息
            Utility.WriteFile(Application.persistentDataPath, "AuthInfo.txt", ssdk.GetAuthInfo(PlatformType.SinaWeibo).toJson());
            Utility.MakeToast("微博用戶:" + ssdk.GetAuthInfo(PlatformType.SinaWeibo)["userName"] + "\n登陸成功!"); // 信息詳情查看輸入的文件
            ShareSDKManager.Instance.userPlatform = PlatformType.SinaWeibo;
            SceneManager.LoadScene(2); }
else // 指定的平臺還沒有受權,給它受權 { ssdk.Authorize(PlatformType.SinaWeibo); } } /// <summary> /// 受權結果的回調函數 /// </summary> /// <param name="reqID"></param> /// <param name="state">受權狀態:成功,失敗,取消</param> /// <param name="type">受權平臺類型</param> /// <param name="data">返回的數據</param> void OnAuthResultHandler(int reqID, ResponseState state, PlatformType type, Hashtable data) { if (state == ResponseState.Success) {
        // 受權結果寫入文件
            Utility.WriteFile(Application.persistentDataPath, "AuthData.txt", data.toJson());
            Utility.WriteFile(Application.persistentDataPath, "AuthInfo.txt", ssdk.GetAuthInfo(PlatformType.SinaWeibo).toJson());
            Utility.MakeToast("微博用戶:" + ssdk.GetAuthInfo(PlatformType.SinaWeibo)["userName"] + "\n登陸成功!"); // 信息詳情查看輸入的文件
            ShareSDKManager.Instance.userPlatform = PlatformType.SinaWeibo;
            SceneManager.LoadScene(2); }
else if (state == ResponseState.Fail) { // 失敗或取消要清除指定平臺的受權信息 ssdk.CancelAuthorize(type); Utility.MakeToast("登陸失敗!"); } else if (state == ResponseState.Cancel) { // 失敗或取消要清除指定平臺的受權信息 ssdk.CancelAuthorize(type); Utility.MakeToast("登陸被取消!"); } } }
寫一個文件讀寫的工具類。
using System.IO; /// <summary>
/// 讀寫文件的工具類。 /// 用於查看ShareSDK受權時返回的data中有哪些數據。 /// </summary>
public static class Utility { public static void WriteFile(string path, string name, string info) { StreamWriter writer; FileInfo fi = new FileInfo(path + "/" + name); writer = fi.CreateText(); writer.WriteLine(info); writer.Close(); writer.Dispose(); } public static string ReadFile(string path, string name) { StreamReader reader; FileInfo fi = new FileInfo(path + "/" + name); reader = fi.OpenText(); string info = reader.ReadToEnd(); reader.Close(); reader.Dispose(); return info; } }
九、打包APK後在安卓模擬器上運行。點擊【用新浪微博登陸】按鈕後便可看到效果:首次登陸時要填微博帳號和密碼,輸入正確後會跳轉到微博受權頁面,點擊肯定受權完成後,遊戲進入下一個場景,完成操做。再次登陸時直接完成操做,進入下一場景。
打開輸出的兩個dat文件,查看返回的詳細數據。其中用戶ID,用戶名,用戶頭像等是經常使用的數據。這裏爲便於本身查看,後綴改爲了txt(我用的逍遙遊安卓模擬器不讓選擇.dat打開方式)
坑點
  • 若是點擊按鈕沒反應,到微博開放平臺測試信息—添加測試賬號,關聯到本身的微博,由於開發者身份認證未經過審覈時不能拿到數據。
  • 若是點擊按鈕後頁面回退,是Unity中ShareSDK腳本的微博App Key和App Secret沒填對。(有默認的Debug賬號的數據,注意檢查)。
  • 報錯「你所訪問的站點在微博認證失敗 錯誤號21322 重定向地址不匹配」。是由於在Unity腳本中沒有填寫回調url,要跟微博開放平臺中輸入的回調頁地址一致才行!
  • 報錯 21323 : 請求不合法。該方法登陸若是碰到這個問題,過一段時間後再試試就沒問題了,很是詭異,也許是新浪服務端那邊的問題???懷疑是請求過於頻繁致使。沒搞懂這個錯誤。

獲取用戶的賬號詳細信息

接着上面的工程,在用戶詳情頁中寫一個腳本,在已登陸的狀態下獲取微博帳號的詳情。數組

using cn.sharesdk.unity3d; using System.Collections; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; public class Info : MonoBehaviour { public Image userIcon; public Text userName; public Text userID; ShareSDK ssdk; void Start () { ssdk = ShareSDKManager.Instance.ssdk; ssdk.showUserHandler = OnGetUserInfoResultHandler; // 在前一個場景中已把受權返回的數據寫入到了本地
        Hashtable authInfo = Utility.ReadFile(Application.persistentDataPath, "AuthInfo.dat").hashtableFromJson(); StartCoroutine(LoadUserIcon(authInfo["userIcon"].ToString())); userName.text = authInfo["userName"].ToString(); userID.text = "ID:" + authInfo["userID"].ToString(); } // 協程下載用戶頭像Icon
    IEnumerator LoadUserIcon(string url) { WWW www = new WWW(url); yield return www; // 等待下載完才執行下面的代碼
        if (www.isDone && www.error == null) { Texture2D texture2D = www.texture; userIcon.sprite = Sprite.Create(texture2D, new Rect(0, 0, texture2D.width, texture2D.height), Vector2.zero); } } // 進入遊戲主場景
    public void OnEnterButtonClick() { } // 查看用戶詳細信息
    public void OnDetailButtonClick() { ssdk.GetUserInfo(PlatformType.SinaWeibo); } // 獲取用戶詳情的回調
    void OnGetUserInfoResultHandler(int reqID, ResponseState state, PlatformType type, Hashtable data) { if (state == ResponseState.Success) { // 將用戶詳情寫入文件中,以後隨意使用。
            Utility.WriteFile(Application.persistentDataPath, "UserInfo.dat", data.toJson()); // 如獲取用戶位置
            Utility.MakeToast("所在地:" + Utility.Unicode2String(data["location"].ToString())); } else if (state == ResponseState.Fail) { Utility.MakeToast("獲取用戶詳情失敗!"); } else if (state == ResponseState.Cancel) { Utility.MakeToast("獲取用戶詳情被取消!"); } } // 註銷,退出登陸
    public void OnSignOutButtonClick() { // 取消指定平臺的受權
 ssdk.CancelAuthorize(PlatformType.SinaWeibo); // 回調登陸場景
        SceneManager.LoadScene(1); } }

打開UserInfo.dat查看能獲取到哪些賬號詳情。網絡

獲取好友列表

using cn.sharesdk.unity3d; using System.Collections; using UnityEngine; using UnityEngine.UI; public class Play : MonoBehaviour { public Text resultText; ShareSDK ssdk; void Start () { ssdk = ShareSDKManager.Instance.ssdk; ssdk.getFriendsHandler = OnGetFriendsResultHandler; } // 點擊獲取好友列表
    public void OnFriendsButtonClick() { // 分頁獲取當前登陸用戶平臺的好友列表,每頁容量,第幾頁(從0開始) // 但此接口已被棄用,目前只能準確得到好友總數,且一次請求只能返回2個好友(第三參數填0返回第1和2位好友),後兩個參數已失效 // 若是想靠該接口分頁獲取全部好友,須要自行屢次獲取,自行分頁
        ssdk.GetFriendList(PlatformType.SinaWeibo, 20, 0); } void OnGetFriendsResultHandler(int reqID, ResponseState state, PlatformType type, Hashtable data) { if (state == ResponseState.Success) { // 將好友列表寫入文件中,以後隨意使用。
            Utility.WriteFile(Application.persistentDataPath, "FriendsList.dat", data.toJson()); } else if (state == ResponseState.Fail) { Utility.MakeToast("獲取好友列表失敗!"); } else if (state == ResponseState.Cancel) { Utility.MakeToast("獲取好友列表被取消!"); } } }

查看FriendsList.dat,每一個好友的信息有不少數據,一樣中文是Unicode須要轉成String顯示。該接口謹慎使用。app

分享功能

void Start () { ssdk = ShareSDKManager.Instance.ssdk; ssdk.shareHandler = OnShareResultHandler; } // 點擊分享:截圖,配文字,分享
public void OnShareButtonClick() { // 屏幕截圖,默認存放路徑Application.persistentDataPath,屢次調用會同名替換圖片。
    ScreenCapture.CaptureScreenshot("Screenshot.png"); // 分享的內容
    ShareContent content = new ShareContent(); // ★通用分享內容的設置 // 設置分享的文字(正文)
    content.SetText("測試ShareSDK分享功能"); // 設置分享的圖片 // SetImagePath:用於本地圖片,參數爲圖片路徑 // SetImageUrl:用於網絡圖片,參數爲圖片網址 // SetImageArray:用於多圖分享,參數爲圖片網址string數組。僅支持網絡圖片,僅支持Android。
    content.SetImagePath(Application.persistentDataPath + "/Screenshot.png"); // 其餘可設置的額外參數
    content.SetTitle("ShareSDKDemo");           // 標題
    content.SetTitleUrl("http://www.guxin.me"); // 標題的Url
    content.SetSite("guxin.me");                // 分享來源的站點
    content.SetTitle("http://www.guxin.me");    // 站點的Url
    content.SetUrl("http://www.guxin.me");      // 分享的網站
    content.SetUrlDescription("我的學習ShareSDK的Demo"); // ... // 設定分享內容的主要類型,放在最後一步
 content.SetShareType(ContentType.Image); // ★其餘平臺特異性分享內容的設置
    ShareContent sinaWeiboContent = new ShareContent(); sinaWeiboContent.SetText(resultText.text + "\n via 新浪微博"); // 在指定平臺上,使用第二個參數中的內容覆蓋主內容裏的值
 content.SetShareContentCustomize(PlatformType.SinaWeibo, sinaWeiboContent); // ★顯示分享框 // PlatformType[] platforms = { PlatformType.SinaWeibo, PlatformType.QQ, PlatformType.WeChat }; // ssdk.ShowPlatformList(platforms, content, 100, 100); // 指定顯示平臺的方法已棄用,第一個參數穿null便可。 // string[] platforms = { "5" }; // 查看PlatformType枚舉值,如豆瓣是「5」 // string[] platforms = { ((int)PlatformType.DouBan).ToString() }; // 能夠設置哪些平臺不顯示。
    string[] platforms = { "5", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "20", "25", "26", "27", "28", "29", "30", "34", "35", "36", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "50", "51", "52", "53", "54" }; content.SetHidePlatforms(platforms); ssdk.ShowPlatformList(null, content, 100, 100); } // 分享結果的回調
void OnShareResultHandler(int reqID, ResponseState state, PlatformType type, Hashtable data) { // 注意:並不是全部平臺都會報告正確的狀態,如短信、郵件平臺,只要界面跳轉成功了都算成功(無論玩家接下來是否真的有點發送)。
    if (state == ResponseState.Success) { Utility.MakeToast("分享成功!"); // 遊戲中分享成功可能會得到一些道具,在這裏處理。注意不能正確報告的平臺,防止玩家未分享也能得到道具。 // ......
 } else if (state == ResponseState.Fail) { Utility.MakeToast("分享失敗!"); } else if (state == ResponseState.Cancel) { Utility.MakeToast("分享被取消!"); } }

Bug:指定了分享界面的顯示的可選平臺,但仍是顯示了全部的平臺。即設置指定的分享平臺無效。ide

解決辦法有三種:
1、設置setHidePlatforms,填上全部隱藏的平臺,只保留想要的平臺。
2、在ShareSDK腳本上把不須要的平臺的Enable取消勾選,直接關閉與該平臺的全部交互。
3、在Plugins-Android-lib裏刪除不須要的平臺的包(ShareSDK開頭的lib文件)
建議使用方法一,可適應如不一樣界面要顯示不一樣的分享平臺等需求。

導入SMSSDK報錯,包衝突問題

一、登陸mob.com後臺,給應用添加SMSSDK功能。並從官網 下載短信驗證碼SDK(https://github.com/MobClub/SMSSDK-for-Unity3D),內含詳細文檔。
二、將SMSSDK.unitypackage導入項目中。會報錯MiniJSON已存在,這是由於已同時存在Assets/Plugins/SMSSDK/MiniJSON.cs和Assets/Plugins/ShareSDK/MiniJSON.cs文件(名稱空間相同),刪掉一個便可,如刪掉SMSSDK文件夾下的。
三、打包運行,發現報錯,AndroidManifest清單文件沒法合併等問題。這是由於Assets/Plugins/Android/ShareSDK/lib和Assets/Plugins/Android/SMSSDK/lib文件夾下有相同的MobCommons.lib和MobTools.lib,包衝突了(雖而後邊版本號不一樣)。任意刪除一邊的兩個包便可,如刪除SMSSDK文件夾下的。把兩個清單的都設置 android:minSdkVersion="16" , android:targetSdkVersion="26"
AndroidManifest清單合併報錯。
F:\workspace\Unity Learning\ShareSDKDemo\Temp\StagingArea\AndroidManifest-main.xml:28:13-74 Error: Attribute activity#com.mob.tools.MobUIShell@configChanges value=(keyboardHidden|orientation|screenSize) from AndroidManifest.xml:28:13-74 is also present at AndroidManifest.xml:15:13-97 value=(keyboardHidden|orientation|screenSize|locale|layoutDirection). Suggestion: add 'tools:replace="android:configChanges"' to <activity> element at AndroidManifest-main.xml:26:9-44:20 to override. F:\workspace\Unity Learning\ShareSDKDemo\Temp\StagingArea\AndroidManifest-main.xml:29:13-72 Error: Attribute activity#com.mob.tools.MobUIShell@theme value=(@android:style/Theme.Translucent.NoTitleBar) from AndroidManifest.xml:29:13-72 is also present at AndroidManifest.xml:16:13-60 value=(@android:style/Theme.NoTitleBar). Suggestion: add 'tools:replace="android:theme"' to <activity> element at AndroidManifest-main.xml:26:9-44:20 to override. UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
這是由於在 Assets/Plugins/Android/ShareSDK/AndroidManifest.xml與Assets/Plugins/Android/SMSSDKGUI/AndroidManifest.xml中有重複設置android:configChanges和android:theme屬性。去掉SMSSDKGUI/AndroidManifest.xml中的該屬性便可。

短信登陸

SMSSDK主要使用發驗證碼、收驗證碼、比對驗證碼功能,其餘功能已多年未維護,不推薦使用。
在Init場景中給物體掛上SMSSDK腳本,該腳本已默認填有App Key和App Secret。雖然已在mob後臺添加了SMSSDK功能,但測試時依然能夠繼續用該Debug賬號,由於不受天天20條短信限制。(發佈時再改用本身的Key和Secret,上線後不受數量限制,且可定製短信)
在自定義的管理類中初始化smssdk。
// SMSSDK初始化
smssdk = gameObject.GetComponent<SMSSDK>(); smssdk.init("moba6b6c6d6", "b89d2427a3bc7ad1aea1e1e8c1d36bf3", true); // 用默認的Debug賬號的App Key和App Secret測試。上線時改用在mob後臺給的值。

主邏輯腳本繼承SMSSDKHandler接口,實現onComplete()和onError()這兩個回調函數,smssdk.setHandler()註冊。注意枚舉ActionType.SubmitUserInfo和ActionType.GetFriends已好久未維護,不推薦使用。函數

最終整合了微博登陸與短信登陸的腳本以下。工具

using cn.sharesdk.unity3d; using cn.SMSSDK.Unity; using System.Collections; using UnityEngine; using UnityEngine.SceneManagement; public class Login : MonoBehaviour, SMSSDKHandler { ShareSDK ssdk; SMSSDK smssdk; void Start () { ssdk = ShareSDKManager.Instance.ssdk; ssdk.authHandler = OnAuthResultHandler; // 受權結果的回調函數
 smssdk = ShareSDKManager.Instance.smssdk; smssdk.setHandler(this); // 短信操做的回調
 } // 用新浪微博登陸
    public void OnSinaLoginButtonClick() { if (ssdk.IsAuthorized(PlatformType.SinaWeibo)) // 檢測指定的平臺是否已經受權過了
 { // 寫入受權信息
            Utility.WriteFile(Application.persistentDataPath, "AuthInfo.txt", ssdk.GetAuthInfo(PlatformType.SinaWeibo).toJson()); Utility.MakeToast("微博用戶:" + ssdk.GetAuthInfo(PlatformType.SinaWeibo)["userName"] + "\n登陸成功!"); // 信息詳情查看輸入的文件
            ShareSDKManager.Instance.userPlatform = PlatformType.SinaWeibo; SceneManager.LoadScene(2); } else // 指定的平臺還沒有受權,給它受權
 { ssdk.Authorize(PlatformType.SinaWeibo); } } /// <summary>
    /// 受權結果的回調函數 /// </summary>
    /// <param name="reqID"></param>
    /// <param name="state">受權狀態:成功,失敗,取消</param>
    /// <param name="type">受權平臺類型</param>
    /// <param name="data">返回的數據</param>
    void OnAuthResultHandler(int reqID, ResponseState state, PlatformType type, Hashtable data) { if (state == ResponseState.Success) { // 受權結果寫入文件
            Utility.WriteFile(Application.persistentDataPath, "AuthData.txt", data.toJson()); Utility.WriteFile(Application.persistentDataPath, "AuthInfo.txt", ssdk.GetAuthInfo(PlatformType.SinaWeibo).toJson()); Utility.MakeToast("微博用戶:" + ssdk.GetAuthInfo(PlatformType.SinaWeibo)["userName"] + "\n登陸成功!"); // 信息詳情查看輸入的文件
            ShareSDKManager.Instance.userPlatform = PlatformType.SinaWeibo; SceneManager.LoadScene(2); } else if (state == ResponseState.Fail) { // 失敗或取消要清除指定平臺的受權信息
 ssdk.CancelAuthorize(type); Utility.MakeToast("登陸失敗!"); } else if (state == ResponseState.Cancel) { // 失敗或取消要清除指定平臺的受權信息
 ssdk.CancelAuthorize(type); Utility.MakeToast("登陸被取消!"); } } // 用短信登陸,有兩種方式
    public void OnSmsButtonClick() { // 方式一:非UI方式,須要搭配Unity裏本身製做的UI
        /* * 經過getCode()得到驗證碼,參數是:驗證碼類型(短信/語音),手機號,國際區域號(大陸爲86,非國內電話的區號),模板號 * smssdk.getCode(CodeType, phone, zone, tempCode); * 經過commitCode()方式提交驗證碼,參數:手機號,國際區域號(大陸爲86,非國內電話的區號),驗證碼 * smssdk.commitCode(phone, zone, code); */

        // 方式二:UI方式,直接使用SMSSDK自帶的UI(Android下的界面)
        smssdk.showRegisterPage(CodeType.TextCode, null); //tempcode是模板編號,如還未申請傳null便可。申請新模板要等審覈經過。
 } // 短信操做,完成
    public void onComplete(int action, object resp) { ActionType act = (ActionType)action; //Debug.Log(act);
        if (act == ActionType.CommitCode) { ShareSDKManager.Instance.userPlatform = PlatformType.SMS; ShareSDKManager.Instance.userID = ((string)resp).hashtableFromJson()["phone"].ToString(); Utility.MakeToast("手機用戶:" + ShareSDKManager.Instance.userID + "\n登陸成功!"); SceneManager.LoadScene(2); } } // 短信操做,失敗
    public void onError(int action, object resp) { Utility.MakeToast("短信驗證失敗!"); } }

自用Demo:https://gitee.com/guxin233/Unity_ShareSDK_Demo學習

相關文章
相關標籤/搜索