很久没有写关于微博的东西,最近在写微博的认证,结果发现微博的认证接口发生了变化了,搞得我有点麻烦,所以就写下来给以后的我使用
新浪提供了一个SDK来获取认证信息,但是调用新浪的SDK认证UI是在是太难看了。弹出一个Dialog也就算了,输入的时候还会折叠,导致可视面积过少
所以还是自力更生,自己写一个吧(不过要使用SSO登陆还是需要新浪的SDK的)
认证过程
1.请求https://api.weibo.com/oauth2/authorize 获取Code
例子:
public static final String URL_WEIBO_AUTHORIZATION = "https://api.weibo" + ".com/oauth2/authorize?client_id="+APP_KEY+"&response_type=code&redirect_uri=" +URL_REDIRECT+"&display=mobile";2.页面会重定向到redirect_uri(这个是你在新浪上填写的回调地址),后面接着code=””
例如:https://api.weibo.com/oauth2/default.html?code=kjsdjsdjkjkdjkdsjkjksdjkdsjkks
我们就是要截取后面的Code
3.获取到Code后,访问这个地址https://api.weibo.com/oauth2/access_token 获取access_token
注意,这里必须是要使用POST方法 不能使用浏览器调试了,以前是可以的。
具体参数查看http://open.weibo.com/wiki/Oauth2/access_token,这里不多说了。下面开始贴代码
AuthorizeActivity,这个是套了一个webView的Acitivity布局就贴出来的.所有的认证过程都在这个类中。
import android.app.Activity; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.ProgressBar; import android.widget.Toast; import com.weibo.sdk.android.Oauth2AccessToken; import org.json.JSONException; import org.json.JSONObject; import name.auggie.mumu.bean.WeiboUserInfo; import name.auggie.mumu.net.IEasy; import name.auggie.mumu.util.WeiboUtil; public class AuthorizeActivity extends Activity implements View.OnClickListener { public static final String TAG = AuthorizeActivity.class.getName(); public static class ModelCode { /** * 新浪微博 */ public static final int SINA_WEIBO = 0x000001; /** * QQ空间 */ public static final int QQ_ZONE = 0x000002; } ProgressDialog dialog; private int currentModel; private WebView mWebView; private MyWebViewClient mWebViewClient; private ProgressBar progressBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_autiorize); currentModel = getIntent().getIntExtra("model", -1); if (currentModel == -1) { Toast.makeText(this, R.string.error_code, Toast.LENGTH_LONG).show(); } initView(); initWebView(); } private void initSavaInstance(Bundle savedIntanceState) { } private void initView() { progressBar = (ProgressBar) findViewById(R.id.progressbar); findViewById(R.id.tView_back).setOnClickListener(this); dialog = new ProgressDialog(this); dialog.setCanceledOnTouchOutside(false); } private void initWebView() { mWebView = (WebView) findViewById(R.id.wView_login); WebSettings settings = mWebView.getSettings(); settings.setJavaScriptEnabled(true);//启用JavaScript mWebViewClient = new MyWebViewClient(); mWebView.setWebViewClient(mWebViewClient); switch (currentModel) { case ModelCode.SINA_WEIBO: mWebView.loadUrl(WeiboUtil.URL_WEIBO_AUTHORIZATION); break; case ModelCode.QQ_ZONE: break; } } @Override public void onClick(View v) { switch (v.getId()) { case R.id.tView_back: onBackPressed(); break; } } Thread getToken; class MyWebViewClient extends WebViewClient { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); progressBar.setVisibility(View.VISIBLE); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); Log.v(TAG, "url = " + url); progressBar.setVisibility(View.GONE); //用户点击确认后跳转到空白页面获取code if (url.startsWith(WeiboUtil.URL_REDIRECT)) { int startIndex = url.lastIndexOf("code="); if (startIndex == -1) { Log.e(TAG, "not find code"); AuthorizeActivity.this.finish(); return; } final String code = url.substring(startIndex + "code=".length()); Log.v(TAG, "code=" + code); Toast.makeText(AuthorizeActivity.this,R.string.log_in_successd,Toast.LENGTH_SHORT).show(); dialog.setMessage(getString(R.string.loading_user_information)); dialog.show(); getToken = new Thread(){ @Override public void run(){ IEasy iEasy = new IEasy(); String result = iEasy.getWeiboToken(code); Log.v(TAG,"result ="+result); if(result != null){ try { JSONObject jResult = new JSONObject(result); String access_token = jResult.getString("access_token"); long expires_in = jResult.getLong("expires_in"); String uid = jResult.getString("uid"); //保存到轻量级缓存中 WeiboUserInfo info = new WeiboUserInfo(AuthorizeActivity.this, uid,new Oauth2AccessToken(access_token,expires_in+"")); info.save(); Message msg = handler.obtainMessage(); msg.what = LOADING_INFORMATION_SUCCEED; Object[] objects = {AuthorizeActivity.this,dialog, getString(R.string.loading_succeed)}; msg.obj = objects; handler.sendMessage(msg); } catch (JSONException e) { e.printStackTrace(); Message msg = handler.obtainMessage(); Object[] objs = {dialog, getString(R.string.loading_information_faild), AuthorizeActivity.this}; msg.obj = objs; msg.what = LOADING_INFORMATION_FAIL; } } } }; getToken.start(); } } } @Override public void onBackPressed() { super.onBackPressed(); } public static final int LOADING_INFORMATION_FAIL =0x00000001; public static final int LOADING_INFORMATION_SUCCEED = 0X0000002; private static class MyHandler extends Handler{ @Override public void handleMessage(Message msg) { switch (msg.what){ case LOADING_INFORMATION_FAIL: Object[] objs = (Object[]) msg.obj; ProgressDialog progressDialog = (ProgressDialog) objs[0]; progressDialog.setMessage(objs[1].toString()); Activity activity = (Activity) objs[2]; activity.onBackPressed(); break; case LOADING_INFORMATION_SUCCEED: Object[] objects = (Object[]) msg.obj; activity = (Activity) objects[0]; activity.setResult(1); progressDialog = (ProgressDialog) objects[1]; progressDialog.setMessage(objects[2].toString()); activity.finish(); break; } } } private Handler handler = new MyHandler(); @Override protected void onDestroy() { super.onDestroy(); if(dialog != null && dialog.isShowing()){ dialog.dismiss(); } } }
IEasy.java
import org.apache.http.NameValuePair; import org.apache.http.message.BasicNameValuePair; import java.io.IOException; import name.auggie.mumu.util.WeiboUtil; /** * Created With Android Studio * User Auggie Liang * Date 13-10-3 * Time 上午12:42 * 网络接口 */ public class IEasy { private HttpUtil httpUtil = new HttpUtil(); /** * 获取微博的Token * @param code * @return */ public String getWeiboToken(String code){ NameValuePair[] nameValuePairs = { new BasicNameValuePair("client_id", WeiboUtil.APP_KEY), new BasicNameValuePair("client_secret",WeiboUtil.APP_SECRET), new BasicNameValuePair("grant_type","authorization_code"), new BasicNameValuePair("code",code), new BasicNameValuePair("redirect_uri", WeiboUtil.URL_REDIRECT) }; try { return httpUtil.doHttpPost(WeiboUtil.URL_GET_ACCESS_TOKEN,nameValuePairs); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 上传文字微博 * @param accessToken token 必须 * @param status 微博内容 ,少于140字 必须 * @param visible 微博的可见性,0:所有人能看,1:仅自己可见,2:密友可见,3:指定分组可见,默认为0 不是必须,可以为null * @param listId 微博的保护投递指定分组ID,只有当visible参数为3时生效且必选。 * @param lat 纬度,有效范围:-90.0到+90.0,+表示北纬,默认为0.0。 * @param longlong 经度,有效范围:-180.0到+180.0,+表示东经,默认为0.0。 * @param annotations 元数据,主要是为了方便第三方应用记录一些适合于自己使用的信息,每条微博可以包含一个或者多个元数据,必须以json * 字串的形式提交,字串长度不超过512个字符,具体内容可以自定 * @return */ public String uploadWeiboText(String accessToken,String status,String visible,String listId, String lat,String longlong,String annotations){ NameValuePair[] nameValuePairs = { new BasicNameValuePair("access_token", accessToken), new BasicNameValuePair("status",status), new BasicNameValuePair("visible",visible), new BasicNameValuePair("list_id",listId), new BasicNameValuePair("lat", lat), new BasicNameValuePair("long", longlong), new BasicNameValuePair("annotations", annotations) }; try { return httpUtil.doHttpPost(WeiboUtil.URL_UPLOAD_WEIBO_TEXT,nameValuePairs); } catch (IOException e) { e.printStackTrace(); } return null; } }
HttpUtil.java
package name.auggie.mumu.net; import android.util.Log; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.params.HttpClientParams; import org.apache.http.client.utils.URLEncodedUtils; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.HttpConnectionParams; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; /** * Created With Android Studio * User Auggie Liang * Date 13-10-2 * Time 下午8:26 * 访问http使用 */ public class HttpUtil { public static final String TAG = HttpUtil.class.getName(); public static final String CLIENT_VERSION_HEADER = "User-Agent"; public static final int TIME_OUT = 60; private DefaultHttpClient mHttpClient ; public HttpUtil(){ mHttpClient = createHttpClient(); } public static DefaultHttpClient createHttpClient(){ final SchemeRegistry supportedSchemes = new SchemeRegistry(); supportedSchemes.register(new Scheme("http",PlainSocketFactory.getSocketFactory(),80)); supportedSchemes.register(new Scheme("https", SSLSocketFactory.getSocketFactory(),443)); HttpParams httpParams = createHttpParams(); HttpClientParams.setRedirecting(httpParams,false); ClientConnectionManager ccm = new ThreadSafeClientConnManager(httpParams, supportedSchemes); return new DefaultHttpClient(ccm,httpParams); } /** * 做post请求 * @param url * @param nameValuePairs * @return * @throws IOException */ public String doHttpPost(String url, NameValuePair... nameValuePairs) throws IOException { HttpPost httpPost = createHttpPost(url,nameValuePairs); HttpResponse response = executeHttpRequest(httpPost); int statusCode = response.getStatusLine().getStatusCode(); switch (statusCode){ case 200: return EntityUtils.toString(response.getEntity(),HTTP.UTF_8); default: Log.e(TAG,"error stateCode = " + statusCode); Log.e(TAG,"result ="+EntityUtils.toString(response.getEntity(),HTTP.UTF_8)); } return null; } /*** * 做get请求 * @param url * @param nameValuePairs * @return * @throws IOException */ public String doHttpGet(String url, NameValuePair... nameValuePairs) throws IOException { HttpGet httpPost = createHttpGet(url, nameValuePairs); HttpResponse response = executeHttpRequest(httpPost); int statusCode = response.getStatusLine().getStatusCode(); switch (statusCode){ case 200: return EntityUtils.toString(response.getEntity(),HTTP.UTF_8); default: Log.e(TAG,"error stateCode = " + statusCode); } return null; } /** * 创建post连接 * @param url * @param nameValuePairs * @return */ public HttpPost createHttpPost(String url, NameValuePair... nameValuePairs) { HttpPost httpPost = new HttpPost(url); try { httpPost.setEntity(new UrlEncodedFormEntity(stripNulls(nameValuePairs), HTTP.UTF_8)); } catch (UnsupportedEncodingException e) { Log.v(TAG, e.getMessage()); // e.printStackTrace(); } return httpPost; } /** * 创建httpGet连接 * @param url * @param nameValuePairs * @return */ public HttpGet createHttpGet(String url,NameValuePair... nameValuePairs){ String query = URLEncodedUtils.format(stripNulls(nameValuePairs),HTTP.UTF_8); return new HttpGet(url+"?"+query); } /** * 去掉空变量 * * @param nameValuePairs * @return */ private List<NameValuePair> stripNulls(NameValuePair... nameValuePairs) { List<NameValuePair> params = new ArrayList<NameValuePair>(); for (NameValuePair param : nameValuePairs) { if (param.getValue() != null) { params.add(param); } } return params; } public HttpResponse executeHttpRequest(HttpRequestBase httpRequest) throws IOException { try { mHttpClient.getConnectionManager().closeExpiredConnections(); return mHttpClient.execute(httpRequest); } catch (IOException e) { httpRequest.abort(); throw e; } } private static final HttpParams createHttpParams() { final HttpParams params = new BasicHttpParams(); HttpConnectionParams.setStaleCheckingEnabled(params, false); HttpConnectionParams.setConnectionTimeout(params, TIME_OUT * 1000); HttpConnectionParams.setSoTimeout(params, TIME_OUT * 1000); HttpConnectionParams.setSocketBufferSize(params, 8192); return params; } }