diff --git a/app/build.gradle b/app/build.gradle index 7e9c3b2..84cebd1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -78,6 +78,7 @@ dependencies { ksp 'com.highcapable.yukihookapi:ksp-xposed:1.1.6' implementation 'com.microsoft.appcenter:appcenter-analytics:4.4.5' implementation 'com.microsoft.appcenter:appcenter-crashes:4.4.5' + implementation 'com.squareup.okhttp3:okhttp:5.0.0-alpha.7' implementation 'com.google.code.gson:gson:2.9.0' implementation 'com.github.duanhong169:drawabletoolbox:1.0.7' implementation 'com.github.topjohnwu.libsu:core:3.1.2' diff --git a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt index f28bc78..c9813b0 100644 --- a/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt +++ b/app/src/main/java/com/fankes/apperrorstracking/ui/activity/main/MainActivity.kt @@ -38,6 +38,7 @@ import com.fankes.apperrorstracking.ui.activity.errors.AppErrorsRecordActivity import com.fankes.apperrorstracking.utils.factory.* import com.fankes.apperrorstracking.utils.tool.AppAnalyticsTool.bindAppAnalytics import com.fankes.apperrorstracking.utils.tool.FrameworkTool +import com.fankes.apperrorstracking.utils.tool.GithubReleaseTool import com.highcapable.yukihookapi.YukiHookAPI class MainActivity : BaseActivity() { @@ -53,6 +54,14 @@ class MainActivity : BaseActivity() { override fun onCreate() { checkingTopComponentName() + /** 检查更新 */ + GithubReleaseTool.checkingForUpdate(context = this, BuildConfig.VERSION_NAME) { version, function -> + binding.mainTextReleaseVersion.apply { + text = LocaleString.clickToUpdate(version) + isVisible = true + setOnClickListener { function() } + } + } binding.mainTextVersion.text = LocaleString.moduleVersion(BuildConfig.VERSION_NAME) binding.mainTextSystemVersion.text = LocaleString.systemVersion(systemVersion) binding.onlyShowErrorsInFrontSwitch.bind(ConfigData.ENABLE_ONLY_SHOW_ERRORS_IN_FRONT) diff --git a/app/src/main/java/com/fankes/apperrorstracking/utils/tool/GithubReleaseTool.kt b/app/src/main/java/com/fankes/apperrorstracking/utils/tool/GithubReleaseTool.kt new file mode 100644 index 0000000..06a67c3 --- /dev/null +++ b/app/src/main/java/com/fankes/apperrorstracking/utils/tool/GithubReleaseTool.kt @@ -0,0 +1,113 @@ +/* + * AppErrorsTracking - Added more features to app's crash dialog, fixed custom rom deleted dialog, the best experience to Android developer. + * Copyright (C) 2019-2022 Fankes Studio(qzmmcn@163.com) + * https://github.com/KitsunePie/AppErrorsTracking + * + * This software is non-free but opensource software: you can redistribute it + * and/or modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * and eula along with this software. If not, see + * + * + * This file is Created by fankes on 2023/1/23. + */ +package com.fankes.apperrorstracking.utils.tool + +import android.app.Activity +import android.content.Context +import android.icu.text.SimpleDateFormat +import android.icu.util.Calendar +import android.icu.util.TimeZone +import com.fankes.apperrorstracking.locale.LocaleString +import com.fankes.apperrorstracking.utils.factory.openBrowser +import com.fankes.apperrorstracking.utils.factory.showDialog +import okhttp3.* +import org.json.JSONObject +import java.io.IOException +import java.io.Serializable +import java.util.* + +/** + * 获取 Github Release 最新版本工具类 + */ +object GithubReleaseTool { + + /** 仓库作者 */ + private const val REPO_AUTHOR = "KitsunePie" + + /** 仓库名称 */ + private const val REPO_NAME = "AppErrorsTracking" + + /** + * 获取最新版本信息 + * @param context 实例 + * @param version 当前版本 + * @param result 成功后回调 - ([String] 最新版本,[Function] 更新对话框方法体) + */ + fun checkingForUpdate(context: Context, version: String, result: (String, () -> Unit) -> Unit) = runCatching { + OkHttpClient().newBuilder().build().newCall( + Request.Builder() + .url("https://api.github.com/repos/$REPO_AUTHOR/$REPO_NAME/releases/latest") + .get() + .build() + ).enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) {} + + override fun onResponse(call: Call, response: Response) = runCatching { + JSONObject(response.body.string()).apply { + GithubReleaseBean( + name = getString("name"), + htmlUrl = getString("html_url"), + content = getString("body"), + date = getString("published_at").localTime() + ).apply { + fun showUpdate() = context.showDialog { + title = LocaleString.latestVersion(name) + msg = LocaleString.latestVersionTip(date, content) + confirmButton(LocaleString.updateNow) { context.openBrowser(htmlUrl) } + cancelButton() + } + if (name != version) (context as? Activity?)?.runOnUiThread { + showUpdate() + result(name) { showUpdate() } + } + } + } + }.getOrNull().let {} + }) + }.getOrNull().let {} + + /** + * 格式化时间为本地时区 + * @return [String] 本地时区时间 + */ + private fun String.localTime() = replace("T", " ").replace("Z", "").let { + runCatching { + val local = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ROOT).apply { timeZone = Calendar.getInstance().timeZone } + val current = SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ROOT).apply { timeZone = TimeZone.getTimeZone("GMT") } + local.format(current.parse(it)) + }.getOrNull() ?: it + } + + /** + * Github Release bean + * @param name 版本名称 + * @param htmlUrl 网页地址 + * @param content 更新日志 + * @param date 发布时间 + */ + private data class GithubReleaseBean( + var name: String, + var htmlUrl: String, + var content: String, + var date: String + ) : Serializable +} \ No newline at end of file