zoukankan      html  css  js  c++  java
  • Android应用内使用新浪微博SDK发送微博(不调用微博客户端)

    需求

    手头的一个应用需要添加分享到新浪微博的功能,这个功能在现在的应用上是非常的普遍的了。

    分享到新浪微博,其实就是发送一条特定内容的微博,所以需要用到新浪微博SDK了。

    微博SDK

    SDK的下载地址 http://open.weibo.com/wiki/SDK,包括很多平台的封装,其中就有android版本的。

    下载后,请务必读一下SDK文档,运行其中自带的demo,对sdk的使用有个大概的了解。

    发送微博的困扰

    运行DEMO后发现,其中发送微博的功能竟然是通过调用微博客户端的方式来实现的,如果用户没有安装,会提示用户下载,或者选择放弃发送。。。这明显不靠谱啊,因为还是有很多用户没有安装微博客户端的。

    网上也有不少人遇到这个问题,从他们的说法中可以看出微博sdk前一个版本中似乎还是有发送微博这个功能的,不过新版的sdk中没有了。

    不过demo中还是给了提示了:如果不想使用微博客户端进行分享,请参考OpenAPI。

    那我们就来看看这OpenAPI有什么功能。

    OpenAPI

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

    可以看出OpenAPI就是通过Http请求的方式来进行一些操作,可以进行的操作基本涵盖了微博应用的所有方面。

    我们找到发送微博的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:UsersXXXXX.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 + "
      Obtained 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 
      有效期:%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

  • 相关阅读:
    Gradle学习之基础篇
    springmvc上传文件方法及注意事项
    SpringCloud学习之feign
    SpringCloud学习之eureka集群配置
    SpringMvc+Spring+MyBatis 基于注解整合
    SpringBoot学习之SpringBoot执行器
    SpringBoot跨域问题解决方案
    SpringCloud学习之快速搭建分布式配置
    MySQL-Innodb存储结构
    PG-流复制
  • 原文地址:https://www.cnblogs.com/mushan/p/3512444.html
Copyright © 2011-2022 走看看