/** * $id$ * Copyright 2011-2012 Renren Inc. All rights reserved. */ package com.renren.api.connect.android; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; import android.os.Bundle; import com.renren.api.connect.android.exception.RenrenAuthError; import com.renren.api.connect.android.view.RenrenAuthListener; /** * 提供方法检查是否有调用相关接口的权限以及认证信息等 * * @author Shaofeng Wang (shaofeng.wang@renren-inc.com) */ public class AuthorizationHelper { private static final String PERMISSIONS = "permissions"; //用于在验证Activity与调用者间传递结果的key值 private static final String KEY_RESPONSE_TYPE = "type"; private static final String AUTH_ERROR = "auth_error"; private static final String AUTH_COMPLETE = "auth_complete"; private static final String AUTH_CANCEL_LOGIN = "auth_cancel_login"; private static final String AUTH_CANCEL = "key_auth_cancel"; private static final String KEY_AUTH_ERROR = "error"; private static final String KEY_AUTH_ERROR_DESCRIPTION = "error_description"; private static final String KEY_AUTH_ERROR_URI = "error_uri"; private static final String KEY_RESPONSE_BUNDLE = "response_bundle"; private static final String ACTION = "com.renren.api.connect.android" + ".AuthorizationHelper.RenrenAuthAdapter"; private static Renren renren; /** * 检查当前是否有权限发送相关请求,若无权限,引导用户进行认证 * <p>注意: * <p>使用者需要在AndroidManifest.xml中声明Activity如下: * <p> * <activity android:name= * "com.renren.api.connect.android.AuthorizationHelper$BlockActivity" * android:theme="@android:style/Theme.Dialog" * ></activity> * @param renren * {@link Renren}的对象 * @param activity * 当前Activity * @param permissions * 访问的api需要的权限列表 * @param listener * 认证结果的监听器 */ public synchronized static void check(Renren renren, Activity activity, String[] permissions, RenrenAuthListener listener) { //首先检查当前sessionKey是否正确 if(renren.isSessionKeyValid()) { if(listener != null) { Bundle bundle = new Bundle(); bundle.putString("session_key", renren.getSessionKey()); bundle.putString("access_token", renren.getAccessToken()); bundle.putLong("user_id", renren.getCurrentUid()); listener.onComplete(bundle); } return; } //若当前sessionKey 不正确,则启动认证过程 AuthorizationHelper.renren = renren; int requestCode = Math.abs((int)System.currentTimeMillis()); //注册BroadcastReceiver if(listener != null) { RenrenAuthAdapter adapter = new RenrenAuthAdapter(listener); IntentFilter filter = new IntentFilter(); filter.addAction(ACTION); activity.registerReceiver(adapter, filter); } //启动验证 Intent intent = new Intent(activity, BlockActivity.class); Bundle bundle = new Bundle(); bundle.putStringArray(PERMISSIONS, permissions); intent.putExtras(bundle); activity.startActivityForResult(intent, requestCode); } /** * 拦截认证的返回信息,并将结果转发至调用者传入的listener。开发者不直接使用该类型。 * * @author Shaofeng Wang (shaofeng.wang@renren-inc.com) */ private static class RenrenAuthAdapter extends BroadcastReceiver{ /** * 调用者传入的listener引用 */ private RenrenAuthListener listener; public RenrenAuthAdapter(RenrenAuthListener listener) { this.listener = listener; } @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); if(bundle != null) { if(bundle.containsKey(KEY_RESPONSE_TYPE)) { String code = bundle.getString(KEY_RESPONSE_TYPE); if(code.equals(AUTH_COMPLETE)) { Bundle responseBundle = bundle.getBundle(KEY_RESPONSE_BUNDLE); listener.onComplete(responseBundle); } else if(code.equals(AUTH_ERROR)) { String error = bundle.getString(KEY_AUTH_ERROR); String errorDescription = bundle.getString(KEY_AUTH_ERROR_DESCRIPTION); String errorUri = bundle.getString(KEY_AUTH_ERROR_URI); listener.onRenrenAuthError(new RenrenAuthError( error, errorDescription, errorUri)); } else if(code.equals(AUTH_CANCEL_LOGIN)) { listener.onCancelLogin(); } else if(code.equals(AUTH_CANCEL)) { Bundle responseBundle = bundle.getBundle(KEY_RESPONSE_BUNDLE); listener.onCancelAuth(responseBundle); } else { } } } try { context.unregisterReceiver(this); } catch (Exception e) { Util.logger(e.getMessage()); } } } /** * 拦截SSO以及OAuth认证的结果,开发者不直接使用该类型 */ public static final class BlockActivity extends Activity { private static final String KEY_PARCEL_RENREN = "renren"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState != null) { renren = savedInstanceState.getParcelable(KEY_PARCEL_RENREN); renren.init(this); } this.setVisible(false); authorize(); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { if (renren == null) { renren = savedInstanceState.getParcelable(KEY_PARCEL_RENREN); renren.init(this); } super.onRestoreInstanceState(savedInstanceState); } @Override protected void onSaveInstanceState(Bundle outState) { outState.putParcelable(KEY_PARCEL_RENREN, renren); super.onSaveInstanceState(outState); } @Override protected void onStart() { super.onStart(); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { renren.authorizeCallback(requestCode, resultCode, data); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } /** * 使用SSO验证方式 */ private void authorize() { Bundle bundle = getIntent().getExtras(); String[] permissions = bundle.getStringArray(PERMISSIONS); renren.authorize(this, permissions, new RenrenAuthListener() { @Override public void onRenrenAuthError(RenrenAuthError renrenAuthError) { Bundle bundle = new Bundle(); bundle.putString(KEY_RESPONSE_TYPE, AUTH_ERROR); if(renrenAuthError != null) { bundle.putString(KEY_AUTH_ERROR, renrenAuthError.getError()); bundle.putString(KEY_AUTH_ERROR_DESCRIPTION, renrenAuthError.getErrorDescription()); bundle.putString(KEY_AUTH_ERROR_URI, renrenAuthError.getErrorUri()); } Intent intent = new Intent(); intent.setAction(ACTION); intent.putExtras(bundle); sendBroadcast(intent); finish(); } @Override public void onComplete(Bundle values) { values.putString(KEY_RESPONSE_TYPE, AUTH_COMPLETE); Intent intent = new Intent(); intent.putExtras(values); intent.setAction(ACTION); sendBroadcast(intent); finish(); } @Override public void onCancelLogin() { Bundle bundle = new Bundle(); bundle.putString(KEY_RESPONSE_TYPE, AUTH_CANCEL_LOGIN); Intent intent = new Intent(); intent.putExtras(bundle); intent.setAction(ACTION); sendBroadcast(intent); finish(); } @Override public void onCancelAuth(Bundle values) { values.putString(KEY_RESPONSE_TYPE, AUTH_CANCEL); Intent intent = new Intent(); intent.putExtras(values); intent.setAction(ACTION); sendBroadcast(intent); finish(); } }, 1); } }; }