最近研究了一下Android下 Unity分享 for QQ空间,作法类似以前我在博客中写过分享新浪微博的方法,也就是自己写插件。测试用的手机Google Nexus ,Unity版本4.1,如下图所示,这是我发布成功后在QQ空间的截图。
写插件的方式我就不再说了,如果不懂的朋友看我之前的博客吧,写的很清楚。
QQ空间分享属于腾讯开放平台。然而腾讯开放平台的东西也比较多,移动平台包括:空间分享、说说分享、微薄分享。这一篇就说空间分享,如果空间分享搞定后可以按照同样的方式实现微薄分享。
先下载腾讯开放平台的API。
API我下载后里面有一个DEMO。我在MAC OS系统下Eclipse尽然不能运行,提示错误。后来我简单改了一下才可以运行,好蛋疼啊。
废话就不多说了,先来在Elipse下Android的插件。下段代码是Eclipse中的Android代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
package com.example.qqzone; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLEncoder; import java.util.Date; import org.apache.http.conn.ConnectTimeoutException; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.graphics.Bitmap; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.Menu; import android.widget.Toast; import com.tencent.open.HttpStatusException; import com.tencent.open.NetworkUnavailableException; import com.tencent.tauth.Constants; import com.tencent.tauth.IRequestListener; import com.tencent.tauth.IUiListener; import com.tencent.tauth.Tencent; import com.tencent.tauth.UiError; import com.unity3d.player.UnityPlayerActivity; public class MainActivity extends UnityPlayerActivity { // public class MainActivity extends Activity { public Tencent mTencent; public SharedPreferences sharedPrefrences; public Editor editor; public Context context; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sharedPrefrences = this.getSharedPreferences("info", MODE_WORLD_READABLE); editor = sharedPrefrences.edit(); context = this.getApplicationContext(); } //这个方法是在Unity中调用的。参数是当前的Activity。 public void LoginAndSend(final Activity currentActivity) { //一定要在UI线程中来执行腾讯API中的方法。 //API中的方法应该是开启了一个线程,一切由Unity调用的方法里面只要开启线程就会出现 //Can’t create handler inside thread that has not called Looper.prepare() 错误 //写在runOnUiThread 的线程中可以避免这个错误没,以前在处理Unity发送新浪微博的时候也遇到这样的错误。 //同样可以按照这种方法来解决。 currentActivity.runOnUiThread(new Runnable() { @Override public void run() { //得到Tencent实例, 腾讯API的方法都写在这里类中。 //"222222"是APPID 这个是腾讯DEMO里带的, 你最好自己申请一个。 mTencent = Tencent.createInstance("222222",context ); //这里是处理Token的, 避免用户重复授权应用,每次登录成功后会获取一个新Token //得到新Token后一定要保存在本地中。用上次保存的token就可以避免再次登录。 //Token的过期时间是3个月,3个月后需要重新登录。 //登录后返回值 String openid = sharedPrefrences.getString("openid", null); //登录后返回值 String access_token = sharedPrefrences.getString("access_token", null); //过期时间 long expires_in = sharedPrefrences.getLong("expires_in", 0); if (openid != null && access_token != null && expires_in != 0) { //如果以前保存过Token 这里直接使用上次保存的openid 和access_token //这里最好在判断一下token过期时间 mTencent.setOpenId(openid); mTencent.setAccessToken(access_token, expires_in + ""); //发送说说 SendMessage(); } else { //如果之前没有保存过token信息,在这里让用户先登录 if (!mTencent.isSessionValid()) { IUiListener listener = new IUiListener() { @Override public void onError(UiError arg0) { Toast.makeText(getApplicationContext(), "登录错误", Toast.LENGTH_SHORT).show(); } @Override public void onComplete(JSONObject arg0) { Log.v("登录成功", "登录成功"); //发送信息 SendMessage(); //登录成功后把token信息保存在本地中 editor.putString("openid", mTencent.getOpenId()); editor.putString("access_token", mTencent.getAccessToken()); //777600 表示token的过期时间。 它是以秒为单位的, 24(小时)*60(分钟)*60(秒) *90(天) = 777600(秒) //每次登录后需要获取现在时间 然后减去以前保存的 //如果过期了 让用户重新登录 editor.putLong("expires_in", 7776000); editor.commit(); } @Override public void onCancel() { Log.v("登录取消", "登录取消"); } }; mTencent.login(currentActivity, "all", listener); } else { mTencent.logout(context); } } } }); } private void SendMessage() { //下面这段代码基本上是API中的,我简单的改了一下。 if (mTencent.isSessionValid() && mTencent.getOpenId() != null) { Bundle parmas = new Bundle(); parmas.putString("title", "雨松MOMO程序研究院");// 必须。feeds的标题,最长36个中文字,超出部分会被截断。 parmas.putString( "url", "http://www.xuanyusong.com" + "#" + System.currentTimeMillis());// 必须。分享所在网页资源的链接,点击后跳转至第三方网页, // 请以http://开头。 parmas.putString("comment", ("欢迎光临雨松MOMO程序研究院。" + new Date()));// 用户评论内容,也叫发表分享时的分享理由。禁止使用系统生产的语句进行代替。最长40个中文字,超出部分会被截断。 parmas.putString("summary", "在Unity3D中调用QQ空间分享接口,哇咔咔哇咔咔");// 所分享的网页资源的摘要内容,或者是网页的概要描述。 // 最长80个中文字,超出部分会被截断。 parmas.putString("images", "https://www.xuanyusong.com/wp-content/uploads/2012/04/0.jpg");// 所分享的网页资源的代表性图片链接",请以http://开头,长度限制255字符。多张图片以竖线(|)分隔,目前只有第一张图片有效,图片规格100*100为佳。 parmas.putString("type", "4");// 分享内容的类型。 mTencent.requestAsync(Constants.GRAPH_ADD_SHARE, parmas, Constants.HTTP_POST, new BaseApiListener(), null); } } //这个方法一定要加, 不然有错误、、 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { mTencent.onActivityResult(requestCode, resultCode, data); } private class BaseApiListener implements IRequestListener { @Override public void onComplete(final JSONObject response, Object state) { doComplete(response, state); } protected void doComplete(JSONObject response, Object state) { Log.v("发送成功", "发送成功"); } @Override public void onIOException(final IOException e, Object state) { Log.v("发表错误", "onIOException"); } @Override public void onMalformedURLException(final MalformedURLException e, Object state) { Log.v("发表错误", "onMalformedURLException"); } @Override public void onJSONException(final JSONException e, Object state) { Log.v("发表错误", "onJSONException"); } @Override public void onConnectTimeoutException(ConnectTimeoutException arg0, Object arg1) { Log.v("发表错误", "onConnectTimeoutException"); } @Override public void onSocketTimeoutException(SocketTimeoutException arg0, Object arg1) { Log.v("发表错误", "onSocketTimeoutException"); } @Override public void onUnknowException(Exception arg0, Object arg1) { Log.v("发表错误", "onUnknowException"); } @Override public void onHttpStatusException(HttpStatusException arg0, Object arg1) { Log.v("发表错误", "onHttpStatusException"); } @Override public void onNetworkUnavailableException( NetworkUnavailableException arg0, Object arg1) { Log.v("发表错误", "onNetworkUnavailableException"); } } } |
如果你不需要在U3d中分享说说?把上段代码简单的改一改吧。把登录放在Creat()方法中吧,会安卓的都知道嘿嘿。
然后在U3D中,绑定在任意对象中, 把Activity传递给Android插件中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
using UnityEngine; using System.Collections; public class NewBehaviourScript : MonoBehaviour { void OnGUI() { if(GUILayout.Button(" Send QQ zone", GUILayout.Height(50))) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); using (AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity")) { jo.Call("LoginAndSend",jo); } } } } |
下面是Andorid插件的路径,记住把open_Sdk放进去,这个是腾讯提供的第三方包。运行后点击按钮就可以登录与分享说说。
然后在Android手机上编译运行吧。
最后我在说说我使用QQ空间的感受。 空间分享包括2部分 分享链接 和分享说说,仔细查了一下才发现这两个东西差别挺大的。 文档上说这两个分享接口会被合并,最重要的是暂时不能分享本地图片、如果想分享本地图片有一个办法就是先调用上传图片的接口,把本地图片上传至QQ相册中,然后拿到URL后分享。总体来说希望企鹅的文档以后能写的在清楚一点,我是“连蒙带猜” 哎~
本文的源码下载,包括Android工程和U3D工程。
http://vdisk.weibo.com/s/uW42H
- 本文固定链接: https://www.xuanyusong.com/archives/2159
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
大侠能出个微信登陆片吗?
GRAPH_ADD_SHARE cannot be resolved or is not a field这个参数错误,是怎么回事?
解决了吗?同样的问题
请问你解决了吗?我也遇到这个问题
大神、、我直接把的demo放上去。运行都是ok的、但是qq空间没有你代码里面发表的图片、、是什么意思啊、、
manifest 文件中有activity,我这里这样写public class MainActivity extends UnityPlayerActivity {private String client_key = “”;private String client_id = “”;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);}public void Login() {GyyxMobile.getInstance(MainActivity.this, client_id, “test”, client_key).login(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, new GyyxListener() {@Overridepublic void onException(Exception e) {UnityPlayer.UnitySendMessage(“Main Camera”, “messgae”,”11111111″));}@Overridepublic void onError(GyyxError e) {UnityPlayer.UnitySendMessage(“Main Camera”, “messgae”,”2222222″));}@Overridepublic void onComplete(Bundle bundle) {UnityPlayer.UnitySendMessage(“Main Camera”, “messgae”,”333333″));}@Overridepublic void onCancel() {UnityPlayer.UnitySendMessage(“Main Camera”, “messgae”,”4444444″));}}}}client_key和client_id 都有真实数据,但是在执行到GyyxMobile.getInstance这里时就没反应了,不知道为什么
momo大神,U3D和Android数据交互时,U3D导出安卓版本,总会出现Unable to find unity activity in manifest. You need to make sure orientation attribut is set to portrait manually.UnityEditor.HostView:OnGUI()这个警告, 安装后,执行到有上下文参数的时候,就不执行了,请问知道怎么解决吗?
请问,class,jar文件是什么内容 ?
出现登录错误什么原因哦
请问momo,我在接入SDK的时候在手机上运行,为什么提示请插入SIM?然后会弹出“ 部分设备无法支持当前登录方式,建议下载手机qq ”的界面。谢谢啦
谢谢MOMO分享!再问个问题,能取得QQ上的好友信息吗?
谢谢。。。
这样肯定不能传递。。。API中的方法介绍,参数1是方法名参数2是多个对象。function Call (methodName : string, params args : object[]) : void所以你传递的时候可以jo.Call(“LoginAndSend”,jo,height);
嗯,改过来了。。小白一个,感谢分享
过奖啦, 蛤蛤。。。
感谢雨松分享
威哥。。。。
谢谢momo,俺用的3.5,打包总是出错,然后把res文件夹删了之后就成了,可以分享到空间,不过那个按钮只能按下一次,还有图片也没有成功显示出来,正在研究,哇哈哈~
3.5 不可以 因为这个项目我实在unity4下做的, 3。5打开会报错。。
嗯,第一次打不开,提示版本低,然后我新建了一工程,把那些文件拷贝过来了,嘿嘿
聪明 蛤蛤
默默跟着大牛们学习。新手,力顶
建议导出package,谢谢!
果断分享,现在N多游戏都有分享了!
蛤蛤 谢谢小马。。。