Android應用內使用新浪微博SDK發送微博(不調用微博客戶端)

需求

手頭的一個應用須要添加分享到新浪微博的功能,這個功能在如今的應用上是很是的廣泛的了。java

分享到新浪微博,其實就是發送一條特定內容的微博,因此須要用到新浪微博SDK了。android

微博SDK

SDK的下載地址 http://open.weibo.com/wiki/SDK,包括不少平臺的封裝,其中就有android版本的。json

下載後,請務必讀一下SDK文檔,運行其中自帶的demo,對sdk的使用有個大概的瞭解。api

發送微博的困擾

運行DEMO後發現,其中發送微博的功能居然是經過調用微博客戶端的方式來實現的,若是用戶沒有安裝,會提示用戶下載,或者選擇放棄發送。。。這明顯不靠譜啊,由於仍是有不少用戶沒有安裝微博客戶端的。安全

網上也有很多人遇到這個問題,從他們的說法中能夠看出微博sdk前一個版本中彷佛仍是有發送微博這個功能的,不過新版的sdk中沒有了。ide

不過demo中仍是給了提示了:若是不想使用微博客戶端進行分享,請參考OpenAPI。佈局

那咱們就來看看這OpenAPI有什麼功能。post

OpenAPI

OpenAPI的文檔:http://open.weibo.com/wiki/%E5%BE%AE%E5%8D%9AAPIthis

能夠看出OpenAPI就是經過Http請求的方式來進行一些操做,能夠進行的操做基本涵蓋了微博應用的全部方面。debug

咱們找到發送微博的API:statuses/update

文檔的說明很詳細,改接口經過POST方法,請求參數有不少,不過必須的只有一個。不過,改接口是須要登陸的,因此參數中還需加上登陸受權過的AccessToken:

參數名 必選 類型及範圍 說明
status true string 要發佈的微博文本內容,必須作URLencode,內容不超過140個漢字。
access_token true string 登陸後獲得,詳見後文

如今,發送微博的邏輯很明確了,就是一個post請求。還須要解決的一個問題就是AccessToken,即登陸受權。

登陸受權

並非你想讓用戶在你的應用裏登陸微博就能夠直接寫代碼實現的,由於用戶是在你的應用裏輸入帳戶信息,因此對於用戶的帳戶安全來講,這是有風險的,因此若是你的應用須要加入微博功能,是需經過新浪審覈的。這個流程我也沒有完整的走過,不過你們能夠參考微博文檔的幫助:移動客戶端接入

這篇文章主要講程序,因此不在這些流程上糾結。總之,咱們須要的是一個APPKEY,登陸受權須要它。咱們如今能夠先用SDK微博應用demo的APPKEY來實驗。

DEMO實踐步驟

  1. 由於使用的是微博DEMO的APPKEY因此須要替換默認的 debug.keystore
    在 C:\Users\XXXXX.android 目錄下,把 Android 默認的 debug.keystore 替換成官方在 GitHub 上提供的debug.keystore。
    請注意:這一步是必須的,若是沒有替換,demo 程序在運行時將沒法正確的受權成功。用戶在替換前,最好先備份一下原始的 debug.keystore。另外,該 debug.keysotre 是新浪官方的,除了編譯運行官方 DEMO 外,請不要直接使用它,出於安全的考慮,您應該爲本身的應用提供一份 keysotre。
  2. 新建android工程,包名取名爲:com.sina.weibo.sdk.demo
  3. 拷貝微博DEMO中的Constants.java到工程中
  4. 在AndroidManifest.xml中添加權限:

    <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  5. 主界面的代碼,登陸受權部分的代碼直接取自微博官方DEMO,發送微博部分是上文分析的實現:

    public class MainActivity extends Activity {
         private static final String TAG = "MainActivity";
    
         /** 微博 Web 受權類,提供登錄等功能 */
         private WeiboAuth mWeiboAuth;
    
         /** 封裝了 "access_token","expires_in","refresh_token",並提供了他們的管理功能 */
         private Oauth2AccessToken mAccessToken;
    
         private TextView mTokenInfoTV;
         private EditText mMessageET;
         private Button mSendBtn;
    
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_main);
    
             mWeiboAuth = new WeiboAuth(this, Constants.APP_KEY, Constants.REDIRECT_URL, Constants.SCOPE);
    
             mTokenInfoTV = (TextView) findViewById(R.id.textView_tokenInfo);
             mMessageET = (EditText) findViewById(R.id.editText_message);
             mSendBtn = (Button) findViewById(R.id.button_sendWeibo);
    
             // 獲取Token
             findViewById(R.id.button_getToken).setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
                     mWeiboAuth.anthorize(new AuthListener());
                 }
             });
    
             // 發送微博
             mMessageET.setVisibility(View.GONE);
             mSendBtn.setVisibility(View.GONE);
             mSendBtn.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
                     sendWeibo(mMessageET.getText().toString());
                 }
             });
         }
    
         // 發送微博
         protected void sendWeibo(String string) {
             //組織post參數
             List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();
             params.add(new BasicNameValuePair("status", string));
             params.add(new BasicNameValuePair("access_token", mAccessToken.getToken()));
    
             HttpClient httpClient = new DefaultHttpClient();
    
             //傳入post方法的請求地址,即發送微博的api接口
             HttpPost postMethod = new HttpPost("https://api.weibo.com/2/statuses/update.json");
             try {
                 postMethod.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
                 HttpResponse httpResponse = httpClient.execute(postMethod);
    
                 //將返回結果轉爲字符串,經過文檔可知返回結果爲json字符串,結構請參考文檔
                 String resultStr=EntityUtils.toString(httpResponse.getEntity());
                 Log.e(TAG, resultStr);
    
                 //從json字符串中創建JSONObject
                 JSONObject resultJson = new JSONObject(resultStr);
    
                 //若是發送微博失敗的話,返回字段中有"error"字段,經過判斷是否存在該字段便可知道是否發送成功
                 if (resultJson.has("error")) {
                     Toast.makeText(this, "發送失敗", Toast.LENGTH_SHORT).show();
                 } else {
                     Toast.makeText(this, "發送成功", Toast.LENGTH_SHORT).show();
                 }
    
             } catch (UnsupportedEncodingException e) {
                 Log.e(TAG, e.getLocalizedMessage());
             } catch (ClientProtocolException e) {
                 Log.e(TAG, e.getLocalizedMessage());
             } catch (IOException e) {
                 Log.e(TAG, e.getLocalizedMessage());
             } catch (ParseException e) {
                 Log.e(TAG, e.getLocalizedMessage());
             } catch (JSONException e) {
                 Log.e(TAG, e.getLocalizedMessage());
             }
         }
    
         //登陸受權接口
         class AuthListener implements WeiboAuthListener {
    
             //登陸成功
             @Override
             public void onComplete(Bundle values) {
                 // 從 Bundle 中解析 Token
                 mAccessToken = Oauth2AccessToken.parseAccessToken(values);
                 if (mAccessToken.isSessionValid()) {
                     // 顯示 Token
                     updateTokenView();
    
                     // 顯示發送微博的按鈕和輸入框
                     mSendBtn.setVisibility(View.VISIBLE);
                     mMessageET.setVisibility(View.VISIBLE);
    
                     // 保存 Token 到 SharedPreferences
                     // AccessTokenKeeper.writeAccessToken(MainActivity.this,
                     // mAccessToken);
                     Toast.makeText(MainActivity.this, "受權成功", Toast.LENGTH_SHORT).show();
                 } else {
                     // 當您註冊的應用程序簽名不正確時,就會收到 Code,請確保簽名正確
                     String code = values.getString("code");
                     String message = "受權失敗";
                     if (!TextUtils.isEmpty(code)) {
                         message = message + "\nObtained the code: " + code;
                     }
                     Toast.makeText(MainActivity.this, message, Toast.LENGTH_LONG).show();
                 }
             }
    
             @Override
             public void onCancel() {
                 Toast.makeText(MainActivity.this, "取消受權", Toast.LENGTH_LONG).show();
             }
    
             @Override
             public void onWeiboException(WeiboException e) {
                 Toast.makeText(MainActivity.this, "Auth exception : " + e.getMessage(), Toast.LENGTH_LONG).show();
             }
         }
    
         //顯示token信息
         private void updateTokenView() {
             String date = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new java.util.Date(mAccessToken
                     .getExpiresTime()));
             String format = "Token:%1$s \n有效期:%2$s";
             mTokenInfoTV.setText(String.format(format, mAccessToken.getToken(), date));
         }
    
         @Override
         public boolean onCreateOptionsMenu(Menu menu) {
             // Inflate the menu; this adds items to the action bar if it is present.
             getMenuInflater().inflate(R.menu.main, menu);
             return true;
         }
    
     }
  1. 主界面的佈局代碼:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:tools="http://schemas.android.com/tools"
         android:id="@+id/LinearLayout1"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical"
         tools:context=".MainActivity" >
    
         <Button
             android:id="@+id/button_getToken"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="獲取token" />
    
         <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="Token 信息:"
             android:textSize="20sp" />
    
         <TextView
             android:id="@+id/textView_tokenInfo"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text=""
             android:textSize="20sp" />
    
         <EditText
             android:id="@+id/editText_message"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:ems="10" >
    
             <requestFocus />
         </EditText>
    
         <Button
             android:id="@+id/button_sendWeibo"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:text="發送微博" />
    
     </LinearLayout>

運行效果

發送微博DEMO下載地址

http://files.cnblogs.com/mushan/WeiboSDKTest.zip

相關文章
相關標籤/搜索