Sfoglia il codice sorgente

<app自动升级功能>

weizhengliang 4 anni fa
parent
commit
10cb030f25

+ 4 - 0
callingbed/src/main/AndroidManifest.xml

@@ -17,5 +17,9 @@
         <activity android:name=".activity.CallingbedActivity"
             android:screenOrientation="landscape"
             android:launchMode="singleTask"/>
+
+        <activity android:name=".activity.AppUpdateActivity"
+            android:screenOrientation="landscape"
+            android:launchMode="singleTask"/>
     </application>
 </manifest>

+ 63 - 0
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/activity/AppUpdateActivity.kt

@@ -0,0 +1,63 @@
+package com.wdkl.app.ncs.callingbed.activity
+
+import com.enation.javashop.android.jrouter.external.annotation.Router
+import com.enation.javashop.net.engine.model.NetState
+import com.wdkl.app.ncs.callingbed.R
+import com.wdkl.app.ncs.callingbed.databinding.UpdateLayBinding
+import com.wdkl.app.ncs.callingbed.helper.AppUpdateHelper
+import com.wdkl.app.ncs.callingbed.launch.CallingbedLaunch
+import com.wdkl.ncs.android.lib.base.BaseActivity
+import com.wdkl.ncs.android.lib.utils.showMessage
+import com.wdkl.ncs.android.lib.vo.filter
+import com.wdkl.ncs.android.middleware.logic.contract.callingbed.AppUpdateContract
+import com.wdkl.ncs.android.middleware.logic.presenter.callingbed.AppUpdatePresenter
+
+@Router(path = "/callingbed/update")
+class AppUpdateActivity :BaseActivity<AppUpdatePresenter, UpdateLayBinding>(), AppUpdateContract.View {
+
+    override fun getLayId(): Int {
+        return R.layout.update_lay
+    }
+
+    override fun bindDagger() {
+        CallingbedLaunch.component.inject(this)
+    }
+
+    override fun init() {
+        //
+    }
+
+    override fun bindEvent() {
+        //
+    }
+
+    override fun destory() {
+        //
+    }
+
+    //数据加载错误
+    override fun onError(message: String, type: Int) {
+        //
+    }
+
+    //数据加载完成
+    override fun complete(message: String, type: Int) {
+        //
+    }
+
+    //开始获取数据
+    override fun start() {
+        //
+    }
+
+    //网络监听
+    override fun networkMonitor(state: NetState) {
+        state.filter(onMobile = {
+
+        },onWifi = {
+
+        },offline = {
+
+        })
+    }
+}

+ 7 - 10
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/activity/CallingbedActivity.kt

@@ -62,8 +62,6 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
     //一定时间无操作返回主界面
     private var backTimeout = 0
 
-    private val TIME_WHAT = 1000
-
     //主信息
     private val mainFragment = "main_fragment"
     //医嘱
@@ -79,6 +77,10 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
     //呼叫护士
     private val callNurseFragment = "call_nurse_fragment"
 
+    companion object {
+        private const val TIME_WHAT = 1000
+    }
+
     override fun getLayId(): Int {
         return R.layout.callingbed_main_lay;
     }
@@ -111,7 +113,6 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
     }
 
     override fun bindEvent() {
-
     }
 
     override fun destory() {
@@ -120,7 +121,7 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         SipHelper.getInstance().unRegisterSip()
         SoundPoolHelper.getInstance().release()
         unRegReceiver()
-        releaseHandler()
+        handler.removeCallbacksAndMessages(null)
         isTimeWorking = false
     }
 
@@ -593,7 +594,7 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
         }
     }
 
-    internal inner class MyHandler(activity: CallingbedActivity) : Handler() {
+    class MyHandler(activity: CallingbedActivity) : Handler() {
         // 弱引用 ,防止内存泄露
         private val weakReference: WeakReference<CallingbedActivity>
 
@@ -609,7 +610,7 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
             if (handlerMemoryActivity != null) {
                 when (msg.what) {
                     TIME_WHAT -> {
-                        backToMain()
+                        handlerMemoryActivity.backToMain()
                     }
                 }
             } else {
@@ -636,8 +637,4 @@ class CallingbedActivity :BaseActivity<CallingbedActivityPresenter, CallingbedMa
             backTimeout = 0
         }
     }
-
-    fun releaseHandler() {
-        handler.removeMessages(TIME_WHAT)
-    }
 }

+ 4 - 2
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/activity/InitActivity.kt

@@ -1,5 +1,6 @@
 package com.wdkl.app.ncs.callingbed.activity
 
+import android.os.Build
 import com.enation.javashop.android.jrouter.external.annotation.Router
 import com.enation.javashop.net.engine.model.NetState
 import com.wdkl.app.ncs.callingbed.BuildConfig
@@ -19,8 +20,9 @@ import serialporttest.utils.SerialPortUtil
 @Router(path = "/callingbed/init")
 class InitActivity :BaseActivity<InitActivityPresenter, InitLayBinding>(), InitActivityContract.View {
 
-    val sdk_version = android.os.Build.VERSION.SDK_INT
-    val product_name = ReflectHelper.getProperty("ro.product.name", "null")
+    val sdk_version = Build.VERSION.SDK_INT
+    //val product_name = ReflectHelper.getProperty("ro.product.name", "null")
+    val product_name = Build.PRODUCT;
 
     override fun getLayId(): Int {
         return R.layout.init_lay

+ 3 - 0
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/di/CallingbedComponent.kt

@@ -1,5 +1,6 @@
 package com.wdkl.app.ncs.callingbed.di
 
+import com.wdkl.app.ncs.callingbed.activity.AppUpdateActivity
 import com.wdkl.app.ncs.callingbed.activity.CallingbedActivity
 import com.wdkl.app.ncs.callingbed.activity.InitActivity
 import com.wdkl.app.ncs.callingbed.fragment.*
@@ -12,6 +13,8 @@ interface CallingbedComponent {
 
     fun inject(activity: InitActivity)
 
+    fun inject(activity: AppUpdateActivity)
+
     fun inject(activity: MainFragment)
 
     fun inject(activity: DoctorOrderFragment)

+ 1 - 1
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/fragment/CallNurseFragment.kt

@@ -21,7 +21,7 @@ class CallNurseFragment : BaseFragment<CallNurseFragmentPresenter, CallNurseView
     val TAG = "CallNurseFragment"
 
     //呼叫状态:0-呼叫中,1-接通,2-挂断
-    var callState : Int = 0
+    var callState : Int = 1
     //呼叫倒计时
     lateinit var countDownTimer: CountDownTimer
 

+ 93 - 0
callingbed/src/main/java/com/wdkl/app/ncs/callingbed/helper/AppUpdateHelper.java

@@ -0,0 +1,93 @@
+package com.wdkl.app.ncs.callingbed.helper;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.util.Log;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+public class AppUpdateHelper {
+    private final static String TAG = "AppUpdate";
+
+    /**
+     * 下载的APK文件绝对路径
+     */
+    public static final String FILE_APK_PATH = Environment.getExternalStorageDirectory() + "/CallingBed";
+    /**
+     * 下载的APK文件的文件名
+     */
+    public static final String FILE_APK_NAME = "CallingBedAPK.apk";
+
+    public static void updateApp(Context context) {
+        if (checkApkExit(context)) {
+            Log.d(TAG, "文件存在");
+        } else {
+            Log.d(TAG, "文件不存在");
+            return;
+        }
+
+        /*if (!checkApkAvailable(context, DownloadUtil.FILE_APK_PATH + "/" + DownloadUtil.FILE_APK_NAME)) {
+            ToastUtil.showToast("apk文件不匹配,升级失败!");
+            return;
+        }*/
+
+
+        if (silentInstall(context, FILE_APK_PATH + "/" + FILE_APK_NAME)) {
+            Log.d(TAG, "app 安装成功");
+        }
+    }
+
+    private static boolean checkApkExit(Context context) {
+        File file = new File(FILE_APK_PATH + "/" + FILE_APK_NAME);
+        return file.exists();
+    }
+
+    private static boolean checkApkAvailable(Context context, String path) {
+        try {
+            PackageManager pm = context.getPackageManager();
+            PackageInfo info = pm.getPackageArchiveInfo(path, 0);
+            ApplicationInfo applicationInfo = info.applicationInfo;
+            String newPkg = applicationInfo.packageName;
+            String curPkg = context.getPackageName();
+            Log.d(TAG, "new package: " + newPkg + ", cur package: " + curPkg);
+            if (curPkg.equals(newPkg)) {
+                return true;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return false;
+    }
+
+    public static boolean silentInstall(Context context, String apkPath) {
+        PackageManager packageManager = context.getPackageManager();
+        Class pmClz = packageManager.getClass();
+        try {
+            if (Build.VERSION.SDK_INT >= 21) {
+                Class aClass = Class.forName("android.app.PackageInstallObserver");
+                Constructor constructor = aClass.getDeclaredConstructor();
+                constructor.setAccessible(true);
+                Object installObserver = constructor.newInstance();
+                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class, aClass, int.class, String.class);
+                method.setAccessible(true);
+                method.invoke(packageManager, Uri.fromFile(new File(apkPath)), installObserver, 2, null);
+            } else {
+                Method method = pmClz.getDeclaredMethod("installPackage", Uri.class, Class.forName("android.content.pm.IPackageInstallObserver"), int.class, String.class);
+                method.setAccessible(true);
+                method.invoke(packageManager, Uri.fromFile(new File(apkPath)), null, 2, null);
+            }
+            return true;
+        } catch (Exception e) {
+            Log.e(TAG, e.toString());
+        }
+        return false;
+    }
+}

+ 35 - 0
callingbed/src/main/res/layout/update_lay.xml

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<layout>
+    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/white"
+        android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/activity_calling_bed_text_download"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerInParent="true"
+            android:text="正在升级中,请勿操作..."
+            android:textColor="#3D3D63"
+            android:textSize="30sp" />
+
+        <com.wdkl.ncs.android.lib.widget.ProgressView
+            android:id="@+id/activity_appupdate_dialog_progressview"
+            android:layout_width="match_parent"
+            android:layout_height="20dp"
+            android:layout_alignParentBottom="true"
+            android:layout_marginBottom="30dp"
+            android:layout_marginLeft="50dp"
+            android:layout_marginRight="50dp"
+            app:haveChangeColor="true"
+            app:isShowDesc="false"
+            app:max="100"
+            app:progress="0"
+            app:progressDesc="进度:"
+            app:progressRadius="10dp" />
+
+    </RelativeLayout>
+</layout>

+ 2 - 2
callingbed/src/main/res/values/strings.xml

@@ -1,5 +1,5 @@
 <resources>
-    <string name="app_name"></string>
-    <string name="local_sip">4000360960</string>
+    <string name="app_name">Callingbed</string>
+    <string name="local_sip">4000000470</string>
     <string name="target_sip">4000348830</string>
 </resources>

+ 357 - 0
common/src/main/code/com/wdkl/ncs/android/lib/widget/ProgressView.kt

@@ -0,0 +1,357 @@
+package com.wdkl.ncs.android.lib.widget
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ObjectAnimator
+import android.content.Context
+import android.graphics.*
+import android.os.Looper
+import android.text.TextPaint
+import android.util.AttributeSet
+import android.util.TypedValue
+import android.view.View
+import com.wdkl.ncs.android.lib.R
+
+class ProgressView :View{
+
+    private var mPaint: Paint? = null
+    private var mTextPaint: TextPaint? = null
+
+    private var mRadius: Int
+    private var mBorderColor: Int
+    private var mProgressColor: Int = 0
+    private var mProgressDescColor: Int
+    private var mMax: Int = 0
+    private var mProgress: Int = 0
+    private var mBorderWidth: Int
+    private var mIsShowDesc: Boolean = false
+    private var mHaveChangeColor: Boolean = false
+
+    private val DEFAULT_MAX = 10
+    private val DEFAULT_PROGRESS = 0
+    var changeColor = arrayOf("#CDFDCB", "#65FDCC", "#65FDCC", "#55CA7C", "#55CA7C", "#52CD53", "#52CD53", "#52CD53", "#3D9A5C", "#3D9A5C")
+
+    private val DEFAULT_RADIUS = TypedValue.applyDimension(
+            TypedValue.COMPLEX_UNIT_DIP, 5f, resources.displayMetrics).toInt()
+    private val DEFAULT_BORDER_COLOR = Color.parseColor("#FD0005")
+    private val DEFAULT_PROGRESS_COLOR = Color.parseColor("#77D178")
+    private val DEFAULT_PROGRESS_DESC_COLOR = Color.parseColor("#000000")
+    private val DEFAULT_BORDER_WIDTH = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f, resources.displayMetrics).toInt()
+    private val DEFAULT_ISSHOWDESC = true
+
+    private var mWidth: Int = 0
+    private var mHeight: Int = 0
+    private var mTextBounds: Rect? = null
+    private var mProgressDesc: String? = ""
+
+    private var mOnFinishedListener: OnFinishedListener? = null
+    private var mOnAnimationEndListener: OnAnimationEndListener? = null
+
+    constructor(context: Context): this(context, null)
+
+    constructor(context: Context, attrs: AttributeSet?): this(context, attrs, 0)
+
+    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr) {
+        val a = context.obtainStyledAttributes(attrs, R.styleable.ProgressView)
+        mMax = a.getInt(R.styleable.ProgressView_max, DEFAULT_MAX)
+        mProgress = a.getInt(R.styleable.ProgressView_progress, DEFAULT_PROGRESS)
+        mRadius = a.getDimension(R.styleable.ProgressView_progressRadius, DEFAULT_RADIUS.toFloat()).toInt()
+        mBorderColor = a.getColor(R.styleable.ProgressView_borderColor, DEFAULT_BORDER_COLOR)
+        mProgressColor = a.getColor(R.styleable.ProgressView_progressColor, DEFAULT_PROGRESS_COLOR)
+        mProgressDescColor = a.getColor(R.styleable.ProgressView_progressDescColor, DEFAULT_PROGRESS_DESC_COLOR)
+        mBorderWidth = a.getDimension(R.styleable.ProgressView_borderWidth, DEFAULT_BORDER_WIDTH.toFloat()).toInt()
+        mProgressDesc = a.getString(R.styleable.ProgressView_progressDesc)
+        mIsShowDesc = a.getBoolean(R.styleable.ProgressView_isShowDesc, DEFAULT_ISSHOWDESC)
+        mHaveChangeColor = a.getBoolean(R.styleable.ProgressView_haveChangeColor, true)
+        a.recycle()
+        init()
+    }
+
+    private fun init() {
+        mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
+        mTextBounds = Rect()
+        mTextPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
+        mTextPaint!!.textSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12f, resources.displayMetrics)
+        mTextPaint!!.color = mProgressDescColor
+    }
+
+    /**
+     * 设置结束监听
+     *
+     * @param onFinishedListener
+     */
+    fun setOnFinishedListener(onFinishedListener: OnFinishedListener) {
+        mOnFinishedListener = onFinishedListener
+    }
+
+    /**
+     * 设置进度停止监听
+     *
+     * @param onAnimationEndListener
+     */
+    fun setOnAnimationEndListener(onAnimationEndListener: OnAnimationEndListener) {
+        mOnAnimationEndListener = onAnimationEndListener
+    }
+
+    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
+        super.onSizeChanged(w, h, oldw, oldh)
+        mWidth = w
+        mHeight = h
+    }
+
+    override fun onDraw(canvas: Canvas) {
+        drawBorder(canvas)
+        drawProgress(canvas)
+        if (mIsShowDesc) drawProgressDesc(canvas)
+    }
+
+    private fun drawBorder(canvas: Canvas) {
+        mPaint!!.reset()
+        mPaint!!.style = Paint.Style.STROKE
+        mPaint!!.strokeJoin = Paint.Join.MITER
+        mPaint!!.isAntiAlias = true
+        mPaint!!.color = mBorderColor
+        mPaint!!.strokeWidth = mBorderWidth.toFloat()
+
+        val left = mBorderWidth / 2
+        val top = mBorderWidth / 2
+        val right = mWidth - mBorderWidth / 2
+        val bottom = mHeight - mBorderWidth / 2
+
+        val path = Path()
+        path.moveTo((left + mRadius).toFloat(), top.toFloat())
+        path.lineTo((right - mRadius).toFloat(), top.toFloat())
+        path.arcTo(RectF((right - 2 * mRadius).toFloat(), top.toFloat(), right.toFloat(), (top + 2 * mRadius).toFloat()), -90f, 90f)
+        path.lineTo(right.toFloat(), (bottom - mRadius).toFloat())
+        path.arcTo(RectF((right - 2 * mRadius).toFloat(), (bottom - 2 * mRadius).toFloat(), right.toFloat(), bottom.toFloat()), 0f, 90f)
+        path.lineTo((left + mRadius).toFloat(), bottom.toFloat())
+        path.arcTo(RectF(left.toFloat(), (bottom - 2 * mRadius).toFloat(), (left + 2 * mRadius).toFloat(), bottom.toFloat()), 90f, 90f)
+        path.lineTo(left.toFloat(), (top + mRadius).toFloat())
+        path.arcTo(RectF(left.toFloat(), top.toFloat(), (left + 2 * mRadius).toFloat(), (top + 2 * mRadius).toFloat()), 180f, 90f)
+        path.close()
+        canvas.drawPath(path, mPaint!!)
+    }
+
+    private fun drawProgress(canvas: Canvas) {
+
+        mPaint!!.reset()
+        mPaint!!.style = Paint.Style.FILL
+        mPaint!!.isAntiAlias = true
+        mPaint!!.color = mProgressColor
+        mPaint!!.strokeWidth = mBorderWidth.toFloat()
+
+        val left = mBorderWidth * .5f
+        val top = mBorderWidth * .5f
+        val right = mWidth - mBorderWidth * .5f
+        val bottom = mHeight - mBorderWidth * .5f
+
+        val path = Path()
+        path.moveTo(left, top + mRadius)
+        val scale = mProgress * 1f / mMax / (mRadius * 1f / (right - left))
+        val scale2 = mProgress * 1f / mMax / ((right - mRadius) * 1f / (right - left))
+        if (scale <= 1) {
+            val a = scale * mRadius
+            val angle = Math.acos(((mRadius - a) / mRadius).toDouble())
+            path.arcTo(RectF(left, top, left + 2 * mRadius, top + 2 * mRadius), 180f, (angle * 180 / Math.PI).toFloat())
+            val y = (Math.pow(Math.pow(mRadius.toDouble(), 2.0) - Math.pow((a - mRadius).toDouble(), 2.0), 0.5) + bottom - mRadius).toFloat()
+            path.lineTo(left + a, y)
+            path.arcTo(RectF(left, bottom - 2 * mRadius, left + 2 * mRadius, bottom), 180 - (angle * 180 / Math.PI).toFloat(),
+                    (angle * 180 / Math.PI).toFloat())
+            path.close()
+            canvas.drawPath(path, mPaint!!)
+        } else if (scale2 <= 1) {
+            path.arcTo(RectF(left, top, left + 2 * mRadius, top + 2 * mRadius), 180f, 90f)
+            path.lineTo(left + mProgress * 1f / mMax * (right - left), top)
+            path.lineTo(left + mProgress * 1f / mMax * (right - left), bottom)
+            path.lineTo(left + mRadius, bottom)
+            path.arcTo(RectF(left, bottom - 2 * mRadius, left + 2 * mRadius, bottom), 90f, 90f)
+            path.close()
+            canvas.drawPath(path, mPaint!!)
+        } else {
+            val a = mProgress * 1f / mMax * (right - left) - (right - mRadius)
+            val angle = Math.asin((a / mRadius).toDouble())
+            path.arcTo(RectF(left, top, left + 2 * mRadius, top + 2 * mRadius), 180f, 90f)
+            path.lineTo(right - mRadius, top)
+            path.arcTo(RectF(right - 2 * mRadius, top, right, top + 2 * mRadius), -90f, (angle * 180 / Math.PI).toFloat())
+            val y = Math.pow(Math.pow(mRadius.toDouble(), 2.0) - Math.pow(a.toDouble(), 2.0), .5) + top.toDouble() + mRadius.toDouble()
+
+            path.lineTo(right - mRadius + a, y.toFloat())
+            path.arcTo(RectF(right - 2 * mRadius, bottom - 2 * mRadius,
+                    right, bottom), (90 - angle * 180 / Math.PI).toFloat(),
+                    (angle * 180 / Math.PI).toFloat())
+            path.lineTo(left + mRadius, bottom)
+            path.arcTo(RectF(left, bottom - 2 * mRadius,
+                    left + 2 * mRadius, bottom), 90f, 90f)
+            path.close()
+
+            canvas.drawPath(path, mPaint!!)
+        }
+    }
+
+    private fun drawProgressDesc(canvas: Canvas) {
+        var finalProgressDesc = ""
+        if (100 == mMax) {
+            finalProgressDesc = "$mProgressDesc$mProgress %"
+        } else {
+            finalProgressDesc = "$mProgressDesc$mProgress/$mMax"
+        }
+        mTextPaint!!.getTextBounds(finalProgressDesc, 0, finalProgressDesc.length, mTextBounds)
+        canvas.drawText(finalProgressDesc, (mWidth / 2.0 - mTextBounds!!.width() / 2.0).toInt().toFloat(), (mHeight / 2.0 - (mTextPaint!!.ascent() + mTextPaint!!.descent()) / 2.0f).toInt().toFloat(), mTextPaint!!)
+    }
+
+
+    private fun setProgress(progress: Int) {
+
+        mProgress = if (progress > mMax) mMax else progress
+        invalidateView()
+
+        if (mProgress >= mMax && mOnFinishedListener != null) {
+            mOnFinishedListener!!.onFinish()
+        }
+
+    }
+
+    /**
+     * 得到ProgressBar的最大进度
+     *
+     * @return
+     */
+    fun getMax(): Int {
+        return mMax
+    }
+
+    /**
+     * 获取当前ProgressBar的进度
+     *
+     * @return
+     */
+    fun getProgress(): Int {
+        return mProgress
+    }
+
+    fun setMaxProgress(max: Int) {
+        this.mMax = if (max < 0) 0 else max
+        invalidateView()
+    }
+
+    fun setProgressDesc(desc: String) {
+        mProgressDesc = desc
+        invalidateView()
+    }
+
+    /**
+     * 设置当前进度条的进度(默认动画时间1.5s)
+     *
+     * @param progress
+     */
+    fun setCurProgress(progress: Int) {
+        if (mHaveChangeColor) {
+            setProgressColor(getProgressChangeColor(progress.toFloat() / mMax.toFloat()))
+        } else {
+            setProgressColor(DEFAULT_PROGRESS_COLOR)
+        }
+        val animator = ObjectAnimator.ofInt(this, "progress", progress).setDuration(0)
+        animator.addListener(object : AnimatorListenerAdapter() {
+            override fun onAnimationEnd(animation: Animator) {
+                super.onAnimationEnd(animation)
+                if (mOnAnimationEndListener != null) {
+                    mOnAnimationEndListener!!.onAnimationEnd()
+                }
+            }
+        })
+        animator.start()
+    }
+
+    /**
+     * 设置当前进度条的进度
+     *
+     * @param progress 目标进度
+     * @param duration 动画时长
+     */
+    fun setCurProgress(progress: Int, duration: Long) {
+        if (mHaveChangeColor) {
+            setProgressColor(getProgressChangeColor(progress.toFloat() / mMax.toFloat()))
+        } else {
+            setProgressColor(DEFAULT_PROGRESS_COLOR)
+        }
+        val animator = ObjectAnimator.ofInt(this, "progress", progress).setDuration(duration)
+        animator.addListener(object : AnimatorListenerAdapter() {
+            override fun onAnimationEnd(animation: Animator) {
+                super.onAnimationEnd(animation)
+                if (mOnAnimationEndListener != null) {
+                    mOnAnimationEndListener!!.onAnimationEnd()
+                }
+            }
+        })
+        animator.start()
+    }
+
+    private fun getProgressChangeColor(percentage: Float): Int {
+        if (0 < percentage && percentage <= 0.1) {
+            return Color.parseColor(changeColor[0])
+        } else if (0.1 < percentage && percentage <= 0.2) {
+            return Color.parseColor(changeColor[1])
+        } else if (0.2 < percentage && percentage <= 0.3) {
+            return Color.parseColor(changeColor[2])
+        } else if (0.3 < percentage && percentage <= 0.4) {
+            return Color.parseColor(changeColor[3])
+        } else if (0.4 < percentage && percentage <= 0.5) {
+            return Color.parseColor(changeColor[4])
+        } else if (0.5 < percentage && percentage <= 0.6) {
+            return Color.parseColor(changeColor[5])
+        } else if (0.6 < percentage && percentage <= 0.7) {
+            return Color.parseColor(changeColor[6])
+        } else if (0.7 < percentage && percentage <= 0.8) {
+            return Color.parseColor(changeColor[7])
+        } else if (0.8 < percentage && percentage <= 0.9) {
+            return Color.parseColor(changeColor[8])
+        } else if (0.9 < percentage && percentage <= 1.0) {
+            return Color.parseColor(changeColor[9])
+        }
+        return DEFAULT_PROGRESS_COLOR
+    }
+
+    /**
+     * 设置ProgressBar的颜色
+     *
+     * @param color
+     */
+    fun setProgressColor(color: Int) {
+        mProgressColor = color
+        invalidateView()
+    }
+
+    /**
+     * 设置是否显示当前进度
+     *
+     * @param isShowDesc true:显示
+     */
+    fun setIsShowDesc(isShowDesc: Boolean) {
+        mIsShowDesc = isShowDesc
+        invalidateView()
+    }
+
+    /**
+     * 设置是否需要颜色渐变
+     */
+    fun setHaveChangeColor(haveChangeColor: Boolean) {
+        mHaveChangeColor = haveChangeColor
+        invalidateView()
+    }
+
+    private fun invalidateView() {
+        if (Looper.getMainLooper() == Looper.myLooper()) {
+            invalidate()
+        } else {
+            postInvalidate()
+        }
+    }
+
+    interface OnFinishedListener {
+        fun onFinish()
+    }
+
+    interface OnAnimationEndListener {
+        fun onAnimationEnd()
+    }
+}

+ 13 - 0
common/src/main/res/values/attrs.xml

@@ -75,4 +75,17 @@
         <attr name="textHeader" format="string" />
         <attr name="onlyColor" format="string" />
     </declare-styleable>
+
+    <declare-styleable name="ProgressView">
+        <attr name="progressColor" format="color" />
+        <attr name="borderColor" format="color" />
+        <attr name="progressDescColor" format="color" />
+        <attr name="progressRadius" format="dimension" />
+        <attr name="max" format="integer" />
+        <attr name="progress" format="integer" />
+        <attr name="borderWidth" format="dimension" />
+        <attr name="progressDesc" format="string" />
+        <attr name="isShowDesc" format="boolean" />
+        <attr name="haveChangeColor" format="boolean" />
+    </declare-styleable>
 </resources>

+ 2 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/di/PresenterComponent.kt

@@ -57,6 +57,8 @@ interface PresenterComponent {
 
     fun inject(presenter: InitActivityPresenter)
 
+    fun inject(presenter: AppUpdatePresenter)
+
     fun inject(presenter: MainFragmentPresenter)
 
     fun inject(presenter: DoctorOrderFragmentPresenter)

+ 13 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/contract/callingbed/AppUpdateContract.kt

@@ -0,0 +1,13 @@
+package com.wdkl.ncs.android.middleware.logic.contract.callingbed
+
+import com.wdkl.ncs.android.lib.base.BaseContract
+
+interface AppUpdateContract {
+    interface View : BaseContract.BaseView {
+
+    }
+
+    interface Presenter : BaseContract.BasePresenter {
+
+    }
+}

+ 12 - 0
middleware/src/main/code/com/wdkl/ncs/android/middleware/logic/presenter/callingbed/AppUpdatePresenter.kt

@@ -0,0 +1,12 @@
+package com.wdkl.ncs.android.middleware.logic.presenter.callingbed
+
+import com.wdkl.ncs.android.lib.base.RxPresenter
+import com.wdkl.ncs.android.middleware.di.MiddlewareDaggerComponent
+import com.wdkl.ncs.android.middleware.logic.contract.callingbed.AppUpdateContract
+import javax.inject.Inject
+
+class AppUpdatePresenter @Inject constructor() : RxPresenter<AppUpdateContract.View>(), AppUpdateContract.Presenter {
+    override fun bindDagger() {
+        MiddlewareDaggerComponent.component.inject(this)
+    }
+}

+ 1 - 1
welcome/src/main/code/com/wdkl/ncs/android/component/welcome/activity/WelcomeActivity.kt

@@ -92,7 +92,7 @@ class WelcomeActivity :BaseActivity<WelcomePresenter, ActivityWelcomeBinding>(),
     override fun toHome() {
         AppTool.Time.delay(200) {
             //push("/home/main")
-            push("/callingbed/init")
+            push("/callingbed/main")
             finish()
         }
     }