001package com.aispeech.dui.dds.update; 002 003import android.app.Dialog; 004import android.app.Notification; 005import android.app.NotificationManager; 006import android.content.Context; 007import android.os.Handler; 008import android.text.TextUtils; 009 010import com.aispeech.dui.manager.AILog; 011import com.aispeech.dui.BusClient; 012import com.aispeech.dui.dds.DDSConfig; 013import com.aispeech.dui.dds.R; 014import com.aispeech.dui.dds.agent.Agent; 015import com.aispeech.dui.dds.agent.MessageObserver; 016import com.aispeech.dui.dds.utils.AssetsUtil; 017import com.aispeech.libcomm.business.LocalKeys; 018import com.aispeech.libcomm.business.LocalKeysUtil; 019import com.aispeech.libcomm.business.topic.AgentTopicUtil; 020import com.aispeech.libcomm.business.topic.Topic; 021 022import org.json.JSONException; 023import org.json.JSONObject; 024 025 026public class DDSUpdater { 027 public static final String TAG = "DDSUpdater"; 028 029 private Context context; 030 031 private DDSConfig configs; 032 033 private DDSUpdateListener listener; 034 035 private Agent agent; 036 037 private Notification.Builder builder; 038 039 private Dialog dialog; 040 041 private String[] ddsUpdateResultMsg = new String[]{ 042 "资源加载成功", 043 "服务授权失败", 044 "解码失败", 045 "未发现新的版本", 046 "请先升级您的客户端", 047 "网络异常, 无法连接至服务器", 048 "解码失败", 049 "补丁安装失败", 050 "备份压缩文件不存在", 051 "提取压缩文件失败", 052 "还未设置产品ID,请先扫码绑定", 053 "无效客户端版本", 054 "无效用户ID", 055 "无效设备ID", 056 "资源地址无效", 057 "无效的产品分支", 058 "无法找到资源", 059 "资源校验失败", 060 "无效的授权token", 061 "当前产品中内核资源版本过低,请前往DUI控制台对应的产品中,选择最新的内核资源版本并重新发布产品。", 062 "未知错误" 063 }; 064 065 public void release() { 066 agent = null; 067 context = null; 068 } 069 070 /** 071 * 构造方法,开发者可以不关注该构造方法, 072 * 而是可以通过{@link com.aispeech.dui.dds.DDS#getUpdater}获取DDSUpdater实例 073 * 074 * @param context context 075 * @param configs DDSConfig配置 076 * @param agent agent 077 */ 078 public DDSUpdater(Context context, DDSConfig configs, Agent agent) { 079 this.context = context; 080 this.configs = configs; 081 this.agent = agent; 082 agent.subscribe(new String[]{ 083 Topic.Update.UpdateFound.TOPIC_NAME, 084 Topic.Update.UpdateFinish.TOPIC_NAME, 085 Topic.Update.UpdatePercentage.TOPIC_NAME 086 }, messageObserver); 087 } 088 089 private boolean isUseNotificationBar() { 090 String value = configs.getConfig(DDSConfig.K_USE_UPDATE_NOTIFICATION); 091 return TextUtils.equals(value, "true"); 092 } 093 094 private BusClient getBusClient() { 095 if (agent != null) { 096 return agent.getBusClient(); 097 } 098 return null; 099 } 100 101 /** 102 * 请求开始检测以及更新 103 * 104 * @param ddsUpdateListener 更新回调监听器 105 */ 106 public void update(final DDSUpdateListener ddsUpdateListener) { 107 AILog.userI(TAG, "DDSUpdater.update input =", (ddsUpdateListener == null)); 108 this.listener = ddsUpdateListener; 109 try { 110 JSONObject obj = new JSONObject(); 111 obj.put(Topic.Agent.AgentEvent.EVENT, "update.start"); 112 BusClient bc = getBusClient(); 113 if (bc != null) { 114 LocalKeysUtil.getInstance().put(LocalKeys.Update.LOCAL_KEYS_AVAILABLE_STORAGE, String.valueOf(getAvailableStorage()), false); 115 AgentTopicUtil.publishAgentEvent(bc, obj); 116 } 117 } catch (Exception e) { 118 com.aispeech.dui.manager.AIJavaException.printException(e); 119 } 120 } 121 122 private long getAvailableStorage() { 123 long available = 0; 124 available = AssetsUtil.getAvailableInternalMemorySize(); 125 AILog.i(TAG, "available space->", String.valueOf(available)); 126 127 return available; 128 } 129 130 private MessageObserver messageObserver = new MessageObserver() { 131 132 @Override 133 public void onMessage(String message, String data) { 134 AILog.d(TAG, "onMessage->", message); 135 if (Topic.Update.UpdateFound.TOPIC_NAME.equals(message)) { 136 JSONObject args = null; 137 try { 138 args = new JSONObject(data); 139 final String title = "发现新的更新资源, 正在为您更新..."; 140 final String changeLogs = args.optString(Topic.Update.UpdateFound.CHANGE_LOGS); 141 if (isUseNotificationBar()) { 142 AILog.d(TAG, "use notification bar"); 143 showUpdatingNotification(title, changeLogs); 144 } 145 if (listener != null) { 146 listener.onUpdateFound(changeLogs); 147 } 148 } catch (JSONException e) { 149 com.aispeech.dui.manager.AIJavaException.printException(e); 150 } 151 152 } else if (Topic.Update.UpdateFinish.TOPIC_NAME.equals(message)) { 153 JSONObject args = null; 154 try { 155 args = new JSONObject(data); 156 BusClient bc = getBusClient(); 157 if (bc == null) { 158 return; 159 } 160 if ("success".equals(args.optString(Topic.Update.UpdateFinish.STATE))) { 161// RecorderTopicUtil.publishRecorderCtrl(bc, "stopall", "", false); 162 163 if (isUseNotificationBar()) { 164 showUpdateResultNotification("资源加载成功"); 165 } 166 if (listener != null) { 167 listener.onUpdateFinish(); 168 } 169 } else if ("070303".equals(args.optString(Topic.Update.UpdateFinish.ERR_ID))) { 170 //no new version found, do nothing 171 } else if ("070304".equals(args.optString(Topic.Update.UpdateFinish.ERR_ID))) { 172 if (listener != null) { 173 listener.onUpgrade(""); 174 } 175 } else { 176 int errId = Integer.valueOf(TextUtils.isEmpty(args.optString(Topic.Update.UpdateFinish.ERR_ID)) ? "0" : args 177 .optString(Topic.Update.UpdateFinish.ERR_ID)); 178 int index = errId - 70300; 179 int length = ddsUpdateResultMsg.length; 180 if (index < 0 || index >= length) { 181 index = length - 1; 182 } 183 String msg = ddsUpdateResultMsg[index]; 184 if (isUseNotificationBar()) { 185 showUpdateResultNotification(msg); 186 } 187 if (listener != null) { 188 listener.onError(errId, msg); 189 } 190 } 191 } catch (Exception e) { 192 com.aispeech.dui.manager.AIJavaException.printException(e); 193 } 194 195 } else if (Topic.Update.UpdatePercentage.TOPIC_NAME.equals(message)) { 196 try { 197 JSONObject jsonObject = new JSONObject(data); 198 float progress = Float.valueOf(jsonObject.optString(Topic.Update.UpdatePercentage.PROGRESS)); 199 if (isUseNotificationBar()) { 200 updateProgress(progress); 201 } 202 if (listener != null) { 203 listener.onDownloadProgress(progress); 204 } 205 } catch (Exception e) { 206 com.aispeech.dui.manager.AIJavaException.printException(e); 207 } 208 } 209 } 210 }; 211 212 private void showUpdatingNotification(final String title, final String info) { 213 Handler handler = new Handler(context.getMainLooper()); 214 handler.post(new Runnable() { 215 @Override 216 public void run() { 217 builder = new Notification.Builder(context) 218 .setSmallIcon(R.drawable.icon) 219 .setContentTitle(title) 220 .setContentText(info).setAutoCancel(false); 221 builder.setProgress(0, 0, false); 222 NotificationManager mNotificationManager = 223 (NotificationManager) context.getSystemService(Context 224 .NOTIFICATION_SERVICE); 225 mNotificationManager.notify(1024, builder.getNotification()); 226 } 227 }); 228 } 229 230 private void updateProgress(final Float percentage) { 231 Handler handler = new Handler(context.getMainLooper()); 232 handler.post(new Runnable() { 233 @Override 234 public void run() { 235 AILog.i(TAG, "update, ", percentage); 236 if (builder == null) { 237 AILog.w(TAG, "builder is null, renew one."); 238 builder = new Notification.Builder(context) 239 .setSmallIcon(R.drawable.icon).setAutoCancel(false); 240 } 241 builder.setProgress(100, percentage.intValue(), false); 242 builder.setContentTitle("正在更新资源..." + 243 percentage + "%"); 244 NotificationManager mNotificationManager = 245 (NotificationManager) context.getSystemService(Context 246 .NOTIFICATION_SERVICE); 247 mNotificationManager.notify(1024, builder.getNotification()); 248 } 249 }); 250 } 251 252 private void showUpdateResultNotification(final String info) { 253 Handler handler = new Handler(context.getMainLooper()); 254 handler.post(new Runnable() { 255 @Override 256 public void run() { 257 builder = new Notification.Builder(context) 258 .setSmallIcon(R.drawable.icon) 259 .setContentTitle("更新结果:") 260 .setContentText(info).setAutoCancel(true); 261 NotificationManager mNotificationManager = 262 (NotificationManager) context.getSystemService(Context 263 .NOTIFICATION_SERVICE); 264 mNotificationManager.notify(1024, builder.getNotification()); 265 } 266 }); 267 } 268 269}