【IOS和Android】Cocos2d-x 集成Facebook分享功能

(二)集成Facebook分享:


1、先到Facebook官网下载最先的IOS和Android的SDK:【IOS】Facebook开放SDK 和【Android】Facebook开放SDK


2、环境配置:

官网详细的配置说明:【IOS】xcdoe上的详细环境配置说明和 【Android】Eclipse上的详细环境配置

最新和详细的配置说明可以参考上面两个链接,考虑到要需要翻墙才能访问facebook的网站,这里就简单扼要的分别说明一下IOS和Android两台平台的环境配置。

本文所用的版本说明:IOS版和Android版SDK版本都为:V3.20.0。

这里说明一下:在Mac下面从Facebook官网下载下来的SDK是一个安装包,安装好的SDK默认放到了系统路径:/Users/log/Documents/FacebookSDK。


【IOS环境配置】

注意:IOS版本的Facebook SDK v3.17+版本支持IOS 6.x和更高版本的苹果设备;v3.17之前的SDK只支持IOS 5.x。


步骤1:登录Facebook开发者后台(Facebook开发者后台链接),新建一个Facebook App。

填写好应用显示名称、命名空间以及类别之后,点击了上面的“Create App”按钮之后,Facebook App的app ID就会显示在控制面板的顶部。如下图:

注意:IOS平台和Android平台都是共用同一个App ID。

接着,你需要为新建的app设置:Bundle Identifier和配置你的Facebook应用,具体如下:

选择页面左边导航栏上的“Settings”(可参考上图),然后单击“Add Platform”,然后选择“IOS”。接着填写以下信息:

Bundle ID:其实就是应用的包名,对应于Xcdoe里面的“Bundle Identifier”。

iPhone Store ID:就是你的应用在App store上面的游戏或应用ID(具体可以登录到IOS开发者后台,选择具体的游戏或应用详情页面的网页链接后面的那一串数字)

iPad Strore ID:如果你的游戏或者应用支持iPad,那么这个ID跟iPhone Strore ID是一样的。

然后激活:“Single Sign On”和“Deep Linking”这两个选项。


步骤2:配置Xcode工程

把下载好的FacebookSDK.framework文件拖拽到工程目录的framework下面去,然后确保把这个文件复制一份到了工程的相应目录下就可以了。

接着配置ios目录下的Info.plist文件:

1)添加一个项:FacebookAppID,Type为:String,Value为:【Facebook应用的App ID】

2)添加一个项:FacebookDisplayName,Type为:String,Value为:【新增Facebook应用时对应的显示名称】

3)在“URL types”项下添加一项,然后在添加的项上面的“URL Schemes”添加一个子项,把该值设置成:【fb+app ID】,比如我的facebook的app ID为123456,那么这里就应该设置为:fb123456。具体看下图:




【Android环境配置】

步骤1:

回到Facebook刚才新建的那个Facebook应用的详情页面上,点击左边导航栏的“Settings”,点击下面的“Add Platform”,然后添加“Android”,填写下面的信息:

Package Name:游戏包名

Class Name:启动的Activity的完整类名,也就是最先启动的Activity。

Key Hashes:签名的Hash值(后面会说怎么获取)


步骤2:

1)首先解压下载下来的压缩包

2)把解压后的目录下的:facebook目录拷贝到一个安全地方去,因为这个就是Facebook的工程也就是library project。

3)在Eclipse导入FacebookSDK这个库工程,然后在你要使用Facebook分享功能的Android工程里面添加这个库工程。


步骤3:

在你的游戏里面调用这个函数:

/**
	 * 获取签名Key的hash值(facebook后台需要添加这个,如果这个值跟后台的对不上,那么会分享失败,提示Key Hash值不对)
	 */
	public static void getKeyHash(){
		if(mActivity == null) return;
		// Add code to print out the key hash
	    try {
	        PackageInfo info = mActivity.getPackageManager().getPackageInfo(
	                "com.sharetest.test", //替换成你游戏的包名
	                PackageManager.GET_SIGNATURES);
	        for (Signature signature : info.signatures) {
	            MessageDigest md = MessageDigest.getInstance("SHA");
	            md.update(signature.toByteArray());
	            Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
	            }
	    } catch (Exception e) {
	    	
	    }
	}


用你发布的签名key把你的游戏打包成apk,然后安装到手机上,查看日志“KeyHash:”,拿到一串字符串,把它粘贴到【步骤1】中的“Key Hashes”项中。注意:打包后的apk的签名必须跟拿这个值的时候的签名一致,不然即使成功调用了Facebook的分享对话框出来,但是最后分享的时候,会提示:key hash不一致的错误,从而导致分享失败。

4)在工程values目录下面的strings.xml文件里面添加一项:

    <!-- Facebook应用ID -->
    <string name="app_id">1234567890</string>
就是设置Facebook的app ID。


5)如果有做代码混淆处理的话,为了保障起见,请在文件proguard-project.txt里面添加下面一段代码:

-keep class com.facebook.** { *; }
-keepattributes Signature


3、接口定义和实现

SocialUtils.h头文件,Android和IOS的公共接口头文件。

// 一定要先引入"cocos2d.h"头文件,不然会包找不到<jni.h>
#include "cocos2d.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#include <android/log.h>
#endif

// 一定要加上这个命名空间不然在Android工程里编译的时候会编译不通过,
// 因为像JniMethodInfo、JniHelper这些类是在cocos2d这个命名空间里
USING_NS_CC;

class SocialUtils {
    
public:
    static void registerWeixin(char* appID); // 注册微信
    static void shareToWeixin();// 分享内容到微信
    static void shareToFacebook();// 分享内容到Facebook
    static void destroy();// 释放资源
    
public:
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) // 判断如果是Android系统才会有这几个方法
    // Android
    static void registerWeixinForAndroid(char* appID);
    static void shareToWeixinForAndroid();
    static void shareToFacebookForAndroid();
    static void destroyForAndroid();
#endif
    
#if(CC_TARGET_PLATFORM == CC_PLATFORM_IOS)// 判断如果是IOS系统才会有这几个方法

    // IOS
    static void registerWeixinForIOS(char* appID);
    static void shareToWeixinForIOS();
    static void shareToFacebookforIOS();
    static void destroyForIOS();
    
public:
    static void setUIViewController(void* viewController);
    
#endif
};

这个头文件是为了兼顾微信分享功能的,所以我们只需要关注以下这个几个函数就可以了,分别是:shareToFacebok()、shareToFacebokForAndroid()、 shareToFacebokForIOS()。

具体为什么我要这样定义接口,可以参考我上一篇的文章:【IOS和Android】Cocos2d-x 集成微信分享功能,这里就不重复说明了。

首先是公共接口以及Android接口的实现,在xcdoe打开SocialUtils.cpp,写上如下代码:

void SocialUtils::shareToFacebook(){
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    // Android
    SocialUtils::shareToFacebookForAndroid();
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    // IOS
    SocialUtils::shareToFacebookforIOS();
#endif
}

// ============================【微信】Android通过Jni调用java层接口============================
// 说明:其中的Utils::getAndroidPackageInfo()返回的是java完整的类包名。具体涉及到Jni的知识,同学们可以参考:http://blog.csdn.net/lognic10/article/details/22269537 学习一下。

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
// ============================【Facebook】Android通过Jni调用java层接口============================
void SocialUtils::shareToFacebookForAndroid(){
    JniMethodInfo jmi;
    bool ishave = JniHelper::getStaticMethodInfo(jmi,Utils::getAndroidPackageInfo(),"shareToFacebook","()V");
    
    if(ishave){
        jmi.env->CallStaticVoidMethod(jmi.classID,jmi.methodID);
    }
}
#endif

上面Android接口实现其实只是利用了Cocos2d-x为我们提供的方便的Jni接口调用了Android本地的java方法,具体的java方法代码如下:

// ===========================分享功能======================================
	// 分别是分享需要的内容:应用名字、标题、描述、图片链接地址、应用链接地址。
	private static final String SHARE_APP_NAME = mActivity.getString(R.string.app_name);
	private static final String SHARE_CAPTION = mActivity.getString(R.string.share_caption);
	private static final String SHARE_DESCRIPTION = mActivity.getString(R.string.share_description);
	private static final String SHARE_PICTURE_URL = "";
	private static final String SHARE_LINK = "http://www.baidu.com";
	
	
	/**
	 * 分享到Facebook
	 * */
	public static void shareToFacebook() {
		if (mActivity == null) {
			return;
		}
		
		// 先判断设备上是否已经安装了Facebook客户端。如果有就直接弹出Share Dialog;如果没有就调用Feed Dialog		
		if (FacebookDialog.canPresentShareDialog(mActivity, FacebookDialog.ShareDialogFeature.SHARE_DIALOG)) {
			// Publish the post using the Share Dialog
			FacebookDialog shareDialog = new FacebookDialog.ShareDialogBuilder(mActivity)
						.setLink(SHARE_LINK) //设置分享链接
						.setCaption(SHARE_CAPTION) 				 // 设置分享标题
						.setDescription(SHARE_DESCRIPTION)				// 设置描述
						.setPicture(SHARE_PICTURE_URL)					// 设置缩略图
						.build();
			// 追踪分享的回调函数,返回相应的结果以便于针对不同的情况进行处理
//			uiHelper.trackPendingDialogCall(shareDialog.present());
			shareDialog.present();
		} else {
			// Fallback. For example, publish the post using the Feed Dialog
			publishFeedDialog();
		}
	}
	
	// 显示Feed Dialog
	private static void publishFeedDialog() {
		if (mActivity == null) {
			return;
		}
	    Bundle params = new Bundle();
	    params.putString("name", SHARE_APP_NAME);
	    params.putString("caption", SHARE_CAPTION);
	    params.putString("description", SHARE_DESCRIPTION);
	    params.putString("link", SHARE_LINK);
	    params.putString("picture", SHARE_PICTURE_URL);

	    WebDialog feedDialog = (
	        new WebDialog.FeedDialogBuilder(mActivity,
	            Session.getActiveSession(),params)).setOnCompleteListener(new WebDialog.OnCompleteListener() {

	            @Override
	            public void onComplete(Bundle values,
	                FacebookException error) {
	                if (error == null) {
	                    // When the story is posted, echo the success
	                    // and the post Id.
	                    final String postId = values.getString("post_id");
	                    if (postId != null) {
	                        Toast.makeText(mActivity,
	                            "Posted story, id: "+postId,
	                            Toast.LENGTH_SHORT).show();
	                    } else {
	                        // User clicked the Cancel button
	                        Toast.makeText(mActivity.getApplicationContext(), 
	                            "Publish cancelled", 
	                            Toast.LENGTH_SHORT).show();
	                    }
	                } else if (error instanceof FacebookOperationCanceledException) {
	                    // User clicked the "x" button
	                    Toast.makeText(mActivity.getApplicationContext(), 
	                        "Publish cancelled", 
	                        Toast.LENGTH_SHORT).show();
	                } else {
	                    // Generic, ex: network error
	                    Toast.makeText(mActivity.getApplicationContext(), 
	                        "Error posting story", 
	                        Toast.LENGTH_SHORT).show();
	                }
	            }

	        })
	        .build();
	    feedDialog.show();
	}

这里说明一下:Facebook的缩略图片只支持http或https的链接地址,没找到直接读取本地图片的方法。分享链接也是只支持http或者https。还有如果手机上没安装Facebook的Android客户端,那么会直接跳转到网页的方式登陆授权,然后就可以进行分享了。

至此Andrond端的Facebook分享功能就完成了!

接着就是IOS端的实现了,到xcode对应的工程里面的ios目录下新建一个SocialUtils_ios.mm文件,然后写上以下代码:

#include "SocialUtils.h"
#import <FacebookSDK/FacebookSDK.h>

static UIViewController* m_viewController;

// 分享的内容,包括:应用名、标题、描述、链接
static NSString* SHARE_APP_NAME;
static NSString* SHARE_CAPTION;
static NSString* SHARE_DESCRIPTION;
static NSString* SHARE_LINK = @"http://www.baidu.com";

void SocialUtils::setUIViewController(void* viewController){
    m_viewController = (UIViewController*)viewController;
}

// 注册Facebook
void SocialUtils::shareToFacebookforIOS(){
    // 设置分享内容
    setShareContent();
    
    // Check if the Facebook app is installed and we can present the share dialog
    FBLinkShareParams *params = [[FBLinkShareParams alloc] init];
    params.link = [NSURL URLWithString:SHARE_LINK];

    // If the Facebook app is installed and we can present the share dialog
    if ([FBDialogs canPresentShareDialogWithParams:params]) {
        
        // Present share dialog
        [FBDialogs presentShareDialogWithLink:params.link
                                         name:SHARE_APP_NAME
                                      caption:SHARE_CAPTION
                                  description:SHARE_DESCRIPTION
                                      picture:nil
                                  clientState:nil
                                      handler:^(FBAppCall *call, NSDictionary *results, NSError *error) {
                                          if(error) {
                                              // An error occurred, we need to handle the error
                                              // See: https://developers.facebook.com/docs/ios/errors
                                              NSLog(@"Error publishing story: %@", error.description);
                                          } else {
                                              // Success
                                              NSLog(@"result %@", results);
                                          }
                                      }];
        
        // If the Facebook app is NOT installed and we can't present the share dialog
    } else {
        // FALLBACK: publish just a link using the Feed dialog
        
        // Put together the dialog parameters
        NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                       SHARE_APP_NAME, @"name",
                                       SHARE_CAPTION, @"caption",
                                       SHARE_DESCRIPTION, @"description",
                                       SHARE_LINK, @"link",
                                       nil, @"picture",
                                       nil];
        
        // Show the feed dialog
        [FBWebDialogs presentFeedDialogModallyWithSession:nil
                                               parameters:params
                                                  handler:^(FBWebDialogResult result, NSURL *resultURL, NSError *error) {
                                                      if (error) {
                                                          // An error occurred, we need to handle the error
                                                          // See: https://developers.facebook.com/docs/ios/errors
                                                          NSLog(@"Error publishing story: %@", error.description);
                                                      } else {
                                                          if (result == FBWebDialogResultDialogNotCompleted) {
                                                              // User canceled.
                                                              NSLog(@"User cancelled.");
                                                          } else {
                                                              // Handle the publish feed callback
                                                              NSDictionary *urlParams = [m_viewController parseURLParams:[resultURL query]];
                                                              
                                                              if (![urlParams valueForKey:@"post_id"]) {
                                                                  // User canceled.
                                                                  NSLog(@"User cancelled.");
                                                                  
                                                              } else {
                                                                  // User clicked the Share button
                                                                  NSString *result = [NSString stringWithFormat: @"Posted story, id: %@", [urlParams valueForKey:@"post_id"]];
                                                                  NSLog(@"result %@", result);
                                                              }
                                                          }
                                                      }
                                                  }];
    }

}


同样如果IOS设备上没安装Facebook的客户端,那么会自动跳转到Facebook网页上去登陆授权后,就可以分享内容了。至此IOS端的实现也完成了!

上面有个接口是:setUIViewController(void* viewController),先说明一下为什么会这样定义呢?因为前面都说过了,Android和IOS都是公用一个头文件,SocialUtils.h这个文件是定义在C++环境下的,但是这个参数真正传递的是IOS的组件类:
UIViewController,如果直接是传UIViewController这个类型的参数的话,编译器会报错的。所以就用了void*,因为void*代表任何的类型,跟obejct-c的id关键字有点类似。

再说说为什么要有这个接口吧,因为Facebook开发接口需要用到UIViewController这个作为一个载体,有点类似于Android中的Activity的一个上下文吧(个人理解),所以需要这个接口。


下面来看看如何在Cocos2d-x调用Facebook分享功能:
在文件:AppController.mm中的didFinishLaunchingWithOpthons消息中(也就是函数,obejct-c叫消息),调用:

SocialUtils::setUIViewController(viewController);

然后,你就可以在程序需要调用Facebook分享功能的地方调用:

SocialUtils::shareToFacebook();
就可以了。




转载请标明出处:http://blog.csdn.net/lognic10/article/details/40741551

关于微信分享功能的集成可以参考上一篇:【IOS和Android】Cocos2d-x 集成微信分享功能



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值