355 lines
13 KiB
Java
355 lines
13 KiB
Java
package com.gh.gamecenter.changeskin;
|
||
|
||
import android.content.Context;
|
||
import android.os.Handler;
|
||
import android.os.Message;
|
||
import android.view.View;
|
||
import android.widget.ProgressBar;
|
||
import android.widget.TextView;
|
||
|
||
import com.gh.common.util.Utils;
|
||
import com.gh.gamecenter.R;
|
||
import com.gh.gamecenter.gamedetail.GameDetailSkinViewHolder;
|
||
import com.google.gson.Gson;
|
||
import com.google.gson.reflect.TypeToken;
|
||
|
||
import java.io.File;
|
||
import java.lang.reflect.Type;
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
import java.util.Timer;
|
||
import java.util.TimerTask;
|
||
|
||
/**
|
||
* Created by khy on 2016/11/16.
|
||
*/
|
||
public class ChangeSkinUtils {
|
||
|
||
private static List<PatchEntity> patchDatas = new ArrayList<PatchEntity>();
|
||
private static List<PatchEntity> updatePatchList;
|
||
|
||
private static Timer timer;
|
||
private static Timer poiTimer;
|
||
private static int pageNum = 1;
|
||
private static int curProgress = 0;
|
||
private static int pg = 0;
|
||
private static int maxPoogress = 0;
|
||
private static int curMD5Num; //当前检查过的本地MD5文件数量
|
||
private static int localMD5Num;//文件总数量
|
||
|
||
private static ProgressBar pgPatch;
|
||
|
||
private static String checkPoint = ".";
|
||
private static String speed = " 0kb/s";
|
||
private static String filePath = "/mnt/sdcard/Android/data/" + SkinConfig.patchVersion + "/files";
|
||
|
||
private static TextView tvPatch;
|
||
private static TextView tvPer;
|
||
|
||
private static int downPosition = -1;
|
||
private static int downState = 0; // 0:无操作 1:暂停 2:正在下载 3:下载完成
|
||
|
||
public static boolean isChecking = false;
|
||
|
||
|
||
private static Handler handler = new Handler(){
|
||
@Override
|
||
public void handleMessage(Message msg) {
|
||
super.handleMessage(msg);
|
||
switch (msg.what) {
|
||
//下载完成
|
||
case SkinConfig.MSG_DOWNLOAD_OVER :
|
||
String jsonRuslt = (String) msg.obj;
|
||
if( "".equals(jsonRuslt) ){
|
||
startCheckMD5Thread();
|
||
}else {
|
||
List<PatchEntity> patchData = parseDesPatchJson(jsonRuslt);
|
||
patchDatas.addAll(patchData);
|
||
if( patchData.size() < SkinConfig.perPage ) {
|
||
startCheckMD5Thread();
|
||
}else{
|
||
pageNum++;
|
||
String urlPath = SkinConfig.JSON_PATCHURL + pageNum;
|
||
DownloadUtils.downloadJson( urlPath, handler );
|
||
}
|
||
}
|
||
break;
|
||
//进度条更新
|
||
case SkinConfig.MSG_PROGRESS_UPDATE :
|
||
tvPatch.setVisibility(View.GONE);
|
||
pgPatch.setVisibility(View.VISIBLE);
|
||
tvPer.setVisibility(View.VISIBLE);
|
||
curProgress++;
|
||
pg = curProgress * 100 / maxPoogress;
|
||
pgPatch.setProgress(pg);
|
||
Utils.log("当前下载:" + pg + "% (" + speed + ")" + "::" + curProgress);
|
||
if (pg >= 100) {
|
||
tvPatch.setText("更新完成");
|
||
tvPatch.setVisibility(View.VISIBLE);
|
||
pgPatch.setVisibility(View.GONE);
|
||
tvPer.setVisibility(View.GONE);
|
||
tvPatch.setEnabled(false);
|
||
pgPatch.setEnabled(false);
|
||
tvPer.setEnabled(false);
|
||
downState = 3;
|
||
timer.cancel();
|
||
} else {
|
||
if (downState == 1) {
|
||
tvPer.setText("继续");
|
||
} else {
|
||
tvPer.setText( pg + "% (" + speed + ")" );
|
||
}
|
||
}
|
||
break;
|
||
//更新下载速度
|
||
case SkinConfig.MSG_NETWORK_SPEED :
|
||
speed = (String) msg.obj;
|
||
break;
|
||
//更新检测当前文件MD5值数量
|
||
case SkinConfig.MSG_MD5_PROGRSS :
|
||
curMD5Num++;
|
||
String showTxt = "检测中(" + curMD5Num + "/" + localMD5Num + ")" + checkPoint;
|
||
changeViewState(showTxt, "blue", SkinConfig.TYPE_DESUPDATE, false);
|
||
break;
|
||
//文件MD5值检查完
|
||
case SkinConfig.MSG_MD5_OVER :
|
||
poiTimer.cancel();
|
||
Map<String,String> map = (Map<String, String>) msg.obj;
|
||
relMD5File( map );
|
||
break;
|
||
//网络error
|
||
case SkinConfig.MSG_NETWORK_ERROR :
|
||
changeViewState( "网络异常,请保持网络通畅", "gray", SkinConfig.TYPE_DESUPDATE, true );
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
|
||
public static void changeSkinControl(GameDetailSkinViewHolder holder, final Context context){
|
||
|
||
tvPatch = holder.skinDownloadTv;
|
||
pgPatch = holder.skinDownloadPb;
|
||
tvPer = holder.skinDownloadPerTv;
|
||
pgPatch.setMax(100);
|
||
|
||
if (downState == 0) {
|
||
tvPatch.setText("检查更新");
|
||
tvPatch.setVisibility(View.VISIBLE);
|
||
pgPatch.setVisibility(View.GONE);
|
||
tvPer.setVisibility(View.GONE);
|
||
} else if (downState == 1) {
|
||
tvPatch.setVisibility(View.GONE);
|
||
pgPatch.setVisibility(View.VISIBLE);
|
||
tvPer.setVisibility(View.VISIBLE);
|
||
pgPatch.setProgress( pg );
|
||
tvPer.setText("继续");
|
||
} else if (downState == 2){
|
||
tvPatch.setVisibility(View.GONE);
|
||
pgPatch.setVisibility(View.VISIBLE);
|
||
tvPer.setVisibility(View.VISIBLE);
|
||
tvPer.setText( pg + "% (" + speed + ")" );
|
||
} else if (downState == 3) {
|
||
tvPatch.setText("更新完成");
|
||
tvPatch.setVisibility(View.VISIBLE);
|
||
pgPatch.setVisibility(View.GONE);
|
||
tvPer.setVisibility(View.GONE);
|
||
}
|
||
|
||
holder.skinDownloadTv.setOnClickListener(new View.OnClickListener() {
|
||
@Override
|
||
public void onClick(View v) {
|
||
if ("更新完成".equals(tvPatch.getText().toString())) return;
|
||
switch ( SkinConfig.PG_STATE ){
|
||
case SkinConfig.TYPE_DESUPDATE :
|
||
if (!"检查更新".equals(tvPatch.getText().toString())) return;
|
||
// /data/data目录下包名文件
|
||
File pgFile = new File( "/data/data/" + SkinConfig.patchVersion );
|
||
// 内部sdcard中版本文件
|
||
String pgFilePath = "/mnt/sdcard/Android/data/" + SkinConfig.patchVersion + "/files";
|
||
File verFile = new File( pgFilePath );
|
||
if( !pgFile.exists() || !verFile.exists() ) {
|
||
String showTxt = "请先安装游戏,并更新好所有补丁";
|
||
tvPatch.setBackgroundResource(R.drawable.textview_cancel_style);
|
||
changeViewState( showTxt, "gray", SkinConfig.TYPE_DESUPDATE, true );
|
||
} else {
|
||
isChecking = true;
|
||
String showTxt = "检测中" + checkPoint;
|
||
changeViewState( showTxt, "blue", SkinConfig.TYPE_DESUPDATE, false );
|
||
startSetPoint();
|
||
|
||
String urlPath = SkinConfig.JSON_PATCHURL + pageNum;
|
||
//下载数据json
|
||
DownloadUtils.downloadJson( urlPath, handler);
|
||
}
|
||
break;
|
||
case SkinConfig.TYPE_UPDATE :
|
||
String showTxt = "开始更新...";
|
||
changeViewState( showTxt, "blue", SkinConfig.TYPE_DESUPDATE, false );
|
||
maxPoogress = updatePatchList.size();
|
||
startTimer(context);
|
||
|
||
updateProgress();
|
||
break;
|
||
}
|
||
}
|
||
});
|
||
|
||
tvPer.setOnClickListener(new View.OnClickListener() {
|
||
@Override
|
||
public void onClick(View v) {
|
||
|
||
if ("继续".equals(tvPer.getText().toString())){
|
||
downState = 2;
|
||
tvPer.setText( pg + "% (" + speed + ")" );
|
||
updateProgress();
|
||
} else {
|
||
tvPer.setText("继续");
|
||
downState = 1;
|
||
}
|
||
}
|
||
});
|
||
|
||
}
|
||
|
||
//按钮状态改变
|
||
private static void changeViewState( String txt, String color, int type, boolean isEnabled) {
|
||
tvPatch.setText( txt );
|
||
SkinConfig.PG_STATE = type;
|
||
pgPatch.setEnabled( isEnabled );
|
||
}
|
||
|
||
//正在下载 ... 点用计时器控制
|
||
private static void startSetPoint(){
|
||
final int[] curPoint = {0};
|
||
final TimerTask task = new TimerTask() {
|
||
@Override
|
||
public void run() {
|
||
|
||
curPoint[0] += 1;
|
||
if(curPoint[0] == 1){
|
||
checkPoint = ".";
|
||
}else if(curPoint[0] == 2){
|
||
checkPoint = "..";
|
||
}else if(curPoint[0] == 3){
|
||
curPoint[0] = 0;
|
||
checkPoint = "...";
|
||
}
|
||
}
|
||
};
|
||
poiTimer = new Timer( true );
|
||
poiTimer.schedule( task, 1000, 1000 );
|
||
}
|
||
|
||
//开启计时器,计算下载速度
|
||
private static void startTimer(final Context context) {
|
||
|
||
final TimerTask task = new TimerTask() {
|
||
@Override
|
||
public void run() {
|
||
NetSpeed.showNetSpeed(context, handler);
|
||
}
|
||
};
|
||
timer = new Timer( true );
|
||
timer.schedule( task, 1000, 1000 );
|
||
}
|
||
|
||
//比较文件的MD5值,返回MD5值不同的文件个数
|
||
private static void relMD5File( Map<String, String> dirMD5Map ) {
|
||
updatePatchList = new ArrayList<PatchEntity>();
|
||
int patchSize = 0;
|
||
curMD5Num = 0;
|
||
//获取目录下所有文件的 MD5 值
|
||
for ( int i = 0; i < patchDatas.size(); i++ ) {
|
||
PatchEntity data = patchDatas.get( i );
|
||
String path = data.path;
|
||
String updateMD5 = data.md5;
|
||
String updateUrl = data.url;
|
||
String updateSize = data.size;
|
||
|
||
//替换地址中标识符&
|
||
String replacePath = path.replace("&", SkinConfig.patchVersion);
|
||
patchDatas.get(i).path = replacePath;
|
||
|
||
String localMD5 = dirMD5Map.get( "/" + replacePath );
|
||
if ( localMD5 != null ) {
|
||
if ( !updateMD5.equals( localMD5 ) ) {
|
||
updatePatchList.add( data );
|
||
patchSize += Integer.parseInt( updateSize );
|
||
}
|
||
}
|
||
}
|
||
|
||
isChecking = false;
|
||
|
||
if (patchSize == 0) {
|
||
String showTxt = "暂无更新";
|
||
tvPatch.setBackgroundResource(R.drawable.textview_cancel_style);
|
||
changeViewState( showTxt, "gray", SkinConfig.TYPE_DESUPDATE, true);
|
||
} else {
|
||
patchSize = patchSize / 1024 / 1024;
|
||
String showTxt = "点击开始更新(" + patchSize + "MB)";
|
||
changeViewState( showTxt, "blue", SkinConfig.TYPE_UPDATE, true );
|
||
}
|
||
}
|
||
|
||
private static void startCheckMD5Thread(){
|
||
final Thread checkMD5Thrad = new Thread(new Runnable() {
|
||
@Override
|
||
public void run() {
|
||
localMD5Num = FileMD5Utils.getDirNum(new File(filePath));
|
||
Map<String, String> dirMD5Map = FileMD5Utils.getDirMD5(new File(filePath), handler);
|
||
Message msg = Message.obtain();
|
||
msg.obj = dirMD5Map;
|
||
msg.what = SkinConfig.MSG_MD5_OVER;
|
||
handler.sendMessage(msg);
|
||
}
|
||
});
|
||
checkMD5Thrad.start();
|
||
}
|
||
|
||
//解析json数据
|
||
private static List<PatchEntity> parseDesPatchJson(String jsonString) {
|
||
Type listType = new TypeToken<ArrayList<PatchEntity>>() {}.getType();
|
||
Gson gson = new Gson();
|
||
return gson.fromJson(jsonString, listType);
|
||
}
|
||
|
||
//指定目录,下载替换文件
|
||
private static void updateProgress() {
|
||
|
||
Thread downThread = new Thread(new Runnable() {
|
||
@Override
|
||
public void run() {
|
||
for( int i = 0; i < updatePatchList.size(); i++ ) {
|
||
if (downState == 1) {
|
||
break;
|
||
}
|
||
if (i < downPosition) { // 重复下载暂停前的一张图片,防止断网下载失败 漏掉下载的图片
|
||
continue;
|
||
}
|
||
downPosition = i;
|
||
|
||
PatchEntity patchData = updatePatchList.get( i );
|
||
String filePath = patchData.path;
|
||
Utils.log("updateProgress---" + updatePatchList.size() + "::" + i);
|
||
DownloadUtils.saveUrlToFile( filePath, patchData.url, handler );
|
||
}
|
||
}
|
||
});
|
||
downThread.start();
|
||
}
|
||
|
||
//断网或者写入文件失败的操作
|
||
public static void NetWorkErrorControl (){
|
||
downState = 1;
|
||
handler.post(new Runnable() {
|
||
@Override
|
||
public void run() {
|
||
tvPer.setText("继续");
|
||
}
|
||
});
|
||
|
||
}
|
||
}
|