一、代码流程
1.组织好sign-post需要的token,secrect
2.组织好发微博需要的信息
3.用sign-post进行签名
4.把签名结果从header中拿出来,转成entity,用httpclient以post的形式发送微博
二、简介
三、代码
1.xml
(1)activity_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:id="@+id/btn_launch_oauth"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Launch OAuth Flow"/> <Button
android:id="@+id/btn_sendWeiBo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送一条微博消息"
/>
</LinearLayout>
(2)AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.marsdroid.oauth03"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <activity android:name=".PrepareRequestTokenActivity" android:launchMode="singleTask">
<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="x-oauthflow" android:host="callback" />
</intent-filter>
</activity>
</application>
</manifest>
2.java
(1)MainActivity.java
package org.marsdroid.oauth03; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import oauth.signpost.OAuth;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button; public class MainActivity extends Activity { final String TAG = getClass().getName();
private SharedPreferences prefs;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); prefs = PreferenceManager.getDefaultSharedPreferences(this);
Button launchOauth = (Button) findViewById(R.id.btn_launch_oauth);
Button sendWeiBoButton = (Button)findViewById(R.id.btn_sendWeiBo); sendWeiBoButton.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
//收集需要向腾讯微博服务器端发送的数据
Map<String,String> map = new HashMap<String,String>();
map.put("content", "test");
map.put("clientip", "127.0.0.1");
map.put("format", "json");
//URL编码
List<String> decodeNames = new ArrayList<String>();
decodeNames.add("oauth_signature");//最后生成的oauth_signature可以包含“=“等,所以要进行url编码
//生成WeiboClient对象需要四个参数:Consumer_key,Consumer_key_secret,Oauth_tokent,OAuth_token_secret
String OAuth_token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String OAuth_token_secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
WeiBoClient weiBoClient = new WeiBoClient(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET, OAuth_token, OAuth_token_secret);
weiBoClient.doPost("http://open.t.qq.com/api/t/add",map,decodeNames);
}
}); launchOauth.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startActivity(new Intent().setClass(v.getContext(), PrepareRequestTokenActivity.class));
}
});
}
(2)Constants.java
package org.marsdroid.oauth03; public class Constants { public static final String CONSUMER_KEY = "99e9494ff07e42489f4ace16b63e1f47";
public static final String CONSUMER_SECRET = "154f6f9ab4c1cf527f8ad8ab1f8e1ec9"; public static final String REQUEST_URL = "https://open.t.qq.com/cgi-bin/request_token";
public static final String ACCESS_URL = "https://open.t.qq.com/cgi-bin/access_token";
public static final String AUTHORIZE_URL = "https://open.t.qq.com/cgi-bin/authorize"; public static final String ENCODING = "UTF-8"; public static final String OAUTH_CALLBACK_SCHEME = "x-oauthflow";
public static final String OAUTH_CALLBACK_HOST = "callback";
public static final String OAUTH_CALLBACK_URL = OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST; }
(3)WeiBoClient.java
import java.util.List;
import java.util.Map; import oauth.signpost.OAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer; import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.marsdroid.oauth03.utils.ApacheUtils;
import org.marsdroid.oauth03.utils.HttpUtils;
import org.marsdroid.oauth03.utils.OAuthUtils;
import org.marsdroid.oauth03.utils.StringUtils; public class WeiBoClient {
private OAuthConsumer consumer;
public WeiBoClient(){ } public WeiBoClient(String consumerKey,String consumerSecret,String oauthToken,String oauthTokenSecret){
//生成一个OAuthConsumer对象
consumer = new CommonsHttpOAuthConsumer(consumerKey, consumerSecret);
//设置OAuth_Token和OAuth_Token_Secret
consumer.setTokenWithSecret(oauthToken, oauthTokenSecret);
}
public String doPost(String url,Map<String,String> addtionalParams,List<String> decodeNames){
//生成一个HttpPost对象
HttpPost postRequest = new HttpPost(url);
//把腾讯微博所需要的数据也加上
consumer = OAuthUtils.addAddtionalParametersFromMap(consumer, addtionalParams);
try {
//用sing-post对信息签名,sing-post会把签名结果放到header中,但腾讯不支持
consumer.sign(postRequest);
} catch (Exception e) {
e.printStackTrace();
} Header oauthHeader = postRequest.getFirstHeader("Authorization");
System.out.println(oauthHeader.getValue());
String baseString = oauthHeader.getValue().substring(5).trim();
Map<String,String> oauthMap = StringUtils.parseMapFromString(baseString);
oauthMap = HttpUtils.decodeByDecodeNames(decodeNames, oauthMap);
addtionalParams = HttpUtils.decodeByDecodeNames(decodeNames, addtionalParams);
List<NameValuePair> pairs = ApacheUtils.convertMapToNameValuePairs(oauthMap);
List<NameValuePair> weiboPairs = ApacheUtils.convertMapToNameValuePairs(addtionalParams);
pairs.addAll(weiboPairs); HttpEntity entity = null;
HttpResponse response = null;
try {
entity = new UrlEncodedFormEntity(pairs);
postRequest.setEntity(entity);
response = new DefaultHttpClient().execute(postRequest);
} catch (Exception e) {
e.printStackTrace();
} String result = ApacheUtils.getResponseText(response); return result;
}
}
(4)ApacheUtils.java
package org.marsdroid.oauth03.utils; import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair; public class ApacheUtils {
public static List<NameValuePair> convertMapToNameValuePairs(Map<String, String> oauthMap) {
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
Set<String> keys = oauthMap.keySet();
Iterator<String> it = keys.iterator();
while(it.hasNext()){
String key = it.next();
String value = oauthMap.get(key);
NameValuePair pair = new BasicNameValuePair(key, value);
pairs.add(pair);
}
return pairs;
}
public static String getResponseText(HttpResponse response) {
HttpEntity responseEntity = response.getEntity();
InputStream input = null;
String result = null;
try {
input = responseEntity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line = null;
StringBuffer sb = new StringBuffer();
while((line = reader.readLine()) != null){
sb.append(line);
}
result = sb.toString();
System.out.println("reuslt---->" + result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
public static String parseStringFromEntity(HttpEntity entity){
String result = null;
try{
InputStream input = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line = null;
StringBuffer sb = new StringBuffer();
while((line = reader.readLine()) != null){
sb.append(line);
}
result = sb.toString();
}
catch(Exception e){
System.out.println(e);
}
return result;
}
}
(5)HttpUtils.java
import java.net.URLDecoder;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set; public class HttpUtils {
public static Map<String,String> decodeByDecodeNames(List<String> decodeNames,Map<String,String> map){
Set<String> keys = map.keySet();
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
String key = it.next();
String value = map.get(key);
for(String decodeName : decodeNames){
if(key.equals(decodeName)){
value = URLDecoder.decode(value);
map.put(key, value);
}
}
}
return map;
}
}
(6)OAuthUtils.java
import java.util.Iterator;
import java.util.Map;
import java.util.Set; import oauth.signpost.OAuthConsumer;
import oauth.signpost.http.HttpParameters; public class OAuthUtils { public static OAuthConsumer addAddtionalParametersFromMap(OAuthConsumer consumer,
Map<String, String> addtionalParams) {
Set<String> keys = addtionalParams.keySet();
Iterator<String> it = keys.iterator(); HttpParameters httpParameters = new HttpParameters();
while(it.hasNext()){
String key = it.next();
String value = addtionalParams.get(key);
httpParameters.put(key, value);
}
consumer.setAdditionalParameters(httpParameters);
return consumer;
}
}
(7)StringUtils.java
import java.util.HashMap;
import java.util.Map; public class StringUtils {
//key1="value1",key2="value2"........
public static Map<String,String> parseMapFromString(String baseString) {
String [] arr = baseString.split(",");
Map<String,String > result = new HashMap<String,String>();
for (int i = 0; i < arr.length; i++) {
String temp [] = arr[i].split("=");
String key = temp[0].trim();
//去掉双引号
String value = temp[1].substring(1, temp[1].length()-1);
result.put(key, value);
}
return result;
}
}
(8)UrlUtils.java
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set; import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair; public class UrlUtils {
public static String buildQueryString(Map<String,String> map){
List<NameValuePair> pairs = buildNameValuePairs(map);
String queryStr = URLEncodedUtils.format(pairs, "UTF-8");
return queryStr;
} public static String buildUrlByQueryStringAndBaseUrl(String baseUrl,String queryString){
return baseUrl + "?" + queryString;
} public static String buildUrlByQueryStringMapAndBaseUrl(String baseUrl,Map<String,String> map){
return buildUrlByQueryStringAndBaseUrl(baseUrl, buildQueryString(map));
} public static List<NameValuePair> buildNameValuePairs(Map<String,String> map){
Set<String> keySet = map.keySet();
List<NameValuePair> pairs = new ArrayList<NameValuePair>();
for(String key: keySet){
NameValuePair pair = new BasicNameValuePair(key, map.get(key));
pairs.add(pair);
}
return pairs;
}
}
(9)OAuthRequestTokenTask.java
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask; public class OAuthRequestTokenTask extends AsyncTask<Void, Void, Void>{ private Context context;
private OAuthConsumer consumer;
private OAuthProvider provider; public OAuthRequestTokenTask(Context context, OAuthConsumer consumer,
OAuthProvider provider) {
super();
this.context = context;
this.consumer = consumer;
this.provider = provider;
} @Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
try {
System.out.println("请求Request Token之前" + consumer.getToken());
final String url = provider.retrieveRequestToken(consumer, Constants.OAUTH_CALLBACK_URL);
System.out.println("请求Request Toker之后" + consumer.getToken());
System.out.println("url---->" + url);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
context.startActivity(intent);
} catch(Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
} }
(10)PrepareRequestTokenActivity.java
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthProvider;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager; public class PrepareRequestTokenActivity extends Activity { private OAuthConsumer consumer;
private OAuthProvider provider; @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState); System.setProperty("debug", "true");
consumer = new CommonsHttpOAuthConsumer(Constants.CONSUMER_KEY,
Constants.CONSUMER_SECRET);
provider = new CommonsHttpOAuthProvider(Constants.REQUEST_URL,
Constants.ACCESS_URL, Constants.AUTHORIZE_URL); new OAuthRequestTokenTask(this, consumer, provider).execute();
} @Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
final Uri uri = intent.getData();
System.out.println(uri.toString());
if (uri != null
&& uri.getScheme().equals(Constants.OAUTH_CALLBACK_SCHEME)) {
new RetrieveAccessTokenTask(this, consumer, provider, prefs)
.execute(uri);
finish();
}
}
}
(11)RetrieveAccessTokenTask.java
import oauth.signpost.OAuth;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.AsyncTask;
import android.util.Log; public class RetrieveAccessTokenTask extends AsyncTask<Uri, Void, Void> { final String TAG = "OAuth"; private Context context;
private OAuthProvider provider;
private OAuthConsumer consumer;
private SharedPreferences prefs; public RetrieveAccessTokenTask(Context context, OAuthConsumer consumer,OAuthProvider provider, SharedPreferences prefs) {
this.context = context;
this.consumer = consumer;
this.provider = provider;
this.prefs=prefs;
} @Override
protected Void doInBackground(Uri...params) {
final Uri uri = params[0]; System.out.println(getClass().getName()); final String oauth_verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER); try {
provider.retrieveAccessToken(consumer, oauth_verifier); final Editor edit = prefs.edit();
edit.putString(OAuth.OAUTH_TOKEN, consumer.getToken());
edit.putString(OAuth.OAUTH_TOKEN_SECRET, consumer.getTokenSecret());
edit.commit(); String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, ""); consumer.setTokenWithSecret(token, secret);
context.startActivity(new Intent(context,MainActivity.class)); Log.i(TAG, "OAuth - Access Token Retrieved");
System.out.println("------------>" + provider.getAccessTokenEndpointUrl()); } catch (Exception e) {
Log.e(TAG, "OAuth - Access Token Retrieval Error", e);
} return null;
}
}