最近工作比较忙 加上感觉自己好像有点上了年纪 整个人感觉非常的疲惫啊, 希望国庆期间可以好好休息一下,调养一下自己。这两天研究了一下如何在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.csusing 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希望大家学习愉快。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主线程来执行原先的子线程。。