Cocos2d-x 3.0中集成社交分享ShareSDK的詳細(xì)步驟和常見問題解決
給自己的手機(jī)游戲增加些社交分享功能,有助于游戲宣傳和提升知名度,是一種不錯的社交營銷手段。國內(nèi)這方面的第三方插件有不少,比如ShareSDK、友 盟分享組件、Baidu分享組件等,之前在研究2.2.2版本時(shí),集成了ShareSDK這個組件,這次遷移到Cocos2d-x 3.0rc2依舊選擇集成ShareSDK,這里就來說說集成的過程,遇到的一些問題以及解決方法。這里僅以Android平臺游戲集成為例。
一、功能描述、SDK版本和帳號準(zhǔn)備
功能大致是這樣的:在游戲中設(shè)置一個按鈕,點(diǎn)擊這個按鈕,彈出知名社交平臺的分享圖標(biāo)集窗口,用戶選擇分享目標(biāo)后,相關(guān)信息分享到對應(yīng)的社交平臺。分享結(jié)果通知通過Toast顯示在屏幕的下方。
這次依舊使用ShareSDK for Android 2.3.7版本(ShareSDK-Android-2.3.7),Cocos2d-x的版本為3.0rc2。
集成前,你需要有一個基于Cocos2d-x 3.0rc2的可運(yùn)行的Android平臺游戲project,我們的集成就基于該project,這里我們的project名為GameDemo,GameDemo的源碼結(jié)構(gòu)大致是:
GameDemo/
– Classes/
– proj.android/
– Resources/
– cocos2d/
– CMakeLists.txt
– … …
使用ShareSDK前,你需要在各大主流社交平臺(微信、微博)申請開發(fā)者帳號以及游戲接入權(quán)限(app_key、app_secret)等,當(dāng)然在ShareSDK站點(diǎn)也應(yīng)該有自己的帳號和應(yīng)用AppKey,這些申請的審核需要幾個工作日,甚至更長。
二、ShareSDK集成步驟
按照ShareSDK官方manual說法,Cocos2d-x集成ShareSDK有三種方式,之前在Cocos2d-x 2.2.2引擎中采用的是專用組件集成的方式,該組件(C2DXShareSDKSample)可以在這里下載(https://github.com/ShareSDKPlatform/C2DXShareSDKSample,該組件近期已經(jīng)fix了我之前發(fā)現(xiàn)的bug)。
1.jar包集成
這次我們主要做微博、微信的社交分享,因此只需要微博、微信相關(guān)jar包。在C2DXShareSDKSample/proj.android/libs下,我們找到以下幾個jar包:
-rw-rw-r– 1 tonybai tonybai 97K 4月 8 18:10 mframework.jar
-rw-rw-r– 1 tonybai tonybai 112K 4月 8 17:39 ShareSDK-Core-2.3.7.jar
-rw-rw-r– 1 tonybai tonybai 19K 4月 8 17:39 ShareSDK-SinaWeibo-2.3.7.jar
-rw-rw-r– 1 tonybai tonybai 4.3K 4月 8 17:39 ShareSDK-Wechat-2.3.7.jar
-rw-rw-r– 1 tonybai tonybai 29K 4月 8 17:39 ShareSDK-Wechat-Core-2.3.7.jar
-rw-rw-r– 1 tonybai tonybai 4.6K 4月 8 17:39 ShareSDK-Wechat-Favorite-2.3.7.jar
-rw-rw-r– 1 tonybai tonybai 4.4K 4月 8 17:39 ShareSDK-Wechat-Moments-2.3.7.jar
把這些jar包文件Copy到GameDemo/proj.android/libs下。
2. 配置文件與資源部分集成
修改GameDemo/proj.android/AndroidManifest.xml文件,在application標(biāo)簽下,添加如下Activity標(biāo)簽:
<activity
android:name="cn.sharesdk.framework.ShareSDKUIShell"
android:configChanges="keyboardHidden|orientation|screenSize"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:windowSoftInputMode="stateHidden|adjustResize" >
</activity>
<activity
android:name=".wxapi.WXEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
將C2DXShareSDKSample/proj.android/res下的如下目錄中的文件復(fù)制到GameDemo/proj.android/res下:
drawable-hdpi/ drawable-ldpi/ drawable-mdpi/
drawable-xhdpi/ layout/ values/ values-en/
注意,類似icon.png這種文件就不要復(fù)制了,自己做一下判斷就好。
3. C++部分代碼集成
將C2DXShareSDKSample/Classes下的C2DXShareSDK文件夾Copy到GameDemo/Classes下面。
由于Cocos2d-x 3.0rc2的類命名發(fā)生了變化,我們需要對C2DXShareSDK中使用到的引擎中的類名以及方法名進(jìn)行修改。但實(shí)際上Cocos2d-x 3.0rc2考慮到了一些兼容性的問題,大部分名字通過cocos2d/cocos/deprecated/CCDeprecated.h中定義的typedef得以保留,雖然這些名字已經(jīng)被建議deprecated了。rc2中CCObject被改名為Ref了,這個我們需要手工在C2DXShareSDK進(jìn)行修改。
另外ShareSDK組件在實(shí)現(xiàn)時(shí)大量使用了CCDictionary、CCArray和CCString,而這三個類在Cocos2d-x 3.0rc2中均被deprecated了,但我們依然可以使用,所以我們可以不做修改。但以后隨著cocos2d-x版本的演進(jìn),這些類很可能被徹底移除出引擎,我們就需要重新使用其替代品進(jìn)行實(shí)現(xiàn)了。
此外我們還需要手工修改一下C2DXShareSDK/Android/JSON/CCJSONConverter.cpp文件中的getObjJson方 法,因?yàn)閞c2中CCDictionary、CCString、CCArray這些類的真實(shí)名稱都已經(jīng)換成了__Dictionary、__String 和__Array,CCDictionary、CCString、CCArray只是些typedef,因此要像下面這樣做些修改(如果你是集成 cocos2d-x 2.x.x版本,則無需做下面修改):
cJSON * CCJSONConverter::getObjJson(Ref * obj)
{
std::string s = typeid(*obj).name();
if(s.find("__Dictionary")!=std::string::npos){
cJSON * json = cJSON_CreateObject();
convertDictionaryToJson((CCDictionary *)obj, json);
return json;
}else if(s.find("__Array")!=std::string::npos){
cJSON * json = cJSON_CreateArray();
convertArrayToJson((CCArray *)obj, json);
return json;
}else if(s.find("__String")!=std::string::npos){
CCString * s = (CCString *)obj;
cJSON * json = cJSON_CreateString(s->getCString());
return json;
}else if(s.find("CCNumber")!=std::string::npos){
CCNumber * n = (CCNumber *)obj;
cJSON * json = cJSON_CreateNumber(n->getDoubleValue());
return json;
}else if(s.find("CCNull")!=std::string::npos){
cJSON * json = cJSON_CreateNull();
return json;
}
CCLog("CCJSONConverter encountered an unrecognized type");
return NULL;
}
CCNumber和CCNull是ShareSDK組件自己實(shí)現(xiàn)的類名,這里無需修改。
接下來我們需要在AppDelegate.cpp中對ShareSDK做初始化了:
bool AppDelegate::applicationDidFinishLaunching() {
… …
initShareSDK();
… ..
}
void AppDelegate::initShareSDK()
{
// sina weibo
CCDictionary *sinaConfigDict = CCDictionary::create();
sinaConfigDict->setObject(CCString::create("YOUR_WEIBO_APPKEY"), "app_key");
sinaConfigDict->setObject(CCString::create("YOUR_WEBIO_APPSECRET"), "app_secret");
sinaConfigDict->setObject(CCString::create("http://www.sharesdk.cn"), "redirect_uri");
C2DXShareSDK::setPlatformConfig(C2DXPlatTypeSinaWeibo, sinaConfigDict);
// wechat
CCDictionary *wcConfigDict = CCDictionary::create();
wcConfigDict->setObject(CCString::create("YOUR_WECHAT_APPID"), "app_id");
C2DXShareSDK::setPlatformConfig(C2DXPlatTypeWeixiSession, wcConfigDict);
C2DXShareSDK::setPlatformConfig(C2DXPlatTypeWeixiTimeline, wcConfigDict);
C2DXShareSDK::setPlatformConfig(C2DXPlatTypeWeixiFav, wcConfigDict);
C2DXShareSDK::open(CCString::create("YOUR_SHARESDK_APPKEY"), false);
}
在Share按鈕的事件回調(diào)函數(shù)中調(diào)用ShareSDK的接口進(jìn)行社交平臺分享:
void GameScene::menuShareCallback(Ref* sender)
{
Dictionary *content = Dictionary::create();
content->setObject(String::create("ShareSDK for Cocos2d-x 3.0rc2社交分享測試。")
, "content");
content->setObject(String::create("ShareSDK分享測試"), "title");
content->setObject(String::create("http://tonybai.com"), "titleUrl");
content->setObject(String::create("http://tonybai.com"), "url");
content->setObject(String::create("Tony Bai"), "site");
content->setObject(String::create("http://tonybai.com"), "siteUrl");
content->setObject(String::createWithFormat("%s", YOUR_LOCAL_IMAGE_PATH)
, "image");
content->setObject(String::createWithFormat("%d", C2DXContentTypeNews)
, "type");
C2DXShareSDK::showShareMenu(NULL, content, CCPointMake(100, 100),
C2DXMenuArrowDirectionLeft, shareResultHandler);
}
void shareResultHandler(C2DXResponseState state,
C2DXPlatType platType,
Dictionary *shareInfo,
Dictionary *error)
{
AppDelegate *app = (AppDelegate*)Application::getInstance();
switch (state) {
case C2DXResponseStateSuccess:
CCLog("Share Ok");
app->showShareResultToast("分享成功");
break;
case C2DXResponseStateFail:
app->showShareResultToast("分享失敗");
CCLog("Share Failed");
break;
default:
break;
}
}
showShareResultToast實(shí)現(xiàn)如下:
void AppDelegate::showShareResultToast(const char *msg)
{
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t, "YOUR_ACTIVITY_NAME",
"showShareResultToast", "(Ljava/lang/String;)V")) {
jstring jmsg = t.env->NewStringUTF(msg);
t.env->CallStaticVoidMethod(t.classID, t.methodID, jmsg);
if (t.env->ExceptionOccurred()) {
t.env->ExceptionDescribe();
t.env->ExceptionClear();
return;
}
t.env->DeleteLocalRef(t.classID);
}
}
4. Java部分代碼集成
在GameDemo/proj.android/src下面建立cn/sharesdk路徑,將C2DXShareSDKSample /proj.android/src/cn/sharesdk下的onekeyshare和ShareSDKUtils.java Copy到GameDemo/proj.android/src/cn/sharesdk下面。
將ShareSDK-Android-2.3.7.zip解壓后的ShareSDK for Android/Src/wxapi Copy到GameDemo/proj.android/src/com.tonybai.game/下。
修改GameDemo/proj.android/src/com.tonybai.game/GameDemoActivity.java文件:
import android.widget.Toast;
import cn.sharesdk.ShareSDKUtils;
…
public class GameDemoActivity extends Cocos2dxActivity {
private static Context context;
private static Handler notifyHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
String message = (String) msg.obj;
Toast.makeText(context, message,
Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
ShareSDKUtils.prepare();
ShareSDKUtils.initSDK("YOUR_SHARESDK_APPKEY", true);
}
public static void showShareResultToast(String result) {
Message msg = new Message();
msg.what = 1;
msg.obj = result;
notifyHandler.sendMessage(msg);
}
@Override
public void onDestroy() {
ShareSDKUtils.stopSDK();
super.onDestroy();
}
}
三、問題與解決方法
按照上面的集成方法修改后,通過cocos編譯app,在模擬器運(yùn)行GameDemo,點(diǎn)擊Share,理論上屏幕下方會出現(xiàn)ShareSDK的分享窗口,選擇“新浪微博”圖標(biāo),會打開“圖文分享”內(nèi)容窗口,點(diǎn)擊窗口右上角的“分享”即可。
【問題1】“圖文分享”窗口內(nèi)容可編輯,并且總是彈出軟鍵盤,影響體驗(yàn)。
期望:內(nèi)容不可編輯,默認(rèn)不彈出軟鍵盤
解決方法:
打開proj.android/src/cn/sharesdk/onekeyshare/EditPage.java,做如下修改:
將窗口的軟輸入方式默認(rèn)改為SOFT_INPUT_STATE_HIDDEN。
public void setActivity(Activity activity) {
super.setActivity(activity);
if (dialogMode) {
activity.setTheme(android.R.style.Theme_Dialog);
activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
}
activity.getWindow().setSoftInputMode(
//WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);//default: hidden
}
在initPageView中增加一行:etContent.setKeyListener(null)。讓窗口內(nèi)容無法修改。
… …
// 文字輸入?yún)^(qū)域
etContent = new EditText(getContext());
etContent.setGravity(Gravity.LEFT | Gravity.TOP);
etContent.setBackgroundDrawable(null);
etContent.setText(String.valueOf(reqData.get("text")));
etContent.setKeyListener(null);//make the edittext uneditable
etContent.setLayoutParams(lpEt);
… …
}
【問題2】向微博分享,點(diǎn)擊“分享”后,過一會程序異常停止。
原因分析:
通過調(diào)試觀察,發(fā)現(xiàn)ShareSDK在解析從Weibo收到的Json包時(shí)出現(xiàn)內(nèi)存違法訪問。具體位置是在解析一個數(shù)組對象時(shí)出現(xiàn)的問題。 ShareSDK用CCArray來存儲Json中的數(shù)組對象。該問題在cocos2d-x 2.2.2版本中不會出現(xiàn),但在cocos2d-x 3.0rc2版本中會出現(xiàn)。經(jīng)代碼對比發(fā)現(xiàn),3.0rc2版本中的CCArray的實(shí)現(xiàn)與2.2.2 CCArray實(shí)現(xiàn)有很大不同,似乎是做了較大重構(gòu),暫不能確定是否是3.0rc2版本中CCArray實(shí)現(xiàn)的bug。
解決方法:由于后續(xù)的分享結(jié)果通知成功與否只需要根據(jù)分享的狀態(tài)來決定,因此我們只需解析出"status"、“action”和“platform” 這三個CCNumber類型字段的值即可。CCArray類型的對象我們并不需要,因此我們只需繞過對Array類型字段的解析和存儲即可,修改如下:
// Classes/C2DXShareSDK/Android/JSON/CCJSONConverter.cpp
void CCJSONConverter::convertJsonToDictionary(cJSON *json, CCDictionary *dictionary)
{
dictionary->removeAllObjects();
cJSON * j = json->child;
while (j) {
if (j->type == cJSON_Number) {
Ref * obj = getJsonObj(j);
dictionary->setObject(obj, j->string);
}
j = j->next;
}
}
四、其他
在使用ShareSDK做社交分享時(shí),注意下面兩個現(xiàn)象:
1) 第一次進(jìn)行微博或微信分享時(shí),會打開授權(quán)頁面,授權(quán)后才能分享成功;
2) 微信分享窗口只有在手機(jī)聯(lián)網(wǎng)狀態(tài)下才能打開。如果手機(jī)無法聯(lián)網(wǎng),那微信好友、朋友圈和收藏分享將無法打開分享窗口,也不會有什么提示。
- 在AndroidManifest.xml中uses-sdk內(nèi)屬性意思
- Android下如何使用百度地圖sdk
- ShareSDK造成App崩潰的一個BUG原因分析以及Fix方法
- 微信公眾平臺開發(fā)接口PHP SDK完整版
- android開發(fā)環(huán)境搭建詳解(eclipse + android sdk)
- Intellij IDEA + Android SDK + Genymotion Emulator打造最佳Android開發(fā)環(huán)境
- Android SDK三種更新失敗及其解決方法
- php實(shí)現(xiàn)基于微信公眾平臺開發(fā)SDK(demo)擴(kuò)展的方法
- Python Web框架Flask中使用七牛云存儲實(shí)例
- 通過Python來使用七牛云存儲的方法詳解
- 如何使用七牛Python SDK寫一個同步腳本及使用教程
相關(guān)文章
Android如何監(jiān)測文件夾內(nèi)容變化詳解
最近在開發(fā)android應(yīng)用程序的時(shí)候遇到了一個監(jiān)測文件夾的功能,所以下面這篇文章主要給大家介紹了關(guān)于Android如何監(jiān)測文件夾內(nèi)容變化的相關(guān)資料,需要的朋友可以參考下2021-12-12XRecyclerView實(shí)現(xiàn)下拉刷新、滾動到底部加載更多等功能
這篇文章主要為大家詳細(xì)介紹了XRecyclerView實(shí)現(xiàn)下拉刷新、滾動到底部加載更多等功能,以及添加header功能的RecyclerView,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08Android HelloChart開源庫圖表之折線圖的實(shí)例代碼
這篇文章主要介紹了Android HelloChart開源庫圖表之折線圖的實(shí)例代碼,具有很好的參考價(jià)值,希望對大家有所幫助,一起跟隨小編過來看看吧2018-05-05Android實(shí)現(xiàn)RecyclerView下拉刷新效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)RecyclerView下拉刷新效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07Android編程實(shí)現(xiàn)簡單設(shè)置按鈕顏色的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)簡單設(shè)置按鈕顏色的方法,涉及Android控件布局與屬性設(shè)置相關(guān)操作技巧,需要的朋友可以參考下2017-03-03解決Android加殼過程中mprotect調(diào)用失敗的原因分析
本文探討的主要內(nèi)容是mprotect調(diào)用失敗的根本原因,以及在加殼實(shí)現(xiàn)中的解決方案,通過本文的闡述,一方面能夠幫助遇到同類問題的小伙伴解決心中的疑惑,另一方面能夠給大家提供可落地的實(shí)現(xiàn)方案,需要的朋友可以參考下2022-01-01Android 創(chuàng)建/驗(yàn)證/刪除桌面快捷方式(已測試可用)
桌面快捷方式的出現(xiàn)方便了用戶操作,在某些程度上提高了用戶體驗(yàn),接下來將介紹下Android創(chuàng)建/驗(yàn)證/刪除桌面快捷方式的實(shí)現(xiàn)思路及代碼,感興趣的朋友可以了解下,或許本文可以幫助到你2013-02-02Android Loader的使用以及手機(jī)通訊錄的獲取方法
下面小編就為大家分享一篇Android Loader的使用以及手機(jī)通訊錄的獲取方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01