Unity3D研究院之在Unity中分享QQ空间(四十九)

转载:http://www.xuanyusong.com/archives/2159


最近研究了一下Android下 Unity分享 for QQ空间,作法类似以前我在博客中写过分享新浪微博的方法,也就是自己写插件。测试用的手机Google Nexus  ,Unity版本4.1,如下图所示,这是我发布成功后在QQ空间的截图。

屏幕快照 2013-03-24 下午8.56.16

 

 

 

写插件的方式我就不再说了,如果不懂的朋友看我之前的博客吧,写的很清楚。

QQ空间分享属于腾讯开放平台。然而腾讯开放平台的东西也比较多,移动平台包括:空间分享、说说分享、微薄分享。这一篇就说空间分享,如果空间分享搞定后可以按照同样的方式实现微薄分享。

先下载腾讯开放平台的API。

http://wiki.opensns.qq.com/wiki/%E3%80%90QQ%E7%99%BB%E5%BD%95%E3%80%91%E7%A7%BB%E5%8A%A8%E5%BA%94%E7%94%A8%E6%8E%A5%E5%85%A5

API我下载后里面有一个DEMO。我在MAC OS系统下Eclipse尽然不能运行,提示错误。后来我简单改了一下才可以运行,好蛋疼啊。

废话就不多说了,先来在Elipse下Android的插件。下段代码是Eclipse中的Android代码。

001package com.example.qqzone;
002 
003import java.io.BufferedInputStream;
004import java.io.BufferedOutputStream;
005import java.io.ByteArrayOutputStream;
006import java.io.IOException;
007import java.io.InputStream;
008import java.net.MalformedURLException;
009import java.net.SocketTimeoutException;
010import java.net.URL;
011import java.net.URLEncoder;
012import java.util.Date;
013 
014import org.apache.http.conn.ConnectTimeoutException;
015import org.json.JSONException;
016import org.json.JSONObject;
017 
018import android.app.Activity;
019import android.content.Context;
020import android.content.Intent;
021import android.content.SharedPreferences;
022import android.content.SharedPreferences.Editor;
023import android.graphics.Bitmap;
024import android.os.Bundle;
025import android.os.Environment;
026import android.util.Log;
027import android.view.Menu;
028import android.widget.Toast;
029 
030import com.tencent.open.HttpStatusException;
031import com.tencent.open.NetworkUnavailableException;
032import com.tencent.tauth.Constants;
033import com.tencent.tauth.IRequestListener;
034import com.tencent.tauth.IUiListener;
035import com.tencent.tauth.Tencent;
036import com.tencent.tauth.UiError;
037import com.unity3d.player.UnityPlayerActivity;
038 
039public class MainActivity extends UnityPlayerActivity {
040//   public class MainActivity extends Activity {
041 
042    public Tencent mTencent;
043    public SharedPreferences sharedPrefrences;
044    public Editor editor;
045    public Context context;
046    @Override
047    protected void onCreate(Bundle savedInstanceState) {
048        super.onCreate(savedInstanceState);
049 
050        sharedPrefrences = this.getSharedPreferences("info",
051                MODE_WORLD_READABLE);
052        editor = sharedPrefrences.edit();
053        context = this.getApplicationContext();
054 
055    }
056 
057    //这个方法是在Unity中调用的。参数是当前的Activity。
058    public void LoginAndSend(final Activity currentActivity)
059    {
060        //一定要在UI线程中来执行腾讯API中的方法。
061        //API中的方法应该是开启了一个线程,一切由Unity调用的方法里面只要开启线程就会出现
062        //Can’t create handler inside thread that has not called Looper.prepare() 错误
063        //写在runOnUiThread 的线程中可以避免这个错误没,以前在处理Unity发送新浪微博的时候也遇到这样的错误。
064        //同样可以按照这种方法来解决。
065 
066        currentActivity.runOnUiThread(new Runnable() {
067 
068            @Override
069            public void run() {
070 
071                //得到Tencent实例, 腾讯API的方法都写在这里类中。
072                //"222222"是APPID 这个是腾讯DEMO里带的, 你最好自己申请一个。
073                mTencent = Tencent.createInstance("222222",context
074                        );
075                //这里是处理Token的, 避免用户重复授权应用,每次登录成功后会获取一个新Token
076                //得到新Token后一定要保存在本地中。用上次保存的token就可以避免再次登录。
077                //Token的过期时间是3个月,3个月后需要重新登录。
078 
079                //登录后返回值
080                String openid = sharedPrefrences.getString("openid", null);
081                //登录后返回值
082                String access_token = sharedPrefrences.getString("access_token", null);
083                //过期时间
084                long expires_in = sharedPrefrences.getLong("expires_in", 0);
085 
086                if (openid != null && access_token != null && expires_in != 0)
087                {
088                    //如果以前保存过Token 这里直接使用上次保存的openid 和access_token
089                    //这里最好在判断一下token过期时间
090                    mTencent.setOpenId(openid);
091                    mTencent.setAccessToken(access_token, expires_in + "");
092                    //发送说说
093                    SendMessage();
094 
095                } else
096                {
097                    //如果之前没有保存过token信息,在这里让用户先登录
098                    if (!mTencent.isSessionValid()) {
099                        IUiListener listener = new IUiListener() {
100 
101                            @Override
102                            public void onError(UiError arg0) {
103                                Toast.makeText(getApplicationContext(), "登录错误",
104                                        Toast.LENGTH_SHORT).show();
105                            }
106 
107                            @Override
108                            public void onComplete(JSONObject arg0) {
109                                Log.v("登录成功", "登录成功");
110                                //发送信息
111                                SendMessage();
112 
113                                //登录成功后把token信息保存在本地中
114                                editor.putString("openid", mTencent.getOpenId());
115                                editor.putString("access_token",
116                                        mTencent.getAccessToken());
117                                //777600 表示token的过期时间。 它是以秒为单位的, 24(小时)*60(分钟)*60(秒) *90(天) = 777600(秒)
118                                //每次登录后需要获取现在时间 然后减去以前保存的
119                                //如果过期了 让用户重新登录
120                                editor.putLong("expires_in", 7776000);
121                                editor.commit();
122 
123                            }
124 
125                            @Override
126                            public void onCancel() {
127                                Log.v("登录取消", "登录取消");
128                            }
129                        };
130 
131                        mTencent.login(currentActivity, "all", listener);
132                    } else {
133                        mTencent.logout(context);
134                    }
135 
136                }
137 
138            }
139           });
140 
141    }
142 
143    private void SendMessage() {
144 
145        //下面这段代码基本上是API中的,我简单的改了一下。
146        if (mTencent.isSessionValid() && mTencent.getOpenId() != null) {
147 
148            Bundle parmas = new Bundle();
149            parmas.putString("title", "雨松MOMO程序研究院");// 必须。feeds的标题,最长36个中文字,超出部分会被截断。
150            parmas.putString(
151                    "url",
152                    "http://www.xuanyusong.com" + "#"
153                            + System.currentTimeMillis());// 必须。分享所在网页资源的链接,点击后跳转至第三方网页,
154            // 请以http://开头。
155            parmas.putString("comment", ("欢迎光临雨松MOMO程序研究院。" + new Date()));// 用户评论内容,也叫发表分享时的分享理由。禁止使用系统生产的语句进行代替。最长40个中文字,超出部分会被截断。
156            parmas.putString("summary", "在Unity3D中调用QQ空间分享接口,哇咔咔哇咔咔");// 所分享的网页资源的摘要内容,或者是网页的概要描述。
157            // 最长80个中文字,超出部分会被截断。
158            parmas.putString("images",
159                    "http://www.xuanyusong.com/wp-content/uploads/2012/04/0.jpg");// 所分享的网页资源的代表性图片链接",请以http://开头,长度限制255字符。多张图片以竖线(|)分隔,目前只有第一张图片有效,图片规格100*100为佳。
160            parmas.putString("type", "4");// 分享内容的类型。
161 
162            mTencent.requestAsync(Constants.GRAPH_ADD_SHARE, parmas,
163                    Constants.HTTP_POST, new BaseApiListener(), null);
164 
165        }
166    }
167 
168    //这个方法一定要加, 不然有错误、、
169    @Override
170    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
171        mTencent.onActivityResult(requestCode, resultCode, data);
172    }
173 
174    private class BaseApiListener implements IRequestListener {
175 
176        @Override
177        public void onComplete(final JSONObject response, Object state) {
178            doComplete(response, state);
179        }
180 
181        protected void doComplete(JSONObject response, Object state) {
182            Log.v("发送成功", "发送成功");
183        }
184 
185        @Override
186        public void onIOException(final IOException e, Object state) {
187            Log.v("发表错误", "onIOException");
188        }
189 
190        @Override
191        public void onMalformedURLException(final MalformedURLException e,
192                Object state) {
193            Log.v("发表错误", "onMalformedURLException");
194        }
195 
196        @Override
197        public void onJSONException(final JSONException e, Object state) {
198            Log.v("发表错误", "onJSONException");
199        }
200 
201        @Override
202        public void onConnectTimeoutException(ConnectTimeoutException arg0,
203                Object arg1) {
204            Log.v("发表错误", "onConnectTimeoutException");
205        }
206 
207        @Override
208        public void onSocketTimeoutException(SocketTimeoutException arg0,
209                Object arg1) {
210            Log.v("发表错误", "onSocketTimeoutException");
211        }
212 
213        @Override
214        public void onUnknowException(Exception arg0, Object arg1) {
215            Log.v("发表错误", "onUnknowException");
216        }
217 
218        @Override
219        public void onHttpStatusException(HttpStatusException arg0, Object arg1) {
220            Log.v("发表错误", "onHttpStatusException");
221        }
222 
223        @Override
224        public void onNetworkUnavailableException(
225                NetworkUnavailableException arg0, Object arg1) {
226            Log.v("发表错误", "onNetworkUnavailableException");
227        }
228    }
229 
230}

 

如果你不需要在U3d中分享说说?把上段代码简单的改一改吧。把登录放在Creat()方法中吧,会安卓的都知道嘿嘿。

然后在U3D中,绑定在任意对象中, 把Activity传递给Android插件中。

01using UnityEngine;
02using System.Collections;
03 
04public class NewBehaviourScript : MonoBehaviour
05{
06 
07    void OnGUI()
08    {
09 
10        if(GUILayout.Button(" Send QQ zone", GUILayout.Height(50)))
11        {
12 
13             AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
14 
15             using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"))
16             {
17                jo.Call("LoginAndSend",jo);
18 
19             }
20 
21        }
22 
23    }
24}

 下面是Andorid插件的路径,记住把open_Sdk放进去,这个是腾讯提供的第三方包。运行后点击按钮就可以登录与分享说说。

屏幕快照 2013-03-24 下午9.30.59

 

然后在Android手机上编译运行吧。

最后我在说说我使用QQ空间的感受。 空间分享包括2部分 分享链接 和分享说说,仔细查了一下才发现这两个东西差别挺大的。 文档上说这两个分享接口会被合并,最重要的是暂时不能分享本地图片、如果想分享本地图片有一个办法就是先调用上传图片的接口,把本地图片上传至QQ相册中,然后拿到URL后分享。总体来说希望企鹅的文档以后能写的在清楚一点,我是“连蒙带猜” 哎~

本文的源码下载,包括Android工程和U3D工程。

http://vdisk.weibo.com/s/uW42H


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值