最近工作比较忙 加上感觉自己好像有点上了年纪 整个人感觉非常的疲惫啊, 希望国庆期间可以好好休息一下,调养一下自己。这两天研究了一下如何在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 中准备好 文字与图片数据的时候调用它即可发送信息。
/*
* 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
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#脚本,方法名我就不换了。。。主要说原理。。
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插件中。在插件中这样来写。
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接口对象,以便发送完成后回调。 这个该怎么处理,求大神指点~