diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 80d3516..c763f2f 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -10,8 +10,8 @@ { "type": "SINGLE", "filters": [], - "versionCode": 15, - "versionName": "1.1.4", + "versionCode": 14, + "versionName": "1.1.3", "outputFile": "app-release.apk" } ] diff --git a/baselib/src/main/java/com/tenlionsoft/baselib/constant/PathConfig.java b/baselib/src/main/java/com/tenlionsoft/baselib/constant/PathConfig.java index 9becda3..4630afe 100755 --- a/baselib/src/main/java/com/tenlionsoft/baselib/constant/PathConfig.java +++ b/baselib/src/main/java/com/tenlionsoft/baselib/constant/PathConfig.java @@ -794,4 +794,8 @@ public class PathConfig { public static final String DEFAULT_PWD_8 = "88888888"; public static final String DEFAULT_PWD_6 = "888888"; + public static final String ACTION_UPDATE_ERROR = "com.tenlionsoft.girdcclient.update_error"; + public static final String ACTION_UPDATE_PROGRESS = "com.tenlionsoft.girdcclient.update_progress"; + public static final String ACTION_UPDATE_SUCCESS = "com.tenlionsoft.girdcclient.update_success"; + } diff --git a/baselib/src/main/java/com/tenlionsoft/baselib/core/network/update/service/DownloadService.java b/baselib/src/main/java/com/tenlionsoft/baselib/core/network/update/service/DownloadService.java index a60bb6d..45095d5 100644 --- a/baselib/src/main/java/com/tenlionsoft/baselib/core/network/update/service/DownloadService.java +++ b/baselib/src/main/java/com/tenlionsoft/baselib/core/network/update/service/DownloadService.java @@ -4,19 +4,17 @@ import android.app.Service; import android.content.Intent; import android.os.IBinder; -import com.tenlionsoft.baselib.utils.ToastUtils; +import androidx.annotation.Nullable; + +import com.tenlionsoft.baselib.constant.PathConfig; import com.tenlionsoft.baselib.core.network.HttpUtils; import com.tenlionsoft.baselib.core.network.response.DownloadResponseHandler; -import com.tenlionsoft.baselib.core.network.update.utils.ApkUtils; import com.tenlionsoft.baselib.core.network.update.utils.Constants; -import com.tenlionsoft.baselib.core.network.update.utils.NotificationBarUtil; -import com.tenlionsoft.baselib.core.network.update.utils.NotificationHelper; import com.tenlionsoft.baselib.core.network.update.utils.StorageUtils; +import com.tenlionsoft.baselib.utils.ToastUtils; import java.io.File; -import androidx.annotation.Nullable; - /** * 下载服务 */ @@ -24,13 +22,11 @@ public class DownloadService extends Service { private DownInfo downInfo; private int oldProgress = 0; - private NotificationHelper notificationHelper; @Override public void onCreate() { super.onCreate(); downInfo = new DownInfo(); - notificationHelper = new NotificationHelper(this); } @Override @@ -48,33 +44,46 @@ public class DownloadService extends Service { private void downLoadFile() { - HttpUtils.getInstance().download(downInfo.getUrl(), downInfo.getSavePath(), downInfo.getApkName(), new DownloadResponseHandler() { - @Override - public void onFinish(File download_file) { - //收起通知栏 - NotificationBarUtil.setNotificationBarVisibility(DownloadService.this, false); - //安装 - ApkUtils.installAPk(DownloadService.this, download_file); - notificationHelper.cancel(); - stopSelf(); - } + HttpUtils.getInstance().download(downInfo.getUrl(), downInfo.getSavePath(), downInfo.getApkName(), + new DownloadResponseHandler() { + @Override + public void onFinish(File download_file) { + //收起通知栏 + Intent intent = new Intent(); + intent.setAction(PathConfig.ACTION_UPDATE_SUCCESS); + intent.putExtra("apkFile", download_file); + sendBroadcast(intent); +// NotificationBarUtil.setNotificationBarVisibility(DownloadService.this, false); + //安装 - @Override - public void onProgress(long currentBytes, long totalBytes) { - int progress = (int) ((currentBytes * 1.0 / totalBytes) * 100); - if (progress != oldProgress) { - notificationHelper.updateProgress(progress); - } - oldProgress = progress; - } +// notificationHelper.cancel(); - @Override - public void onFailure(String error_msg) { - ToastUtils.show("App下载失败,请稍后重试"); - notificationHelper.cancel(); - stopSelf(); - } - }); + stopSelf(); + } + + @Override + public void onProgress(long currentBytes, long totalBytes) { + int progress = (int) ((currentBytes * 1.0 / totalBytes) * 100); + if (progress != oldProgress) { +// notificationHelper.updateProgress(progress); + Intent intent = new Intent(); + intent.setAction(PathConfig.ACTION_UPDATE_PROGRESS); + intent.putExtra("progress", progress); + sendBroadcast(intent); + } + oldProgress = progress; + } + + @Override + public void onFailure(String error_msg) { + ToastUtils.show("App下载失败,请稍后重试"); + Intent intent = new Intent(); + intent.setAction(PathConfig.ACTION_UPDATE_ERROR); + sendBroadcast(intent); +// notificationHelper.cancel(); + stopSelf(); + } + }); } diff --git a/baselib/src/main/java/com/tenlionsoft/baselib/core/widget/base/BaseActivity.java b/baselib/src/main/java/com/tenlionsoft/baselib/core/widget/base/BaseActivity.java index b6ffc2c..0a1a38a 100755 --- a/baselib/src/main/java/com/tenlionsoft/baselib/core/widget/base/BaseActivity.java +++ b/baselib/src/main/java/com/tenlionsoft/baselib/core/widget/base/BaseActivity.java @@ -47,11 +47,11 @@ import androidx.appcompat.app.AppCompatActivity; import com.alibaba.android.arouter.launcher.ARouter; import com.gyf.immersionbar.ImmersionBar; -import com.tenlionsoft.baselib.utils.ToastUtils; import com.tenlionsoft.baselib.R; import com.tenlionsoft.baselib.constant.PathConfig; import com.tenlionsoft.baselib.core.widget.views.AfxTextView; import com.tenlionsoft.baselib.utils.LogUtils; +import com.tenlionsoft.baselib.utils.ToastUtils; import com.tenlionsoft.baselib.utils.UserLgUtils; import java.util.ArrayList; @@ -621,7 +621,7 @@ public abstract class BaseActivity extends AppCompatActivity { hideSoftKeyboard(getCurrentFocus()); } - public void hideSoftKeyboard(EditText editText){ + public void hideSoftKeyboard(EditText editText) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); if (editText != null) { imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); @@ -836,4 +836,8 @@ public abstract class BaseActivity extends AppCompatActivity { }); } + public void showUpdate() { + + } + } diff --git a/baselib/src/main/java/com/tenlionsoft/baselib/core/widget/views/CenterProgressUpdateView.java b/baselib/src/main/java/com/tenlionsoft/baselib/core/widget/views/CenterProgressUpdateView.java new file mode 100755 index 0000000..1d7efd0 --- /dev/null +++ b/baselib/src/main/java/com/tenlionsoft/baselib/core/widget/views/CenterProgressUpdateView.java @@ -0,0 +1,146 @@ +package com.tenlionsoft.baselib.core.widget.views; + +import android.app.Dialog; +import android.content.Context; +import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.util.DisplayMetrics; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.TouchDelegate; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; + +import com.tenlionsoft.baselib.R; + + +/** + * 作者 : Adam on 2018/7/23. + * 邮箱 : itgaojian@163.com + * 描述 : 升级进度条 + */ +public class CenterProgressUpdateView extends Dialog { + + private View view; + private Context context; + private OnChoseListener mListener; + public ImageView mIvImg; + private String content; + private CircleProgress mCpProgress; + + private CenterProgressUpdateView(Context context, String content) { + super(context, R.style.dialog_center); + this.context = context; + this.content = content; + } + + /** + * 将view的点击区域放大 + * + * @param view 需要放大的view + * @param expandTouchWidth 放大的宽度 + */ + public void setTouchDelegate(final View view, final int expandTouchWidth) { + final View parentView = (View) view.getParent(); + parentView.post(() -> { + final Rect rect = new Rect(); + view.getHitRect(rect); + rect.top -= expandTouchWidth; + rect.bottom += expandTouchWidth; + rect.left -= expandTouchWidth; + rect.right += expandTouchWidth; + TouchDelegate touchDelegate = new TouchDelegate(rect, view); + parentView.setTouchDelegate(touchDelegate); + }); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + view = LayoutInflater.from(context).inflate(R.layout.dialog_center_update_progress, null); + mCpProgress = view.findViewById(R.id.cp_progress); + setContentView(view); + setCancelable(false); + setCanceledOnTouchOutside(false); + DisplayMetrics dm = new DisplayMetrics(); + WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + windowManager.getDefaultDisplay().getMetrics(dm); + Window window = this.getWindow(); + window.setGravity(Gravity.CENTER); + window.setWindowAnimations(R.style.Dialog_ChoseFile); + WindowManager.LayoutParams params = window.getAttributes(); + params.width = (int) (dm.widthPixels * 0.7); + params.height = WindowManager.LayoutParams.WRAP_CONTENT; + window.setAttributes(params); + window.setBackgroundDrawable(new ColorDrawable()); + } + + /** + * 设置当前进度 + */ + public void setCurrentProgress(int progress) { + if (mCpProgress != null) { + mCpProgress.setCurrentProgress(progress); + } + } + + private void showSoftKeyBoardDialog(EditText editText) { + if (editText != null) { + editText.setFocusable(true); + editText.setFocusableInTouchMode(true); + //请求获得焦点 + editText.requestFocus(); + //调用系统输入法 + InputMethodManager inputManager = + (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + inputManager.showSoftInput(editText, 0); + } + } + + public void addOnChoseListener(OnChoseListener listener) { + this.mListener = listener; + } + + /** + * 选择 + * + * @param i + */ + private void choseType(int i) { + if (mListener != null) { + switch (i) { + case 1: + mListener.doUpdate(); + break; + } + } + this.dismiss(); + } + + public interface OnChoseListener { + void doUpdate(); + } + + public static class DialogBuilder { + private Context mContext; + private String content; + + public DialogBuilder(Context context) { + this.mContext = context; + } + + public CenterProgressUpdateView build() { + return new CenterProgressUpdateView(this.mContext, this.content); + } + + public DialogBuilder setContent(String content) { + this.content = content; + return this; + } + } +} \ No newline at end of file diff --git a/baselib/src/main/java/com/tenlionsoft/baselib/core/widget/views/CircleProgress.java b/baselib/src/main/java/com/tenlionsoft/baselib/core/widget/views/CircleProgress.java new file mode 100755 index 0000000..9f0d84b --- /dev/null +++ b/baselib/src/main/java/com/tenlionsoft/baselib/core/widget/views/CircleProgress.java @@ -0,0 +1,506 @@ +package com.tenlionsoft.baselib.core.widget.views; /** + * CircleProgress 2017-10-28 + * Copyright (c) 2017 KL Co.Ltd. All right reserved. + */ + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PointF; +import android.graphics.RectF; +import android.graphics.Shader; +import android.os.Build; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.LinearInterpolator; + +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; + +import com.tenlionsoft.baselib.R; +import com.tenlionsoft.baselib.utils.ConvertUtils; + +import java.text.DecimalFormat; + + +/** + * 圆形进度条 + * + * @author Adam + * since 2023 6 23 + */ +public class CircleProgress extends View { + private Context mContext; + + /** + * 默认进度圆环渐变色值集合 + */ + private int[] mDefColors = {Color.rgb(0, 187, 238), Color.rgb(0, 34, 255)}; + /** + * 100%进度圆环渐变色值集合 + */ + private int[] mEndColors = {Color.rgb(255, 196, 0), Color.rgb(255, 110, 77)}; + private int mStartColor = Color.rgb(101, 226, 175); + private int mEndColor = Color.rgb(88, 181, 250); + + // 圆心x坐标 + private float centerX, centerY; + // 圆的半径 + private float radius; + // 进度 + private float mProgress; + // 当前进度 + private float currentProgress; + // 圆形进度条底色画笔 + private Paint circleBgPaint; + // 圆形进度条进度画笔 + private Paint progressPaint; + // 进度条背景颜色 + private int circleBgColor = Color.rgb(225, 229, 232); + // 进度条颜色 + private int progressColor = Color.RED; + // 默认圆环的宽度 + private int defaultStrokeWidth = 10; + // 圆形背景画笔宽度 + private int circleBgStrokeWidth = defaultStrokeWidth; + // 圆形进度画笔宽度 + private int progressStrokeWidth = defaultStrokeWidth; + private int lineWidth; + private boolean isDrawCenterProgressText; + private int centerProgressTextSize = 23; + private int centerProgressTextColor = Color.BLACK; + private int targetTextSize = 10; + private int targetTextColor = Color.GRAY; + private int targetNumSize = 20; + private int targetNumColor = Color.BLACK; + private int lineColor = Color.GRAY; + + // 各种画笔 + private Paint centerProgressTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private Paint trainPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private Paint linePaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private Paint targetTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); +// private Paint targetNumPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + + // 扇形所在矩形 + private RectF rectF = new RectF(); + // 进度动画 + private ValueAnimator progressAnimator; + // 动画执行时间 + private int duration = 1000; + // 动画延时启动时间 + private int startDelay = 500; + + private ProgressListener progressListener; + private String targetText; + private String targetNum = "0"; + private int dp1, dp2, dp4, dp5, dp6, dp7, dp8, dp30; + + public CircleProgress(Context context) { + this(context, null); + } + + public CircleProgress(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + mContext = context; + dp1 = ConvertUtils.dp2px(1); + dp2 = ConvertUtils.dp2px(2); + dp4 = ConvertUtils.dp2px(4); + dp5 = ConvertUtils.dp2px(5); + dp6 = ConvertUtils.dp2px(6); + dp7 = ConvertUtils.dp2px(7); + dp8 = ConvertUtils.dp2px(8); + dp30 = ConvertUtils.dp2px(30); + getAttr(attrs); + initPaint(); + } + + private void getAttr(AttributeSet attrs) { + TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.CircleProgressBarView); + + circleBgStrokeWidth = + typedArray.getDimensionPixelOffset(R.styleable.CircleProgressBarView_circleBgStrokeWidth, + defaultStrokeWidth); + progressStrokeWidth = + typedArray.getDimensionPixelOffset(R.styleable.CircleProgressBarView_progressStrokeWidth, + defaultStrokeWidth); + + circleBgColor = typedArray.getColor(R.styleable.CircleProgressBarView_circleBgColor, circleBgColor); + progressColor = typedArray.getColor(R.styleable.CircleProgressBarView_progressColor, progressColor); + + duration = typedArray.getColor(R.styleable.CircleProgressBarView_circleAnimationDuration, duration); + + isDrawCenterProgressText = typedArray.getBoolean(R.styleable.CircleProgressBarView_isDrawCenterProgressText, + false); + + centerProgressTextColor = typedArray.getColor(R.styleable.CircleProgressBarView_centerProgressTextColor, + mEndColor); + centerProgressTextSize = + typedArray.getDimensionPixelOffset(R.styleable.CircleProgressBarView_centerProgressTextSize, + ConvertUtils.sp2px(centerProgressTextSize)); + lineWidth = typedArray.getDimensionPixelOffset(R.styleable.CircleProgressBarView_lineWidth, + ConvertUtils.dp2px(1)); + lineColor = typedArray.getColor(R.styleable.CircleProgressBarView_lineColor, circleBgColor); + targetNumColor = typedArray.getColor(R.styleable.CircleProgressBarView_targetNumColor, targetNumColor); + targetNumSize = typedArray.getDimensionPixelSize(R.styleable.CircleProgressBarView_targetNumSize, + ConvertUtils.sp2px(20)); + targetTextSize = typedArray.getDimensionPixelSize(R.styleable.CircleProgressBarView_targetTextSize, + ConvertUtils.sp2px(12)); + targetTextColor = typedArray.getColor(R.styleable.CircleProgressBarView_targetTextColor, targetTextColor); + targetText = typedArray.getString(R.styleable.CircleProgressBarView_target_text); + typedArray.recycle(); + } + + public void setCenterProgressTextColor(int color) { + this.centerProgressTextColor = color; + centerProgressTextPaint.setColor(color); + } + + private void initPaint() { + circleBgPaint = getPaint(circleBgStrokeWidth, circleBgColor); + + progressPaint = getPaint(progressStrokeWidth, progressColor); + trainPaint = getPaint(ConvertUtils.dp2px(1), progressColor); + trainPaint.setStyle(Paint.Style.FILL); + + linePaint = getPaint(lineWidth, lineColor); + + // 目标文本画笔配置 + targetTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + targetTextPaint.setTextSize(targetTextSize); + targetTextPaint.setColor(targetTextColor); + targetTextPaint.setTextAlign(Paint.Align.CENTER); + + // 目标数字画笔配置 +// targetNumPaint = new Paint(Paint.ANTI_ALIAS_FLAG); +// targetNumPaint.setTextSize(targetNumSize); +// targetNumPaint.setColor(targetNumColor); +// targetNumPaint.setTextAlign(Paint.Align.CENTER); + + // 中间文本画笔配置 + centerProgressTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + centerProgressTextPaint.setTextSize(centerProgressTextSize); + centerProgressTextPaint.setColor(centerProgressTextColor); + centerProgressTextPaint.setTextAlign(Paint.Align.CENTER); + } + + private Paint getPaint(int strokeWidth, int color) { + Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + paint.setStrokeWidth(strokeWidth); + paint.setColor(color); + paint.setAntiAlias(true); + paint.setStrokeCap(Paint.Cap.ROUND); + paint.setStyle(Paint.Style.STROKE); + return paint; + } + + private LinearGradient mShader; + + private void configShader() { +// Log.d("201801251336", "progress = " + mProgress); +// int colors[] = { +// Color.rgb(97, 212, 198), Color.rgb(100, 225, 176), +// Color.rgb(93, 198, 221), Color.rgb(90, 187, 239) +// }; +// float positions[] = { +// 0.2f, 0.3f, 0.3f, 0.2f +// }; + // 清空画笔 + progressPaint.setShader(null); + if (mProgress >= 100) { + mShader = new LinearGradient(centerX, 0, centerX, getHeight(), + mEndColors, null, Shader.TileMode.CLAMP); + } else { + mShader = new LinearGradient(centerX, 0, centerX, getHeight(), + mDefColors, null, Shader.TileMode.CLAMP); + } + + // 圆内纵向直径为着色路径,圆环的左半边和右半边的色值有点对称的感觉 +// mShader = new LinearGradient(centerX, centerY - radius, centerX, centerY + radius, +// mColors, +// null, Shader.TileMode.CLAMP); + // 圆内横向直径为着色路径,可以达到首尾渐变效果,但进度不超过50%,看不出渐变后的效果 +// mShader = new LinearGradient(centerX + radius, centerY, centerX - radius, centerY, +// mColors, +// null, Shader.TileMode.CLAMP); + +// mShader = new SweepGradient(centerX,centerY,mColors,new float[]{0.5f,0.5f}); +// mShader = new SweepGradient(centerX,centerY,colors,null); +// mShader = new SweepGradient(centerX,centerY,mEndColor,mStartColor); +// mShader = new RadialGradient(centerX,centerY,radius,mColors,null, Shader.TileMode.CLAMP); + + progressPaint.setShader(mShader); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (progressAnimator != null) { + progressAnimator.cancel(); + } + } + + private boolean proAnimIsEnd = false; + + private void initAnimation() { + proAnimIsEnd = false; + progressAnimator = ValueAnimator.ofFloat(0, mProgress); + progressAnimator.setDuration(duration); + progressAnimator.setStartDelay(startDelay); + progressAnimator.setInterpolator(new LinearInterpolator()); + progressAnimator.addUpdateListener(valueAnimator -> { + float value = (float) valueAnimator.getAnimatedValue(); + mProgress = value; + currentProgress = value * 360 / 100; + if (progressListener != null) { + progressListener.currentProgressListener(value); + } + invalidate(); + }); + progressAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + proAnimIsEnd = true; + invalidate(); + } + }); + } + + public void setTargetNum(String num) { + targetNum = num; + } + + @Override + protected void onSizeChanged(int w, int h, int oldW, int oldH) { + super.onSizeChanged(w, h, oldW, oldH); + centerX = w / 2; + centerY = h / 2; + + // 半径再缩小点,给小三角形空出距离 + radius = Math.min(w, h) / 2 - Math.max(circleBgStrokeWidth, progressStrokeWidth) - dp4; + + rectF.set(centerX - radius, + centerY - radius, + centerX + radius, + centerY + radius); + trainPaint.setColor(circleBgColor); + + configShader(); + } + + public void setColors(int[] colors) { + mDefColors = colors; + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); +// LogUtil.logD("201801251106", "centerX = " + centerX + "->centerY = " +// + centerY + "->mProgress = " + mProgress); + canvas.drawCircle(centerX, centerY, radius, circleBgPaint); + canvas.drawArc(rectF, -90, currentProgress, false, progressPaint); + if (isDrawCenterProgressText) { + drawCenterProgressText(canvas, formatNum(mProgress) + "%"); + } + if (proAnimIsEnd) { + drawTriangle(canvas); + } + } + + private void drawCenterProgressText(Canvas canvas, String currentProgress) { + Paint.FontMetricsInt fontMetrics1 = centerProgressTextPaint.getFontMetricsInt(); + int baseline = (int) ((rectF.bottom + rectF.top - fontMetrics1.bottom - fontMetrics1.top) / 2); + //文字绘制到整个布局的中心位置 +// canvas.drawLine(centerX - dp30, centerY, centerX + dp30, centerY, linePaint); +// canvas.drawText(currentProgress, rectF.centerX(), centerY - dp5, centerProgressTextPaint); + canvas.drawText(currentProgress, rectF.centerX(), rectF.centerY()+dp5, centerProgressTextPaint); + +// Paint.FontMetricsInt fontMetrics2 = targetNumPaint.getFontMetricsInt(); +// int baseline2 = baseline + (fontMetrics2.bottom - fontMetrics2.top); +// canvas.drawText("升级中...", rectF.centerX(), baseline + dp7, targetTextPaint); + +// canvas.drawText(targetNum, rectF.centerX(), baseline2 + dp5, targetNumPaint); + } + + /** + * 绘制三角形 + * + * @param canvas + */ + private void drawTriangle(Canvas canvas) { + Path path = new Path(); + PointF pf1, pf2, pf3; +// LogUtil.logD("20190124", "绘制小三角 mProgress = " + mProgress); + if (mProgress < 49) { + trainPaint.setColor(circleBgColor); + pf1 = new PointF(centerX - dp8, centerY * 2 - progressStrokeWidth - dp2); + pf2 = new PointF(centerX - dp1, getHeight() - dp2); + pf3 = new PointF(centerX + dp6, centerY * 2 - progressStrokeWidth - dp2); + } else if (mProgress >= 49 && mProgress < 51) { + float[] positions; + int pro = (int) (mProgress * 100); + if (mProgress >= 49 && pro < 49.2 * 100) { + positions = new float[]{0.39f, 0.39f}; +// LogUtil.logD("20190124", "阶段1 -> pro = " + pro); + } else if (pro >= 49.2 * 100 && pro < 49.4 * 100) { + positions = new float[]{0.46f, 0.46f}; +// LogUtil.logD("20190124", "阶段2"); + } else if (pro >= 49.4 * 100 && pro < 49.6 * 100) { + positions = new float[]{0.5f, 0.5f}; +// LogUtil.logD("20190124", "阶段3 -> pro = " + pro); + } else if (pro >= 49.6 * 100 && pro < 49.8 * 100) { + positions = new float[]{0.62f, 0.38f}; +// LogUtil.logD("20190124", "阶段4 -> pro = " + pro); + } else if (pro >= 49.8 * 100 && pro < 50 * 100) { + positions = new float[]{0.64f, 0.36f}; +// LogUtil.logD("20190124", "阶段5 -> pro = " + pro); + } else if (pro >= 50 * 100 && pro < 50.2 * 100) { + positions = new float[]{0.7f, 0.3f}; +// LogUtil.logD("20190124", "阶段6 -> pro = " + pro); + } else if (pro >= 50.2 * 100 && pro < 50.4 * 100) { + positions = new float[]{0.75f, 0.25f}; +// LogUtil.logD("20190124", "阶段7 -> pro = " + pro); + } else if (pro >= 50.4 * 100 && pro < 50.6 * 100) { + positions = new float[]{0.8f, 0.2f}; +// LogUtil.logD("20190124", "阶段8 -> pro = " + pro); + } else if (pro >= 50.6 * 100 && pro <= 50.8 * 100) { + positions = new float[]{0.9f, 0.1f}; +// LogUtil.logD("20190124", "阶段9 -> pro = " + pro); + } else { + positions = new float[]{1.0f, 0.f}; +// LogUtil.logD("20190124", "阶段 else"); + } + LinearGradient triangleGdt = new LinearGradient( + centerX + dp6, + 0, + centerX - dp8, + 0, + new int[]{Color.rgb(88, 181, 250), Color.rgb(225, 229, 232)}, + positions, Shader.TileMode.CLAMP); + trainPaint.setShader(triangleGdt); + pf1 = new PointF(centerX - dp8, centerY * 2 - progressStrokeWidth - dp2); + pf2 = new PointF(centerX - dp1, getHeight() - dp2); + pf3 = new PointF(centerX + dp6, centerY * 2 - progressStrokeWidth - dp2); + } else { + trainPaint.setShader(null); // 不要忘记清空着色器,不能设置的color没有效果,会优先显示shader + if (mProgress >= 100) { + trainPaint.setColor(mEndColors[mEndColors.length - 1]); + } else { + trainPaint.setColor(mDefColors[mDefColors.length - 1]); + } + pf1 = new PointF(centerX - dp8, centerY * 2 - progressStrokeWidth - dp2); + pf2 = new PointF(centerX - dp1, getHeight()); + pf3 = new PointF(centerX + dp6, centerY * 2 - progressStrokeWidth - dp2); + } + path.moveTo(pf1.x, pf1.y); + path.lineTo(pf2.x, pf2.y); + path.lineTo(pf3.x, pf3.y); + canvas.drawPath(path, trainPaint); + path.reset(); + } + + + public void startProgressAnimation() { + progressAnimator.start(); + } + + @RequiresApi(api = Build.VERSION_CODES.KITKAT) + public void pauseProgressAnimation() { + progressAnimator.pause(); + } + + @RequiresApi(api = Build.VERSION_CODES.KITKAT) + public void resumeProgressAnimation() { + progressAnimator.resume(); + } + + public void stopProgressAnimation() { + progressAnimator.end(); + } + + + /** + * 传入一个进度值,从0到progress动画变化 + * + * @param progress + * @return + */ + public CircleProgress setProgressWithAnimation(float progress) { +// if (progress <= 0f || String.valueOf(progress).equals(String.valueOf(Float.NaN))) { + if (progress <= 0f || Float.isNaN(progress)) { + setCurrentProgress(0f, true); + return this; + } + mProgress = progress; +// if (progress >= 100) { +// configShader(); +// }else{ + configShader(); +// } + initAnimation(); + startProgressAnimation(); + return this; + } + + /** + * 实时进度,适用于下载进度回调时候之类的场景 + * + * @param progress + * @return + */ + public CircleProgress setCurrentProgress(float progress) { + mProgress = progress; + currentProgress = progress * 360 / 100; + if (progress >= 100) { + configShader(); + } + invalidate(); + return this; + } + + /** + * 实时进度,适用于下载进度回调时候之类的场景 + * + * @param progress + * @param isArrow 是否有小箭头 + * @return + */ + public CircleProgress setCurrentProgress(float progress, boolean isArrow) { + proAnimIsEnd = isArrow; + setCurrentProgress(progress); + return this; + } + + /** + * 格式化数字(保留两位小数) + * + * @param money + * @return + */ + public static String formatNum(float money) { + if (((int) money * 100) == (int) (money * 100)) { + //如果是一个整数 + return String.valueOf((int) money); + } + DecimalFormat format = new DecimalFormat("0.00"); + return format.format(money); + } + + public interface ProgressListener { + void currentProgressListener(float currentProgress); + } + + public CircleProgress setProgressListener(ProgressListener listener) { + progressListener = listener; + return this; + } +} + diff --git a/baselib/src/main/res/layout/dialog_center_update_progress.xml b/baselib/src/main/res/layout/dialog_center_update_progress.xml new file mode 100755 index 0000000..be5f4e9 --- /dev/null +++ b/baselib/src/main/res/layout/dialog_center_update_progress.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/baselib/src/main/res/values/attrs.xml b/baselib/src/main/res/values/attrs.xml index 93c4f4e..2502fce 100755 --- a/baselib/src/main/res/values/attrs.xml +++ b/baselib/src/main/res/values/attrs.xml @@ -196,4 +196,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index ff1b28e..1204f56 100644 --- a/build.gradle +++ b/build.gradle @@ -58,8 +58,8 @@ ext { gCompileSdkVersion = 30 gMinSdkVersion = 21 gTargetSdkVersion = 30 - gVersionCode = 15 - gVersionName = '1.1.4' + gVersionCode = 14 + gVersionName = '1.1.3' gBuildToolsVersion = "29.0.2" // gVersionCode=26 // gVersionName='1.3.0' diff --git a/commonmodule/src/main/java/com/tengshisoft/commonmodule/activitys/usercenter/UserCenterFragment.java b/commonmodule/src/main/java/com/tengshisoft/commonmodule/activitys/usercenter/UserCenterFragment.java index bebcd4c..2a5bbe8 100755 --- a/commonmodule/src/main/java/com/tengshisoft/commonmodule/activitys/usercenter/UserCenterFragment.java +++ b/commonmodule/src/main/java/com/tengshisoft/commonmodule/activitys/usercenter/UserCenterFragment.java @@ -752,7 +752,8 @@ public class UserCenterFragment extends BaseFragment { * 开始下载Apk */ private void startDownloadApk() { - ToastUtils.show("检测到新版本,开始下载,请在通知栏查看下载进度"); + mHomeActivity.showUpdate(); + ToastUtils.show("检测到新版本,开始下载."); Intent intent = new Intent(mActivity, DownloadService.class); intent.putExtra(Constants.APK_DOWNLOAD_URL, BaseUrlApi.APP_DOWNLOAD_URL); mActivity.startService(intent); diff --git a/mainmodule/src/main/java/com/tengshisoft/mainmodule/base/MainTabActivity.java b/mainmodule/src/main/java/com/tengshisoft/mainmodule/base/MainTabActivity.java index f3c2ef9..f3a8450 100644 --- a/mainmodule/src/main/java/com/tengshisoft/mainmodule/base/MainTabActivity.java +++ b/mainmodule/src/main/java/com/tengshisoft/mainmodule/base/MainTabActivity.java @@ -17,6 +17,9 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.core.content.ContextCompat; import androidx.viewpager2.widget.ViewPager2; @@ -27,7 +30,6 @@ import com.baidu.location.BDLocation; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.gyf.immersionbar.ImmersionBar; -import com.tenlionsoft.baselib.utils.ToastUtils; import com.huawei.ecterminalsdk.base.TsdkConfJoinParam; import com.huawei.ecterminalsdk.base.TsdkLocalAddress; import com.huawei.ecterminalsdk.models.TsdkManager; @@ -68,6 +70,7 @@ import com.tenlionsoft.baselib.core.beans.UserExpandInfoBean; import com.tenlionsoft.baselib.core.db.AppDatabase; import com.tenlionsoft.baselib.core.network.update.CheckUpdateUtils; import com.tenlionsoft.baselib.core.network.update.service.DownloadService; +import com.tenlionsoft.baselib.core.network.update.utils.ApkUtils; import com.tenlionsoft.baselib.core.network.update.utils.Constants; import com.tenlionsoft.baselib.core.retrofit_net.BaseUrlApi; import com.tenlionsoft.baselib.core.retrofit_net.RetrofitManager; @@ -79,6 +82,7 @@ import com.tenlionsoft.baselib.core.widget.base.BaseFragment; import com.tenlionsoft.baselib.core.widget.base.BaseViewPage2Adapter; import com.tenlionsoft.baselib.core.widget.base.FragmentUtils; import com.tenlionsoft.baselib.core.widget.base.NotificationUtils; +import com.tenlionsoft.baselib.core.widget.views.CenterProgressUpdateView; import com.tenlionsoft.baselib.core.widget.views.ChangePwdDialog; import com.tenlionsoft.baselib.utils.AppUtils; import com.tenlionsoft.baselib.utils.EncryptUtils; @@ -87,6 +91,7 @@ import com.tenlionsoft.baselib.utils.GpsUtils; import com.tenlionsoft.baselib.utils.IntentWrapper; import com.tenlionsoft.baselib.utils.KeyBoardListener; import com.tenlionsoft.baselib.utils.LogUtils; +import com.tenlionsoft.baselib.utils.ToastUtils; import com.tenlionsoft.baselib.utils.UIUtil; import com.tenlionsoft.baselib.utils.UserLgUtils; @@ -94,6 +99,7 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import java.io.File; import java.util.ArrayList; import java.util.List; @@ -146,6 +152,9 @@ public class MainTabActivity extends BaseActivity implements LoginView, LocalBro private String mConfId; private ProgressDialog mDialog; private boolean isCallIn; + private CenterProgressUpdateView mUpdateView; + private File mApkFile; + private ActivityResultLauncher mInstallLauncher; @Override protected int setLayoutId() { @@ -160,6 +169,20 @@ public class MainTabActivity extends BaseActivity implements LoginView, LocalBro refreshView(STATE_LOAD_SUCCESS); mFragments = new ArrayList<>(); initContentView(); + mInstallLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), + result -> { + boolean b = false; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { + LogUtils.e("是否可以安装:" + b); + b = getPackageManager().canRequestPackageInstalls(); + if (b) { + installApk(mApkFile); + } else { + mApkFile = null; + ToastUtils.showLong("您未授权安装未知应用,无法安装,请前往设置自行授权."); + } + } + }); getUserExpand(); getAppConfig(); startLocation(); @@ -169,6 +192,7 @@ public class MainTabActivity extends BaseActivity implements LoginView, LocalBro showOpenPermissionDialog(); } } + } /** @@ -217,7 +241,12 @@ public class MainTabActivity extends BaseActivity implements LoginView, LocalBro } }); + } + private void showUpdateProgress() { + mUpdateView = new CenterProgressUpdateView.DialogBuilder(mActivity) + .build(); + mUpdateView.show(); } /** @@ -427,7 +456,8 @@ public class MainTabActivity extends BaseActivity implements LoginView, LocalBro * 开始下载Apk */ private void startDownloadApk() { - ToastUtils.show("检测到新版本,开始下载,请在通知栏查看下载进度"); + ToastUtils.show("检测到新版本,开始下载"); + showUpdateProgress(); Intent intent = new Intent(mActivity, DownloadService.class); intent.putExtra(Constants.APK_DOWNLOAD_URL, BaseUrlApi.APP_DOWNLOAD_URL); startService(intent); @@ -487,6 +517,9 @@ public class MainTabActivity extends BaseActivity implements LoginView, LocalBro filter.addAction(PathConfig.ACTION_LOGIN_OUT);//强制退出 filter.addAction(PathConfig.ACTION_SOCKET_NOT_ALIVE);//重新连接socket filter.addAction(PathConfig.ACTION_RELINK_HW_RHTX);//重新登录融合通信 + filter.addAction(PathConfig.ACTION_UPDATE_SUCCESS);//下载成功 + filter.addAction(PathConfig.ACTION_UPDATE_ERROR);//下载失败 + filter.addAction(PathConfig.ACTION_UPDATE_PROGRESS);//进度更新 registerReceiver(mReceiver, filter); } @@ -873,6 +906,11 @@ public class MainTabActivity extends BaseActivity implements LoginView, LocalBro } } + @Override + public void showUpdate() { + showUpdateProgress(); + } + @Override protected void onResume() { super.onResume(); @@ -996,9 +1034,65 @@ public class MainTabActivity extends BaseActivity implements LoginView, LocalBro int logout = LoginMangerV2.getInstance().logout(); LogUtils.e("退出登录===" + logout); getAppConfig(); + } else if (PathConfig.ACTION_UPDATE_ERROR.equals(action)) { + //下载失败 + if (mUpdateView != null && mUpdateView.isShowing()) { + mUpdateView.dismiss(); + } + } else if (PathConfig.ACTION_UPDATE_PROGRESS.equals(action)) { + //进度更新 + if (mUpdateView != null && mUpdateView.isShowing()) { + int progress = intent.getIntExtra("progress", 0); + LogUtils.e("当前进度:" + progress); + mUpdateView.setCurrentProgress(progress); + } + } else if (PathConfig.ACTION_UPDATE_SUCCESS.equals(action)) { + //下载成功 + if (mUpdateView != null && mUpdateView.isShowing()) { + mUpdateView.dismiss(); + } + //判断是否可以安装 + File apkFile = (File) intent.getSerializableExtra("apkFile"); + installApk(apkFile); } } + } + /** + * 安装Apk + * + * @param file + */ + private void installApk(File file) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { + boolean b = getPackageManager().canRequestPackageInstalls(); + if (b) { + ApkUtils.installAPk(mActivity, file); + } else { + //申请权限 + mApkFile = file; + Uri packageURI = Uri.parse("package:" + mActivity.getPackageName()); + Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI); + startActivityForResult(intent, 298); + } + } else { + ApkUtils.installAPk(mActivity, file); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 298) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { + boolean b = getPackageManager().canRequestPackageInstalls(); + if (b) { + installApk(mApkFile); + } else { + ToastUtils.showLong("您未授权\"安装未知应用\"权限,导致无法安装软件,请自行前往设置授权。"); + } + } + } } /**