Files
assistant-android/app/src/main/java/com/gh/gamecenter/adapter/CleanApkAdapter.java

405 lines
15 KiB
Java

package com.gh.gamecenter.adapter;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Environment;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.collection.ArrayMap;
import androidx.core.content.ContextCompat;
import com.gh.common.util.PackageHelper;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.KcSelectGameViewHolder;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.BitmapUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.TimeUtils;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.databinding.KcGameSelectItemBinding;
import com.gh.gamecenter.feature.entity.InstallGameEntity;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.utils.RuntimeUtils;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
/**
* Created by khy on 2017/1/24.
*/
public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder> {
private static int INSTALLED = 0; // 表示已经安装
private static int UNINSTALLED = 1; // 表示未安装
private CheckBox mApkSelectAll;
private TextView mApkDeleteBtn;
private OnScanListener mScanListener;
private List<String> mApkPath;
private List<InstallGameEntity> mApkList;
private ArrayMap<Integer, Boolean> mSelectPosition;
private boolean mIsStopScan;
private boolean mIsScanOver;
private boolean mIsChooseApk;
public CleanApkAdapter(Context context, OnScanListener listener, TextView apkDeleteBtn, CheckBox apkSelectAll, boolean isChooseApk) {
super(context);
mApkDeleteBtn = apkDeleteBtn;
mApkSelectAll = apkSelectAll;
mIsChooseApk = isChooseApk;
mScanListener = listener;
mApkList = new ArrayList<>();
mSelectPosition = new ArrayMap<>();
mApkPath = new ArrayList<>();
mIsStopScan = false;
mIsScanOver = false;
init();
}
private void init() {
Observable.create(emitter -> {
// 扫描和获取apk数据 分步操作 尽量避免 StackoverflowError
FindAllAPKPath(Environment.getExternalStorageDirectory());
FindAllAPKPath(mContext.getFilesDir());
LoadApkData();
emitter.onComplete();
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<Object>() {
@Override
public void onComplete() {
super.onComplete();
mIsScanOver = true;
mScanListener.onScanOver();
if (mApkList.size() == 0) {
mScanListener.noData();
}
notifyItemRangeChanged(0, getItemCount());
}
});
}
/**
* 根据apk文件路径检查可用的apk和获取apk数据
*/
private void LoadApkData() {
for (String apk_path : mApkPath) {
InstallGameEntity apkEntity = new InstallGameEntity();
PackageManager pm = mContext.getApplicationContext().getPackageManager();
PackageInfo packageInfo = pm.getPackageArchiveInfo(apk_path, 0);
if (packageInfo == null) continue;
ApplicationInfo appInfo = packageInfo.applicationInfo;
/**获取apk的图标 */
appInfo.sourceDir = apk_path;
appInfo.publicSourceDir = apk_path;
Drawable apk_icon = appInfo.loadIcon(pm);
Bitmap originalBitmap = BitmapUtils.drawableToBitmap(apk_icon, true);
apkEntity.setGameBm(BitmapUtils.compressBitmap(originalBitmap, 100));
/** apk的绝对路劲 */
apkEntity.setGamePath(apk_path);
/** apk的版本名称 String */
String versionName = packageInfo.versionName;
apkEntity.setGameVersion(versionName);
String apkName = packageInfo.applicationInfo.loadLabel(pm).toString();
apkEntity.setGameName(apkName);
File file = new File(apk_path);
apkEntity.setGameSize(file.length());
apkEntity.setLastUpdateTime(file.lastModified());
apkEntity.setPackageName(PackageUtils.getPackageNameByPath(mContext, apk_path));
apkEntity.setVersionCode(packageInfo.versionCode);
if (apkEntity.getGamePath() != null && apkEntity.getGamePath().length() > 0) {
int dot = apkEntity.getGamePath().lastIndexOf('.');
if ((dot > -1) && (dot < apkEntity.getGamePath().length() - 1)) {
apkEntity.setFormat(apkEntity.getGamePath().substring(dot + 1));
}
}
/**安装处理类型*/
/** 得到包名 */
String packageName = packageInfo.packageName;
int type = doType(packageName);
apkEntity.setInstallStatus(type);
mApkList.add(apkEntity);
mSelectPosition.put((mApkList.size() - 1), false);
RuntimeUtils.getInstance().runOnUiThread(() -> notifyItemChanged((mApkList.size() - 1)));
}
}
/**
* 扫描内存卡 获取apk文件路径
*
* @param file 文件路径
*/
public void FindAllAPKPath(File file) {
if (mIsStopScan) {
return;
}
if (file.isFile()) {
// Utils.log("===== 是文件" + file.getAbsolutePath().toString());
String name_s = file.getName();
String apk_path;
if (name_s.toLowerCase().endsWith(".apk")) {
apk_path = file.getAbsolutePath();// apk文件的绝对路劲
mApkPath.add(apk_path);
}
} else {
// Utils.log("===== 是文件夹" + file.getAbsolutePath().toString());
File[] files = file.listFiles();
if (files != null && files.length > 0) {
for (File file_str : files) {
FindAllAPKPath(file_str);
}
}
}
}
private int doType(String packageName) {
List<PackageInfo> pakageinfos = PackageHelper.INSTANCE.getInstalledPackages(mContext, 0);
for (PackageInfo pi : pakageinfos) {
if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
String pi_packageName = pi.packageName;
//如果这个包名在系统已经安装过的应用中存在
if (packageName.endsWith(pi_packageName)) {
return INSTALLED;
}
}
}
return UNINSTALLED;
}
@Override
public KcSelectGameViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new KcSelectGameViewHolder(KcGameSelectItemBinding.inflate(mLayoutInflater, parent, false));
}
@Override
public void onBindViewHolder(final KcSelectGameViewHolder holder, int position) {
final InstallGameEntity gameEntity = mApkList.get(position);
double size = (((float) gameEntity.getGameSize() / 1024) / 1024);
DecimalFormat df = new DecimalFormat("#.00");
String sizeName = df.format(size) + "MB";
View itemView = holder.itemView;
Drawable background = ContextCompat.getDrawable(itemView.getContext(), R.drawable.reuse_listview_item_style);
itemView.setBackground(background);
holder.binding.selectGameCbRl.setVisibility(View.VISIBLE);
holder.binding.selectGameBtn.setVisibility(View.VISIBLE);
if (mSelectPosition.get(position)) {
holder.binding.selectGameBtn.setChecked(true);
} else {
holder.binding.selectGameBtn.setChecked(false);
}
holder.binding.selectGameNameAndsize.setText(gameEntity.getGameName());
holder.binding.selectGameThumb.setImageBitmap(gameEntity.getGameBm());
if (!mIsChooseApk) {
if (gameEntity.getInstallStatus() == INSTALLED) {
holder.binding.selectGameSize.setText(R.string.installed);
holder.binding.selectGameSize.setTextColor(ContextCompat.getColor(mContext, R.color.text_theme));
} else {
holder.binding.selectGameSize.setText(R.string.installed_not);
holder.binding.selectGameSize.setTextColor(ContextCompat.getColor(mContext, R.color.secondary_red));
}
holder.binding.selectGameDes.setText(mContext.getString(R.string.clean_apk_version, gameEntity.getGameVersion(), sizeName));
holder.binding.selectGameDes.setTextColor(ContextCompat.getColor(mContext, R.color.content));
} else {
holder.binding.selectGameSize.setVisibility(View.GONE);
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.binding.selectGameDes.getLayoutParams();
params.bottomMargin = 0;
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
holder.binding.selectGameDes.setLayoutParams(params);
String des = TimeUtils.getFormatTime(gameEntity.getLastUpdateTime(), "yyyy-MM-dd HH:mm") + " " + sizeName;
holder.binding.selectGameDes.setText(des);
}
if (mIsScanOver) {
holder.binding.selectGameBtn.setEnabled(true);
} else {
holder.binding.selectGameBtn.setEnabled(false);
}
holder.binding.selectGameCbRl.setOnClickListener(v -> {
if (!mIsChooseApk) {
if (mSelectPosition.get(holder.getAdapterPosition())) {
checkBoxControl(false, holder.getAdapterPosition());
holder.binding.selectGameBtn.setChecked(false);
} else {
checkBoxControl(true, holder.getAdapterPosition());
holder.binding.selectGameBtn.setChecked(true);
}
} else {
singleChoose(position);
}
});
holder.binding.selectGameBtn.setOnClickListener(v -> {
if (!mIsChooseApk) {
if (mSelectPosition.get(holder.getAdapterPosition())) {
checkBoxControl(false, holder.getAdapterPosition());
holder.binding.selectGameBtn.setChecked(false);
MtaHelper.onEvent("我的光环_设置", "安装包清理", "取消选中");
} else {
checkBoxControl(true, holder.getAdapterPosition());
holder.binding.selectGameBtn.setChecked(true);
MtaHelper.onEvent("我的光环_设置", "安装包清理", "选中");
}
} else {
singleChoose(position);
}
});
holder.itemView.setOnClickListener(v -> {
if (mIsChooseApk) {
singleChoose(position);
} else {
if (mIsScanOver) {
try {
mContext.startActivity(PackageInstaller.getInstallIntent(mContext, gameEntity.getGamePath()));
} catch (ActivityNotFoundException e) {
ToastUtils.toast("找不到 APK 安装器,请稍后再试");
}
}
}
});
}
public void checkBoxControl(boolean isChecked, int position) {
if (isChecked) {
mSelectPosition.put(position, true);
} else {
mSelectPosition.put(position, false);
}
long gameSize = 0;
int i = 0;
if (mApkList.size() == 0) return;
for (Integer integer : mSelectPosition.keySet()) {
if (mSelectPosition.get(integer)) {
gameSize = gameSize + mApkList.get(integer).getGameSize();
i++;
}
}
if (i == mApkList.size()) {
mApkSelectAll.setChecked(true);
} else {
mApkSelectAll.setChecked(false);
}
if (gameSize == 0) {
mApkDeleteBtn.setText("一键删除");
} else {
double size = (((float) gameSize / 1024) / 1024);
DecimalFormat df = new DecimalFormat("0.00");
String sizeName = df.format(size) + "MB";
mApkDeleteBtn.setText(mContext.getString(R.string.clean_apk_deleteall, i, sizeName));
}
}
public void singleChoose(int position) {
for (Integer integer : mSelectPosition.keySet()) {
mSelectPosition.put(integer, false);
}
mSelectPosition.put(position, true);
notifyDataSetChanged();
}
@Override
public int getItemCount() {
return mApkList.size();
}
public List<InstallGameEntity> getApkList() {
return mApkList;
}
public ArrayMap<Integer, Boolean> getSelectPosition() {
return mSelectPosition;
}
public void setSelectPosition(ArrayMap<Integer, Boolean> selectPosition) {
this.mSelectPosition = selectPosition;
}
public void isStopScan() {
this.mIsStopScan = true;
}
public void deleteApk(int position) {
mApkList.remove(position);
Iterator<Map.Entry<Integer, Boolean>> iterator = mSelectPosition.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, Boolean> entry = iterator.next();
Integer key = entry.getKey();
if (key == position) {
iterator.remove();
}
}
ArrayMap<Integer, Boolean> newMap = new ArrayMap<>(mSelectPosition);
for (Integer integer : newMap.keySet()) {
if (integer > position) {
int newPosition = integer - 1;
mSelectPosition.put(newPosition, mSelectPosition.get(integer));
}
}
if (mSelectPosition.size() > mApkList.size()) {
mSelectPosition.removeAt(mSelectPosition.size() - 1);
}
notifyItemRemoved(position);
}
public interface OnScanListener {
void onScanOver();
void noData();
}
}