/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package cn.bidaround.ytcore.kaixin; import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; import java.security.GeneralSecurityException; import java.security.cert.X509Certificate; import java.util.Map; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.X509TrustManager; import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.text.TextUtils; import android.webkit.CookieSyncManager; import cn.bidaround.ytcore.data.YtPlatform; import cn.bidaround.ytcore.login.AuthListener; public class Kaixin { /** * 组件申请时获得的api key,在调用接口时它代表该组件的唯一身份。 */ public static final String API_KEY = YtPlatform.PLATFORM_KAIXIN.getAppId(); /** * 组件申请时获得的secret key */ public static final String SECRET_KEY = YtPlatform.PLATFORM_KAIXIN.getAppSecret(); /** * 组件申请时填写的网站地址 */ public static String KX_AUTHORIZE_CALLBACK_URL = "http://localhost/"; /** * Kaixin授权地址 */ public static final String KX_AUTHORIZE_URL = "http://api.kaixin001.com/oauth2/authorize"; /** * rest api接口地址 */ public static String KX_REST_URL = "https://api.kaixin001.com"; /** * 常量字符串 */ public static final String ACCESS_TOKEN = "access_token"; public static final String REFRESH_TOKEN = "refresh_token"; public static final String EXPIRES_IN = "expires_in"; public static final String ACCESS_DENIED = "access_denied"; public static final String LOGIN_DENIED = "login_denied"; /** * 本地缓存字段 */ private static final String KAIXIN_SDK_STORAGE = "kaixin_sdk_storage"; private static final String KAIXIN_SDK_STORAGE_ACCESS_TOKEN = "kaixin_sdk_storage_access_token"; private static final String KAIXIN_SDK_STORAGE_REFRESH_TOKEN = "kaixin_sdk_storage_refresh_token"; private static final String KAIXIN_SDK_STORAGE_EXPIRES = "kaixin_sdk_storage_expires"; /** * Kaixin单实例 */ private static Kaixin instance = null; public static synchronized Kaixin getInstance() { if (null == instance) instance = new Kaixin(); return instance; } private X509TrustManager xtm = new X509TrustManager() { public void checkClientTrusted(X509Certificate[] chain, String authType) { } public void checkServerTrusted(X509Certificate[] chain, String authType) { } public X509Certificate[] getAcceptedIssuers() { return null; } }; private HostnameVerifier hnv = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; } }; @SuppressLint("TrulyRandom") private Kaixin() { SSLContext sslContext = null; try { sslContext = SSLContext.getInstance("TLS"); X509TrustManager[] xtmArray = new X509TrustManager[] { xtm }; sslContext.init(null, xtmArray, new java.security.SecureRandom()); } catch (GeneralSecurityException gse) { } if (sslContext != null) { HttpsURLConnection.setDefaultSSLSocketFactory(sslContext .getSocketFactory()); } HttpsURLConnection.setDefaultHostnameVerifier(hnv); } /** * 完成登录并获取access_token(User-Agent Flow方式) * * @param context * @param listener */ public void authorize(final Context context, final AuthListener listener) { this.authorize(context, null, listener); } /** * 完成登录并获取access_token(User-Agent Flow方式) * * @param context * @param permissions * @param listener */ public void authorize(final Context context, String[] permissions, final AuthListener listener) { this.authorize(context, permissions, listener, KX_AUTHORIZE_CALLBACK_URL, "token"); } /** * 完成登录并获取access_token(User-Agent Flow方式) * * @param context * @param permissions * 权限列表,参见http://wiki.open.kaixin001.com/index.php?id=OAuth%E6%96% * 87%E6%A1%A3#REST%E6% * 8E%A5%E5%8F%A3%E5%92%8COAuth%E6%9D%83%E9%99%90%E5%AF%B9%E7%85% * A 7%E8%A1%A8 * @param listener * @param redirectUrl * @param responseType */ private void authorize(final Context context, String[] permissions, final AuthListener listener, final String redirectUrl, String responseType) { CookieSyncManager.createInstance(context); Bundle params = new Bundle(); params.putString("client_id", API_KEY); params.putString("response_type", responseType); params.putString("redirect_uri", redirectUrl); params.putString("state", ""); params.putString("display", "page"); params.putString("oauth_client", "1"); if (permissions != null && permissions.length > 0) { String scope = TextUtils.join(" ", permissions); params.putString("scope", scope); } String url = KX_AUTHORIZE_URL + "?" + KaixinUtil.encodeUrl(params); new KaixinAuth(context, listener, url); } /** * 判断会话是否有效 * * @return 会话是否有效 true : 有效 ; false : 无效 */ public boolean isSessionValid(Context context) { return !TextUtils.isEmpty(getAccessToken(context)) && (getAccessExpires(context) != 0 && (System.currentTimeMillis() < getAccessExpires(context))); } public void writeAccessToken(Context context, String accessToken, String refreshToken, String expiresIn){ SharedPreferences pref = context.getSharedPreferences(KAIXIN_SDK_STORAGE, Context.MODE_PRIVATE); Editor editor = pref.edit(); editor.putString(KAIXIN_SDK_STORAGE_ACCESS_TOKEN, accessToken); editor.putString(KAIXIN_SDK_STORAGE_REFRESH_TOKEN, refreshToken); editor.putLong(KAIXIN_SDK_STORAGE_EXPIRES, System.currentTimeMillis() + Long.parseLong(expiresIn) * 1000); editor.commit(); } public String getAccessToken(Context context) { SharedPreferences pref = context.getSharedPreferences(KAIXIN_SDK_STORAGE, Context.MODE_PRIVATE); return pref.getString(KAIXIN_SDK_STORAGE_ACCESS_TOKEN, null); } public String getRefreshToken(Context context) { SharedPreferences pref = context.getSharedPreferences(KAIXIN_SDK_STORAGE, Context.MODE_PRIVATE); return pref.getString(KAIXIN_SDK_STORAGE_REFRESH_TOKEN, null); } public long getAccessExpires(Context context) { SharedPreferences pref = context.getSharedPreferences(KAIXIN_SDK_STORAGE, Context.MODE_PRIVATE); return pref.getLong(KAIXIN_SDK_STORAGE_EXPIRES, 0); } /** * 上传内容接口,采用multi-part post方式上传数据 * * @param params * 参数列表 * @param photos * key-value形式的图像数据集, key为filename, * value为图像数据,参数类型可以是InputStream或byte[] * 如果参数类型为InputStream,会在openUrl函数中将此流关闭 * @return 服务器返回的JSON串 * @throws FileNotFoundException * @throws MalformedURLException * @throws IOException */ public String uploadContent(Context context, String restInterface, Bundle params, Map<String, Object> photos) throws FileNotFoundException, MalformedURLException, IOException { if (params == null) { params = new Bundle(); } params.putString("access_token", getAccessToken(context)); return KaixinUtil.openUrl(context, KX_REST_URL + restInterface, "POST", params, photos); } /** * 调用kaixin rest apis * * @param context * 应用环境 * @param restInterface * rest api接口 * @param params * key-value形式的参数集,key为参数名,value为参数值,数据类型可以是String或byte[] * @param httpMethod * GET 或 POST * @return 服务器返回的JSON串 * @throws FileNotFoundException * @throws MalformedURLException * @throws IOException */ public String request(Context context, String restInterface, Bundle params, String httpMethod) throws FileNotFoundException, MalformedURLException, IOException { if (params == null) { params = new Bundle(); } params.putString("access_token", getAccessToken(context)); return KaixinUtil.openUrl(context, KX_REST_URL + restInterface, httpMethod, params, null); } // /** // * 读取本地缓存 // * // * @param context // * @return 读取本地缓存是否成功 // */ // public boolean loadStorage(Context context) { // SharedPreferences sp = context.getSharedPreferences(KAIXIN_SDK_STORAGE, Context.MODE_PRIVATE); // String accessToken = sp.getString(KAIXIN_SDK_STORAGE_ACCESS_TOKEN, null); // if (accessToken == null) { // return false; // } // // String refreshToken = sp.getString(KAIXIN_SDK_STORAGE_REFRESH_TOKEN, // null); // if (refreshToken == null) { // return false; // } // // long expires = sp.getLong(KAIXIN_SDK_STORAGE_EXPIRES, 0); // long currenct = System.currentTimeMillis(); // if (expires < (currenct - ONE_HOUR)) { // clearStorage(context); // return false; // } // // writeAccessToken(context, accessToken, refreshToken, String.valueOf(expires)); // return true; // } // /** // * 清除本地缓存 // * // * @param context // */ // public void clearStorage(Context context) { // Editor editor = context.getSharedPreferences(KAIXIN_SDK_STORAGE, // Context.MODE_PRIVATE).edit(); // editor.remove(KAIXIN_SDK_STORAGE_ACCESS_TOKEN); // editor.remove(KAIXIN_SDK_STORAGE_REFRESH_TOKEN); // editor.remove(KAIXIN_SDK_STORAGE_EXPIRES); // editor.commit(); // } }