package com.novelbook.android.upgrade; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import android.Manifest; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.support.v4.content.FileProvider; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ProgressBar; import android.widget.Toast; import com.novelbook.android.Activity_base; import com.novelbook.android.BookActivity; import com.novelbook.android.BuildConfig; import com.novelbook.android.MyApp; import com.novelbook.android.R; import com.novelbook.android.ReadActivity; import com.novelbook.android.db.Novel; import com.novelbook.android.netsubscribe.BookSubscribe; import com.novelbook.android.netutils.HttpMethods; import com.novelbook.android.netutils.OnSuccessAndFaultListener; import com.novelbook.android.netutils.OnSuccessAndFaultSub; import com.novelbook.android.utils.CommonUtil; import com.novelbook.android.utils.Constants; import com.novelbook.android.utils.GsonUtil; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; import static com.novelbook.android.FileActivity.EXTERNAL_STORAGE_REQ_CODE; import static com.novelbook.android.netapi.URLConstant.getRootUrl; import static java.lang.System.exit; public class UpdateManager { public static final String TAG =UpdateManager.class.getSimpleName(); private static final int DOWNLOAD = 1; private static final int DOWNLOAD_FINISH = 2; private static final int showDialog =3; HashMap mHashMap; HashMap> multiHashMap; private String mSavePath; private int progress; private boolean cancelUpdate = false; private Activity_base mContext; private ProgressBar mProgress; private Dialog mDownloadDialog; private boolean isForceRefresh; int serviceCode; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case DOWNLOAD: mProgress.setProgress(progress); break; case DOWNLOAD_FINISH: installApk(); break; case showDialog: showNoticeDialog(); break; default: break; } }; }; public UpdateManager(Activity_base context) { this.mContext = context; // app =(QiYouApplication)context; } /** * 濡拷绁存潪顖欐閺囧瓨鏌� */ public void checkUpdate() { String urlStr = getRootUrl()+ Constants.VERSION_ADDRESS; urlStr = Constants.updateUrl;//"http://xiaoshuofenxiang.com/version.xml"; if(!TextUtils.isEmpty(urlStr)) checkUpdate(urlStr); /*if (isUpdate()) { showNoticeDialog(); } else { Toast.makeText(mContext, R.string.soft_update_no, Toast.LENGTH_LONG).show(); }*/ } boolean isSilence =false; public void checkUpdateSilence() { isSilence=true; checkUpdate(); } void checkUpdate(String url){ Request request = new Request.Builder() .url(url).build(); HttpMethods.getOkClient().newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.d(TAG, " 版本检查错误 onFailure(int, Header[],byte[], Throwable ) was received"); if(!isSilence) Toast.makeText(mContext, "版本检查出错了", Toast.LENGTH_LONG).show(); } @Override public void onResponse(Call call, Response response) throws IOException { if(response.code()!=200) { Log.e(TAG, "check update onResponse:return code" +response.code() ); } ResponseBody body = response.body(); try { byte[] bytes = body.bytes(); // String s = body.string(); // Log.d(TAG, "onSuccess: response is " + s); if (bytes != null) { // processTxtOnSuccess(bytes); processMultiTxtOnSuccess(bytes); } // body.close(); }catch (Exception e){ Log.e(TAG, "onResponse: ",e ); }finally { } } }); } void processMultiTxtOnSuccess(byte[] paramArrayOfByte) { boolean isUpdate=false; int versionCode = getVersionCode(mContext); InputStream inputStream = null; inputStream =new ByteArrayInputStream(paramArrayOfByte); ParseXmlService service = new ParseXmlService(); try { if(inputStream!=null) multiHashMap = service.parseMultiXml(inputStream); } catch (Exception e) { e.printStackTrace(); } if (null != multiHashMap) { String packgename = mContext.getPackageName(); mHashMap = multiHashMap.get(packgename); if (mHashMap != null) { serviceCode = Integer.valueOf(mHashMap.get("version")); Constants.serverVersion = serviceCode; if(mHashMap.containsKey("minVersion")) Constants.minVersion = Integer.valueOf(mHashMap.get("minVersion")); // need update or not isUpdate = serviceCode > versionCode; isForceRefresh = versionCode versionCode; } if (isUpdate) { mHandler.sendEmptyMessage(showDialog); } else { if(!isSilence) Toast.makeText(mContext, R.string.soft_update_no, Toast.LENGTH_LONG).show(); } } /** * 閼惧嘲褰囨潪顖欐閻楀牊婀伴崣锟� * * @param context * @return */ public int getVersionCode(Context context) { int versionCode = 0; try { // 閼惧嘲褰囨潪顖欐閻楀牊婀伴崣鍑ょ礉鐎电懓绨睞ndroidManifest.xml娑撳獘ndroid:versionCode versionCode =(int)CommonUtil.getVersionCodeLong(context);// context.getPackageManager().getPackageInfo("com.novelbook.android", 0).versionCode; /*int versionCode2 = CommonUtil.getVersionCode(context); long versioncode3 = CommonUtil.getVersionCodeLong(context); String versionname = CommonUtil.getVersion(context); String v = CommonUtil.getVersionName(context); String packnm = context.getPackageName(); String p ="A";*/ } catch ( Exception e) { Log.e(TAG, "getVersionCode: ",e); } return versionCode; } /** * 閼惧嘲褰囨潪顖欐閻楀牊婀伴崣锟� * * @param context * @return */ public static String getVersionName(Context context) { String versionName = ""; try { // 閼惧嘲褰囨潪顖欐閻楀牊婀伴崣鍑ょ礉鐎电懓绨睞ndroidManifest.xml娑撳獘ndroid:versionCode versionName = context.getPackageManager().getPackageInfo("com.qiyou.mb.android", 0).versionName; } catch (NameNotFoundException e) { Log.e(TAG, "getVersionCode: ",e); } return versionName; } /** * 閺勫墽銇氭潪顖欐閺囧瓨鏌婄�纭呯樈濡楋拷 */ private void showNoticeDialog() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { CommonUtil.checkPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE, EXTERNAL_STORAGE_REQ_CODE, "下载更新需要此权限,请允许"); CommonUtil.checkPermission(mContext, Manifest.permission.INSTALL_PACKAGES, 1024, "下载更新需要此权限,请允许"); } // 閺嬪嫰锟界�纭呯樈濡楋拷 Builder builder = new Builder(mContext); if(isForceRefresh) { builder.setTitle(R.string.soft_force_update_title); }else { builder.setTitle(R.string.soft_update_title); } String upgradeDetails=mHashMap.get("details"); String forceRefresh =isForceRefresh? "本地版本过低,请升级新版本":""; builder.setMessage( forceRefresh +/*mContext.getPackageName() +*/ "\n当前版本:"+getVersionCode(mContext) +"\n" +"最新版本:"+ serviceCode +"\n" + mContext.getString(R.string.soft_update_info) + upgradeDetails ); builder.setPositiveButton(R.string.soft_update_updatebtn, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); showDownloadDialog(); } }); // 缁嬪秴鎮楅弴瀛樻煀 builder.setNegativeButton(R.string.soft_update_later, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); if(isForceRefresh){ exit(-1); } } }); Dialog noticeDialog = builder.create(); noticeDialog.setCancelable(false); noticeDialog.show(); } /** * 閺勫墽銇氭潪顖欐娑撳娴囩�纭呯樈濡楋拷 */ private void showDownloadDialog() { // 閺嬪嫰锟芥潪顖欐娑撳娴囩�纭呯樈濡楋拷 Builder builder = new Builder(mContext); builder.setTitle(R.string.soft_updating); // 缂佹瑤绗呮潪钘夘嚠鐠囨繃顢嬫晶鐐插鏉╂稑瀹抽弶锟� final LayoutInflater inflater = LayoutInflater.from(mContext); View v = inflater.inflate(R.layout.softupgrade_progress, null); mProgress = (ProgressBar) v.findViewById(R.id.update_progress); builder.setView(v); // 閸欐牗绉烽弴瀛樻煀 builder.setNegativeButton(R.string.soft_update_cancel, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); // 鐠佸墽鐤嗛崣鏍ㄧХ閻樿埖锟� cancelUpdate = true; if(isForceRefresh){ exit(-1); } } }); mDownloadDialog = builder.create(); mDownloadDialog.setCancelable(true); mDownloadDialog.show(); // 閻滄澘婀弬鍥︽ downloadApk(); } /** * 娑撳娴嘺pk閺傚洣娆� */ private void downloadApk() { // 閸氼垰濮╅弬鎵殠缁嬪绗呮潪鍊熻拫娴狅拷 new downloadApkThread().start(); } /** * 娑撳娴囬弬鍥︽缁捐法鈻� */ private class downloadApkThread extends Thread { @Override public void run() { try { // 閸掋倖鏌嘢D閸椻剝妲搁崥锕�摠閸︻煉绱濋獮鏈电瑬閺勵垰鎯侀崗閿嬫箒鐠囪鍟撻弶鍐 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { // 閼惧嘲绶辩�妯哄亶閸楋紕娈戠捄顖氱窞 String sdpath = Environment.getExternalStorageDirectory() + "/" +"GDTDOWNLOAD/"; mSavePath = sdpath + "download"; URL url = new URL(mHashMap.get("url")); // 閸掓稑缂撴潻鐐村复 HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.connect(); // 閼惧嘲褰囬弬鍥︽婢堆冪毈 int length = conn.getContentLength(); // 閸掓稑缂撴潏鎾冲弳濞达拷 InputStream is = conn.getInputStream(); File file = new File(mSavePath); // 閸掋倖鏌囬弬鍥︽閻╊喖缍嶉弰顖氭儊鐎涙ê婀� if (!file.exists()) { file.mkdir(); } File apkFile = new File(mSavePath, mHashMap.get("name")); FileOutputStream fos = new FileOutputStream(apkFile); int count = 0; // 缂傛挸鐡� byte buf[] = new byte[1024]; // 閸愭瑥鍙嗛崚鐗堟瀮娴犳湹鑵� do { int numread = is.read(buf); count += numread; // 鐠侊紕鐣绘潻娑樺閺夆�缍呯純锟� progress = (int) (((float) count / length) * 100); // 閺囧瓨鏌婃潻娑樺 mHandler.sendEmptyMessage(DOWNLOAD); if (numread <= 0) { // 娑撳娴囩�灞惧灇 mHandler.sendEmptyMessage(DOWNLOAD_FINISH); break; } // 閸愭瑥鍙嗛弬鍥︽ fos.write(buf, 0, numread); } while (!cancelUpdate);// 閻愮懓鍤崣鏍ㄧХ鐏忓崬浠犲顤嶇瑓鏉烇拷 fos.close(); is.close(); } } catch (MalformedURLException e) { if(isForceRefresh){ exit(-1); } Log.e(TAG, "run: ", e); } catch (IOException e) { mContext.checkAndRequestPermission(); if(isForceRefresh){ // exit(-1); } Log.e(TAG, "run: ", e); } // 閸欐牗绉锋稉瀣祰鐎电鐦藉鍡樻▔缁�拷 mDownloadDialog.dismiss(); } }; /** * 鐎瑰顥朅PK閺傚洣娆� */ private void installApk() { File apkfile = new File(mSavePath, mHashMap.get("name")); if (!apkfile.exists()) { return; } // 闁俺绻僆ntent鐎瑰顥朅PK閺傚洣娆� Intent i = new Intent(Intent.ACTION_VIEW); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive"); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } else { // 声明需要的临时权限 // 第二个参数,即第一步中配置的authorities Uri contentUri = FileProvider.getUriForFile(MyApp.applicationContext, BuildConfig.APPLICATION_ID + ".fileprovider", apkfile); i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); i.setDataAndType(contentUri, "application/vnd.android.package-archive"); } mContext.startActivity(i); exit(-1); } }