diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 135b8bc..562e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 135b8bc..562e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt index e585cca..efc2b5e 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/String.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt @@ -25,6 +25,17 @@ return errorModel.message.toString() } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this}" +} + //拼接图片地址 fun String.combineImagePath(): String { if (this.isEmpty()) return this diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 135b8bc..562e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt index e585cca..efc2b5e 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/String.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt @@ -25,6 +25,17 @@ return errorModel.message.toString() } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this}" +} + //拼接图片地址 fun String.combineImagePath(): String { if (this.isEmpty()) return this diff --git a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt index 021a8b3..77a77b1 100644 --- a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt @@ -1,7 +1,14 @@ package com.casic.smarttube.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.BuildConfig import com.casic.smarttube.R +import com.casic.smarttube.extensions.appendDownloadUrl import com.casic.smarttube.model.UserDetailModel import com.casic.smarttube.utils.AuthenticationHelper import com.casic.smarttube.utils.DialogHelper @@ -10,9 +17,13 @@ import com.casic.smarttube.view.LoginActivity import com.casic.smarttube.vm.LoginViewModel import com.casic.smarttube.vm.UserViewModel +import com.casic.smarttube.vm.VersionViewModel import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.KotlinBaseFragment +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.PageNavigationManager @@ -21,6 +32,7 @@ import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.ChangePasswordDialog import kotlinx.android.synthetic.main.fragment_mine.* +import java.io.File import java.nio.charset.StandardCharsets class MinePageFragment : KotlinBaseFragment() { @@ -29,6 +41,8 @@ private lateinit var userData: UserDetailModel.Data private lateinit var userViewModel: UserViewModel private lateinit var loginViewModel: LoginViewModel + private lateinit var versionViewModel: VersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -39,6 +53,14 @@ override fun initData() { userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java) + versionViewModel = ViewModelProvider(this).get(VersionViewModel::class.java) + + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -72,6 +94,22 @@ }).build().show() } + aboutUsLayout.setOnClickListener { + + } + + updateVersionLayout.setOnClickListener { + versionViewModel.updateVersion() + } + + updateLogLayout.setOnClickListener { + + } + + clearCacheLayout.setOnClickListener { + + } + loginOutButton.setOnClickListener { AlertControlDialog.Builder() .setContext(requireContext()) @@ -96,9 +134,6 @@ } private fun dataObserve() { - /** - * 用户信息数据监听 - * */ userViewModel.userDetailModel.observe(this, { if (it.code == 200) { DialogHelper.dismissLoadingDialog() @@ -113,6 +148,7 @@ DialogHelper.showLoadingDialog(requireActivity(), "修改中,请稍后") } is LoadState.Success -> { + "修改成功,请重新登录".show(requireContext()) DialogHelper.dismissLoadingDialog() AuthenticationHelper.removeToken() requireContext().navigatePageTo() @@ -124,6 +160,40 @@ } }) + versionViewModel.versionResultModel.observe(this, { + if (BuildConfig.VERSION_NAME == it.version) { + "已是最新版本,无需更新".show(requireContext()) + } else { + AlertControlDialog.Builder() + .setContext(requireContext()) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.downloadUrl) + } + + override fun onCancelClick() { + + } + }).build().show() + } + }) + + versionViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(requireActivity(), "检查版本中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + loginViewModel.outResultModel.observe(this, { if (it.code == 200) { AuthenticationHelper.removeToken() @@ -141,6 +211,8 @@ ) updateUserInfo() } + //缓存 + cacheSizeView.text = "" super.onResume() } @@ -149,4 +221,54 @@ userPhoneView.text = String.format("电话:${userData.phone}") userDeptView.text = String.format("部门:${userData.deptName}") } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(requireContext()) + return + } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(requireContext().createDownloadFileDir().toString(), + object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile( + requireContext(), LocalConstant.APP_AUTHORITY, apkPackage + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) + } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 135b8bc..562e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt index e585cca..efc2b5e 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/String.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt @@ -25,6 +25,17 @@ return errorModel.message.toString() } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this}" +} + //拼接图片地址 fun String.combineImagePath(): String { if (this.isEmpty()) return this diff --git a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt index 021a8b3..77a77b1 100644 --- a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt @@ -1,7 +1,14 @@ package com.casic.smarttube.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.BuildConfig import com.casic.smarttube.R +import com.casic.smarttube.extensions.appendDownloadUrl import com.casic.smarttube.model.UserDetailModel import com.casic.smarttube.utils.AuthenticationHelper import com.casic.smarttube.utils.DialogHelper @@ -10,9 +17,13 @@ import com.casic.smarttube.view.LoginActivity import com.casic.smarttube.vm.LoginViewModel import com.casic.smarttube.vm.UserViewModel +import com.casic.smarttube.vm.VersionViewModel import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.KotlinBaseFragment +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.PageNavigationManager @@ -21,6 +32,7 @@ import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.ChangePasswordDialog import kotlinx.android.synthetic.main.fragment_mine.* +import java.io.File import java.nio.charset.StandardCharsets class MinePageFragment : KotlinBaseFragment() { @@ -29,6 +41,8 @@ private lateinit var userData: UserDetailModel.Data private lateinit var userViewModel: UserViewModel private lateinit var loginViewModel: LoginViewModel + private lateinit var versionViewModel: VersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -39,6 +53,14 @@ override fun initData() { userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java) + versionViewModel = ViewModelProvider(this).get(VersionViewModel::class.java) + + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -72,6 +94,22 @@ }).build().show() } + aboutUsLayout.setOnClickListener { + + } + + updateVersionLayout.setOnClickListener { + versionViewModel.updateVersion() + } + + updateLogLayout.setOnClickListener { + + } + + clearCacheLayout.setOnClickListener { + + } + loginOutButton.setOnClickListener { AlertControlDialog.Builder() .setContext(requireContext()) @@ -96,9 +134,6 @@ } private fun dataObserve() { - /** - * 用户信息数据监听 - * */ userViewModel.userDetailModel.observe(this, { if (it.code == 200) { DialogHelper.dismissLoadingDialog() @@ -113,6 +148,7 @@ DialogHelper.showLoadingDialog(requireActivity(), "修改中,请稍后") } is LoadState.Success -> { + "修改成功,请重新登录".show(requireContext()) DialogHelper.dismissLoadingDialog() AuthenticationHelper.removeToken() requireContext().navigatePageTo() @@ -124,6 +160,40 @@ } }) + versionViewModel.versionResultModel.observe(this, { + if (BuildConfig.VERSION_NAME == it.version) { + "已是最新版本,无需更新".show(requireContext()) + } else { + AlertControlDialog.Builder() + .setContext(requireContext()) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.downloadUrl) + } + + override fun onCancelClick() { + + } + }).build().show() + } + }) + + versionViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(requireActivity(), "检查版本中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + loginViewModel.outResultModel.observe(this, { if (it.code == 200) { AuthenticationHelper.removeToken() @@ -141,6 +211,8 @@ ) updateUserInfo() } + //缓存 + cacheSizeView.text = "" super.onResume() } @@ -149,4 +221,54 @@ userPhoneView.text = String.format("电话:${userData.phone}") userDeptView.text = String.format("部门:${userData.deptName}") } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(requireContext()) + return + } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(requireContext().createDownloadFileDir().toString(), + object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile( + requireContext(), LocalConstant.APP_AUTHORITY, apkPackage + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java new file mode 100644 index 0000000..3f2ba02 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java @@ -0,0 +1,61 @@ +package com.casic.smarttube.model; + +public class VersionResultModel { + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private String downloadUrl; + private String version; + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 135b8bc..562e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt index e585cca..efc2b5e 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/String.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt @@ -25,6 +25,17 @@ return errorModel.message.toString() } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this}" +} + //拼接图片地址 fun String.combineImagePath(): String { if (this.isEmpty()) return this diff --git a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt index 021a8b3..77a77b1 100644 --- a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt @@ -1,7 +1,14 @@ package com.casic.smarttube.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.BuildConfig import com.casic.smarttube.R +import com.casic.smarttube.extensions.appendDownloadUrl import com.casic.smarttube.model.UserDetailModel import com.casic.smarttube.utils.AuthenticationHelper import com.casic.smarttube.utils.DialogHelper @@ -10,9 +17,13 @@ import com.casic.smarttube.view.LoginActivity import com.casic.smarttube.vm.LoginViewModel import com.casic.smarttube.vm.UserViewModel +import com.casic.smarttube.vm.VersionViewModel import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.KotlinBaseFragment +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.PageNavigationManager @@ -21,6 +32,7 @@ import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.ChangePasswordDialog import kotlinx.android.synthetic.main.fragment_mine.* +import java.io.File import java.nio.charset.StandardCharsets class MinePageFragment : KotlinBaseFragment() { @@ -29,6 +41,8 @@ private lateinit var userData: UserDetailModel.Data private lateinit var userViewModel: UserViewModel private lateinit var loginViewModel: LoginViewModel + private lateinit var versionViewModel: VersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -39,6 +53,14 @@ override fun initData() { userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java) + versionViewModel = ViewModelProvider(this).get(VersionViewModel::class.java) + + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -72,6 +94,22 @@ }).build().show() } + aboutUsLayout.setOnClickListener { + + } + + updateVersionLayout.setOnClickListener { + versionViewModel.updateVersion() + } + + updateLogLayout.setOnClickListener { + + } + + clearCacheLayout.setOnClickListener { + + } + loginOutButton.setOnClickListener { AlertControlDialog.Builder() .setContext(requireContext()) @@ -96,9 +134,6 @@ } private fun dataObserve() { - /** - * 用户信息数据监听 - * */ userViewModel.userDetailModel.observe(this, { if (it.code == 200) { DialogHelper.dismissLoadingDialog() @@ -113,6 +148,7 @@ DialogHelper.showLoadingDialog(requireActivity(), "修改中,请稍后") } is LoadState.Success -> { + "修改成功,请重新登录".show(requireContext()) DialogHelper.dismissLoadingDialog() AuthenticationHelper.removeToken() requireContext().navigatePageTo() @@ -124,6 +160,40 @@ } }) + versionViewModel.versionResultModel.observe(this, { + if (BuildConfig.VERSION_NAME == it.version) { + "已是最新版本,无需更新".show(requireContext()) + } else { + AlertControlDialog.Builder() + .setContext(requireContext()) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.downloadUrl) + } + + override fun onCancelClick() { + + } + }).build().show() + } + }) + + versionViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(requireActivity(), "检查版本中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + loginViewModel.outResultModel.observe(this, { if (it.code == 200) { AuthenticationHelper.removeToken() @@ -141,6 +211,8 @@ ) updateUserInfo() } + //缓存 + cacheSizeView.text = "" super.onResume() } @@ -149,4 +221,54 @@ userPhoneView.text = String.format("电话:${userData.phone}") userDeptView.text = String.format("部门:${userData.deptName}") } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(requireContext()) + return + } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(requireContext().createDownloadFileDir().toString(), + object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile( + requireContext(), LocalConstant.APP_AUTHORITY, apkPackage + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java new file mode 100644 index 0000000..3f2ba02 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java @@ -0,0 +1,61 @@ +package com.casic.smarttube.model; + +public class VersionResultModel { + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private String downloadUrl; + private String version; + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index cee379c..d5ac3ec 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -40,4 +40,5 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" + const val APP_AUTHORITY = "com.casic.smarttube.fileprovider" } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 135b8bc..562e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt index e585cca..efc2b5e 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/String.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt @@ -25,6 +25,17 @@ return errorModel.message.toString() } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this}" +} + //拼接图片地址 fun String.combineImagePath(): String { if (this.isEmpty()) return this diff --git a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt index 021a8b3..77a77b1 100644 --- a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt @@ -1,7 +1,14 @@ package com.casic.smarttube.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.BuildConfig import com.casic.smarttube.R +import com.casic.smarttube.extensions.appendDownloadUrl import com.casic.smarttube.model.UserDetailModel import com.casic.smarttube.utils.AuthenticationHelper import com.casic.smarttube.utils.DialogHelper @@ -10,9 +17,13 @@ import com.casic.smarttube.view.LoginActivity import com.casic.smarttube.vm.LoginViewModel import com.casic.smarttube.vm.UserViewModel +import com.casic.smarttube.vm.VersionViewModel import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.KotlinBaseFragment +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.PageNavigationManager @@ -21,6 +32,7 @@ import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.ChangePasswordDialog import kotlinx.android.synthetic.main.fragment_mine.* +import java.io.File import java.nio.charset.StandardCharsets class MinePageFragment : KotlinBaseFragment() { @@ -29,6 +41,8 @@ private lateinit var userData: UserDetailModel.Data private lateinit var userViewModel: UserViewModel private lateinit var loginViewModel: LoginViewModel + private lateinit var versionViewModel: VersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -39,6 +53,14 @@ override fun initData() { userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java) + versionViewModel = ViewModelProvider(this).get(VersionViewModel::class.java) + + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -72,6 +94,22 @@ }).build().show() } + aboutUsLayout.setOnClickListener { + + } + + updateVersionLayout.setOnClickListener { + versionViewModel.updateVersion() + } + + updateLogLayout.setOnClickListener { + + } + + clearCacheLayout.setOnClickListener { + + } + loginOutButton.setOnClickListener { AlertControlDialog.Builder() .setContext(requireContext()) @@ -96,9 +134,6 @@ } private fun dataObserve() { - /** - * 用户信息数据监听 - * */ userViewModel.userDetailModel.observe(this, { if (it.code == 200) { DialogHelper.dismissLoadingDialog() @@ -113,6 +148,7 @@ DialogHelper.showLoadingDialog(requireActivity(), "修改中,请稍后") } is LoadState.Success -> { + "修改成功,请重新登录".show(requireContext()) DialogHelper.dismissLoadingDialog() AuthenticationHelper.removeToken() requireContext().navigatePageTo() @@ -124,6 +160,40 @@ } }) + versionViewModel.versionResultModel.observe(this, { + if (BuildConfig.VERSION_NAME == it.version) { + "已是最新版本,无需更新".show(requireContext()) + } else { + AlertControlDialog.Builder() + .setContext(requireContext()) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.downloadUrl) + } + + override fun onCancelClick() { + + } + }).build().show() + } + }) + + versionViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(requireActivity(), "检查版本中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + loginViewModel.outResultModel.observe(this, { if (it.code == 200) { AuthenticationHelper.removeToken() @@ -141,6 +211,8 @@ ) updateUserInfo() } + //缓存 + cacheSizeView.text = "" super.onResume() } @@ -149,4 +221,54 @@ userPhoneView.text = String.format("电话:${userData.phone}") userDeptView.text = String.format("部门:${userData.deptName}") } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(requireContext()) + return + } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(requireContext().createDownloadFileDir().toString(), + object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile( + requireContext(), LocalConstant.APP_AUTHORITY, apkPackage + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java new file mode 100644 index 0000000..3f2ba02 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java @@ -0,0 +1,61 @@ +package com.casic.smarttube.model; + +public class VersionResultModel { + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private String downloadUrl; + private String version; + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index cee379c..d5ac3ec 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -40,4 +40,5 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" + const val APP_AUTHORITY = "com.casic.smarttube.fileprovider" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index 5a4e0df..64c5402 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -63,4 +63,10 @@ @Header("token") token: String, @Part file: MultipartBody.Part ): String + + /** + * 更新APK版本 + */ + @POST("/app/checkVersion") + suspend fun obtainVersionResult(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 135b8bc..562e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt index e585cca..efc2b5e 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/String.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt @@ -25,6 +25,17 @@ return errorModel.message.toString() } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this}" +} + //拼接图片地址 fun String.combineImagePath(): String { if (this.isEmpty()) return this diff --git a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt index 021a8b3..77a77b1 100644 --- a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt @@ -1,7 +1,14 @@ package com.casic.smarttube.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.BuildConfig import com.casic.smarttube.R +import com.casic.smarttube.extensions.appendDownloadUrl import com.casic.smarttube.model.UserDetailModel import com.casic.smarttube.utils.AuthenticationHelper import com.casic.smarttube.utils.DialogHelper @@ -10,9 +17,13 @@ import com.casic.smarttube.view.LoginActivity import com.casic.smarttube.vm.LoginViewModel import com.casic.smarttube.vm.UserViewModel +import com.casic.smarttube.vm.VersionViewModel import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.KotlinBaseFragment +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.PageNavigationManager @@ -21,6 +32,7 @@ import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.ChangePasswordDialog import kotlinx.android.synthetic.main.fragment_mine.* +import java.io.File import java.nio.charset.StandardCharsets class MinePageFragment : KotlinBaseFragment() { @@ -29,6 +41,8 @@ private lateinit var userData: UserDetailModel.Data private lateinit var userViewModel: UserViewModel private lateinit var loginViewModel: LoginViewModel + private lateinit var versionViewModel: VersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -39,6 +53,14 @@ override fun initData() { userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java) + versionViewModel = ViewModelProvider(this).get(VersionViewModel::class.java) + + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -72,6 +94,22 @@ }).build().show() } + aboutUsLayout.setOnClickListener { + + } + + updateVersionLayout.setOnClickListener { + versionViewModel.updateVersion() + } + + updateLogLayout.setOnClickListener { + + } + + clearCacheLayout.setOnClickListener { + + } + loginOutButton.setOnClickListener { AlertControlDialog.Builder() .setContext(requireContext()) @@ -96,9 +134,6 @@ } private fun dataObserve() { - /** - * 用户信息数据监听 - * */ userViewModel.userDetailModel.observe(this, { if (it.code == 200) { DialogHelper.dismissLoadingDialog() @@ -113,6 +148,7 @@ DialogHelper.showLoadingDialog(requireActivity(), "修改中,请稍后") } is LoadState.Success -> { + "修改成功,请重新登录".show(requireContext()) DialogHelper.dismissLoadingDialog() AuthenticationHelper.removeToken() requireContext().navigatePageTo() @@ -124,6 +160,40 @@ } }) + versionViewModel.versionResultModel.observe(this, { + if (BuildConfig.VERSION_NAME == it.version) { + "已是最新版本,无需更新".show(requireContext()) + } else { + AlertControlDialog.Builder() + .setContext(requireContext()) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.downloadUrl) + } + + override fun onCancelClick() { + + } + }).build().show() + } + }) + + versionViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(requireActivity(), "检查版本中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + loginViewModel.outResultModel.observe(this, { if (it.code == 200) { AuthenticationHelper.removeToken() @@ -141,6 +211,8 @@ ) updateUserInfo() } + //缓存 + cacheSizeView.text = "" super.onResume() } @@ -149,4 +221,54 @@ userPhoneView.text = String.format("电话:${userData.phone}") userDeptView.text = String.format("部门:${userData.deptName}") } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(requireContext()) + return + } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(requireContext().createDownloadFileDir().toString(), + object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile( + requireContext(), LocalConstant.APP_AUTHORITY, apkPackage + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java new file mode 100644 index 0000000..3f2ba02 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java @@ -0,0 +1,61 @@ +package com.casic.smarttube.model; + +public class VersionResultModel { + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private String downloadUrl; + private String version; + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index cee379c..d5ac3ec 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -40,4 +40,5 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" + const val APP_AUTHORITY = "com.casic.smarttube.fileprovider" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index 5a4e0df..64c5402 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -63,4 +63,10 @@ @Header("token") token: String, @Part file: MultipartBody.Part ): String + + /** + * 更新APK版本 + */ + @POST("/app/checkVersion") + suspend fun obtainVersionResult(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index 8d999db..2af9a24 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -47,6 +47,13 @@ } /** + * 更新APK版本 + */ + suspend fun updateVersion(): String { + return api.obtainVersionResult(AuthenticationHelper.token!!) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 135b8bc..562e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt index e585cca..efc2b5e 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/String.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt @@ -25,6 +25,17 @@ return errorModel.message.toString() } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this}" +} + //拼接图片地址 fun String.combineImagePath(): String { if (this.isEmpty()) return this diff --git a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt index 021a8b3..77a77b1 100644 --- a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt @@ -1,7 +1,14 @@ package com.casic.smarttube.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.BuildConfig import com.casic.smarttube.R +import com.casic.smarttube.extensions.appendDownloadUrl import com.casic.smarttube.model.UserDetailModel import com.casic.smarttube.utils.AuthenticationHelper import com.casic.smarttube.utils.DialogHelper @@ -10,9 +17,13 @@ import com.casic.smarttube.view.LoginActivity import com.casic.smarttube.vm.LoginViewModel import com.casic.smarttube.vm.UserViewModel +import com.casic.smarttube.vm.VersionViewModel import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.KotlinBaseFragment +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.PageNavigationManager @@ -21,6 +32,7 @@ import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.ChangePasswordDialog import kotlinx.android.synthetic.main.fragment_mine.* +import java.io.File import java.nio.charset.StandardCharsets class MinePageFragment : KotlinBaseFragment() { @@ -29,6 +41,8 @@ private lateinit var userData: UserDetailModel.Data private lateinit var userViewModel: UserViewModel private lateinit var loginViewModel: LoginViewModel + private lateinit var versionViewModel: VersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -39,6 +53,14 @@ override fun initData() { userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java) + versionViewModel = ViewModelProvider(this).get(VersionViewModel::class.java) + + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -72,6 +94,22 @@ }).build().show() } + aboutUsLayout.setOnClickListener { + + } + + updateVersionLayout.setOnClickListener { + versionViewModel.updateVersion() + } + + updateLogLayout.setOnClickListener { + + } + + clearCacheLayout.setOnClickListener { + + } + loginOutButton.setOnClickListener { AlertControlDialog.Builder() .setContext(requireContext()) @@ -96,9 +134,6 @@ } private fun dataObserve() { - /** - * 用户信息数据监听 - * */ userViewModel.userDetailModel.observe(this, { if (it.code == 200) { DialogHelper.dismissLoadingDialog() @@ -113,6 +148,7 @@ DialogHelper.showLoadingDialog(requireActivity(), "修改中,请稍后") } is LoadState.Success -> { + "修改成功,请重新登录".show(requireContext()) DialogHelper.dismissLoadingDialog() AuthenticationHelper.removeToken() requireContext().navigatePageTo() @@ -124,6 +160,40 @@ } }) + versionViewModel.versionResultModel.observe(this, { + if (BuildConfig.VERSION_NAME == it.version) { + "已是最新版本,无需更新".show(requireContext()) + } else { + AlertControlDialog.Builder() + .setContext(requireContext()) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.downloadUrl) + } + + override fun onCancelClick() { + + } + }).build().show() + } + }) + + versionViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(requireActivity(), "检查版本中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + loginViewModel.outResultModel.observe(this, { if (it.code == 200) { AuthenticationHelper.removeToken() @@ -141,6 +211,8 @@ ) updateUserInfo() } + //缓存 + cacheSizeView.text = "" super.onResume() } @@ -149,4 +221,54 @@ userPhoneView.text = String.format("电话:${userData.phone}") userDeptView.text = String.format("部门:${userData.deptName}") } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(requireContext()) + return + } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(requireContext().createDownloadFileDir().toString(), + object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile( + requireContext(), LocalConstant.APP_AUTHORITY, apkPackage + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java new file mode 100644 index 0000000..3f2ba02 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java @@ -0,0 +1,61 @@ +package com.casic.smarttube.model; + +public class VersionResultModel { + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private String downloadUrl; + private String version; + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index cee379c..d5ac3ec 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -40,4 +40,5 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" + const val APP_AUTHORITY = "com.casic.smarttube.fileprovider" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index 5a4e0df..64c5402 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -63,4 +63,10 @@ @Header("token") token: String, @Part file: MultipartBody.Part ): String + + /** + * 更新APK版本 + */ + @POST("/app/checkVersion") + suspend fun obtainVersionResult(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index 8d999db..2af9a24 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -47,6 +47,13 @@ } /** + * 更新APK版本 + */ + suspend fun updateVersion(): String { + return api.obtainVersionResult(AuthenticationHelper.token!!) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt index d64679c..8c33d53 100644 --- a/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt @@ -46,7 +46,6 @@ val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success - "修改成功,请重新登录".show(BaseApplication.obtainInstance()) } else { loadState.value = LoadState.Fail response.toErrorMessage().show(BaseApplication.obtainInstance()) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 135b8bc..562e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt index e585cca..efc2b5e 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/String.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt @@ -25,6 +25,17 @@ return errorModel.message.toString() } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this}" +} + //拼接图片地址 fun String.combineImagePath(): String { if (this.isEmpty()) return this diff --git a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt index 021a8b3..77a77b1 100644 --- a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt @@ -1,7 +1,14 @@ package com.casic.smarttube.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.BuildConfig import com.casic.smarttube.R +import com.casic.smarttube.extensions.appendDownloadUrl import com.casic.smarttube.model.UserDetailModel import com.casic.smarttube.utils.AuthenticationHelper import com.casic.smarttube.utils.DialogHelper @@ -10,9 +17,13 @@ import com.casic.smarttube.view.LoginActivity import com.casic.smarttube.vm.LoginViewModel import com.casic.smarttube.vm.UserViewModel +import com.casic.smarttube.vm.VersionViewModel import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.KotlinBaseFragment +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.PageNavigationManager @@ -21,6 +32,7 @@ import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.ChangePasswordDialog import kotlinx.android.synthetic.main.fragment_mine.* +import java.io.File import java.nio.charset.StandardCharsets class MinePageFragment : KotlinBaseFragment() { @@ -29,6 +41,8 @@ private lateinit var userData: UserDetailModel.Data private lateinit var userViewModel: UserViewModel private lateinit var loginViewModel: LoginViewModel + private lateinit var versionViewModel: VersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -39,6 +53,14 @@ override fun initData() { userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java) + versionViewModel = ViewModelProvider(this).get(VersionViewModel::class.java) + + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -72,6 +94,22 @@ }).build().show() } + aboutUsLayout.setOnClickListener { + + } + + updateVersionLayout.setOnClickListener { + versionViewModel.updateVersion() + } + + updateLogLayout.setOnClickListener { + + } + + clearCacheLayout.setOnClickListener { + + } + loginOutButton.setOnClickListener { AlertControlDialog.Builder() .setContext(requireContext()) @@ -96,9 +134,6 @@ } private fun dataObserve() { - /** - * 用户信息数据监听 - * */ userViewModel.userDetailModel.observe(this, { if (it.code == 200) { DialogHelper.dismissLoadingDialog() @@ -113,6 +148,7 @@ DialogHelper.showLoadingDialog(requireActivity(), "修改中,请稍后") } is LoadState.Success -> { + "修改成功,请重新登录".show(requireContext()) DialogHelper.dismissLoadingDialog() AuthenticationHelper.removeToken() requireContext().navigatePageTo() @@ -124,6 +160,40 @@ } }) + versionViewModel.versionResultModel.observe(this, { + if (BuildConfig.VERSION_NAME == it.version) { + "已是最新版本,无需更新".show(requireContext()) + } else { + AlertControlDialog.Builder() + .setContext(requireContext()) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.downloadUrl) + } + + override fun onCancelClick() { + + } + }).build().show() + } + }) + + versionViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(requireActivity(), "检查版本中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + loginViewModel.outResultModel.observe(this, { if (it.code == 200) { AuthenticationHelper.removeToken() @@ -141,6 +211,8 @@ ) updateUserInfo() } + //缓存 + cacheSizeView.text = "" super.onResume() } @@ -149,4 +221,54 @@ userPhoneView.text = String.format("电话:${userData.phone}") userDeptView.text = String.format("部门:${userData.deptName}") } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(requireContext()) + return + } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(requireContext().createDownloadFileDir().toString(), + object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile( + requireContext(), LocalConstant.APP_AUTHORITY, apkPackage + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java new file mode 100644 index 0000000..3f2ba02 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java @@ -0,0 +1,61 @@ +package com.casic.smarttube.model; + +public class VersionResultModel { + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private String downloadUrl; + private String version; + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index cee379c..d5ac3ec 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -40,4 +40,5 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" + const val APP_AUTHORITY = "com.casic.smarttube.fileprovider" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index 5a4e0df..64c5402 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -63,4 +63,10 @@ @Header("token") token: String, @Part file: MultipartBody.Part ): String + + /** + * 更新APK版本 + */ + @POST("/app/checkVersion") + suspend fun obtainVersionResult(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index 8d999db..2af9a24 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -47,6 +47,13 @@ } /** + * 更新APK版本 + */ + suspend fun updateVersion(): String { + return api.obtainVersionResult(AuthenticationHelper.token!!) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt index d64679c..8c33d53 100644 --- a/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt @@ -46,7 +46,6 @@ val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success - "修改成功,请重新登录".show(BaseApplication.obtainInstance()) } else { loadState.value = LoadState.Fail response.toErrorMessage().show(BaseApplication.obtainInstance()) diff --git a/app/src/main/java/com/casic/smarttube/vm/VersionViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/VersionViewModel.kt new file mode 100644 index 0000000..273d595 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/vm/VersionViewModel.kt @@ -0,0 +1,38 @@ +package com.casic.smarttube.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.extensions.separateResponseCode +import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.VersionResultModel +import com.casic.smarttube.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +class VersionViewModel : BaseViewModel() { + + private val gson = Gson() + val versionResultModel = MutableLiveData() + + fun updateVersion() = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.updateVersion() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + versionResultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ).data + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 135b8bc..562e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt index e585cca..efc2b5e 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/String.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt @@ -25,6 +25,17 @@ return errorModel.message.toString() } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this}" +} + //拼接图片地址 fun String.combineImagePath(): String { if (this.isEmpty()) return this diff --git a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt index 021a8b3..77a77b1 100644 --- a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt @@ -1,7 +1,14 @@ package com.casic.smarttube.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.BuildConfig import com.casic.smarttube.R +import com.casic.smarttube.extensions.appendDownloadUrl import com.casic.smarttube.model.UserDetailModel import com.casic.smarttube.utils.AuthenticationHelper import com.casic.smarttube.utils.DialogHelper @@ -10,9 +17,13 @@ import com.casic.smarttube.view.LoginActivity import com.casic.smarttube.vm.LoginViewModel import com.casic.smarttube.vm.UserViewModel +import com.casic.smarttube.vm.VersionViewModel import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.KotlinBaseFragment +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.PageNavigationManager @@ -21,6 +32,7 @@ import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.ChangePasswordDialog import kotlinx.android.synthetic.main.fragment_mine.* +import java.io.File import java.nio.charset.StandardCharsets class MinePageFragment : KotlinBaseFragment() { @@ -29,6 +41,8 @@ private lateinit var userData: UserDetailModel.Data private lateinit var userViewModel: UserViewModel private lateinit var loginViewModel: LoginViewModel + private lateinit var versionViewModel: VersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -39,6 +53,14 @@ override fun initData() { userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java) + versionViewModel = ViewModelProvider(this).get(VersionViewModel::class.java) + + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -72,6 +94,22 @@ }).build().show() } + aboutUsLayout.setOnClickListener { + + } + + updateVersionLayout.setOnClickListener { + versionViewModel.updateVersion() + } + + updateLogLayout.setOnClickListener { + + } + + clearCacheLayout.setOnClickListener { + + } + loginOutButton.setOnClickListener { AlertControlDialog.Builder() .setContext(requireContext()) @@ -96,9 +134,6 @@ } private fun dataObserve() { - /** - * 用户信息数据监听 - * */ userViewModel.userDetailModel.observe(this, { if (it.code == 200) { DialogHelper.dismissLoadingDialog() @@ -113,6 +148,7 @@ DialogHelper.showLoadingDialog(requireActivity(), "修改中,请稍后") } is LoadState.Success -> { + "修改成功,请重新登录".show(requireContext()) DialogHelper.dismissLoadingDialog() AuthenticationHelper.removeToken() requireContext().navigatePageTo() @@ -124,6 +160,40 @@ } }) + versionViewModel.versionResultModel.observe(this, { + if (BuildConfig.VERSION_NAME == it.version) { + "已是最新版本,无需更新".show(requireContext()) + } else { + AlertControlDialog.Builder() + .setContext(requireContext()) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.downloadUrl) + } + + override fun onCancelClick() { + + } + }).build().show() + } + }) + + versionViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(requireActivity(), "检查版本中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + loginViewModel.outResultModel.observe(this, { if (it.code == 200) { AuthenticationHelper.removeToken() @@ -141,6 +211,8 @@ ) updateUserInfo() } + //缓存 + cacheSizeView.text = "" super.onResume() } @@ -149,4 +221,54 @@ userPhoneView.text = String.format("电话:${userData.phone}") userDeptView.text = String.format("部门:${userData.deptName}") } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(requireContext()) + return + } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(requireContext().createDownloadFileDir().toString(), + object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile( + requireContext(), LocalConstant.APP_AUTHORITY, apkPackage + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java new file mode 100644 index 0000000..3f2ba02 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java @@ -0,0 +1,61 @@ +package com.casic.smarttube.model; + +public class VersionResultModel { + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private String downloadUrl; + private String version; + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index cee379c..d5ac3ec 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -40,4 +40,5 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" + const val APP_AUTHORITY = "com.casic.smarttube.fileprovider" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index 5a4e0df..64c5402 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -63,4 +63,10 @@ @Header("token") token: String, @Part file: MultipartBody.Part ): String + + /** + * 更新APK版本 + */ + @POST("/app/checkVersion") + suspend fun obtainVersionResult(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index 8d999db..2af9a24 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -47,6 +47,13 @@ } /** + * 更新APK版本 + */ + suspend fun updateVersion(): String { + return api.obtainVersionResult(AuthenticationHelper.token!!) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt index d64679c..8c33d53 100644 --- a/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt @@ -46,7 +46,6 @@ val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success - "修改成功,请重新登录".show(BaseApplication.obtainInstance()) } else { loadState.value = LoadState.Fail response.toErrorMessage().show(BaseApplication.obtainInstance()) diff --git a/app/src/main/java/com/casic/smarttube/vm/VersionViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/VersionViewModel.kt new file mode 100644 index 0000000..273d595 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/vm/VersionViewModel.kt @@ -0,0 +1,38 @@ +package com.casic.smarttube.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.extensions.separateResponseCode +import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.VersionResultModel +import com.casic.smarttube.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +class VersionViewModel : BaseViewModel() { + + private val gson = Gson() + val versionResultModel = MutableLiveData() + + fun updateVersion() = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.updateVersion() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + versionResultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ).data + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/download_progress.xml b/app/src/main/res/drawable/download_progress.xml new file mode 100644 index 0000000..9704a9f --- /dev/null +++ b/app/src/main/res/drawable/download_progress.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 135b8bc..562e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ + diff --git a/app/src/main/java/com/casic/smarttube/extensions/String.kt b/app/src/main/java/com/casic/smarttube/extensions/String.kt index e585cca..efc2b5e 100644 --- a/app/src/main/java/com/casic/smarttube/extensions/String.kt +++ b/app/src/main/java/com/casic/smarttube/extensions/String.kt @@ -25,6 +25,17 @@ return errorModel.message.toString() } +/** + * 下载路径为 http://xx.com/static/ 拼接downloadUrl + * */ +fun String.appendDownloadUrl(): String { + if (this.isEmpty()) return this + val defaultValue = SaveKeyValues.getValue( + LocalConstant.DEFAULT_SERVER_CONFIG, LocalConstant.SERVER_BASE_URL + ) as String + return "$defaultValue/static/${this}" +} + //拼接图片地址 fun String.combineImagePath(): String { if (this.isEmpty()) return this diff --git a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt index 021a8b3..77a77b1 100644 --- a/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt +++ b/app/src/main/java/com/casic/smarttube/fragment/MinePageFragment.kt @@ -1,7 +1,14 @@ package com.casic.smarttube.fragment +import android.app.ProgressDialog +import android.content.Intent +import android.net.Uri +import android.os.Build +import androidx.core.content.FileProvider import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.BuildConfig import com.casic.smarttube.R +import com.casic.smarttube.extensions.appendDownloadUrl import com.casic.smarttube.model.UserDetailModel import com.casic.smarttube.utils.AuthenticationHelper import com.casic.smarttube.utils.DialogHelper @@ -10,9 +17,13 @@ import com.casic.smarttube.view.LoginActivity import com.casic.smarttube.vm.LoginViewModel import com.casic.smarttube.vm.UserViewModel +import com.casic.smarttube.vm.VersionViewModel import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.pengxh.kt.lite.base.KotlinBaseFragment +import com.pengxh.kt.lite.callback.OnDownloadListener +import com.pengxh.kt.lite.extensions.createDownloadFileDir +import com.pengxh.kt.lite.extensions.downloadFile import com.pengxh.kt.lite.extensions.navigatePageTo import com.pengxh.kt.lite.extensions.show import com.pengxh.kt.lite.utils.PageNavigationManager @@ -21,6 +32,7 @@ import com.pengxh.kt.lite.widget.dialog.AlertControlDialog import com.pengxh.kt.lite.widget.dialog.ChangePasswordDialog import kotlinx.android.synthetic.main.fragment_mine.* +import java.io.File import java.nio.charset.StandardCharsets class MinePageFragment : KotlinBaseFragment() { @@ -29,6 +41,8 @@ private lateinit var userData: UserDetailModel.Data private lateinit var userViewModel: UserViewModel private lateinit var loginViewModel: LoginViewModel + private lateinit var versionViewModel: VersionViewModel + private lateinit var progressDialog: ProgressDialog override fun initLayoutView(): Int = R.layout.fragment_mine @@ -39,6 +53,14 @@ override fun initData() { userViewModel = ViewModelProvider(this).get(UserViewModel::class.java) loginViewModel = ViewModelProvider(this).get(LoginViewModel::class.java) + versionViewModel = ViewModelProvider(this).get(VersionViewModel::class.java) + + //初始化下载对话框 + progressDialog = ProgressDialog(requireContext()) + progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + progressDialog.setProgressDrawable(resources.getDrawable(R.drawable.download_progress)) + progressDialog.setCanceledOnTouchOutside(false) + progressDialog.setCancelable(false) } override fun initEvent() { @@ -72,6 +94,22 @@ }).build().show() } + aboutUsLayout.setOnClickListener { + + } + + updateVersionLayout.setOnClickListener { + versionViewModel.updateVersion() + } + + updateLogLayout.setOnClickListener { + + } + + clearCacheLayout.setOnClickListener { + + } + loginOutButton.setOnClickListener { AlertControlDialog.Builder() .setContext(requireContext()) @@ -96,9 +134,6 @@ } private fun dataObserve() { - /** - * 用户信息数据监听 - * */ userViewModel.userDetailModel.observe(this, { if (it.code == 200) { DialogHelper.dismissLoadingDialog() @@ -113,6 +148,7 @@ DialogHelper.showLoadingDialog(requireActivity(), "修改中,请稍后") } is LoadState.Success -> { + "修改成功,请重新登录".show(requireContext()) DialogHelper.dismissLoadingDialog() AuthenticationHelper.removeToken() requireContext().navigatePageTo() @@ -124,6 +160,40 @@ } }) + versionViewModel.versionResultModel.observe(this, { + if (BuildConfig.VERSION_NAME == it.version) { + "已是最新版本,无需更新".show(requireContext()) + } else { + AlertControlDialog.Builder() + .setContext(requireContext()) + .setTitle("提示") + .setMessage("有新版本,是否更新?") + .setNegativeButton("稍后再说") + .setPositiveButton("立即下载") + .setOnDialogButtonClickListener(object : + AlertControlDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + downloadApk(it.downloadUrl) + } + + override fun onCancelClick() { + + } + }).build().show() + } + }) + + versionViewModel.loadState.observe(this, { + when (it) { + is LoadState.Loading -> { + DialogHelper.showLoadingDialog(requireActivity(), "检查版本中,请稍后") + } + else -> { + DialogHelper.dismissLoadingDialog() + } + } + }) + loginViewModel.outResultModel.observe(this, { if (it.code == 200) { AuthenticationHelper.removeToken() @@ -141,6 +211,8 @@ ) updateUserInfo() } + //缓存 + cacheSizeView.text = "" super.onResume() } @@ -149,4 +221,54 @@ userPhoneView.text = String.format("电话:${userData.phone}") userDeptView.text = String.format("部门:${userData.deptName}") } + + private fun downloadApk(url: String?) { + progressDialog.setMessage("下载新版本中...") + progressDialog.show() + if (url.toString().isBlank()) { + "抱歉,版本下载失败".show(requireContext()) + return + } + /** + * http://111.198.10.15:11304/static/apk/1.0.1.apk + * */ + val downloadPath = url!!.appendDownloadUrl() + //开始下载 + downloadPath.downloadFile(requireContext().createDownloadFileDir().toString(), + object : OnDownloadListener { + override fun onDownloadStart(totalBytes: Long) { + progressDialog.max = totalBytes.toInt() + } + + override fun onProgressChanged(currentBytes: Long) { + progressDialog.progress = currentBytes.toInt() + } + + override fun onDownloadEnd(file: File?) { + progressDialog.dismiss() + progressDialog.progress = 0 + //安装APK + installApk(file) + } + }) + } + + private fun installApk(apkPackage: File?) { + if (apkPackage == null) { + "文件异常,无法安装".show(requireContext()) + return + } + val intent = Intent(Intent.ACTION_VIEW) + val data: Uri + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //判断版本大于等于7.0 + data = FileProvider.getUriForFile( + requireContext(), LocalConstant.APP_AUTHORITY, apkPackage + ) + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) // 给目标应用一个临时授权 + } else { + data = Uri.fromFile(apkPackage) + } + intent.setDataAndType(data, "application/vnd.android.package-archive") + requireContext().startActivity(intent) + } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java new file mode 100644 index 0000000..3f2ba02 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/VersionResultModel.java @@ -0,0 +1,61 @@ +package com.casic.smarttube.model; + +public class VersionResultModel { + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private String downloadUrl; + private String version; + + public String getDownloadUrl() { + return downloadUrl; + } + + public void setDownloadUrl(String downloadUrl) { + this.downloadUrl = downloadUrl; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index cee379c..d5ac3ec 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -40,4 +40,5 @@ const val DEFAULT_SERVER_CONFIG = "defaultServerConfig" const val ACCOUNT = "account" const val PASSWORD = "password" + const val APP_AUTHORITY = "com.casic.smarttube.fileprovider" } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index 5a4e0df..64c5402 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -63,4 +63,10 @@ @Header("token") token: String, @Part file: MultipartBody.Part ): String + + /** + * 更新APK版本 + */ + @POST("/app/checkVersion") + suspend fun obtainVersionResult(@Header("token") token: String): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index 8d999db..2af9a24 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -47,6 +47,13 @@ } /** + * 更新APK版本 + */ + suspend fun updateVersion(): String { + return api.obtainVersionResult(AuthenticationHelper.token!!) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt index d64679c..8c33d53 100644 --- a/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/UserViewModel.kt @@ -46,7 +46,6 @@ val responseCode = response.separateResponseCode() if (responseCode == 200) { loadState.value = LoadState.Success - "修改成功,请重新登录".show(BaseApplication.obtainInstance()) } else { loadState.value = LoadState.Fail response.toErrorMessage().show(BaseApplication.obtainInstance()) diff --git a/app/src/main/java/com/casic/smarttube/vm/VersionViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/VersionViewModel.kt new file mode 100644 index 0000000..273d595 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/vm/VersionViewModel.kt @@ -0,0 +1,38 @@ +package com.casic.smarttube.vm + +import androidx.lifecycle.MutableLiveData +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.extensions.separateResponseCode +import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.VersionResultModel +import com.casic.smarttube.utils.retrofit.RetrofitServiceManager +import com.google.gson.Gson +import com.google.gson.reflect.TypeToken +import com.pengxh.kt.lite.extensions.launch +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.vm.BaseViewModel +import com.pengxh.kt.lite.vm.LoadState + +class VersionViewModel : BaseViewModel() { + + private val gson = Gson() + val versionResultModel = MutableLiveData() + + fun updateVersion() = launch({ + loadState.value = LoadState.Loading + val response = RetrofitServiceManager.updateVersion() + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + loadState.value = LoadState.Success + versionResultModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ).data + } else { + loadState.value = LoadState.Fail + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + loadState.value = LoadState.Fail + it.printStackTrace() + }) +} \ No newline at end of file diff --git a/app/src/main/res/drawable/download_progress.xml b/app/src/main/res/drawable/download_progress.xml new file mode 100644 index 0000000..9704a9f --- /dev/null +++ b/app/src/main/res/drawable/download_progress.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_mine.xml b/app/src/main/res/layout/fragment_mine.xml index adf47e1..370381d 100644 --- a/app/src/main/res/layout/fragment_mine.xml +++ b/app/src/main/res/layout/fragment_mine.xml @@ -34,7 +34,7 @@ android:layout_height="60dp" android:layout_centerVertical="true" android:layout_marginEnd="@dimen/dp_10" - android:src="@mipmap/app_logo" /> + android:src="@mipmap/login_casic" /> - + + +