用3.0实现飞机大战——接入微信分享

本篇博客继续接入第三方SDK——接入微信分享。在接入微信分享之前,我们完善一下上篇博客的广告问题,当我从分数榜场景退出到开始场景的时候迷你广告还在上边,如果用户再进入一个关于作者的场景再玩游戏,上下俩个地方都会出现广告,也就是说广告在退出场景的时候并没有消失,我们需要做的就是解决这个问题。其实接入第三方SDK的原理很简单,以Android为例,在java层写接入代码,实现接入的逻辑,同时留下给c++层调用的接口,c++层通过jni来调用Android层的代码,整个接入SDK的逻辑就是这样。所以为了让广告消失,我们需要在Android层实现具体的逻辑,留下给c++层调用的接口,c++层必要的时候进行调用。

Android的具体实现逻辑如下,主要修改的是内部类AdHandler。

1 class AdHandler extends Handler{
2         //保存俩个layout,广告卸载的时候用
3         private LinearLayout adBannerLayout=null;
4         private LinearLayout adMiniLayout=null;
5  
6         public void handleMessage(Message msg) {
7             switch (msg.what){
8             case 0:
9                 // 显示推荐列表(综合)
10                 AppConnect.getInstance(mContext).showOffers(mContext);
11                 break;
12             case 1:
13                 // 显示插屏广告
14                 // 判断插屏广告是否已初始化完成,用于确定是否能成功调用插屏广告
15                 boolean hasPopAd = AppConnect.getInstance(mContext).hasPopAd(mContext);
16                 if (hasPopAd) {
17                     AppConnect.getInstance(mContext).showPopAd(mContext);
18                 }
19                 break;
20             case 2:
21                 // 显示推荐列表(软件)
22                 AppConnect.getInstance(mContext).showAppOffers(mContext);
23                 break;
24             case 3:
25                 // 显示推荐列表(游戏)
26                 AppConnect.getInstance(mContext).showGameOffers(mContext);
27                 break;
28             case 4:
29                 // 获取全部自定义广告数据
30                 break;
31             case 5:
32                 // 获取一条自定义广告数据
33                 AdInfo adInfo = AppConnect.getInstance(mContext).getAdInfo();
34                 AppDetail.getInstanct().showAdDetail(mContext, adInfo); break;
35             case 6:
36                 // 消费虚拟货币.
37                 AppConnect.getInstance(mContext).spendPoints(10,AppActivity.this);
38                 break;
39             case 7:
40                 // 奖励虚拟货币
41                 AppConnect.getInstance(mContext).awardPoints(10,AppActivity.this);
42                 break;
43             case 8:
44                 // 显示自家应用列表
45                 AppConnect.getInstance(mContext).showMore(mContext);
46                 break;
47             case 9:
48                 // 根据指定的应用app_id展示其详情
49                 AppConnect.getInstance(mContext).showMore(mContext,app_id);
50                 break;
51             case 10:
52                 // 调用功能广告接口(使用浏览器接口)
53                 String uriStr = "http://www.baidu.com"; AppConnect.getInstance(mContext).showBrowser(mContext,uriStr);
54                 break;
55             case 11:
56                 // 用户反馈
57                 AppConnect.getInstance(mContext).showFeedback(mContext);
58                 break;
59             case 12:
60                 // 退屏广告
61                 QuitPopAd.getInstance().show(mContext);
62                 break;
63             case 13:
64                 // banner
65                 AppConnect.getInstance(mContext).showBannerAd(mContext,getBannerAd());
66                 break;
67             case 14:
68                 // 迷你广告
69                 AppConnect.getInstance(mContext).showMiniAd(mContext,getMiniAd(), 10);
70                 break;
71             default:
72                 this.uninstallAd(msg.what-100);
73                 break;
74             }
75         }
76  
77         //添加互动广告
78         private LinearLayout getBannerAd(){
79             // 互动广告
80             adBannerLayout = new LinearLayout(mContext);
81             adBannerLayout.setOrientation(LinearLayout.VERTICAL);
82             FrameLayout.LayoutParams lp_banner = new FrameLayout.LayoutParams(
83             FrameLayout.LayoutParams.FILL_PARENT,
84             FrameLayout.LayoutParams.WRAP_CONTENT);
85             // 设置adBannerLayout的悬浮位置,具体的位置开发者根据需要设置
86             lp_banner.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
87             AppActivity.this.addContentView(adBannerLayout, lp_banner);
88  
89             LinearLayout bannerLayout = new LinearLayout(mContext);
90             adBannerLayout.addView(bannerLayout);
91  
92             return bannerLayout;
93         }
94  
95         //添加迷你广告
96         private LinearLayout getMiniAd(){
97             adMiniLayout = new LinearLayout(mContext);
98             adMiniLayout.setOrientation(LinearLayout.VERTICAL);
99             FrameLayout.LayoutParams lp_mini = new FrameLayout.LayoutParams(
100             FrameLayout.LayoutParams.FILL_PARENT,
101             FrameLayout.LayoutParams.WRAP_CONTENT);
102             // 设置adMiniLayout的悬浮位置,具体的位置开发者根据需要设置
103             lp_mini.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
104             AppActivity.this.addContentView(adMiniLayout, lp_mini);
105             LinearLayout miniLayout = new LinearLayout(mContext);
106             adMiniLayout.addView(miniLayout);
107  
108             return miniLayout;
109         }
110  
111         //在创建的广告的线程中卸载广告
112         public void uninstallAd(int adTag){
113             if(adTag == 13){
114                 adBannerLayout.setVisibility(View.INVISIBLE);
115             }
116             else if(adTag == 14){
117                 adMiniLayout.setVisibility(View.INVISIBLE);
118             }
119         }

留给c++层调用的接口如下:

1 //根据传入的id,卸载广告
2     public static void uninstallAd(int adTag){
3         Message msg = handler.obtainMessage();
4         // 私有静态的整型变量,开发者请自行定义值
5         msg.what = adTag+100;
6         handler.sendMessage(msg);
7     }

c++层使用jni来调用这个接口,代码如下:

1 void WapsAd::uninstallAd(int adTag)
2 {
3 #if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
4     JniMethodInfo minfo;
5     bool isHave = JniHelper::getStaticMethodInfo(minfo,"org/cocos2dx/cpp/AppActivity","uninstallAd""(I)V");
6     if(!isHave)
7     {
8         CCLog("jni:showAdStatic is null");
9     }
10     else
11     {
12         //调用此函数
13         minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID,adTag);
14     }
15 #endif
16 }

这样的话整个广告的代码就完善了,接下来接入微信SDK。

1、首先是准备工作,到官网上注册账号,下载SDK,将下载的jar包放到项目的libs目录下,主要步骤的截图如下。现在如果注册的是游戏会让你到腾讯开放平台注册,还要注册提交审核,我的第一次提交就失败了,所以我把描述信息给改了,让他看不出我是游戏还是应用,为了让你的应用在使用分享功能的时候是正常的,第一注意包名,就是你要上线游戏的包名,还有一个是应用签名,你需要下载微信获取签名的一个工具,使用这个工具来获取你安装包的签名,所以打包的时候就打一个release包吧,安装到手机上,然后使用微信提供的工具去获取签名,工具的下载地址。然后就等待审核了,工作日的话半天就OK了,不是很严格。

用3.0实现飞机大战——接入微信分享用3.0实现飞机大战——接入微信分享用3.0实现飞机大战——接入微信分享用3.0实现飞机大战——接入微信分享用3.0实现飞机大战——接入微信分享

2、接下来我们使用刚才上边提到的思路来写代码,先完成java层的代码,将接口函数留给c++层调用。注意APP_ID是从微信后台获取的,然后在onCreate函数中初始化一下连接微信的代码。

1 //微信SDK
2     private static final String APP_ID = "wx42ca6be8e52eebfb";
3     private static IWXAPI api;
4     private static AppActivity instance;
5  
6     protected void onCreate(Bundle savedInstanceState) {
7         //先调用父类的onCreate方法
8         super.onCreate(savedInstanceState);
9  
10         //给成员变量赋值
11         mContext = this;
12         handler = new AdHandler();
13         instance = this;
14  
15         initAds();
16         regToWX();
17     }
18  
19     //初始化微信
20     private void regToWX(){
21         api = WXAPIFactory.createWXAPI(this, APP_ID, true);
22         api.registerApp(APP_ID);
23     }

3、下面把接口留给c++层调用。调用微信API代码的逻辑是首先生成需要发送的消息对象,然后将消息对象附加到媒体对象中,接着建立请求对象,最后使用通信类发送即可。代码中还用到一个Util类,这个类我们需要在包下新建一个,代码是参考别人的,大家就当工具来用就可以了。消息对象有很多种,包括文本,音乐,视频等等,我们需要根据自己的需要创建不同的消息对象,这些消息对象的类名可以参考官方的文档。

1 public static void sendMsgToFriend(){
2     if(api.openWXApp())
3     {
4             //初始化一个对象WebpageObject
5         WXTextObject textObject = new WXTextObject();
6         textObject.text = "小塔博客写的Plane教程,最后游戏Demo完成,博客地址http://www.zaojiahua.com/tag/3-0%E9%A3%9E%E6%9C%BA%E5%A4%A7%E6%88%98!";
7  
8         //媒体对象中
9         WXMediaMessage msg = new WXMediaMessage(textObject);
10         msg.title = "飞机大战";
11         msg.description = "分享给你的好友,让更多的人来玩!";
12  
13         //建立请求对象
14         SendMessageToWX.Req req = new SendMessageToWX.Req();
15         //transaction是用来表示一个请求的唯一标示符
16         req.transaction = buildTransaction("textObject");
17         req.message = msg;
18         req.scene = SendMessageToWX.Req.WXSceneSession;
19  
20         //使用通信类发送
21         api.sendReq(req);
22     }
23     else
24     {
25          Toast.makeText(instance, "启动微信失败!", Toast.LENGTH_SHORT).show();
26     }
27 }
28  
29 public static void sendMsgToTimeLine(){
30     if(api.openWXApp())
31     {
32         if(api.getWXAppSupportAPI() >= 0x21020001)
33         {
34             WXWebpageObject webpage = new WXWebpageObject();
35             webpage.webpageUrl = "http://m.baidu.com/app?action==content&docid=6561264&f=s1001";
36  
37             WXMediaMessage msg = new WXMediaMessage(webpage);
38             msg.title = "飞机大战";
39             msg.description = "分享到我的朋友圈,让更多的人来玩!";
40  
41             Bitmap thumb = BitmapFactory.decodeResource(instance.getResources(), com.zaojiahua.plane.R.drawable.icon);
42             msg.thumbData = Util.bmpToByteArray(thumb, true);
43  
44             SendMessageToWX.Req req = new SendMessageToWX.Req();
45             req.transaction = buildTransaction("webpage");
46             req.message = msg;
47             req.scene = SendMessageToWX.Req.WXSceneTimeline;
48             api.sendReq(req);
49         }
50         else{
51             Toast.makeText(instance, "微信版本过低", Toast.LENGTH_SHORT).show();
52         }
53     }
54     else
55     {
56          Toast.makeText(instance, "启动微信失败", Toast.LENGTH_SHORT).show();
57     }
58 }
59 private static String buildTransaction(final String type) {
60     return (type == null) ? String.valueOf(System.currentTimeMillis()) : type + System.currentTimeMillis();
61 }

用3.0实现飞机大战——接入微信分享

1 package org.cocos2dx.cpp;
2  
3 import java.io.ByteArrayOutputStream;
4 import java.io.File;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.RandomAccessFile;
8 import java.net.HttpURLConnection;
9 import java.net.MalformedURLException;
10 import java.net.URL;
11 import java.net.URLConnection;
12  
13 import junit.framework.Assert;
14  
15 import android.graphics.Bitmap;
16 import android.graphics.BitmapFactory;
17 import android.graphics.Bitmap.CompressFormat;
18 import android.util.Log;
19  
20 public class Util {
21  
22     private static final String TAG = "SDK_Sample.Util";
23  
24     public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
25         ByteArrayOutputStream output = new ByteArrayOutputStream();
26         bmp.compress(CompressFormat.PNG, 100, output);
27         if (needRecycle) {
28             bmp.recycle();
29         }
30  
31         byte[] result = output.toByteArray();
32         try {
33             output.close();
34         catch (Exception e) {
35             e.printStackTrace();
36         }
37  
38         return result;
39     }
40  
41     public static byte[] getHtmlByteArray(final String url) {
42          URL htmlUrl = null;
43          InputStream inStream = null;
44          try {
45              htmlUrl = new URL(url);
46              URLConnection connection = htmlUrl.openConnection();
47              HttpURLConnection httpConnection = (HttpURLConnection)connection;
48              int responseCode = httpConnection.getResponseCode();
49              if(responseCode == HttpURLConnection.HTTP_OK){
50                  inStream = httpConnection.getInputStream();
51               }
52              catch (MalformedURLException e) {
53                  e.printStackTrace();
54              catch (IOException e) {
55                 e.printStackTrace();
56           }
57         byte[] data = inputStreamToByte(inStream);
58  
59         return data;
60     }
61  
62     public static byte[] inputStreamToByte(InputStream is) {
63         try{
64             ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
65             int ch;
66             while ((ch = is.read()) != -1) {
67                 bytestream.write(ch);
68             }
69             byte imgdata[] = bytestream.toByteArray();
70             bytestream.close();
71             return imgdata;
72         }catch(Exception e){
73             e.printStackTrace();
74         }
75  
76         return null;
77     }
78  
79     public static byte[] readFromFile(String fileName, int offset, int len) {
80         if (fileName == null) {
81             return null;
82         }
83  
84         File file = new File(fileName);
85         if (!file.exists()) {
86             Log.i(TAG, "readFromFile: file not found");
87             return null;
88         }
89  
90         if (len == -1) {
91             len = (int) file.length();
92         }
93  
94         Log.d(TAG, "readFromFile : offset = " + offset + " len = " + len + " offset + len = " + (offset + len));
95  
96         if(offset <0){
97             Log.e(TAG, "readFromFile invalid offset:" + offset);
98             return null;
99         }
100         if(len <=0 ){
101             Log.e(TAG, "readFromFile invalid len:" + len);
102             return null;
103         }
104         if(offset + len > (int) file.length()){
105             Log.e(TAG, "readFromFile invalid file len:" + file.length());
106             return null;
107         }
108  
109         byte[] b = null;
110         try {
111             RandomAccessFile in = new RandomAccessFile(fileName, "r");
112             b = new byte[len];
113             in.seek(offset);
114             in.readFully(b);
115             in.close();
116  
117         catch (Exception e) {
118             Log.e(TAG, "readFromFile : errMsg = " + e.getMessage());
119             e.printStackTrace();
120         }
121         return b;
122     }
123  
124     private static final int MAX_DECODE_PICTURE_SIZE = 1920 1440;
125     public static Bitmap extractThumbNail(final String path, final int height, final int width, final boolean crop) {
126         Assert.assertTrue(path != null && !path.equals("") && height > 0 && width > 0);
127  
128         BitmapFactory.Options options = new BitmapFactory.Options();
129  
130         try {
131             options.inJustDecodeBounds = true;
132             Bitmap tmp = BitmapFactory.decodeFile(path, options);
133             if (tmp != null) {
134                 tmp.recycle();
135                 tmp = null;
136             }
137  
138             Log.d(TAG, "extractThumbNail: round=" + width + "x" + height + ", crop=" + crop);
139             final double beY = options.outHeight * 1.0 / height;
140             final double beX = options.outWidth * 1.0 / width;
141             Log.d(TAG, "extractThumbNail: extract beX = " + beX + ", beY = " + beY);
142             options.inSampleSize = (int) (crop ? (beY > beX ? beX : beY) : (beY < beX ? beX : beY));
143             if (options.inSampleSize <= 1) {
144                 options.inSampleSize = 1;
145             }
146  
147             // NOTE: out of memory error
148             while (options.outHeight * options.outWidth / options.inSampleSize > MAX_DECODE_PICTURE_SIZE) {
149                 options.inSampleSize++;
150             }
151  
152             int newHeight = height;
153             int newWidth = width;
154             if (crop) {
155                 if (beY > beX) {
156                     newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth);
157                 else {
158                     newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight);
159                 }
160             else {
161                 if (beY < beX) {
162                     newHeight = (int) (newWidth * 1.0 * options.outHeight / options.outWidth);
163                 else {
164                     newWidth = (int) (newHeight * 1.0 * options.outWidth / options.outHeight);
165                 }
166             }
167  
168             options.inJustDecodeBounds = false;
169  
170             Log.i(TAG, "bitmap required size=" + newWidth + "x" + newHeight + ", orig=" + options.outWidth + "x" + options.outHeight + ", sample=" + options.inSampleSize);
171             Bitmap bm = BitmapFactory.decodeFile(path, options);
172             if (bm == null) {
173                 Log.e(TAG, "bitmap decode failed");
174                 return null;
175             }
176  
177             Log.i(TAG, "bitmap decoded size=" + bm.getWidth() + "x" + bm.getHeight());
178             final Bitmap scale = Bitmap.createScaledBitmap(bm, newWidth, newHeight, true);
179             if (scale != null) {
180                 bm.recycle();
181                 bm = scale;
182             }
183  
184             if (crop) {
185                 final Bitmap cropped = Bitmap.createBitmap(bm, (bm.getWidth() - width) >>1, (bm.getHeight() - height) >> 1, width, height);
186                 if (cropped == null) {
187                     return bm;
188                 }
189  
190                 bm.recycle();
191                 bm = cropped;
192                 Log.i(TAG, "bitmap croped size=" + bm.getWidth() + "x" + bm.getHeight());
193             }
194             return bm;
195  
196         catch (final OutOfMemoryError e) {
197             Log.e(TAG, "decode bitmap failed: " + e.getMessage());
198             options = null;
199         }
200  
201         return null;
202     }
203 }

4、下面来写c++层的代码,大家可以参考上篇博客介绍的jni调用来完成微信分享接口的调用,我新建了一个WeixinShare类,专门来进行分享,代码如下。

1 #include "WapsAd.h"
2  
3 WapsAd::WapsAd(){}
4  
5 WapsAd::~WapsAd(){}
6  
7 void WapsAd::showAd(int adTag)
8 {
9  
10     //判断当前是否为Android平台 JniMethodInfo showAd;
11 #if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
12     JniMethodInfo minfo;
13     bool isHave = JniHelper::getStaticMethodInfo(minfo,"org/cocos2dx/cpp/AppActivity","showAdStatic""(I)V");
14     if(!isHave)
15     {
16         CCLog("jni:showAdStatic is null");
17     }
18     else
19     {
20         //调用此函数
21         minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID,adTag);
22     }
23 #endif
24 }
25  
26 void WapsAd::uninstallAd(int adTag)
27 {
28 #if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
29     JniMethodInfo minfo;
30     bool isHave = JniHelper::getStaticMethodInfo(minfo,"org/cocos2dx/cpp/AppActivity","uninstallAd""(I)V");
31     if(!isHave)
32     {
33         CCLog("jni:showAdStatic is null");
34     }
35     else
36     {
37         //调用此函数
38         minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID,adTag);
39     }
40 #endif
41 }

最后在合适的地方调用我们的分享接口就好了,这样的话整个Demo就完成的差不多了,下一步我们要做的就是上各个应用平台了,期待好运吧!

用3.0实现飞机大战——接入微信分享用3.0实现飞机大战——接入微信分享用3.0实现飞机大战——接入微信分享用3.0实现飞机大战——接入微信分享用3.0实现飞机大战——接入微信分享用3.0实现飞机大战——接入微信分享

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值