首页 >Unity3D频道 >【Unity3D研究院之游戏开发】 > Unity3D研究院之在Unity中分享QQ空间(四十九)
2013
03-24

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

最近研究了一下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代码。

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",
					"https://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插件中。

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放进去,这个是腾讯提供的第三方包。运行后点击按钮就可以登录与分享说说。

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

 

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

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

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

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

 

 

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

Unity3D研究院之在Unity中分享QQ空间(四十九)》有 32 条评论

  1. 大侠能出个微信登陆片吗?

  2. GRAPH_ADD_SHARE cannot be resolved or is not a field这个参数错误,是怎么回事?

  3. Monster0说:

    请问你解决了吗?我也遇到这个问题

  4. 谭俊说:

    大神、、我直接把的demo放上去。运行都是ok的、但是qq空间没有你代码里面发表的图片、、是什么意思啊、、

  5. 815313452说:

    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这里时就没反应了,不知道为什么

  6. 815313452说:

    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()这个警告, 安装后,执行到有上下文参数的时候,就不执行了,请问知道怎么解决吗?

  7. ajohn说:

    请问,class,jar文件是什么内容 ?

  8. 竹林说:

    出现登录错误什么原因哦

  9. 花雪说:

    请问momo,我在接入SDK的时候在手机上运行,为什么提示请插入SIM?然后会弹出“ 部分设备无法支持当前登录方式,建议下载手机qq ”的界面。谢谢啦

  10. aleraler说:

    谢谢MOMO分享!再问个问题,能取得QQ上的好友信息吗?

  11. 这样肯定不能传递。。。API中的方法介绍,参数1是方法名参数2是多个对象。function Call (methodName : string, params args : object[]) : void所以你传递的时候可以jo.Call(“LoginAndSend”,jo,height);

  12. 小可说:

    感谢雨松分享

  13. 谢谢momo,俺用的3.5,打包总是出错,然后把res文件夹删了之后就成了,可以分享到空间,不过那个按钮只能按下一次,还有图片也没有成功显示出来,正在研究,哇哈哈~

  14. 果断分享,现在N多游戏都有分享了!

留下一个回复

你的email不会被公开。 必填项已用 * 标注。