0%

Android开发 新浪微博API的使用(发布微博)

今天下了个新浪微博的API研究研究,目前实现了发布微博功能,包括带图片的微博。为了安全,新浪微博的API中并没有提供用微博帐号密码登录的功能,而是采用OAuth授权,用户通过浏览器访问新浪网站登录,登录成功后,浏览器再返回key和secret给程序。 main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:id="@+id/login"
        android:text="登录" />
    <EditText android:id="@+id/status" android:layout_width="fill_parent"
        android:layout_height="300sp" android:hint="输入微博消息" />
    <Button android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:id="@+id/send"
        android:text="发布" />
</LinearLayout>

一个登录按钮,一个输入框,一个发布按钮 因为要接收浏览器返回的数据,所以,AndroidManifest.xml注册Activity的时候要加个Intent-Filter

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.pocketdigi.weibo" android:versionCode="1"
    android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Main" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="sina" android:host="weibo" />
                <!-- 监控sina://weibo这样的地址 -->
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>

intent-filter必须分成两段写,如果合在一起写,就启动不了了。 为了简便,直接把新浪Sample里的OAuthConstant类拷过来:

package weibo4android.androidexamples;

import weibo4android.Weibo;
import weibo4android.http.AccessToken;
import weibo4android.http.RequestToken;

public class OAuthConstant {
    private static Weibo weibo=null;
    private static OAuthConstant instance=null;
    private RequestToken requestToken;
    private AccessToken accessToken;
    private String token;
    private String tokenSecret;
    private OAuthConstant(){};
    public static synchronized OAuthConstant getInstance(){
        if(instance==null)
            instance= new OAuthConstant();
        return instance;
    }
    public Weibo getWeibo(){
        if(weibo==null)
            weibo= new Weibo();
        return weibo;
    }
    
    public AccessToken getAccessToken() {
        return accessToken;
    }
    public void setAccessToken(AccessToken accessToken) {
        this.accessToken = accessToken;
        this.token=accessToken.getToken();
        this.tokenSecret=accessToken.getTokenSecret();
    }
    public RequestToken getRequestToken() {
        return requestToken;
    }
    public void setRequestToken(RequestToken requestToken) {
        this.requestToken = requestToken;
    }
    public String getToken() {
        return token;
    }
    public void setToken(String token) {
        this.token = token;
    }
    public String getTokenSecret() {
        return tokenSecret;
    }
    public void setTokenSecret(String tokenSecret) {
        this.tokenSecret = tokenSecret;
    }
    
}

接下来就是最关键的主程序:

package com.pocketdigi.weibo;

import java.io.File;

import weibo4android.Weibo;
import weibo4android.WeiboException;
import weibo4android.http.AccessToken;
import weibo4android.http.RequestToken;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class Main extends Activity {
    /** Called when the activity is first created. */
    String key = "", secret = "";
    Button login,send;
    EditText status;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        System.setProperty("weibo4j.oauth.consumerKey", "3997936609");
        System.setProperty("weibo4j.oauth.consumerSecret",
                "8bc9e3bfd6ae8e3b2b8bda9079918950");
        //设置在新浪应用开放平台申请的应用的key和secret
        login=(Button)findViewById(R.id.login);
        send=(Button)findViewById(R.id.send);
        status=(EditText)findViewById(R.id.status);
        login.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                login();
                //登录
            }});
        send.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                String text=String.valueOf(status.getText());
                Weibo weibo =  new Weibo();
                weibo.setToken(key,secret);
                try {
                    //weibo.updateStatus(text);
                    //只发文字
                    File f=new File("/sdcard/wallpaper/129567208597069400.jpg");
                    weibo.uploadStatus(text,f );
                    //发文字+图片,这里需要导入commons-httpclient-3.0.1.jar,自己网上下
                    //在实际项目上,最好放Thread里,因为按下去的时候按钮会卡
                } catch (WeiboException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }});
    }

    @Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();
        //启动时执行检测是否来自网页登录返回
        //如果是,获取key和secret
        //否则读取SharedPreferences
        //若得不到key和secret,直接跳转登录
        Uri uri = this.getIntent().getData();
        if (uri != null) {
            //如果是浏览器返回
            try {
                RequestToken requestToken = OAuthConstant.getInstance()
                        .getRequestToken();
                AccessToken accessToken = requestToken.getAccessToken(uri
                        .getQueryParameter("oauth_verifier"));
                OAuthConstant.getInstance().setAccessToken(accessToken);
                // 保存
                Editor sharedata = getSharedPreferences("WeiBo", 0).edit();
                sharedata.putString("key", accessToken.getToken());
                sharedata.putString("secret", accessToken.getTokenSecret());
                sharedata.commit();
                key = accessToken.getToken();
                secret = accessToken.getTokenSecret();
            } catch (WeiboException e) {
                e.printStackTrace();
            }
        } else {
            //如果是用户自己启动
            SharedPreferences settings = getSharedPreferences("WeiBo", 0);
            key = settings.getString("key", "");
            secret = settings.getString("secret", "");
        }
        if (key.equals("") || secret.equals("")) {
            Toast.makeText(this, "尚未登录", Toast.LENGTH_LONG).show();
            login();
            //跳转到浏览器登录

        }

    }
    public void login(){
        Weibo weibo = OAuthConstant.getInstance().getWeibo();
        RequestToken requestToken;
        try {
            requestToken =weibo.getOAuthRequestToken("sina://weibo");
            //为了避免与同类应用冲突,还是自己改下URI吧
            Uri uri2 = Uri.parse(requestToken.getAuthenticationURL()+ "&from=xweibo");
            OAuthConstant.getInstance().setRequestToken(requestToken);
            startActivity(new Intent(Intent.ACTION_VIEW, uri2));
        } catch (WeiboException e) {
            e.printStackTrace();
        }
    }
}

发图片需要导入commons-httpclient-3.0.1.jar,否则启动报错,当然weibo4android-1.2.0.jar是不可少的