package com.ectrip.checkincar.license; import android.content.Context; import android.text.TextUtils; import com.baidu.vis.ocrgve.plate.OcrgveEnginePlate; import com.baidu.vis.unified.license.AndroidLicenser; import com.baidu.vis.unified.license.BDLicenseAuthInfo; import com.baidu.vis.unified.license.BDLicenseActivator; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; /** * 百度离线授权 + 模型初始化管理(单例)。 * 所有方法必须在后台线程调用;SDK 全部调用用 try/catch 兜底,防止 so 异常导致崩溃。 */ public class LicenseManager { /** 正式授权拿到后在此配置(license.license 内容中的 key 与 assets 中的文件名),一期留空 */ private static final String LICENSE_KEY = ""; private static final String LICENSE_FILE = "ocrgve.license"; private static volatile LicenseManager instance; private OcrgveEnginePlate engine; private int algId = -1; private String lastError = "未授权"; private LicenseManager() { } public static LicenseManager get() { if (instance == null) { synchronized (LicenseManager.class) { if (instance == null) { instance = new LicenseManager(); } } } return instance; } public OcrgveEnginePlate getEngine() { return engine; } public int getAlgId() { if (algId < 0) { try { algId = OcrgveEnginePlate.getAlgorithmId(); android.util.Log.i("LicenseManager", "getAlgorithmId() = " + algId); } catch (Throwable t) { algId = 0; android.util.Log.e("LicenseManager", "getAlgorithmId() failed", t); } } return algId; } public String getLastError() { return lastError; } /** 设备指纹(授权绑定依据,非硬件 SN)。失败返回空串。 */ public String getDeviceId(Context context) { try { String id = AndroidLicenser.getDeviceId(context.getApplicationContext()); return id == null ? "" : id.trim().toUpperCase(Locale.US); } catch (Throwable t) { return ""; } } /** * 确保授权有效并完成模型初始化(只初始化一次)。 * @return true 引擎可识别 */ public synchronized boolean ensureReady(Context context) { if (engine != null) { return true; } Context app = context.getApplicationContext(); try { // 1. 已有授权(上次在线激活缓存) if (checkAuthSuccess(app)) { return initEngine(app); } // 2. assets 离线授权文件(正式部署方式) if (!TextUtils.isEmpty(LICENSE_KEY)) { AndroidLicenser.ErrorCode code = AndroidLicenser.getInstance().authFromFile(app, LICENSE_KEY, LICENSE_FILE, true, getAlgId()); if (code == AndroidLicenser.ErrorCode.SUCCESS) { return initEngine(app); } lastError = explain(code); return false; } lastError = "未授权(请在设置中输入序列号联网激活,或放入正式授权文件)"; return false; } catch (Throwable t) { lastError = "授权初始化异常: " + t.getMessage(); return false; } } /** * 序列号联网激活,成功后立即初始化模型。 * @return 0 成功;其余为 SDK 错误码 */ public synchronized int activateOnline(Context context, String serial) { Context app = context.getApplicationContext(); String sn = serial.trim(); String deviceId = getDeviceId(app); int alg = getAlgId(); android.util.Log.i("LicenseManager", "=== 联网激活开始 ==="); android.util.Log.i("LicenseManager", " serial=[" + sn + "] len=" + sn.length()); android.util.Log.i("LicenseManager", " algId=" + alg); android.util.Log.i("LicenseManager", " packageName=" + app.getPackageName()); android.util.Log.i("LicenseManager", " deviceFingerprint=" + deviceId); try { int ret = BDLicenseActivator.initLicenseOnLine(app, sn, "", alg); android.util.Log.i("LicenseManager", " initLicenseOnLine ret=" + ret); if (ret == 0) { android.util.Log.i("LicenseManager", "=== 联网激活成功,开始初始化模型 ==="); if (!initEngine(app)) { android.util.Log.e("LicenseManager", "=== 模型初始化失败: " + lastError + " ==="); return -100; } android.util.Log.i("LicenseManager", "=== 全部成功 ==="); return 0; } // SDK 返回错误码,把完整信息拼到 lastError 供界面展示 lastError = "在线激活失败(ret=" + ret + ")\n" + "序列号: " + sn + "\n" + "算法ID: " + alg + "\n" + "包名: " + app.getPackageName() + "\n" + "设备指纹: " + deviceId; android.util.Log.e("LicenseManager", "=== 激活失败 ===\n" + lastError); return ret; } catch (Throwable t) { // 完整堆栈输出到 logcat android.util.Log.e("LicenseManager", "=== 激活异常 ===", t); android.util.Log.e("LicenseManager", " serial=" + sn + " algId=" + alg + " pkg=" + app.getPackageName() + " device=" + deviceId); // 把异常完整信息存入 lastError 供界面展示 java.io.StringWriter sw = new java.io.StringWriter(); t.printStackTrace(new java.io.PrintWriter(sw)); lastError = "在线激活异常: " + t.getClass().getName() + ": " + t.getMessage() + "\n\n序列号: " + sn + "\n算法ID: " + alg + "\n包名: " + app.getPackageName() + "\n设备指纹: " + deviceId + "\n\n完整堆栈:\n" + sw.toString(); return -1; } } private boolean checkAuthSuccess(Context app) { try { return AndroidLicenser.getInstance().getAuthStatus(getAlgId()) == AndroidLicenser.ErrorCode.SUCCESS; } catch (Throwable t) { return false; } } private boolean initEngine(Context app) { try { OcrgveEnginePlate e = new OcrgveEnginePlate(); OcrgveEnginePlate.setPreFiltering(false); int ret = e.initFromAssets(app); // 0 成功;多线程/重复初始化时也视为成功 if (ret == 0) { engine = e; lastError = ""; return true; } lastError = "模型初始化失败(" + initErrText(ret) + ")"; return false; } catch (Throwable t) { lastError = "模型初始化异常: " + t.getMessage(); return false; } } /** 授权状态摘要(设置页展示) */ public String getStatusText(Context context) { if (engine != null) { return "已授权 · 模型已加载"; } try { AndroidLicenser.ErrorCode code = AndroidLicenser.getInstance().getAuthStatus(getAlgId()); if (code == AndroidLicenser.ErrorCode.SUCCESS) { return "已授权 · 模型未加载"; } return explain(code); } catch (Throwable t) { android.util.Log.w("LicenseManager", "getAuthStatus: " + t.getClass().getSimpleName() + " " + t.getMessage()); return "未授权(待激活)"; } } /** 授权到期时间 yyyy-MM-dd,取不到返回空串。注意:未授权时 authGetAuthInfo 会 native 崩溃,必须先判状态 */ public String getExpireText(Context context) { try { if (!checkAuthSuccess(context.getApplicationContext())) { return ""; } BDLicenseAuthInfo info = AndroidLicenser.getInstance().authGetAuthInfo(context.getApplicationContext(), getAlgId()); if (info != null && info.expireTime > 0) { return new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA).format(new Date(info.expireTime)); } } catch (Throwable t) { // ignore } return ""; } public synchronized void release() { if (engine != null) { try { engine.uninit(); } catch (Throwable ignored) { } engine = null; } } private static String initErrText(int code) { switch (code) { case 0: return "成功"; case 4: return "鉴权失败"; case 6: return "重复初始化"; case 9: return "模型文件未找到"; default: return "错误码" + code; } } private static String explain(AndroidLicenser.ErrorCode code) { if (code == null) { return "未知授权错误"; } switch (code) { case SUCCESS: return "已授权"; case LICENSE_DEVICE_ID_CHECK_ERROR: return "设备指纹不匹配"; case LICENSE_PACKAGE_NAME_CHECK_ERROR: return "包名不匹配"; case LICENSE_EXPIRED_TIME_CHECK_ERROR: case LICENSE_TIME_EXPIRED: return "授权已过期"; case LICENSE_REMOTE_DATA_ERROR: return "远程授权失败(检查网络/序列号)"; case LICENSE_LOCAL_FILE_ERROR: case LICENSE_KEY_FILE_ERROR: return "授权文件缺失"; case LICENSE_NOT_INIT_ERROR: return "授权未初始化"; default: return code.name(); } } }