Files
assistant-android/app/src/main/java/com/gh/gamecenter/changeskin/ChangeSkinUtils.java

355 lines
13 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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("继续");
}
});
}
}