最近工作比较忙 加上感觉自己好像有点上了年纪 整个人感觉非常的疲惫啊, 希望国庆期间可以好好休息一下,调养一下自己。这两天研究了一下如何在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 249 250 |
/* * 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 41 42 |
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 13 14 |
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 13 14 |
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接口对象,以便发送完成后回调。 这个该怎么处理,求大神指点~