package com.gh.gamecenter.download; import android.content.Context; import android.graphics.Color; import android.os.Handler; import android.support.v4.util.ArrayMap; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import com.android.volley.Response; import com.android.volley.VolleyError; import com.gh.base.AppController; import com.gh.common.constant.Config; import com.gh.common.constant.Constants; import com.gh.common.util.DataUtils; import com.gh.common.util.DialogUtils; import com.gh.common.util.DisplayUtils; import com.gh.common.util.FileUtils; import com.gh.common.util.ImageUtils; import com.gh.common.util.MD5Utils; import com.gh.common.util.PackageUtils; import com.gh.common.util.PlatformUtils; import com.gh.common.util.TimestampUtils; import com.gh.common.view.CardLinearLayout; import com.gh.common.view.CardRelativeLayout; import com.gh.download.DownloadEntity; import com.gh.download.DownloadManager; import com.gh.gamecenter.R; import com.gh.gamecenter.db.info.ConcernInfo; import com.gh.gamecenter.entity.GameUpdateEntity; import com.gh.gamecenter.eventbus.EBDownloadChanged; import com.gh.gamecenter.eventbus.EBPerformClick; import com.gh.gamecenter.manager.ConcernManager; import com.gh.gamecenter.manager.PackageManager; import com.gh.gamecenter.volley.extended.JsonArrayExtendedRequest; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import org.json.JSONArray; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import de.greenrobot.event.EventBus; /** * Created by LGT on 2016/8/16. */ public class GameUpdateAdapter extends RecyclerView.Adapter { private Context context; private LinearLayout gameupdate_ll_loading; private LinearLayout gameupdate_tv_none; private ArrayMap locationMap; private ArrayMap packageNameMap; private SparseBooleanArray successMap; private SparseArray entryMap; private ArrayList updateList; private String packageName; private Handler handler = new Handler(); public GameUpdateAdapter(Context context, LinearLayout loading, LinearLayout none, String packageName, boolean isUpdate) { this.context = context; gameupdate_ll_loading = loading; gameupdate_tv_none = none; this.packageName = packageName; locationMap = new ArrayMap<>(); packageNameMap = new ArrayMap<>(); successMap = new SparseBooleanArray(); entryMap = new SparseArray<>(); updateList = new ArrayList<>(); if (packageName != null) { getUpdateByPackageName(packageName); } else if (isUpdate) { getUpdateListFromServer(); } else { for (GameUpdateEntity updateEntity : PackageManager.getUpdateList()) { updateList.add(updateEntity); } sortUpdateList(updateList); initMap(); } if (updateList.isEmpty()) { gameupdate_tv_none.setVisibility(View.VISIBLE); } } // 根据包名获取更新(单个) private void getUpdateByPackageName(String packageName) { gameupdate_ll_loading.setVisibility(View.VISIBLE); JsonArrayExtendedRequest request = new JsonArrayExtendedRequest( TimestampUtils.addTimestamp( Config.HOST + "v1d45/support/package/update?package=" + packageName, Constants.UPDATE_CD), new Response.Listener() { @Override public void onResponse(JSONArray response) { if (response.length() != 0) { Gson gson = new Gson(); Type listType = new TypeToken>() {}.getType(); ArrayList games = gson.fromJson(response.toString(), listType); if (!isCanUpdate(games.get(0))) { games.remove(0); } if (games.size() != 0) { updateList.add(games.get(0)); PackageManager.addUpdateList(updateList); EventBus.getDefault().post(new EBDownloadChanged("update", View.VISIBLE, updateList.size())); initMap(); } if (!updateList.isEmpty() && gameupdate_tv_none.getVisibility() == View.VISIBLE) { gameupdate_tv_none.setVisibility(View.GONE); } gameupdate_ll_loading.setVisibility(View.GONE); notifyItemRangeInserted(0, 2); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { gameupdate_ll_loading.setVisibility(View.GONE); } }); AppController.addToRequestQueue(request, GameUpdateFragment.class); } private int mCount; // 从服务器中获取更新(多个) public void getUpdateListFromServer() { gameupdate_ll_loading.setVisibility(View.VISIBLE); List packages = getInstalledList(); if (packages.size() != 0) { sortPackageList(packages); StringBuilder builder = new StringBuilder(); String params; PackageManager.clearUpdateList(); final int count = (packages.size() / 10) + 1; mCount = 0; for (int i = 0; i < count; i++) { builder.delete(0, builder.length()); for (int j = i * 10, size = (i + 1) * 10 > packages.size() ? packages .size() : (i + 1) * 10; j < size; j++) { builder.append(packages.get(j)); builder.append("-"); } params = builder.substring(0, builder.length() - 1); JsonArrayExtendedRequest request = new JsonArrayExtendedRequest( TimestampUtils.addTimestamp( Config.HOST + "v1d45/support/package/update?package=" + params, Constants.UPDATE_CD), new Response.Listener() { @Override public void onResponse(JSONArray response) { if (response.length() != 0) { Gson gson = new Gson(); Type listType = new TypeToken>() {}.getType(); ArrayList games = gson.fromJson(response.toString(), listType); for (int i = 0; i < games.size(); i++) { if (!isCanUpdate(games.get(i))) { games.remove(i); i--; } } updateList.addAll(games); } mCount++; if (mCount == count) { processingData(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { mCount++; if (mCount == count) { processingData(); } } }); AppController.addToRequestQueue(request, GameUpdateFragment.class); } } else { gameupdate_ll_loading.setVisibility(View.GONE); } } private void processingData() { sortUpdateList(updateList); PackageManager.addUpdateList(updateList); EventBus.getDefault().post( new EBDownloadChanged("update", View.VISIBLE, updateList.size())); initMap(); notifyItemRangeInserted(0, 1 + updateList.size()); if (!updateList.isEmpty() && gameupdate_tv_none.getVisibility() == View.VISIBLE) { gameupdate_tv_none.setVisibility(View.GONE); } gameupdate_ll_loading.setVisibility(View.GONE); } // 初始化map等变量 private void initMap() { List entries = DownloadManager.getInstance(context).getAll(); for (int i = 0, size = updateList.size(); i < size; i++) { locationMap.put(updateList.get(i).getPackageName(), i); packageNameMap.put(updateList.get(i).getUrl(), updateList.get(i).getPackageName()); successMap.put(i, false); for (DownloadEntity downloadEntity : entries) { if (updateList.get(i).getUrl().equals(downloadEntity.getUrl())) { entryMap.put(i, downloadEntity); break; } } } } // 获取已安装游戏包名列表 private List getInstalledList() { List packages = new ArrayList<>(); ConcernManager concernManager = new ConcernManager(context); for (ConcernInfo info : concernManager.getInstalledGame()) { for (String key : info.getPackageNames().keySet()) { if (info.getPackageNames().get(key)) { packages.add(key); } } } return packages; } private boolean isCanUpdate(GameUpdateEntity updateEntity) { // 判断是否gh_version是否相同 String gh_version = (String) PackageUtils .getMetaData(context, updateEntity.getPackageName(), "gh_version"); if (gh_version != null) { gh_version = gh_version.substring(2); // 判断gh_version是否相同 if (gh_version.equals(updateEntity.getGhVersion())) { // 判断version是否相同 String version = PackageUtils .getVersionByPackage(context, updateEntity.getPackageName()); if (version != null && version.equals(updateEntity.getVersion())) { // 版本相同,无需显示插件更新,继续查看是否有可更新的游戏包 return false; } } } return true; } // 对包名进行排序 private void sortPackageList(List list) { Comparator comparator = new Comparator() { @Override public int compare(String lhs, String rhs) { char[] clhs = lhs.toCharArray(); char[] crhs = rhs.toCharArray(); int length; if (clhs.length < crhs.length) { length = clhs.length; } else if (clhs.length > crhs.length) { length = crhs.length; } else { length = clhs.length; } for (int i = 0; i < length; i++) { if (clhs[i] > crhs[i]) { return 1; } else if (clhs[i] < crhs[i]) { return -1; } else if (i == length - 1) { if (clhs.length < crhs.length) { return -1; } else if (clhs.length > crhs.length) { return 1; } else { return 0; } } } return 0; } }; Collections.sort(list, comparator); } // 对更新列表进行排序 private void sortUpdateList(ArrayList list) { Comparator comparator = new Comparator() { @Override public int compare(GameUpdateEntity lhs, GameUpdateEntity rhs) { if (rhs.getName().contains("光环助手")) { return 1; } else if (lhs.getName().contains("光环助手")) { return -1; } if (!lhs.isPluggable() && rhs.isPluggable()) { return -1; } else if (lhs.isPluggable() && !rhs.isPluggable()) { return 1; } else { return 0; } } }; Collections.sort(list, comparator); } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == 0) { View view = LayoutInflater.from(parent.getContext()).inflate( R.layout.downloadmanager_item_head, parent, false); return new DownloadHeadViewHolder(view); } else { View view = LayoutInflater.from(parent.getContext()).inflate( R.layout.fm_update_item, parent, false); return new GameUpdateViewHolder(view); } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof DownloadHeadViewHolder) { final DownloadHeadViewHolder viewHolder = (DownloadHeadViewHolder) holder; float size = 0; int count = 0; int done = 0; for (int i = 0; i < updateList.size(); i++) { String str = updateList.get(i).getSize(); str = str.substring(0, str.lastIndexOf("M")); size += Float.valueOf(str); if (entryMap.get(i) != null) { count++; } if (successMap.get(i)) { done++; } } CardRelativeLayout cardRelativeLayout = (CardRelativeLayout) viewHolder.itemView; cardRelativeLayout.setmBottom(DisplayUtils.dip2px(context, 8)); cardRelativeLayout.setmTop(0); viewHolder.dm_item_head_tv_task.setText("共" + updateList.size() + "个游戏可更新,需" + getSize(size)); if (done == updateList.size()) { viewHolder.dm_item_head_tv_allstart.setText("更新完成"); } else { if (count == updateList.size()) { viewHolder.dm_item_head_tv_allstart.setText("更新中"); } else { viewHolder.dm_item_head_tv_allstart.setText("全部更新"); } } viewHolder.dm_item_head_tv_allstart.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String str = viewHolder.dm_item_head_tv_allstart.getText().toString(); if ("全部更新".equals(str)) { // 全部更新 viewHolder.dm_item_head_tv_allstart.setText("更新中"); for (int i = 0; i < updateList.size(); i++) { if (entryMap.get(i) == null) { addUpdateDownload(i); notifyItemChanged(i + 1); } } } } }); } else if (holder instanceof GameUpdateViewHolder) { final GameUpdateViewHolder viewHolder = (GameUpdateViewHolder) holder; final GameUpdateEntity updateEntity = updateList.get(position - 1); // // 第一个 // if (position == 1) { // ((CardLinearLayout) holder.itemView).setmTop(DisplayUtils.dip2px(context, 8)); // } else { // ((CardLinearLayout) holder.itemView).setmTop(0); // } // 最后一个 if (position == updateList.size()) { ((CardLinearLayout) holder.itemView).setBottom(true); } else { ((CardLinearLayout) holder.itemView).setBottom(false); } if (updateEntity.getName().contains("光环助手")) { viewHolder.gu_item_iv_icon.setImageResource(R.drawable.logo); } else { ImageUtils.getInstance(context).display( updateEntity.getIcon(), viewHolder.gu_item_iv_icon); } final String platform = PlatformUtils.getInstance(context) .getPlatformName(updateEntity.getPlatform()); if (platform == null || "官方版".equals(platform)) { viewHolder.gu_item_tv_name.setText(updateEntity.getName()); } else { viewHolder.gu_item_tv_name.setText(updateEntity.getName() + " - " + platform); } String currentVersion = PackageUtils.getVersionByPackage( context, updateEntity.getPackageName()); if (TextUtils.isEmpty(currentVersion)) { viewHolder.gu_item_tv_current.setText("当前:无"); } else { viewHolder.gu_item_tv_current.setText("当前:V" + currentVersion); } viewHolder.gu_item_tv_new.setText("新版:V" + updateEntity.getVersion() + " | " + updateEntity.getSize()); if (successMap.get(position - 1)) { viewHolder.gu_item_btv_update.setText("启动"); viewHolder.gu_item_btv_update.setTextColor(Color.WHITE); viewHolder.gu_item_btv_update.setBackgroundResource(R.drawable.game_item_btn_launch_style); } else { DownloadEntity entry = entryMap.get(position - 1); if (entry != null) { if (updateEntity.isPluggable()) { viewHolder.gu_item_btv_update.setText("插件化中"); viewHolder.gu_item_btv_update.setTextColor(0xFF06D0A8); viewHolder.gu_item_btv_update.setBackgroundResource(R.drawable.game_item_btn_plugining_style); } else { viewHolder.gu_item_btv_update.setText("更新中"); viewHolder.gu_item_btv_update.setTextColor(context.getResources().getColor(R.color.theme)); viewHolder.gu_item_btv_update.setBackgroundResource(R.drawable.game_item_btn_downloading_style); } } else { if (updateEntity.isPluggable()) { viewHolder.gu_item_btv_update.setText("插件化"); viewHolder.gu_item_btv_update.setTextColor(Color.WHITE); viewHolder.gu_item_btv_update.setBackgroundResource(R.drawable.game_item_btn_plugin_style); } else { viewHolder.gu_item_btv_update.setText("更新"); viewHolder.gu_item_btv_update.setTextColor(Color.WHITE); viewHolder.gu_item_btv_update.setBackgroundResource(R.drawable.game_item_btn_download_style); } } } viewHolder.gu_item_btv_update.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final String str = viewHolder.gu_item_btv_update.getText().toString(); if ("更新".equals(str) || "插件化".equals(str)) { DialogUtils.showDownloadDialog(context, new DialogUtils.ConfiremListener() { @Override public void onConfirem() { if ("插件化".equals(str)) { viewHolder.gu_item_btv_update.setText("插件化中"); viewHolder.gu_item_btv_update.setTextColor(0xFF06D0A8); viewHolder.gu_item_btv_update.setBackgroundResource(R.drawable.game_item_btn_plugining_style); } else { viewHolder.gu_item_btv_update.setText("更新中"); viewHolder.gu_item_btv_update.setTextColor(context.getResources().getColor(R.color.theme)); viewHolder.gu_item_btv_update.setBackgroundResource(R.drawable.game_item_btn_downloading_style); } addUpdateDownload(viewHolder.getPosition() - 1); notifyItemChanged(0); } }); } else if ("启动".equals(str)) { Map kv = new HashMap<>(); kv.put("版本", updateEntity.getPlatform()); DataUtils.onEvent(context, "游戏启动", updateEntity.getName(), kv); PackageUtils.launchApplicationByPackageName(context, updateEntity.getPackageName()); } else if ("更新中".equals(str) || "插件化中".equals(str)) { handler.postDelayed(runnable, 300); } } }); if (packageName != null) { viewHolder.gu_item_btv_update.performClick(); packageName = null; handler.postDelayed(runnable, 800); } } } @Override public int getItemCount() { if (updateList.isEmpty()) { return 0; } return 1 + updateList.size(); } @Override public int getItemViewType(int position) { if (position == 0) { return 0; } return 1; } private String getSize(float size) { String unit = "MB"; if (size >= 1000) { size = size / 1024f; unit = "GB"; } String str = String.valueOf(size); int index = str.lastIndexOf("."); if (index != -1 && str.length() >= index + 3) { str = str.substring(0, index + 3); size = Float.valueOf(str); } return size + unit; } // 添加下载 private void addUpdateDownload(int position) { GameUpdateEntity updateEntity = updateList.get(position); Map kv = new HashMap<>(); kv.put("版本", updateEntity.getPlatform()); kv.put("状态", "下载开始"); DataUtils.onEvent(context, "游戏更新", updateEntity.getName(), kv); DownloadEntity downloadEntity = new DownloadEntity(); downloadEntity.setUrl(updateEntity.getUrl()); downloadEntity.setName(updateEntity.getName()); downloadEntity.setPath(FileUtils.getDownloadPath(context, MD5Utils.getContentMD5(updateEntity.getName() + "_" + System.currentTimeMillis()) + ".apk")); downloadEntity.setETag(updateEntity.getEtag()); downloadEntity.setIcon(updateEntity.getIcon()); downloadEntity.setPlatform(updateEntity.getPlatform()); if (updateEntity.isPluggable()) { downloadEntity.setPluggable(true); } else { downloadEntity.setUpdate(true); } if (downloadEntity.getName().contains("光环助手")) { DownloadManager.getInstance(context).pauseAll(); } DownloadManager.getInstance(context).add(downloadEntity); entryMap.put(position, downloadEntity); handler.postDelayed(runnable, 300); } Runnable runnable = new Runnable() { @Override public void run() { notifyItemChanged(0); EventBus.getDefault().post(new EBPerformClick("update")); } }; public ArrayList getUpdateList() { return updateList; } public ArrayMap getLocationMap() { return locationMap; } public SparseBooleanArray getSuccessMap() { return successMap; } public ArrayMap getPackageNameMap() { return packageNameMap; } public SparseArray getEntryMap() { return entryMap; } }