提交 00f7bef5 编写于 作者: F fancy

内部打包自动更新功能

上级 e2980993
......@@ -2,6 +2,10 @@ package net.zoneland.x.bpm.mobile.v1.zoneXBPM
import android.app.Activity
import android.text.TextUtils
import com.xiaomi.push.id
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.api.APIAddressHelper
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.api.RetrofitClient
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.api.service.PackingClientAssembleSurfaceService
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.O2AppUpdateBean
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.O2AppUpdateBeanData
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.AndroidUtils
......@@ -35,7 +39,9 @@ class O2AppUpdateManager private constructor() {
private val client = OkHttpClient()
/**
* 官方app更新
*/
fun checkUpdate(activity: Activity, call: O2AppUpdateCallback) {
val ranStr = getRandomStringOfLength(6)
Observable.just("$o2AppVersionJsonUrl?$ranStr").subscribeOn(Schedulers.io())
......@@ -83,6 +89,99 @@ class O2AppUpdateManager private constructor() {
}
/**
* 自助打包的应用更新
*/
fun checkUpdateInner(activity: Activity, call: O2AppUpdateCallback) {
try {
val service = RetrofitClient.instance().packingClientService()
service.echo()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.o2Subscribe {
onNext {
checkUpdateVipInner(activity, call, service)
}
onError { e, _ ->
XLog.error("", e)
checkUpdateCenterInner(activity, call)
}
}
} catch (e: Exception) {
XLog.error("", e)
checkUpdateCenterInner(activity, call)
}
}
private fun checkUpdateCenterInner(activity: Activity, call: O2AppUpdateCallback) {
try {
val url = O2SDKManager.instance().prefs().getString(O2.PRE_CENTER_URL_KEY, "") ?: ""
RetrofitClient.instance().api(url).androidPackLastAPk()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.o2Subscribe {
onNext {
val vcode = AndroidUtils.getAppVersionCode(activity)
try {
if (it != null && it.data != null && it.data.appVersionNo.isNotBlank() && it.data.appVersionNo.toInt() > vcode) {
XLog.debug("vcode: $vcode , build:${it.data.appVersionNo}")
val needBean = O2AppUpdateBean()
needBean.content = ""
needBean.versionName = it.data.appVersionName
needBean.buildNo = it.data.appVersionNo
needBean.downloadUrl = "${url}jaxrs/apppackanony/pack/info/file/download/${it.data.id}"
call.onUpdate(needBean)
}else {
call.onNoneUpdate("没有新版本!")
}
} catch (e: Exception) {
call.onNoneUpdate(e.message ?: "")
}
}
onError { e, _ ->
XLog.error("", e)
call.onNoneUpdate(e?.message ?: "")
}
}
} catch (e: Exception) {
XLog.error("", e)
call.onNoneUpdate(e.message ?: "")
}
}
private fun checkUpdateVipInner(activity: Activity, call: O2AppUpdateCallback, service: PackingClientAssembleSurfaceService) {
service.androidPackLastAPk()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.o2Subscribe {
onNext {
val vcode = AndroidUtils.getAppVersionCode(activity)
try {
if (it != null && it.data != null && it.data.appVersionNo.isNotBlank() && it.data.appVersionNo.toInt() > vcode) {
XLog.debug("vcode: $vcode , build:${it.data.appVersionNo}")
val needBean = O2AppUpdateBean()
needBean.content = ""
needBean.versionName = it.data.appVersionName
needBean.buildNo = it.data.appVersionNo
needBean.downloadUrl = APIAddressHelper.instance().getPackingClientAppInnerDownloadUrl(it.data.id)
call.onUpdate(needBean)
}else {
call.onNoneUpdate("没有新版本!")
}
} catch (e: Exception) {
call.onNoneUpdate(e.message ?: "")
}
}
onError { e, _ ->
XLog.error("", e)
call.onNoneUpdate(e?.message ?: "")
}
}
}
private val characters = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray()
fun getRandomStringOfLength(len: Int): String {
......
......@@ -56,21 +56,17 @@ class AboutActivity : AppCompatActivity() {
if (!TextUtils.isEmpty(path)) {
BitmapUtil.setImageFromFile(path!!, image_about_logo)
}
if (BuildConfig.NEED_UPDATE) {
ll_about_check_version.visible()
relative_about_check_version.visible()
relative_about_check_version.setOnClickListener {
checkAppUpdate()
}
val isOpen = O2SDKManager.instance().prefs().getBoolean(O2.PRE_APP_AUTO_CHECK_UPDATE_KEY, true)
switch_about_check_version.isChecked = isOpen
switch_about_check_version.setOnCheckedChangeListener { _, isChecked ->
O2SDKManager.instance().prefs().edit {
putBoolean(O2.PRE_APP_AUTO_CHECK_UPDATE_KEY, isChecked);
}
ll_about_check_version.visible()
relative_about_check_version.visible()
relative_about_check_version.setOnClickListener {
checkAppUpdate()
}
val isOpen = O2SDKManager.instance().prefs().getBoolean(O2.PRE_APP_AUTO_CHECK_UPDATE_KEY, true)
switch_about_check_version.isChecked = isOpen
switch_about_check_version.setOnCheckedChangeListener { _, isChecked ->
O2SDKManager.instance().prefs().edit {
putBoolean(O2.PRE_APP_AUTO_CHECK_UPDATE_KEY, isChecked);
}
} else {
ll_about_check_version.gone()
}
if (!BuildConfig.InnerServer) {
ll_about_user_secret.visible()
......@@ -89,20 +85,40 @@ class AboutActivity : AppCompatActivity() {
*/
private fun checkAppUpdate() {
checkAppUpdate(callbackContinue = { result ->
if (result) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !packageManager.canRequestPackageInstalls()) {// 8.0需要判断安装未知来源的权限
startInstallPermissionSettingActivity()
}else { // 下载安装更新
if (downloadFragment == null) {
downloadFragment = DownloadAPKFragment()
if (BuildConfig.InnerServer) {
checkAppUpdateInner(callbackContinue = { result ->
if (result) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !packageManager.canRequestPackageInstalls()) {// 8.0需要判断安装未知来源的权限
startInstallPermissionSettingActivity()
}else { // 下载安装更新
if (downloadFragment == null) {
downloadFragment = DownloadAPKFragment()
}
downloadFragment?.isCancelable = false
downloadFragment?.show(supportFragmentManager, DownloadAPKFragment.DOWNLOAD_FRAGMENT_TAG)
downloadServiceStart()
}
downloadFragment?.isCancelable = false
downloadFragment?.show(supportFragmentManager, DownloadAPKFragment.DOWNLOAD_FRAGMENT_TAG)
downloadServiceStart()
}
}
})
})
} else {
checkAppUpdate(callbackContinue = { result ->
if (result) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !packageManager.canRequestPackageInstalls()) {// 8.0需要判断安装未知来源的权限
startInstallPermissionSettingActivity()
} else { // 下载安装更新
if (downloadFragment == null) {
downloadFragment = DownloadAPKFragment()
}
downloadFragment?.isCancelable = false
downloadFragment?.show(
supportFragmentManager,
DownloadAPKFragment.DOWNLOAD_FRAGMENT_TAG
)
downloadServiceStart()
}
}
})
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
......@@ -145,6 +161,30 @@ class AboutActivity : AppCompatActivity() {
})
}
private fun checkAppUpdateInner(callbackContinue:((flag: Boolean)->Unit)? = null) {
O2AppUpdateManager.instance().checkUpdateInner(this, object : O2AppUpdateCallback {
override fun onUpdate(version: O2AppUpdateBean) {
XLog.debug("onUpdateAvailable $version")
versionName = version.versionName
downloadUrl = version.downloadUrl
XLog.info("versionName:$versionName, downloadUrl:$downloadUrl")
val tips = getString(R.string.message_update_tips, versionName)
O2DialogSupport.openConfirmDialog(this@AboutActivity,tips + version.content, listener = { _ ->
XLog.info("notification is true..........")
callbackContinue?.invoke(true)
}, icon = O2AlertIconEnum.UPDATE, negativeListener = {_->
callbackContinue?.invoke(false)
})
}
override fun onNoneUpdate(error: String) {
XLog.info(error)
XToast.toastShort(this@AboutActivity, getString(R.string.message_update_already))
callbackContinue?.invoke(false)
}
})
}
private fun downloadServiceStart() {
val intent = Intent(this, DownloadAPKService::class.java)
intent.action = packageName + DownloadAPKService.DOWNLOAD_SERVICE_ACTION
......
......@@ -62,10 +62,15 @@ class LaunchActivity : BaseMVPActivity<LaunchContract.View, LaunchContract.Prese
NetworkConnectStatusReceiver { isConnected ->
Log.d("LaunchActivity", "网络连接情况变化,isConnected:$isConnected")
if (isConnected && mCheckNetwork == false){
val isOpen = O2SDKManager.instance().prefs().getBoolean(O2.PRE_APP_AUTO_CHECK_UPDATE_KEY, true)
// 用户自行开关检查
if (isOpen) {
checkAppUpdate()
if (!BuildConfig.InnerServer) {
val isOpen = O2SDKManager.instance().prefs()
.getBoolean(O2.PRE_APP_AUTO_CHECK_UPDATE_KEY, true)
// 用户自行开关检查
if (isOpen) {
checkAppUpdate()
} else {
launch()
}
} else {
launch()
}
......@@ -191,7 +196,7 @@ class LaunchActivity : BaseMVPActivity<LaunchContract.View, LaunchContract.Prese
}else{
mCheckNetwork = true
// 是否检查更新
if (BuildConfig.NEED_UPDATE) {
if (!BuildConfig.InnerServer) {
Log.d("LaunchActivity","检查应用内更新")
val isOpen = O2SDKManager.instance().prefs().getBoolean(O2.PRE_APP_AUTO_CHECK_UPDATE_KEY, true)
// 用户自行开关检查
......@@ -201,7 +206,7 @@ class LaunchActivity : BaseMVPActivity<LaunchContract.View, LaunchContract.Prese
launch()
}
} else {
Log.d("LaunchActivity","不需要应用内更新。。。。。。。")
Log.d("LaunchActivity","内部应用 在主页检查更新。。。。。。。")
launch()
}
}
......
......@@ -8,12 +8,14 @@ import android.content.*
import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.provider.Settings
import android.text.TextUtils
import android.util.AttributeSet
import android.util.DisplayMetrics
import android.util.Log
import android.view.KeyEvent
import android.view.View
import androidx.annotation.RequiresApi
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_main_bottom_bar_image.*
......@@ -22,11 +24,10 @@ import net.zoneland.x.bpm.mobile.v1.zoneXBPM.*
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.base.BaseMVPActivity
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.im.O2IM
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.im.fm.O2IMConversationFragment
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.app.o2.DownloadAPKFragment
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.adapter.MainActivityFragmentAdapter
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.service.ClearTempFileJobService
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.service.PictureLoaderService
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.service.RestartSelfService
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.service.WebSocketService
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.service.*
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.O2AppUpdateBean
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.im.IMMessage
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.BitmapUtil
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.DateHelper
......@@ -36,6 +37,8 @@ import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.extension.*
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.permission.PermissionRequester
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.utils.tbs.WordReadHelper
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.widgets.GrayFrameLayout
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.widgets.dialog.O2AlertIconEnum
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.widgets.dialog.O2DialogSupport
import org.jetbrains.anko.doAsync
......@@ -245,6 +248,10 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
val isX5Init = WordReadHelper.getInstance().initFinish()
XLog.info("x5内核是否已经完成,$isX5Init")
// 检查更新
if (BuildConfig.InnerServer) {
checkAppUpdateInner()
}
}
......@@ -435,6 +442,94 @@ class MainActivity : BaseMVPActivity<MainContract.View, MainContract.Presenter>(
}
/*************检查应用是否需要更新*********/
private var downloadFragment: DownloadAPKFragment? = null
private var versionName = ""
private var downloadUrl = ""
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK && requestCode == 10086) { // 下载安装更新
if (downloadFragment == null) {
downloadFragment = DownloadAPKFragment()
}
downloadFragment?.isCancelable = false
if (downloadFragment?.isAdded == true) {
}else {
downloadFragment?.show(supportFragmentManager, DownloadAPKFragment.DOWNLOAD_FRAGMENT_TAG)
downloadServiceStart()
}
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
private fun startInstallPermissionSettingActivity() {
//注意这个是8.0新API
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
startActivityForResult(intent, 10086)
}
private fun checkAppUpdateInner() {
val isOpen = O2SDKManager.instance().prefs()
.getBoolean(O2.PRE_APP_AUTO_CHECK_UPDATE_KEY, true)
// 用户自行开关检查
if (isOpen) {
checkAppUpdate(callbackContinue = { result ->
if (result) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !packageManager.canRequestPackageInstalls()) {// 8.0需要判断安装未知来源的权限
startInstallPermissionSettingActivity()
}else { // 下载安装更新
if (downloadFragment == null) {
downloadFragment = DownloadAPKFragment()
}
downloadFragment?.isCancelable = false
if (downloadFragment?.isAdded == true) {
}else {
downloadFragment?.show(supportFragmentManager, DownloadAPKFragment.DOWNLOAD_FRAGMENT_TAG)
downloadServiceStart()
}
}
}
})
}
}
private fun downloadServiceStart() {
val intent = Intent(this, DownloadAPKService::class.java)
intent.action = packageName + DownloadAPKService.DOWNLOAD_SERVICE_ACTION
intent.putExtra(DownloadAPKService.VERSIN_NAME_EXTRA_NAME, versionName)
intent.putExtra(DownloadAPKService.DOWNLOAD_URL_EXTRA_NAME, downloadUrl)
startService(intent)
}
private fun checkAppUpdate(callbackContinue:((flag: Boolean)->Unit)? = null) {
O2AppUpdateManager.instance().checkUpdateInner(this, object : O2AppUpdateCallback {
override fun onUpdate(version: O2AppUpdateBean) {
XLog.debug("onUpdateAvailable $version")
versionName = version.versionName
downloadUrl = version.downloadUrl
XLog.info("versionName:$versionName, downloadUrl:$downloadUrl")
val tips = getString(R.string.message_update_tips, versionName)
O2DialogSupport.openConfirmDialog(this@MainActivity,tips + version.content, listener = { _ ->
XLog.info("notification is true..........")
callbackContinue?.invoke(true)
}, icon = O2AlertIconEnum.UPDATE, negativeListener = { _->
callbackContinue?.invoke(false)
})
}
override fun onNoneUpdate(error: String) {
XLog.info(error)
callbackContinue?.invoke(false)
}
})
}
/**
* 存储下手机分辨率
*/
......
......@@ -760,7 +760,7 @@
<string name="message_code_can_not_empty">SMS verification code cannot be empty!</string>
<string name="message_can_not_get_unit_info">No company information!</string>
<string name="message_group_name_is_empty">No group name, unable to get group information!</string>
<string name="message_update_tips">Version %1$s update</string>
<string name="message_update_tips">Version %1$s update </string>
<string name="message_update_already">It is the latest version!</string>
<string name="message_login_fail">Login failed. Please check whether your user name or password is correct!</string>
<string name="message_login_validate_code_fail">Failed to get mobile phone verification code. Please check whether the user name you entered is correct!</string>
......
......@@ -735,7 +735,7 @@
<string name="message_code_can_not_empty">短信验证码不能为空!</string>
<string name="message_can_not_get_unit_info">没有获得单位信息!</string>
<string name="message_group_name_is_empty">没有群组名称,无法获取群组信息!</string>
<string name="message_update_tips">版本 %1$s 更新</string>
<string name="message_update_tips">版本 %1$s 更新 </string>
<string name="message_update_already">已经是最新版本了!</string>
<string name="message_login_fail">登录失败, 请检查您的输入的用户名或密码是否正确!</string>
<string name="message_login_validate_code_fail">获取手机验证码失败,请检查您输入的用户名是否正确!</string>
......
......@@ -251,6 +251,13 @@ class APIAddressHelper private constructor() {
return url
}
/**
* 自助打包 下载apk文件的url
*/
fun getPackingClientAppInnerDownloadUrl(id: String): String {
return getAPIDistribute(APIDistributeTypeEnum.x_app_packaging_client_assemble_control) + "jaxrs/apppackanony/file/download/$id"
}
fun getWebViewHost(): String {
return webServerData?.let { webServerData?.host } ?: ""
}
......@@ -387,6 +394,9 @@ class APIAddressHelper private constructor() {
if (data.x_pan_assemble_control != null) {
apiDistribute[APIDistributeTypeEnum.x_pan_assemble_control] = data.x_pan_assemble_control
}
if (data.x_app_packaging_client_assemble_control != null) {
apiDistribute[APIDistributeTypeEnum.x_app_packaging_client_assemble_control] = data.x_app_packaging_client_assemble_control
}
}
......
......@@ -561,4 +561,20 @@ class RetrofitClient private constructor() {
}
/**
* 自助打包服务
*
*/
fun packingClientService(): PackingClientAssembleSurfaceService {
val url = helper.getAPIDistribute(APIDistributeTypeEnum.x_app_packaging_client_assemble_control)
val retrofitClient = Retrofit.Builder()
.baseUrl(url)
.client(o2HttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build()
return retrofitClient.create(PackingClientAssembleSurfaceService::class.java)
}
}
\ No newline at end of file
package net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.api.service
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.O2OAInnerUpdateBean
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.APIDistributeData
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.ApiResponse
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.main.CustomStyleData
......@@ -35,4 +36,13 @@ interface ApiService {
*/
@GET("jaxrs/appstyle/current/update")
fun getCustomStyleUpdateDate(): Observable<ApiResponse<CustomStyleUpdateData>>
/**
* 最新的打包信息
*/
@GET("jaxrs/apppackanony/pack/info/file/last")
fun androidPackLastAPk(): Observable<ApiResponse<O2OAInnerUpdateBean>>
}
\ No newline at end of file
package net.zoneland.x.bpm.mobile.v1.zoneXBPM.core.component.api.service
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.O2OAInnerUpdateBean
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.ApiResponse
import net.zoneland.x.bpm.mobile.v1.zoneXBPM.model.bo.api.EchoData
import retrofit2.http.GET
import rx.Observable
interface PackingClientAssembleSurfaceService {
/**
* 服务器应答
*/
@GET("jaxrs/echo")
fun echo(): Observable<ApiResponse<EchoData>>
/**
* 最新的打包信息
*/
@GET("jaxrs/apppackanony/file/type/android/last")
fun androidPackLastAPk(): Observable<ApiResponse<O2OAInnerUpdateBean>>
}
\ No newline at end of file
......@@ -45,7 +45,9 @@ public enum APIDistributeTypeEnum {
x_query_assemble_surface, //查询模块包含 视图、统计、自定义表等
x_pan_assemble_control, // 新版网盘
x_pan_assemble_control, // 新版网盘 需要安装应用
x_app_packaging_client_assemble_control, // 自助打包 需要安装应用
x_organizationPermission //custom模块 通讯录 需要到应用市场下载安装
......
package net.zoneland.x.bpm.mobile.v1.zoneXBPM.model
/**
* Created by fancyLou on 2023-01-16.
* Copyright © 2023 o2android. All rights reserved.
*/
//
data class O2OAInnerUpdateBean (
var id: String = "",
var name: String = "",
var storage: String = "",
var extension: String = "",
var lastUpdateTime: String = "",
var length: Long = 0L,
var packInfoId: String = "",
var appVersionName: String = "",
var appVersionNo: String = "",
var status: Int = 0, // 状态,异步下载文件所以需要这个状态,0开启,1下载完成, 2过程有异常.
var isPackAppIdOuter: String = "",
var createTime: String = "",
var updateTime: String = ""
)
\ No newline at end of file
......@@ -41,6 +41,7 @@ public class APIAssemblesData {
private APIDataBean x_message_assemble_communicate; //通信模块 消息收发 还有websocket
private APIDataBean x_organizationPermission; // custom模块 通讯录 需要到应用市场下载安装
private APIDataBean x_pan_assemble_control; // V3 云盘
private APIDataBean x_app_packaging_client_assemble_control; // 自助打包
public APIDataBean getX_pan_assemble_control() {
......@@ -345,4 +346,12 @@ public class APIAssemblesData {
public void setX_portal_assemble_surface(APIDataBean x_portal_assemble_surface) {
this.x_portal_assemble_surface = x_portal_assemble_surface;
}
public APIDataBean getX_app_packaging_client_assemble_control() {
return x_app_packaging_client_assemble_control;
}
public void setX_app_packaging_client_assemble_control(APIDataBean x_app_packaging_client_assemble_control) {
this.x_app_packaging_client_assemble_control = x_app_packaging_client_assemble_control;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册