BaiduCloudToken.java 2.95 KB
package com.ectrip.checkincar.plate;

import android.text.TextUtils;

import com.ectrip.checkincar.core.prefs.AppPrefs;

import org.json.JSONObject;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * 百度智能云 access_token 获取与缓存(AK/SK → token,有效期约 30 天)。
 * 全部方法须在后台线程调用。
 */
public final class BaiduCloudToken {

    private static final String TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";

    private static final OkHttpClient CLIENT = new OkHttpClient.Builder()
            .connectTimeout(5, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .build();

    private BaiduCloudToken() {
    }

    /** 缓存 token 仍有效(剩余 >24h)则直接用,否则重新获取。失败抛 IOException(中文 message)。 */
    public static String getToken() throws IOException {
        if (AppPrefs.isCloudTokenValid()) {
            return AppPrefs.getCloudToken();
        }
        return refreshToken();
    }

    /** 强制用当前 AK/SK 重新鉴权。 */
    public static String refreshToken() throws IOException {
        String ak = AppPrefs.getCloudAk();
        String sk = AppPrefs.getCloudSk();
        if (TextUtils.isEmpty(ak) || TextUtils.isEmpty(sk)) {
            throw new IOException("未配置 API Key / Secret Key");
        }
        RequestBody body = new FormBody.Builder()
                .add("grant_type", "client_credentials")
                .add("client_id", ak)
                .add("client_secret", sk)
                .build();
        Request request = new Request.Builder()
                .url(TOKEN_URL)
                .post(body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        try (Response response = CLIENT.newCall(request).execute()) {
            String rs = response.body() != null ? response.body().string() : "";
            JSONObject json = new JSONObject(rs);
            String token = json.optString("access_token", null);
            if (TextUtils.isEmpty(token)) {
                AppPrefs.clearCloudToken();
                String err = json.optString("error_description",
                        json.optString("error", "鉴权失败"));
                throw new IOException("API Key/Secret 校验失败:" + err);
            }
            long expiresIn = json.optLong("expires_in", 2592000L);
            AppPrefs.setCloudToken(token, expiresIn);
            return token;
        } catch (IOException e) {
            AppPrefs.clearCloudToken();
            throw new IOException("无法连接百度云,请检查外网/WiFi(" + e.getMessage() + ")");
        } catch (Exception e) {
            AppPrefs.clearCloudToken();
            throw new IOException("鉴权响应解析失败:" + e.getMessage());
        }
    }
}