最近工作比较忙 加上感觉自己好像有点上了年纪 整个人感觉非常的疲惫啊, 希望国庆期间可以好好休息一下,调养一下自己。这两天研究了一下如何在Unity中调用新浪微博接口, 上一篇已经IOS平台分享新浪微博,那么本篇文章将写在结合Unity 在 Android平台分享新浪微博。 使用起来我还是觉得IOS平台的接口比较好用,开始基本傻瓜化,可Android平台的接口新手的话估计导入后都无法运行。借此,雨松MOMO希望新浪微博尽快让Android平台下的接口也能好用,废话就不多说了,我们进入正题。
如下图所示,这是MOMO在Android手机中Unity3D下调用新浪微博分享接口。
在继续学习之前请朋友确认你所需要的微薄密钥是否准备完毕。
1.没有密钥的朋友
请在这里注册一个移动应用,http://open.weibo.com/ 。注册成功后在应用信息-》基本信息中即可获得APP KEY 和 APP SECRET,没有这两个KEY你是无法发送微薄的。 仅仅这些还是不够,因为是刚刚注册的新密钥所以是不能被公众所使用的,你应当继续在 应用信息-> 测试帐号 中添加测试账号,只有添加过的测试帐号才能使用新注册的密钥发送微薄。
2.有密钥的朋友
可以直接使用你的密钥来进行开发。
接着我们下载新浪微博Andoid下API接口, 下载地址:http://code.google.com/p/android-weibo-sdk/downloads/list 我个人在选择API的时候习惯选择最新的版本,页面中最上面的下载地址就是最新的API
解压后使用Eclipse将整个工程引入,一定要从解压后的顶层的文件夹将下面的两个工程同时的引入Eclipse,不然你会出现错误 “@style/ContentOverlay” 无法找到。这样的话就会将两个工程都引入至elipse,com_weibo_android 是API包, com_weibo_android_exampe 就是例子程序,直接运行它即可。
然后我们需要在Unity3D中制作Android的插件来调用新浪微博接口,如果你现在对Android的插件还是不是很了解,请阅读Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八)文章。
开始MOMO使用com_weibo_android_exampe 来制作Android插件的时候发现最终Unity导出项目的时候无法运行,并且在手机中也无法找到刚刚编译的项目。非常奇怪,后来我就重新把API的代码整理了一遍,问题就解决了。
SinaMessageActivity.java 它是我们写的Activity插件, 当Unity 中准备好 文字与图片数据的时候调用它即可发送信息。
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 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
/* * Copyright 2011 Sina. * * Licensed under the Apache License and Weibo License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.open.weibo.com * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.yusong.momo; import java.io.IOException; import java.net.MalformedURLException; import com.unity3d.player.UnityPlayerActivity; import com.yusong.momo.AsyncWeiboRunner.RequestListener; import android.app.Activity; import android.content.SharedPreferences; import android.os.Bundle; import android.text.TextUtils; import android.widget.Toast; public class SinaMessageActivity extends UnityPlayerActivity implements RequestListener { //public class SinaMessageActivity extends Activity implements RequestListener { //这个是你的密钥 private static final String CONSUMER_KEY = "1626952933"; private static final String CONSUMER_SECRET = "d92012d3d2ffa5630554723e1825b11c"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } //在Unity中调用此方法进行登录、发送微薄 public void pressed(String name) { Weibo weibo = Weibo.getInstance(); weibo.setupConsumerConfig(CONSUMER_KEY, CONSUMER_SECRET); weibo.setRedirectUrl("http://xuanyusong.com"); SharedPreferences settings = getSharedPreferences("MOMO", Activity.MODE_PRIVATE); //token 和 expires_in 是登录一次成功后服务器返回给你的。 //因为我们不需要用户每次发送微薄时都登录 //所以应当记录用户第一次登录时返回的token 和 expires_in //发送微博时直接使用之前保存的token和expires_in即可 String token = settings.getString("token", ""); String expires_in = settings.getString("expires_in", ""); //SharedPreferences 中如果有数据就直接发微薄,否则让用户重新登录 if (!TextUtils.isEmpty(token) && !TextUtils.isEmpty(expires_in)) { AccessToken accessToken = new AccessToken(token, CONSUMER_SECRET); accessToken.setExpiresIn(expires_in); weibo.setAccessToken(accessToken); accessToken = new AccessToken(weibo.getAccessToken() .getToken(), weibo.getAccessToken().getSecret()); accessToken = new AccessToken(token, CONSUMER_SECRET); weibo.setAccessToken(accessToken); //这里代码一定要加, 不然即时你保存了之前的 token 和 expires_in也 无法发送微薄 Utility.setAuthorization(new Oauth2AccessTokenHeader()); try { //发送一条文字信息 update(weibo, Weibo.getAppKey(), "test1", "", ""); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (WeiboException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { //开始让用户登录 weibo.authorize(SinaMessageActivity.this, new AuthDialogListener()); } } public void onResume() { super.onResume(); } class AuthDialogListener implements WeiboDialogListener { @Override public void onComplete(Bundle values) { //用户登录成功后直接发送微薄 String token = values.getString("access_token"); String expires_in = values.getString("expires_in"); SharedPreferences settings = getSharedPreferences("MOMO", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); editor.putString("token", token); editor.putString("expires_in", expires_in); editor.commit(); AccessToken accessToken = new AccessToken(token, CONSUMER_SECRET); accessToken.setExpiresIn(expires_in); Weibo weibo = Weibo.getInstance(); weibo.setAccessToken(accessToken); accessToken = new AccessToken(weibo.getAccessToken().getToken(), weibo.getAccessToken().getSecret()); accessToken = new AccessToken(token, CONSUMER_SECRET); weibo.setAccessToken(accessToken); //这里代码一定要加, 不然即时你保存了之前的 token 和 expires_in也 无法发送微薄 Utility.setAuthorization(new Oauth2AccessTokenHeader()); try { //在这里发送一条 文字+ 图片的微薄 //路径比较重要,在Unity中将图片保存在这个路径下 //在Android插件中直接通过这个路径即可拿到图片对象 upload(weibo, Weibo.getAppKey(), "/data/data/com.yusong.momo/files/Screenshot.png", "Unity3D 中调用新浪微博接口 分享自 @雨松MOMO ", "", "") ; } catch (WeiboException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void onError(DialogError e) { Toast.makeText(getApplicationContext(), "Auth error : " + e.getMessage(), Toast.LENGTH_LONG).show(); } @Override public void onCancel() { Toast.makeText(getApplicationContext(), "Auth cancel", Toast.LENGTH_LONG).show(); } @Override public void onWeiboException(WeiboException e) { Toast.makeText(getApplicationContext(), "Auth exception : " + e.getMessage(), Toast.LENGTH_LONG) .show(); } } // 发送文字 private String upload(Weibo weibo, String source, String file, String status, String lon, String lat) throws WeiboException { WeiboParameters bundle = new WeiboParameters(); bundle.add("source", source); bundle.add("pic", file); bundle.add("status", status); if (!TextUtils.isEmpty(lon)) { bundle.add("lon", lon); } if (!TextUtils.isEmpty(lat)) { bundle.add("lat", lat); } String rlt = ""; String url = Weibo.SERVER + "statuses/upload.json"; AsyncWeiboRunner weiboRunner = new AsyncWeiboRunner(weibo); weiboRunner.request(this, url, bundle, Utility.HTTPMETHOD_POST, this); return rlt; } // 发送文字 + 图片 private String update(Weibo weibo, String source, String status, String lon, String lat) throws MalformedURLException, IOException, WeiboException { WeiboParameters bundle = new WeiboParameters(); bundle.add("source", source); bundle.add("status", status); if (!TextUtils.isEmpty(lon)) { bundle.add("lon", lon); } if (!TextUtils.isEmpty(lat)) { bundle.add("lat", lat); } String rlt = ""; String url = Weibo.SERVER + "statuses/update.json"; AsyncWeiboRunner weiboRunner = new AsyncWeiboRunner(weibo); weiboRunner.request(this, url, bundle, Utility.HTTPMETHOD_POST, this); return rlt; } @Override public void onComplete(String response) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(SinaMessageActivity.this, "微薄分享成功", Toast.LENGTH_LONG).show(); } }); } @Override public void onIOException(IOException e) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(SinaMessageActivity.this, "微薄分享错误", Toast.LENGTH_LONG).show(); } }); } @Override public void onError(WeiboException e) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(SinaMessageActivity.this, "微薄分享失败", Toast.LENGTH_LONG).show(); } }); } } |
当插件准备完毕后,将它导入至Unity3D中,如果不会的朋友请看我之前的文章。Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八)
我们在看看Unity中是如何调用插件中的分享接口的。
Test.cs
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 |
using System.Collections; using System.IO; using System.Collections.Generic; using System; public class Test : MonoBehaviour { void Start () { //在Unity截取一张图片 //该图片的路径保存在"/data/data/com.yusong.momo/files/Screenshot.png" //在Android插件中根据这个路径即可拿到该图片 Application.CaptureScreenshot("Screenshot.png"); } void Update () { } void OnGUI() { if(GUILayout.Button("sendSinaMessage",GUILayout.Width(200),GUILayout.Height(100))) { //开始登录新浪微博 using (AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) { using( AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity")) { //在这里直接调用pressed方法进行登录与发送微薄 jo.Call("pressed",""); } } } } } |
调用接口后会调用新浪登录界面,继续发送新浪微薄。
最后我把文本的Android插件代码 以及 Unity工程放出来, 下载完毕后解压即可看到工程。雨松MOMO希望大家学习愉快。
下载地址 http://vdisk.weibo.com/s/d3xA1
2013年3月23日补充
在调用新浪微薄Android接口的时候我还出现了一个 Can’t create handler inside thread that has not called Looper.prepare() 错误。
这个错误前段时间一直因为别的事情没有能即时的解决。 这几天MOMO在做Android for QQzone的插件中也遇到了同样的错误。出现这个错误的额原因就是unity调用插件中的方法中又开启了新的线程。
先改动一下上面的unity C#脚本,方法名我就不换了。。。主要说原理。。
1 2 3 4 5 6 7 8 9 10 11 12 |
if(GUILayout.Button(" Send QQ zone", GUILayout.Height(50))) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); using (AndroidJavaObject jo = jc.GetStatic("currentActivity")) { jo.Call("LoginAndSend",jo); } } |
这段代码的意思就是在unity中把当前的Activity对象传递给Android插件中。在插件中这样来写。
1 2 3 4 5 6 7 8 9 10 11 12 |
public void LoginAndSend(final Activity currentActivity) { currentActivity.runOnUiThread(new Runnable() { @Override public void run() { //doyourcode }); } } |
在插件中通过调用UI主线程来执行原先的子线程。。
- 本文固定链接: https://www.xuanyusong.com/archives/1800
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
请问大神用最新sdk的oauth时授权页面弹不出来是该如何解决啊。ssohandler是封装的,根本无法控制会使用sso登陆或是oauth,这是该怎么办呢?
用 share sdk吧。
感谢回复,意思是强制使用者一定要安装微博APP才可以登录吗?还是说用只是用 share sdk 来辨别有否安装再自行处理授权页面的弹出呢?
http://pan.baidu.com/s/1hq4Ahm8 雨松哥我我对着这个平台的登陆一直报错, 在Java- ADT 里面运行没错,只要Unity 一调用就报NULL 找不到 求解 求解 已经被折磨了一天了
已经解决 , 有的 平台会把资源放到 jar 里面 ,unity对接的时候记得拿出来, 天坑啊!!!!
momo大神,为什么我在UnityPlayerActivity里点击登录授权,新浪授权页面弹不出来的
为什么老是在授权的时候出现Auth exception :failed to receive access token 呢,求大神指点~~
发送完成貌似木有callback?现有个需求,unity调用android方法需要传入一个Callback接口对象,以便发送完成后回调。 这个该怎么处理,求大神指点~
集成你这个微博分享。unity3d中设置强制横屏直接退出 找不出原因。大哥怎解哦
您好,运行了您提供的例子,报错如下:Exception: JNI: Init’d AndroidJavaClass with null ptr!UnityEngine.AndroidJavaClass..ctor (IntPtr jclass) (at C:/BuildAgent/work/cac08d8a5e25d4cb/Runtime/Export/AndroidJavaImpl.cs:533)UnityEngine.AndroidJavaObject.get_JavaLangClass () (at C:/BuildAgent/work/cac08d8a5e25d4cb/Runtime/Export/AndroidJavaImpl.cs:511)UnityEngine.AndroidJavaObject.FindClass (System.String name) (at C:/BuildAgent/work/cac08d8a5e25d4cb/Runtime/Export/AndroidJavaImpl.cs:502)UnityEngine.AndroidJavaClass._AndroidJavaClass (System.String className) (at C:/BuildAgent/work/cac08d8a5e25d4cb/Runtime/Export/AndroidJavaImpl.cs:522)UnityEngine.AndroidJavaClass..ctor (System.String className) (at C:/BuildAgent/work/cac08d8a5e25d4cb/Runtime/ExportGenerated/Editor/AndroidJava.cs:91)Test.OnGUI () (at Assets/Test.cs:29)不知道您遇到过这种问题么
Pingback 引用通告: コーチ アウトレット
Pingback 引用通告: ルイヴィトン アウトレッ
Pingback 引用通告: コーチ アウトレット
和楼上出现一样的错误,我发现我用的sdk和博主用的不是一个版本,是不是因为这个问题?
已找到问题所在。WeiboDialog中lp.leftMargin设置的值有问题,改成0就可以正常通过。这个变量的含义有待进一步研究
unity里面调用新浪微博的mWeibo.authorize(MainActivity.this, new AuthDialogListener())代码时出现报错“Resource ID #0x71040000 type #0x3 is not valid”,雨松哥解救啊~~~
雨松哥,我在android里面调用新浪微博是可以的,但是在unity里面调用android包时,每次我执行mWeibo.authorize(MainActivity.this, new AuthDialogListener())就报错,我用的是最新的API,麻烦雨松哥帮忙啊~~~~
你的问题解决了吗?? 我也遇到同样的问题,求助
返回之后 假死解决不了啊 求指导 大神··
现在有unity for weibo的插件。 网上有你试试那个吧。。
你说的是uniweibo么 收费的那个 有木有 免费的
真厉害 亲
过奖啦。。。
向你学习!~
蛤蛤!! 一起学习吧
momo,问下为何用微薄的jar呢?像你这样直接用源码包unity是可以和android通信的。。但是我下载最新的微薄版本,导入sso的jar包写代码…和android通信时候会有问题..请问这是为什么呢..难道就是因为那个loop?
是因为那个loop 你说的是分享后卡死的情况吗?
请问momo webplayer 添加微博分享该怎么办呀
调用新浪的分享接口。。。。
好像是有这个问题 “关闭微博登陆界面后会出现按钮无法再点击,假死。” 当时写的时候没有注意这块。 可惜这段时间在忙别的事情 所以U3D就暂时搁置下了。。 希望有解决的朋友顺便告知一下我, 我转载进博客中。。
谢谢楼主分享,我已经成功的整合到unity里了,现在发现个问题,就是分享微博的时候会出现一个深蓝色的背景,遮盖住原来的界面,请问这个有解决办法吗?
没有注意这个地方 呵呵
你好,今天测试您的例子,发现发布微博后,关闭微博登陆界面后会出现按钮无法再点击,假死。后来发现是因为用了Looper的问题,但是不知道怎么修改才好。希望能解答。还有一点就是您的共享的工程文件Java代码乱码,weibo部分和您自己写的部分编码不一致。微博部分代码都是乱的。doobear
你好,请问我这里报错,能帮忙看下是什么原因吗?谢谢09-28 01:25:24.539: E/AndroidRuntime(909): Uncaught handler: thread main exiting due to uncaught exception09-28 01:25:24.539: E/Monkey(909): exception :java.io.FileNotFoundException: /dev/kmsg (Permission denied)09-28 01:25:24.549: W/System.err(909): java.io.IOException: Permission denied09-28 01:25:24.549: E/AndroidRuntime(909): exception :java.io.FileNotFoundException: /dev/kmsg (Permission denied)09-28 01:25:24.549: E/AndroidRuntime(909): FATAL EXCEPTION: main09-28 01:25:24.549: E/AndroidRuntime(909): java.lang.RuntimeException: Only one Looper may be created per thread09-28 01:25:24.549: E/AndroidRuntime(909): at android.os.Looper.prepare(Looper.java:74)
你好,请问我这里报错,能帮忙看下是什么原因吗?谢谢09-28 01:25:24.539: E/AndroidRuntime(909): Uncaught handler: thread main exiting due to uncaught exception09-28 01:25:24.539: E/Monkey(909): exception :java.io.FileNotFoundException: /dev/kmsg (Permission denied)09-28 01:25:24.549: W/System.err(909): java.io.IOException: Permission denied09-28 01:25:24.549: E/AndroidRuntime(909): exception :java.io.FileNotFoundException: /dev/kmsg (Permission denied)09-28 01:25:24.549: E/AndroidRuntime(909): FATAL EXCEPTION: main09-28 01:25:24.549: E/AndroidRuntime(909): java.lang.RuntimeException: Only one Looper may be created per thread09-28 01:25:24.549: E/AndroidRuntime(909): at android.os.Looper.prepare(Looper.java:74)
文件没有找到、、
谢谢,博主的回复,java.io.FileNotFoundException: /dev/kmsg (Permission denied)但是我没有什么读写文件的操作,调到这句weibo.authorize(AuthorizeActivity.this, new AuthDialogListener());程序就崩溃了。能帮忙看下怎么解决吗?谢谢运行的是sdk自带的那个example
你是不是没加权限?
是这些权限吗?都加了。
谢谢,博主的回复,java.io.FileNotFoundException: /dev/kmsg (Permission denied)但是我没有什么读写文件的操作,调到这句weibo.authorize(AuthorizeActivity.this,new AuthDialogListener());程序就崩溃了。能帮忙看下怎么解决吗?谢谢运行的是sdk自带的那个example
加油!博主!
立刻试试…
请问如果我unity里已经有别的activity了 怎么样才能再调用这个呢?现在做的个小东西里一开始就有了qcar的activity 我想截图发个微博 但我不知道这两个activity之间该怎么切换
你可以把这个写在别的activity中的
非常感谢。。。
客气啦 蛤蛤
感谢你的支持 !!蛤蛤
自己顶一下自己 哈哈哈。。。 想睡觉啊 忽忽。。。
某人,昨晚……..你睡了吗?
额。。。