diff --git a/.gitignore b/.gitignore
index 20f9f30d..c25677cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,6 @@
*.iml
.gradle
/local.properties
-/.idea/caches
-/.idea/libraries
-/.idea/modules.xml
-/.idea/workspace.xml
-/.idea/navEditor.xml
-/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
@@ -14,7 +8,5 @@
.cxx
local.properties
/app/release
-.idea/misc.xml
-.idea/.name
/.idea
/app/debug
diff --git a/README.md b/README.md
index 0f7d7a7f..ddafcc71 100644
--- a/README.md
+++ b/README.md
@@ -211,19 +211,22 @@ QQ 版本列表实用工具采用 [GNU Affero General Public License Version 3](
QQ 版本列表实用工具的诞生离不开以下开源项目,感谢以下开源项目的作者和贡献者:
-- [Material Components for Android](https://github.com/material-components/material-components-android/),Licensed under [Apache License Version 2.0](https://github.com/material-components/material-components-android/blob/master/LICENSE)
-- [Android Jetpack](https://github.com/androidx/androidx/),Licensed under [Apache License Version 2.0](https://github.com/androidx/androidx/blob/androidx-main/LICENSE.txt)
+- [Material Components for Android(Android Open Source Project)](https://github.com/material-components/material-components-android/),Licensed under [Apache License Version 2.0](https://github.com/material-components/material-components-android/blob/master/LICENSE)
+- [Android Jetpack(Android Open Source Project)](https://developer.android.com/jetpack),Licensed under [Apache License Version 2.0](https://github.com/androidx/androidx/blob/androidx-main/LICENSE.txt)
- [Remix Icon(Remix Design)](https://remixicon.com/),Licensed under [Apache License Version 2.0](https://remixicon.com/license)
- [OkHttp(Square)](https://square.github.io/okhttp/),Licensed under [Apache License Version 2.0](https://github.com/square/okhttp/blob/master/LICENSE.txt)
- [Kotlin(JetBrains)](https://kotlinlang.org/),Licensed under [Apache License Version 2.0](https://github.com/JetBrains/kotlin/blob/master/license%2FREADME.md)
- [Gson(Google)](https://github.com/google/gson/),Licensed under [Apache License Version 2.0](https://github.com/google/gson/blob/master/LICENSE)
- [Coil](https://coil-kt.github.io/coil/),Licensed under [Apache License Version 2.0](https://github.com/coil-kt/coil/blob/main/LICENSE.txt)
-- [Eclipse Temurin™](https://adoptium.net/zh-CN/temurin/),Licensed under GNU General Public License, version 2 with the Classpath Exception
+- [Eclipse Temurin™](https://adoptium.net/temurin/),Licensed under GNU General Public License, version 2 with the Classpath Exception
- [Oracle JDK](https://www.oracle.com/java/technologies/downloads/),Licensed under [Oracle No-Fee Terms and Conditions](https://www.java.com/freeuselicense)
-- [JetBrains Runtime](https://github.com/JetBrains/JetBrainsRuntime),Licensed under [GNU General Public License, version 2](https://github.com/JetBrains/JetBrainsRuntime/blob/main/LICENSE)
+- [JetBrains Runtime](https://github.com/JetBrains/JetBrainsRuntime),Licensed under [GNU General Public License Version 2](https://github.com/JetBrains/JetBrainsRuntime/blob/main/LICENSE)
- [Kotlin Serialization](https://github.com/Kotlin/kotlinx.serialization),Licensed under [Apache License Version 2.0](https://github.com/Kotlin/kotlinx.serialization/blob/master/LICENSE.txt)
- [Get QQ Update Link(owo233)](https://github.com/callng/GQUL),Licensed under [The Unlicense](https://github.com/callng/GQUL/blob/master/LICENSE)
- [Paris(Airbnb)](https://github.com/airbnb/paris),Licensed under [Apache License Version 2.0](https://github.com/airbnb/paris/blob/master/LICENSE)
+- [Apache Maven](https://maven.apache.org/),Licensed under [Apache License Version 2.0](https://github.com/apache/maven/blob/master/LICENSE)
+- [Gradle](https://gradle.org/),Licensed under [Apache License Version 2.0](https://github.com/gradle/gradle/blob/master/LICENSE)
+- [Material Symbols / Material Icons(Google)](https://fonts.google.com/icons),Licensed under [Apache License Version 2.0](https://github.com/google/material-design-icons/blob/master/LICENSE)
## 孪生项目
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index e334ce29..817b4879 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -46,8 +46,13 @@ android {
minSdk = 24
targetSdk = 35
versionCode = gitCommitCount
- versionName = "1.3.5-$gitCommitHash"
+ versionName = "1.3.6-$gitCommitHash"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ externalNativeBuild {
+ cmake {
+ arguments += listOf("-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON")
+ }
+ }
}
signingConfigs {
@@ -102,4 +107,5 @@ dependencies {
implementation("androidx.datastore:datastore-preferences:1.1.1")
implementation("com.google.code.gson:gson:2.11.0")
implementation("com.airbnb.android:paris:2.0.2")
+ implementation("org.apache.maven:maven-artifact:3.9.9")
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8969fa88..64ef2adf 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -22,6 +22,7 @@
+
diff --git a/app/src/main/java/com/xiaoniu/qqversionlist/TipTimeApplication.kt b/app/src/main/java/com/xiaoniu/qqversionlist/TipTimeApplication.kt
index f64f24f9..f69ecc6f 100644
--- a/app/src/main/java/com/xiaoniu/qqversionlist/TipTimeApplication.kt
+++ b/app/src/main/java/com/xiaoniu/qqversionlist/TipTimeApplication.kt
@@ -27,6 +27,8 @@ class TipTimeApplication : Application() {
const val SHIPLY_DEFAULT_APPID = "537230561"
const val SHIPLY_DEFAULT_SDK_VERSION = "1.3.36-RC01"
+
+ const val EARLIEST_ACCESSIBILITY_VERSION = false
}
override fun onCreate() {
diff --git a/app/src/main/java/com/xiaoniu/qqversionlist/data/QQVersionBean.kt b/app/src/main/java/com/xiaoniu/qqversionlist/data/QQVersionBean.kt
index 5223b7a1..81998620 100644
--- a/app/src/main/java/com/xiaoniu/qqversionlist/data/QQVersionBean.kt
+++ b/app/src/main/java/com/xiaoniu/qqversionlist/data/QQVersionBean.kt
@@ -32,5 +32,6 @@ data class QQVersionBean(
var jsonString: String = "",
var displayType: Int = 0, // 0为收起
- var displayInstall: Boolean = false // false 为不展示
+ var displayInstall: Boolean = false, // false 为不展示
+ var isAccessibility: Boolean = false
)
diff --git a/app/src/main/java/com/xiaoniu/qqversionlist/ui/MainActivity.kt b/app/src/main/java/com/xiaoniu/qqversionlist/ui/MainActivity.kt
index 398ebc15..f9d6f7c3 100644
--- a/app/src/main/java/com/xiaoniu/qqversionlist/ui/MainActivity.kt
+++ b/app/src/main/java/com/xiaoniu/qqversionlist/ui/MainActivity.kt
@@ -23,6 +23,7 @@ import android.annotation.SuppressLint
import android.app.DownloadManager
import android.content.Context
import android.content.Intent
+import android.content.pm.PackageManager
import android.content.res.Configuration
import android.content.res.Resources
import android.net.Uri
@@ -55,7 +56,6 @@ import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.airbnb.paris.extensions.style
import com.google.android.material.bottomsheet.BottomSheetBehavior
@@ -117,12 +117,13 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
- setContentView(binding.root)
+ val viewRoot = binding.root
+ setContentView(viewRoot)
setContext(this)
if (SDK_INT <= Build.VERSION_CODES.Q) {
- ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view, windowInsets ->
+ ViewCompat.setOnApplyWindowInsetsListener(viewRoot) { view, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars())
view.setPadding(insets.left, 0, insets.right, 0)
binding.apply {
@@ -156,6 +157,11 @@ class MainActivity : AppCompatActivity() {
versionListStaggeredGridLayout()
}
+ override fun onMultiWindowModeChanged(isInMultiWindowMode: Boolean, newConfig: Configuration) {
+ super.onMultiWindowModeChanged(isInMultiWindowMode, newConfig)
+ versionListStaggeredGridLayout()
+ }
+
private fun versionListStaggeredGridLayout() {
binding.rvContent.apply {
adapter = versionAdapter
@@ -228,7 +234,7 @@ class MainActivity : AppCompatActivity() {
// 删除 version Shared Preferences
DataStoreUtil.deletePreferenceAsync("version")
- //这里的“getInt: userAgreement”的值代表着用户协议修订版本,后续更新协议版本后也需要在下面一行把“judgeUARead”+1,以此类推
+ // 这里的“getInt: userAgreement”的值代表着用户协议修订版本,后续更新协议版本后也需要在下面一行把“judgeUARead”+1,以此类推
val judgeUATarget = 2 // 2024.5.30 第二版
if (DataStoreUtil.getInt("userAgreement", 0) < judgeUATarget) showUADialog(
false, judgeUATarget
@@ -242,13 +248,10 @@ class MainActivity : AppCompatActivity() {
hideAnimationBehavior = LinearProgressIndicator.HIDE_ESCAPE
}
- binding.rvContent.addOnScrollListener(object : RecyclerView.OnScrollListener() {
- override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
- super.onScrolled(recyclerView, dx, dy)
- if (dy > 0) binding.btnGuess.shrink()
- else if (dy < 0) binding.btnGuess.extend()
- }
- })
+ binding.rvScroll.setOnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
+ if (scrollY > oldScrollY) binding.btnGuess.shrink()
+ else if (scrollY < oldScrollY) binding.btnGuess.extend()
+ }
binding.bottomAppBar.setOnMenuItemClickListener { menuItem ->
@@ -342,8 +345,7 @@ class MainActivity : AppCompatActivity() {
val linearLayout = LinearLayout(this).apply {
orientation = LinearLayout.VERTICAL
layoutParams = ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT
)
setPadding(128, 64, 128, 0)
gravity = Gravity.CENTER_HORIZONTAL
@@ -370,7 +372,6 @@ class MainActivity : AppCompatActivity() {
findViewById(android.R.id.message)?.movementMethod =
LinkMovementMethodCompat.getInstance()
}
-
true
}
@@ -481,23 +482,19 @@ class MainActivity : AppCompatActivity() {
versionTcloudThickness.addOnChangeListener { _, value, _ ->
when (value) {
1.0f -> DataStoreUtil.putString(
- "versionTCloudThickness",
- "Light"
+ "versionTCloudThickness", "Light"
)
2.0f -> DataStoreUtil.putString(
- "versionTCloudThickness",
- "Regular"
+ "versionTCloudThickness", "Regular"
)
3.0f -> DataStoreUtil.putString(
- "versionTCloudThickness",
- "Bold"
+ "versionTCloudThickness", "Bold"
)
else -> DataStoreUtil.putString(
- "versionTCloudThickness",
- "System"
+ "versionTCloudThickness", "System"
)
}
versionAdapter.updateItemProperty("isTCloud")
@@ -670,8 +667,7 @@ class MainActivity : AppCompatActivity() {
}
R.id.btn_tencent_shiply -> {
- val dialogShiplyBinding =
- DialogShiplyBinding.inflate(layoutInflater)
+ val dialogShiplyBinding = DialogShiplyBinding.inflate(layoutInflater)
val shiplyDialog = MaterialAlertDialogBuilder(this)
@@ -766,24 +762,19 @@ class MainActivity : AppCompatActivity() {
shiplyVersion.editText?.text.toString(),
shiplyUin.editText?.text.toString(),
getString(
- "shiplyAppid",
- ""
+ "shiplyAppid", ""
).ifEmpty { SHIPLY_DEFAULT_APPID },
getString(
- "shiplyOsVersion",
- ""
+ "shiplyOsVersion", ""
).ifEmpty { SDK_INT.toString() },
getString(
- "shiplyModel",
- ""
+ "shiplyModel", ""
).ifEmpty { Build.MODEL.toString() },
getString(
- "shiplySdkVersion",
- ""
+ "shiplySdkVersion", ""
).ifEmpty { SHIPLY_DEFAULT_SDK_VERSION },
getString(
- "shiplyLanguage",
- ""
+ "shiplyLanguage", ""
).ifEmpty { Locale.getDefault().language.toString() })
}
} catch (e: MissingParameterException) {
@@ -802,8 +793,7 @@ class MainActivity : AppCompatActivity() {
}
if (intent.action == "android.intent.action.VIEW" && DataStoreUtil.getInt(
- "userAgreement",
- 0
+ "userAgreement", 0
) >= judgeUATarget
) showGuessVersionDialog()
binding.btnGuess.setOnClickListener {
@@ -818,14 +808,12 @@ class MainActivity : AppCompatActivity() {
dialogGuessBinding.etVersionBig.editText?.setText(verBig)
val memVersion = DataStoreUtil.getString("versionSelect", MODE_OFFICIAL)
if (memVersion == MODE_TEST || memVersion == MODE_UNOFFICIAL || memVersion == MODE_OFFICIAL || memVersion == MODE_WECHAT) dialogGuessBinding.spinnerVersion.setText(
- memVersion,
- false
+ memVersion, false
) else {
dialogGuessBinding.spinnerVersion.setText(MODE_OFFICIAL, false)
DataStoreUtil.putStringAsync("versionSelect", MODE_OFFICIAL)
}
- if (dialogGuessBinding.spinnerVersion.text.toString() == MODE_TEST || dialogGuessBinding.spinnerVersion.text.toString() == MODE_UNOFFICIAL
- ) dialogGuessBinding.apply {
+ if (dialogGuessBinding.spinnerVersion.text.toString() == MODE_TEST || dialogGuessBinding.spinnerVersion.text.toString() == MODE_UNOFFICIAL) dialogGuessBinding.apply {
etVersionSmall.isEnabled = true
etVersionSmall.visibility = View.VISIBLE
guessDialogWarning.visibility = View.VISIBLE
@@ -938,8 +926,7 @@ class MainActivity : AppCompatActivity() {
getString(R.string.missingMajorVersionWarning)
) else {
versionSmall =
- dialogGuessBinding.etVersionSmall.editText?.text.toString()
- .toInt()
+ dialogGuessBinding.etVersionSmall.editText?.text.toString().toInt()
if (versionSmall % 5 != 0 && !DataStoreUtil.getBoolean(
"guessNot5", false
)
@@ -958,8 +945,7 @@ class MainActivity : AppCompatActivity() {
getString(R.string.missingWeixin16CodeWarning)
) else {
versionTrue =
- dialogGuessBinding.etVersionTrue.editText?.text.toString()
- .toInt()
+ dialogGuessBinding.etVersionTrue.editText?.text.toString().toInt()
version16code =
dialogGuessBinding.etVersion16code.editText?.text.toString()
if (version16code != 0.toString()) DataStoreUtil.putStringAsync(
@@ -1001,64 +987,297 @@ class MainActivity : AppCompatActivity() {
}
+ @SuppressLint("SetTextI18n")
private fun getData() {
binding.progressLine.show()
CoroutineScope(Dispatchers.IO).launch {
try {
// 识别本机 Android QQ 版本并放进持久化存储
- val QQPackageInfo = packageManager.getPackageInfo("com.tencent.mobileqq", 0)
- val QQVersionInstall = QQPackageInfo.versionName.toString()
+ val QQVersionInstall =
+ packageManager.getPackageInfo("com.tencent.mobileqq", 0).versionName.toString()
+ val QQVersionCodeInstall =
+ if (SDK_INT >= Build.VERSION_CODES.P) packageManager.getPackageInfo(
+ "com.tencent.mobileqq", 0
+ ).longVersionCode.toString() else ""
+ val QQAppSettingParamsInstall = packageManager.getPackageInfo(
+ "com.tencent.mobileqq", PackageManager.GET_META_DATA
+ ).applicationInfo?.metaData?.getString("AppSetting_params")
+ val QQAppSettingParamsPadInstall = packageManager.getPackageInfo(
+ "com.tencent.mobileqq", PackageManager.GET_META_DATA
+ ).applicationInfo?.metaData?.getString("AppSetting_params_pad")
+ val QQRdmUUIDInstall = packageManager.getPackageInfo(
+ "com.tencent.mobileqq", PackageManager.GET_META_DATA
+ ).applicationInfo?.metaData?.getString("com.tencent.rdm.uuid")
if (QQVersionInstall != DataStoreUtil.getString(
- "QQVersionInstall",
- ""
+ "QQVersionInstall", ""
)
) DataStoreUtil.putString("QQVersionInstall", QQVersionInstall)
- } catch (e: Exception) {
- DataStoreUtil.putStringAsync("QQVersionInstall", "")
+ if (QQVersionCodeInstall != DataStoreUtil.getString(
+ "QQVersionCodeInstall", ""
+ )
+ ) DataStoreUtil.putString("QQVersionCodeInstall", QQVersionCodeInstall)
+ if (QQAppSettingParamsInstall != null && QQAppSettingParamsInstall != DataStoreUtil.getString(
+ "QQAppSettingParamsInstall", ""
+ )
+ ) DataStoreUtil.putString("QQAppSettingParamsInstall", QQAppSettingParamsInstall)
+ if (QQAppSettingParamsPadInstall != null && QQAppSettingParamsPadInstall != DataStoreUtil.getString(
+ "QQAppSettingParamsPadInstall", ""
+ )
+ ) DataStoreUtil.putString(
+ "QQAppSettingParamsPadInstall", QQAppSettingParamsPadInstall
+ )
+ if (QQRdmUUIDInstall != null && QQRdmUUIDInstall != DataStoreUtil.getString(
+ "QQRdmUUIDInstall", ""
+ )
+ ) DataStoreUtil.putString("QQRdmUUIDInstall", QQRdmUUIDInstall)
+ } catch (_: Exception) {
+ DataStoreUtil.putString("QQVersionInstall", "")
+ DataStoreUtil.putString("QQVersionCodeInstall", "")
+ DataStoreUtil.putString("QQAppSettingParamsInstall", "")
} finally {
try {
- val okHttpClient = OkHttpClient()
- val request =
- Request.Builder().url("https://im.qq.com/rainbow/androidQQVersionList")
- .build()
- val response = okHttpClient.newCall(request).execute()
- val responseData = response.body?.string()
- if (responseData != null) {
- val start = (responseData.indexOf("versions64\":[")) + 12
- val end = (responseData.indexOf(";\n" + " typeof"))
- val totalJson = responseData.substring(start, end)
- qqVersion = totalJson.split("},{").reversed().map {
- val pstart = it.indexOf("{\"versions")
- val pend = it.indexOf(",\"length")
- val json = it.substring(pstart, pend)
- Json.decodeFromString(json).apply {
- jsonString = json
- // 标记本机 Android QQ 版本
- this.displayInstall = (DataStoreUtil.getString(
- "QQVersionInstall", ""
- ) == this.versionNumber)
+ // 识别本机 Android QQ 版本并放进持久化存储
+ val TIMVersionInstall =
+ packageManager.getPackageInfo("com.tencent.tim", 0).versionName.toString()
+ val TIMVersionCodeInstall =
+ if (SDK_INT >= Build.VERSION_CODES.P) packageManager.getPackageInfo(
+ "com.tencent.tim", 0
+ ).longVersionCode.toString() else ""
+ val TIMAppSettingParamsInstall = packageManager.getPackageInfo(
+ "com.tencent.tim", PackageManager.GET_META_DATA
+ ).applicationInfo?.metaData?.getString("AppSetting_params")
+ val TIMRdmUUIDInstall = packageManager.getPackageInfo(
+ "com.tencent.tim", PackageManager.GET_META_DATA
+ ).applicationInfo?.metaData?.getString("com.tencent.rdm.uuid")
+ if (TIMVersionInstall != DataStoreUtil.getString(
+ "TIMVersionInstall", ""
+ )
+ ) DataStoreUtil.putString("TIMVersionInstall", TIMVersionInstall)
+ if (TIMVersionCodeInstall != DataStoreUtil.getString(
+ "TIMVersionCodeInstall", ""
+ )
+ ) DataStoreUtil.putString("TIMVersionCodeInstall", TIMVersionCodeInstall)
+ if (TIMAppSettingParamsInstall != null && TIMAppSettingParamsInstall != DataStoreUtil.getString(
+ "TIMAppSettingParamsInstall", ""
+ )
+ ) DataStoreUtil.putString(
+ "TIMAppSettingParamsInstall", TIMAppSettingParamsInstall
+ )
+ if (TIMRdmUUIDInstall != null && TIMRdmUUIDInstall != DataStoreUtil.getString(
+ "TIMRdmUUIDInstall", ""
+ )
+ ) DataStoreUtil.putString("TIMRdmUUIDInstall", TIMRdmUUIDInstall)
+ } catch (_: Exception) {
+ DataStoreUtil.putString("TIMVersionInstall", "")
+ DataStoreUtil.putString("TIMVersionCodeInstall", "")
+ DataStoreUtil.putString("TIMAppSettingParamsInstall", "")
+ } finally {
+ val QQVersionInstall2 = DataStoreUtil.getString("QQVersionInstall", "")
+ val TIMVersionInstall2 = DataStoreUtil.getString("TIMVersionInstall", "")
+ val QQVersionCodeInstall2 = DataStoreUtil.getString("QQVersionCodeInstall", "")
+ val TIMVersionCodeInstall2 =
+ DataStoreUtil.getString("TIMVersionCodeInstall", "")
+ val QQAppSettingParamsInstall =
+ DataStoreUtil.getString("QQAppSettingParamsInstall", "")
+ val TIMAppSettingParamsInstall =
+ DataStoreUtil.getString("TIMAppSettingParamsInstall", "")
+ val QQRdmUUIDInstall = if (DataStoreUtil.getString(
+ "QQRdmUUIDInstall", ""
+ ) != ""
+ ) ".${DataStoreUtil.getString("QQRdmUUIDInstall", "").split("_")[0]}" else ""
+ val TIMRdmUUIDInstall = if (DataStoreUtil.getString(
+ "TIMRdmUUIDInstall", ""
+ ) != ""
+ ) ".${DataStoreUtil.getString("TIMRdmUUIDInstall", "").split("_")[0]}" else ""
+ val QQChannelInstall =
+ if (QQAppSettingParamsInstall != "") DataStoreUtil.getString(
+ "QQAppSettingParamsInstall", ""
+ ).split("#")[3] else ""
+ val TIMChannelInstall =
+ if (TIMAppSettingParamsInstall != "") DataStoreUtil.getString(
+ "TIMAppSettingParamsInstall", ""
+ ).split("#")[3] else ""
+ withContext(Dispatchers.Main) {
+ binding.apply {
+ if (QQVersionInstall2 != "") {
+ itemQqInstallText.text =
+ if (QQChannelInstall != "") getString(R.string.localQQVersion) + DataStoreUtil.getString(
+ "QQVersionInstall", ""
+ ) + QQRdmUUIDInstall + (if (QQVersionCodeInstall2 != "") " (${QQVersionCodeInstall2})" else "") + " - $QQChannelInstall" else getString(
+ R.string.localQQVersion
+ ) + DataStoreUtil.getString("QQVersionInstall", "")
+ itemQqInstallCard.visibility = View.VISIBLE
+
+ // 无障碍标记
+ /*if (DefaultArtifactVersion(QQVersionInstall2) >= DefaultArtifactVersion(
+ EARLIEST_ACCESSIBILITY_VERSION
+ )
+ ) itemQqInstallText.setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.accessibility_new_24px, 0, 0, 0
+ ) else itemQqInstallText.setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.scan_line, 0, 0, 0
+ )
+ val oldItemQqInstallCardDescribe =
+ itemQqInstallText.text.toString()
+ if (DefaultArtifactVersion(QQVersionInstall2) >= DefaultArtifactVersion(
+ EARLIEST_ACCESSIBILITY_VERSION
+ )
+ ) itemQqInstallCard.contentDescription =
+ "$oldItemQqInstallCardDescribe。" + String(
+ Base64.decode(
+ getString(R.string.accessibilityTag),
+ Base64.NO_WRAP
+ ), Charsets.UTF_8
+ )*/
+ itemQqInstallCard.setOnLongClickListener {
+ if (DataStoreUtil.getBoolean("longPressCard", true)) {
+ val tv = TextView(this@MainActivity).apply {
+ text = "Version Name: ${
+ DataStoreUtil.getString(
+ "QQVersionInstall", ""
+ )
+ }" + (if (DataStoreUtil.getString(
+ "QQRdmUUIDInstall", ""
+ ) != ""
+ ) "\n\nRdm UUID: ${
+ DataStoreUtil.getString(
+ "QQRdmUUIDInstall", ""
+ )
+ }" else "") + (if (DataStoreUtil.getString(
+ "QQVersionCodeInstall", ""
+ ) != ""
+ ) "\n\nVersion Code: ${
+ DataStoreUtil.getString(
+ "QQVersionCodeInstall", ""
+ )
+ }" else "") + (if (DataStoreUtil.getString(
+ "QQAppSettingParamsInstall", ""
+ ) != ""
+ ) "\n\nAppSetting_params: ${
+ DataStoreUtil.getString(
+ "QQAppSettingParamsInstall", ""
+ )
+ }" else "") + (if (DataStoreUtil.getString(
+ "QQAppSettingParamsPadInstall", ""
+ ) != ""
+ ) "\n\nAppSetting_params_pad: ${
+ DataStoreUtil.getString(
+ "QQAppSettingParamsPadInstall", ""
+ )
+ }" else "")
+ setTextIsSelectable(true)
+ setPadding(96, 48, 96, 96)
+ }
+ MaterialAlertDialogBuilder(context)
+ .setView(tv)
+ .setTitle(R.string.localQQVersionDetails)
+ .setIcon(R.drawable.scan_line)
+ .show()
+ } else showToast(getString(R.string.longPressToViewSourceDetailsIsDisabledPleaseGoToSettingsToTurnItOn))
+ true
+ }
+ } else itemQqInstallCard.visibility = View.GONE
+ if (TIMVersionInstall2 != "") {
+ itemTimInstallText.text =
+ if (TIMChannelInstall != "") getString(R.string.localTIMVersion) + DataStoreUtil.getString(
+ "TIMVersionInstall", ""
+ ) + TIMRdmUUIDInstall + (if (TIMVersionCodeInstall2 != "") " (${TIMVersionCodeInstall2})" else "") + " - $TIMChannelInstall" else getString(
+ R.string.localTIMVersion
+ ) + DataStoreUtil.getString("TIMVersionInstall", "")
+ itemTimInstallCard.visibility = View.VISIBLE
+ itemTimInstallCard.setOnLongClickListener {
+ if (DataStoreUtil.getBoolean("longPressCard", true)) {
+ val tv = TextView(this@MainActivity).apply {
+ text = "Version Name: ${
+ DataStoreUtil.getString(
+ "TIMVersionInstall", ""
+ )
+ }" + (if (DataStoreUtil.getString(
+ "TIMRdmUUIDInstall", ""
+ ) != ""
+ ) "\n\nRdm UUID: ${
+ DataStoreUtil.getString(
+ "TIMRdmUUIDInstall", ""
+ )
+ }" else "") + (if (DataStoreUtil.getString(
+ "TIMVersionCodeInstall", ""
+ ) != ""
+ ) "\n\nVersion Code: ${
+ DataStoreUtil.getString(
+ "TIMVersionCodeInstall", ""
+ )
+ }" else "") + (if (DataStoreUtil.getString(
+ "TIMAppSettingParamsInstall", ""
+ ) != ""
+ ) "\n\nAppSetting_params: ${
+ DataStoreUtil.getString(
+ "TIMAppSettingParamsInstall", ""
+ )
+ }" else "")
+ setTextIsSelectable(true)
+ setPadding(96, 48, 96, 96)
+ }
+ MaterialAlertDialogBuilder(context)
+ .setView(tv)
+ .setTitle(R.string.localTIMVersionDetails)
+ .setIcon(R.drawable.scan_line)
+ .show()
+ } else showToast(getString(R.string.longPressToViewSourceDetailsIsDisabledPleaseGoToSettingsToTurnItOn))
+ true
+ }
+ } else itemTimInstallCard.visibility = View.GONE
+ }
+ }
+ try {
+ val okHttpClient = OkHttpClient()
+ val request =
+ Request.Builder().url("https://im.qq.com/rainbow/androidQQVersionList")
+ .build()
+ val response = okHttpClient.newCall(request).execute()
+ val responseData = response.body?.string()
+ if (responseData != null) {
+ val start = (responseData.indexOf("versions64\":[")) + 12
+ val end = (responseData.indexOf(";\n" + " typeof"))
+ val totalJson = responseData.substring(start, end)
+ qqVersion = totalJson.split("},{").reversed().map {
+ val pstart = it.indexOf("{\"versions")
+ val pend = it.indexOf(",\"length")
+ val json = it.substring(pstart, pend)
+ Json.decodeFromString(json).apply {
+ jsonString = json
+ // 标记本机 Android QQ 版本
+ this.displayInstall = (DataStoreUtil.getString(
+ "QQVersionInstall", ""
+ ) == this.versionNumber)
+ this.isAccessibility = false
+
+ // 无障碍标记
+ /*DefaultArtifactVersion(this.versionNumber) >= DefaultArtifactVersion(
+ EARLIEST_ACCESSIBILITY_VERSION
+ )*/
+ }
+ }
+ if (DataStoreUtil.getBoolean(
+ "displayFirst", true
+ )
+ ) qqVersion[0].displayType = 1
+ withContext(Dispatchers.Main) {
+ versionAdapter.submitList(qqVersion)
+ // 舍弃 currentQQVersion = qqVersion.first().versionNumber
+ // 大版本号也放持久化存储了,否则猜版 Shortcut 因为加载过快而获取不到东西
+ DataStoreUtil.putStringAsync(
+ "versionBig", qqVersion.first().versionNumber
+ )
}
}
- if (DataStoreUtil.getBoolean(
- "displayFirst", true
- )
- ) qqVersion[0].displayType = 1
+ } catch (e: Exception) {
+ e.printStackTrace()
+ dialogError(e)
+ } finally {
withContext(Dispatchers.Main) {
- versionAdapter.submitList(qqVersion)
- // 舍弃 currentQQVersion = qqVersion.first().versionNumber
- // 大版本号也放持久化存储了,否则猜版 Shortcut 因为加载过快而获取不到东西
- DataStoreUtil.putStringAsync(
- "versionBig", qqVersion.first().versionNumber
- )
+ binding.progressLine.hide()
}
}
- } catch (e: Exception) {
- e.printStackTrace()
- dialogError(e)
- } finally {
- withContext(Dispatchers.Main) {
- binding.progressLine.hide()
- }
}
}
}
@@ -1240,11 +1459,9 @@ class MainActivity : AppCompatActivity() {
}
- MODE_WECHAT -> {
- // https://dldir1.qq.com/weixin/android/weixin8049android2600_0x2800318a_arm64.apk
- link =
- "https://dldir1.qq.com/weixin/android/weixin${versionBig}android${versionTrue}_0x${v16codeStr}_arm64.apk"
- }
+ MODE_WECHAT -> link =
+ "https://dldir1.qq.com/weixin/android/weixin${versionBig}android${versionTrue}_0x${v16codeStr}_arm64.apk"
+ // https://dldir1.qq.com/weixin/android/weixin8049android2600_0x2800318a_arm64.apk
}
runOnUiThread {
updateProgressDialogMessage("${getString(R.string.enumeratingDownloadLink)}$link")
@@ -1252,8 +1469,8 @@ class MainActivity : AppCompatActivity() {
val okHttpClient = OkHttpClient()
val request = Request.Builder().url(link).head().build()
val response = okHttpClient.newCall(request).execute()
- val responseContentType = response.header("Content-Type")
- if (response.isSuccessful && (responseContentType == "application/octet-stream" || responseContentType == "application/vnd.android.package-archive")) {
+ val responseContentType = response.header("Content-Type").toString()
+ if (response.isSuccessful && responseContentType.startsWith("application/")) {
val appSize = "%.2f".format(
response.header("Content-Length")!!.toDouble().div(1024 * 1024)
)
@@ -1276,8 +1493,7 @@ class MainActivity : AppCompatActivity() {
R.string.fileSize
)
}$appSize MB"
- )
- .show()
+ ).show()
// 复制并停止按钮点击事件
@@ -1314,8 +1530,7 @@ class MainActivity : AppCompatActivity() {
val shareIntent = Intent(Intent.ACTION_SEND).apply {
type = "text/plain"
putExtra(
- Intent.EXTRA_TEXT,
- when (mode) {
+ Intent.EXTRA_TEXT, when (mode) {
MODE_OFFICIAL -> "Android QQ $versionBig ${
getString(
R.string.stableVersion
@@ -1361,26 +1576,20 @@ class MainActivity : AppCompatActivity() {
DownloadManager.Request(Uri.parse(link))
requestDownload.apply {
when (mode) {
- MODE_TEST, MODE_UNOFFICIAL -> {
- setDestinationInExternalPublicDir(
- Environment.DIRECTORY_DOWNLOADS,
- "Android_QQ_${versionBig}.${vSmall}_64.apk"
- )
- }
-
- MODE_OFFICIAL -> {
- setDestinationInExternalPublicDir(
- Environment.DIRECTORY_DOWNLOADS,
- "Android_QQ_${versionBig}_64.apk"
- )
- }
-
- MODE_WECHAT -> {
- setDestinationInExternalPublicDir(
- Environment.DIRECTORY_DOWNLOADS,
- "Android_微信_${versionBig}.${versionTrue}.apk"
- )
- }
+ MODE_TEST, MODE_UNOFFICIAL -> setDestinationInExternalPublicDir(
+ Environment.DIRECTORY_DOWNLOADS,
+ "Android_QQ_${versionBig}.${vSmall}_64.apk"
+ )
+
+ MODE_OFFICIAL -> setDestinationInExternalPublicDir(
+ Environment.DIRECTORY_DOWNLOADS,
+ "Android_QQ_${versionBig}_64.apk"
+ )
+
+ MODE_WECHAT -> setDestinationInExternalPublicDir(
+ Environment.DIRECTORY_DOWNLOADS,
+ "Android_微信_${versionBig}.${versionTrue}.apk"
+ )
}
}
val downloadManager =
@@ -1401,8 +1610,7 @@ class MainActivity : AppCompatActivity() {
} else {
when {
- mode == MODE_TEST && (!guessTestExtend || sIndex == (stList.size)) // 测试版情况下,未打开扩展猜版或扩展猜版到最后一步时执行小版本号的递增
- -> {
+ mode == MODE_TEST && (!guessTestExtend || sIndex == (stList.size)) -> { // 测试版情况下,未打开扩展猜版或扩展猜版到最后一步时执行小版本号的递增
vSmall += if (!guessNot5) 5 else 1
sIndex = 0
}
@@ -1416,9 +1624,7 @@ class MainActivity : AppCompatActivity() {
}
}
- STATUS_PAUSE -> {
- sleep(500)
- }
+ STATUS_PAUSE -> sleep(500)
STATUS_END -> {
if (mode != MODE_OFFICIAL) showToast(getString(R.string.enumHasBeenStopped))
@@ -1523,9 +1729,10 @@ class MainActivity : AppCompatActivity() {
shiplyDecodeStringJson.toPrettyFormat().getAllAPKUrl()
dialogShiplyBackBinding.apply {
- MaterialAlertDialogBuilder(this@MainActivity).setView(
- dialogShiplyBackBinding.root
- ).setTitle(R.string.contentReturnedByShiplyPlatform)
+ MaterialAlertDialogBuilder(this@MainActivity)
+ .setView(
+ dialogShiplyBackBinding.root
+ ).setTitle(R.string.contentReturnedByShiplyPlatform)
.setIcon(R.drawable.flask_line)
.show().apply {
shiplyUrlRecyclerView.layoutManager =
diff --git a/app/src/main/java/com/xiaoniu/qqversionlist/ui/VersionAdapter.kt b/app/src/main/java/com/xiaoniu/qqversionlist/ui/VersionAdapter.kt
index 36a9a65f..c7f55a05 100644
--- a/app/src/main/java/com/xiaoniu/qqversionlist/ui/VersionAdapter.kt
+++ b/app/src/main/java/com/xiaoniu/qqversionlist/ui/VersionAdapter.kt
@@ -21,6 +21,7 @@ package com.xiaoniu.qqversionlist.ui
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Typeface
+import android.util.Base64
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
@@ -46,11 +47,6 @@ import com.xiaoniu.qqversionlist.util.StringUtil.toPrettyFormat
import com.xiaoniu.qqversionlist.util.dp
class VersionAdapter : ListAdapter(VersionDiffCallback()) {
- // Extensions -> Number.dp
- /*private fun Context.dpToPx(dp: Int): Int {
- return (dp * resources.displayMetrics.density).toInt()
- }*/
-
private var getProgressSize = DataStoreUtil.getBoolean("progressSize", false)
private var getVersionTCloud = DataStoreUtil.getBoolean("versionTCloud", true)
private var getVersionTCloudThickness =
@@ -83,13 +79,11 @@ class VersionAdapter : ListAdapter(Versi
showDialog(
it.context, currentList[adapterPosition].jsonString.toPrettyFormat()
)
- } else {
- Toast.makeText(
- it.context,
- R.string.longPressToViewJSONDetailsIsDisabledPleaseGoToSettingsToTurnItOn,
- Toast.LENGTH_SHORT
- ).show()
- }
+ } else Toast.makeText(
+ it.context,
+ R.string.longPressToViewSourceDetailsIsDisabledPleaseGoToSettingsToTurnItOn,
+ Toast.LENGTH_SHORT
+ ).show()
true
}
}
@@ -110,13 +104,12 @@ class VersionAdapter : ListAdapter(Versi
showDialog(
it.context, currentList[adapterPosition].jsonString.toPrettyFormat()
)
- } else {
- Toast.makeText(
- it.context,
- R.string.longPressToViewJSONDetailsIsDisabledPleaseGoToSettingsToTurnItOn,
- Toast.LENGTH_SHORT
- ).show()
- }
+ } else Toast.makeText(
+ it.context,
+ R.string.longPressToViewSourceDetailsIsDisabledPleaseGoToSettingsToTurnItOn,
+ Toast.LENGTH_SHORT
+ ).show()
+
true
}
}
@@ -138,21 +131,22 @@ class VersionAdapter : ListAdapter(Versi
)
bindDisplayInstall(tvInstall, tvInstallCard, bean)
bindVersionTCloud(tvVersion, holder.context)
+ bindAccessibilityTag(accessibilityTag, holder.context, bean)
}
}
is ViewHolderDetail -> {
holder.binding.apply {
linearImages.removeAllViews()
- bean.imgs.forEach {
+ bean.imgs.forEachIndexed { index, s ->
val iv = ImageView(holder.itemView.context).apply {
- setPadding(0, 0, 4.dp, 0)
+ setPadding(0, 0, if (index == bean.imgs.size - 1) 0 else 4.dp, 0)
layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT, 150.dp
)
}
linearImages.addView(iv)
- iv.load(it) {
+ iv.load(s) {
crossfade(true)
transformations(RoundedCornersTransformation(2.dp.toFloat()))
}
@@ -170,6 +164,7 @@ class VersionAdapter : ListAdapter(Versi
bindDisplayInstall(tvOldInstall, tvOldInstallCard, bean)
bindVersionTCloud(tvOldVersion, holder.context)
+ bindAccessibilityTag(accessibilityOldTag, holder.context, bean)
bindProgress(
listDetailProgressLine,
@@ -232,30 +227,43 @@ class VersionAdapter : ListAdapter(Versi
if (bean.displayInstall) {
tvInstallCard.isVisible = true
tvInstall.text = tvInstall.context.getString(R.string.installed)
- } else {
- tvInstallCard.isVisible = false
- }
+ if (bean.isAccessibility) {
+ val marginLayoutParams = tvInstallCard.layoutParams as ViewGroup.MarginLayoutParams
+ marginLayoutParams.marginStart = 3.dp
+ tvInstallCard.layoutParams = marginLayoutParams
+ } else {
+ val marginLayoutParams = tvInstallCard.layoutParams as ViewGroup.MarginLayoutParams
+ marginLayoutParams.marginStart = 6.dp
+ tvInstallCard.layoutParams = marginLayoutParams
+ }
+ } else tvInstallCard.isVisible = false
+ }
+
+ private fun bindAccessibilityTag(
+ accessibilityTag: ImageView, context: Context, bean: QQVersionBean
+ ) {
+ if (bean.isAccessibility) {
+ accessibilityTag.contentDescription = String(
+ Base64.decode(
+ context.getString(R.string.accessibilityTag), Base64.NO_WRAP
+ ), Charsets.UTF_8
+ )
+ accessibilityTag.isVisible = true
+ } else accessibilityTag.isVisible = false
}
private fun bindVersionTCloud(
tvVersion: TextView, context: Context
) {
if (getVersionTCloud) {
- val TCloudFont: Typeface
- when (getVersionTCloudThickness) {
- "Light" -> TCloudFont =
- ResourcesCompat.getFont(context, R.font.tcloud_number_light)!!
-
- "Regular" -> TCloudFont =
- ResourcesCompat.getFont(context, R.font.tcloud_number_regular)!!
-
- "Bold" -> TCloudFont = ResourcesCompat.getFont(context, R.font.tcloud_number_bold)!!
- else -> TCloudFont = ResourcesCompat.getFont(context, R.font.tcloud_number_vf)!!
+ val TCloudFont: Typeface = when (getVersionTCloudThickness) {
+ "Light" -> ResourcesCompat.getFont(context, R.font.tcloud_number_light)!!
+ "Regular" -> ResourcesCompat.getFont(context, R.font.tcloud_number_regular)!!
+ "Bold" -> ResourcesCompat.getFont(context, R.font.tcloud_number_bold)!!
+ else -> ResourcesCompat.getFont(context, R.font.tcloud_number_vf)!!
}
tvVersion.typeface = TCloudFont
- } else {
- tvVersion.setTypeface(null, Typeface.NORMAL)
- }
+ } else tvVersion.setTypeface(null, Typeface.NORMAL)
}
private fun showDialog(context: Context, s: String) {
@@ -271,9 +279,8 @@ class VersionAdapter : ListAdapter(Versi
override fun onBindViewHolder(
holder: RecyclerView.ViewHolder, position: Int, payloads: MutableList
) {
- if (payloads.isEmpty()) {
- onBindViewHolder(holder, position)
- } else {
+ if (payloads.isEmpty()) onBindViewHolder(holder, position)
+ else {
val bean = currentList[position]
when (payloads[0]) {
"displayType" -> {
diff --git a/app/src/main/res/drawable/accessibility_new_20px.xml b/app/src/main/res/drawable/accessibility_new_20px.xml
new file mode 100644
index 00000000..6aceaaf8
--- /dev/null
+++ b/app/src/main/res/drawable/accessibility_new_20px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/accessibility_new_24px.xml b/app/src/main/res/drawable/accessibility_new_24px.xml
new file mode 100644
index 00000000..bae44cf8
--- /dev/null
+++ b/app/src/main/res/drawable/accessibility_new_24px.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/apps_line.xml b/app/src/main/res/drawable/apps_line.xml
new file mode 100644
index 00000000..3fb61403
--- /dev/null
+++ b/app/src/main/res/drawable/apps_line.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/scan_line.xml b/app/src/main/res/drawable/scan_line.xml
new file mode 100644
index 00000000..2056b109
--- /dev/null
+++ b/app/src/main/res/drawable/scan_line.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index f369a962..48b5b11b 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -24,19 +24,97 @@
android:fitsSystemWindows="true"
tools:context=".ui.MainActivity">
-
+ app:layout_behavior="@string/appbar_scrolling_view_behavior">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ app:title="@string/appTitle" />
diff --git a/app/src/main/res/layout/dialog_setting.xml b/app/src/main/res/layout/dialog_setting.xml
index 85e01871..f437d026 100644
--- a/app/src/main/res/layout/dialog_setting.xml
+++ b/app/src/main/res/layout/dialog_setting.xml
@@ -43,7 +43,7 @@
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:paddingTop="16dp"
- android:text="@string/longPressTheVersionCardToViewSourceJSONDetails" />
+ android:text="@string/longPressTheVersionCardToViewSourceDetails" />
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_version.xml b/app/src/main/res/layout/item_version.xml
index e512f462..145955c3 100644
--- a/app/src/main/res/layout/item_version.xml
+++ b/app/src/main/res/layout/item_version.xml
@@ -61,15 +61,30 @@
app:layout_constraintTop_toTopOf="parent"
tools:text="9.0.25" />
+
+
diff --git a/app/src/main/res/layout/item_version_detail.xml b/app/src/main/res/layout/item_version_detail.xml
index 5cb3009c..c2815fb0 100644
--- a/app/src/main/res/layout/item_version_detail.xml
+++ b/app/src/main/res/layout/item_version_detail.xml
@@ -56,6 +56,20 @@
app:layout_constraintTop_toTopOf="parent"
tools:text="9.0.25" />
+
+
diff --git a/app/src/main/res/layout/shiply_link_next_button.xml b/app/src/main/res/layout/shiply_link_next_button.xml
index c76666ae..2e97a908 100644
--- a/app/src/main/res/layout/shiply_link_next_button.xml
+++ b/app/src/main/res/layout/shiply_link_next_button.xml
@@ -41,6 +41,7 @@
style="?attr/materialIconButtonFilledTonalStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:contentDescription="@string/share"
app:icon="@drawable/share_line" />
diff --git a/app/src/main/res/layout/success_button.xml b/app/src/main/res/layout/success_button.xml
index d4f08298..86d1bb57 100644
--- a/app/src/main/res/layout/success_button.xml
+++ b/app/src/main/res/layout/success_button.xml
@@ -41,6 +41,7 @@
style="?attr/materialIconButtonFilledTonalStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:contentDescription="@string/share"
app:icon="@drawable/share_line" />
diff --git a/app/src/main/res/values-ar-rSA/strings.xml b/app/src/main/res/values-ar-rSA/strings.xml
index 62a0a7cd..3c500859 100644
--- a/app/src/main/res/values-ar-rSA/strings.xml
+++ b/app/src/main/res/values-ar-rSA/strings.xml
@@ -63,10 +63,10 @@
额定大小:
源 JSON
建议的内容
- 长按版本卡片查看源 JSON 详情
+ 长按版本卡片查看源详情
使用系统下载管理器接管下载意图
解除 QQ 测试版猜版小版本号遵循 5 的倍数限制
- 未开启长按查看 JSON 详情功能,请前往设置开启
+ 未开启长按查看源详情功能,请前往设置开启
占比历史最大包(
):
扩展测试版猜版直链后缀
@@ -116,4 +116,16 @@
跟随系统
返回
使用进阶配置
+ 本机 QQ:
+ (
+ )
+ 本机 TIM:
+ 本机 QQ 版本详情
+ 本机 TIM 版本详情
+ 6IW+6K6vIFFRIOW3suS4iue6v+S4gOmhueaXoOmanOeijeeUqOaIt+S4k+WxnuS8mOWMluaOquaWveabtOaWsOOAguenu+WKqOe7iOerr+iuvuWkh+W8gOWQr+ezu+e7n+aXoOmanOeijeivu+Wxj+acjeWKoe+8iOWmgiBBbmRyb2lkIFRhbGtiYWNr44CBaU9TIFZvaWNlT3Zlcu+8ie+8jOW5tuWQjOaXtuS9v+eUqOiFvuiuryBRUSDnp7vliqjlrqLmiLfnq68gOS4wLjg1IOWPiuS7peS4iueJiOacrOaXtu+8jOiFvuiuryBRUSDlsIblh4/lsJHmiJblgZzmraLlkJHmraTnsbsgUVEg5a6i5oi356uv5LiL5Y+R5bm/5ZGK44CC
+ 应用宣传图
+ 分享
+ 下载
+ 停止
+ 跳过
diff --git a/app/src/main/res/values-en-rUS/strings.xml b/app/src/main/res/values-en-rUS/strings.xml
index a5b62a73..0e80c123 100644
--- a/app/src/main/res/values-en-rUS/strings.xml
+++ b/app/src/main/res/values-en-rUS/strings.xml
@@ -63,10 +63,10 @@
Reated File Size:
Source JSON
Recommendations
- Long press the version card to view source JSON details
+ Long press the version card to view source details
Use the system download manager to take over the download intent
Remove the restriction of adhering to multiples of 5 when enumerating minor version numbers for QQ preview versions
- Long press to view JSON details is disabled. Please go to settings to turn it on.
+ Long press to view source details is disabled. Please go to settings to turn it on.
Current Size VS Largest Historical Package(
):
Extend the suffix for direct download links of enumerated preview versions
@@ -116,4 +116,16 @@
Follow System
Back
Use Advanced Configurations
+ Local QQ:
+ (
+ )
+ Local TIM:
+ Local QQ Version Details
+ Local TIM Version Details
+ VGVuY2VudCBRUSBoYXMgbGF1bmNoZWQgYSBkZWRpY2F0ZWQgYWNjZXNzaWJpbGl0eSBvcHRpbWl6YXRpb24gdXBkYXRlIGZvciB1c2Vycy4gV2hlbiB0aGUgc3lzdGVtJ3Mgc2NyZWVuIHJlYWRlciBzZXJ2aWNlIChzdWNoIGFzIEFuZHJvaWQgVGFsa2JhY2ssIGlPUyBWb2ljZU92ZXIpIGlzIGVuYWJsZWQgb24gdGhlIG1vYmlsZSBkZXZpY2UgYW5kIFRlbmNlbnQgUVEgbW9iaWxlIGNsaWVudCB2ZXJzaW9uIDkuMC44NSBvciBsYXRlciBpcyB1c2VkLCBUZW5jZW50IFFRIHdpbGwgcmVkdWNlIG9yIHN0b3Agc2VydmluZyBhZHMgdG8gc3VjaCBRUSBjbGllbnRzLg==
+ App Promotion Image
+ Share
+ Download
+ Stop
+ Skip
diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml
index 62a0a7cd..3c500859 100644
--- a/app/src/main/res/values-es-rES/strings.xml
+++ b/app/src/main/res/values-es-rES/strings.xml
@@ -63,10 +63,10 @@
额定大小:
源 JSON
建议的内容
- 长按版本卡片查看源 JSON 详情
+ 长按版本卡片查看源详情
使用系统下载管理器接管下载意图
解除 QQ 测试版猜版小版本号遵循 5 的倍数限制
- 未开启长按查看 JSON 详情功能,请前往设置开启
+ 未开启长按查看源详情功能,请前往设置开启
占比历史最大包(
):
扩展测试版猜版直链后缀
@@ -116,4 +116,16 @@
跟随系统
返回
使用进阶配置
+ 本机 QQ:
+ (
+ )
+ 本机 TIM:
+ 本机 QQ 版本详情
+ 本机 TIM 版本详情
+ 6IW+6K6vIFFRIOW3suS4iue6v+S4gOmhueaXoOmanOeijeeUqOaIt+S4k+WxnuS8mOWMluaOquaWveabtOaWsOOAguenu+WKqOe7iOerr+iuvuWkh+W8gOWQr+ezu+e7n+aXoOmanOeijeivu+Wxj+acjeWKoe+8iOWmgiBBbmRyb2lkIFRhbGtiYWNr44CBaU9TIFZvaWNlT3Zlcu+8ie+8jOW5tuWQjOaXtuS9v+eUqOiFvuiuryBRUSDnp7vliqjlrqLmiLfnq68gOS4wLjg1IOWPiuS7peS4iueJiOacrOaXtu+8jOiFvuiuryBRUSDlsIblh4/lsJHmiJblgZzmraLlkJHmraTnsbsgUVEg5a6i5oi356uv5LiL5Y+R5bm/5ZGK44CC
+ 应用宣传图
+ 分享
+ 下载
+ 停止
+ 跳过
diff --git a/app/src/main/res/values-fr-rFR/strings.xml b/app/src/main/res/values-fr-rFR/strings.xml
index 3202e8dc..2575e03f 100644
--- a/app/src/main/res/values-fr-rFR/strings.xml
+++ b/app/src/main/res/values-fr-rFR/strings.xml
@@ -63,10 +63,10 @@
额定大小:
源 JSON
建议的内容
- 长按版本卡片查看源 JSON 详情
+ 长按版本卡片查看源详情
使用系统下载管理器接管下载意图
解除 QQ 测试版猜版小版本号遵循 5 的倍数限制
- 未开启长按查看 JSON 详情功能,请前往设置开启
+ 未开启长按查看源详情功能,请前往设置开启
占比历史最大包(
):
扩展测试版猜版直链后缀
@@ -116,4 +116,16 @@
跟随系统
返回
使用进阶配置
+ 本机 QQ:
+ (
+ )
+ 本机 TIM:
+ 本机 QQ 版本详情
+ 本机 TIM 版本详情
+ 6IW+6K6vIFFRIOW3suS4iue6v+S4gOmhueaXoOmanOeijeeUqOaIt+S4k+WxnuS8mOWMluaOquaWveabtOaWsOOAguenu+WKqOe7iOerr+iuvuWkh+W8gOWQr+ezu+e7n+aXoOmanOeijeivu+Wxj+acjeWKoe+8iOWmgiBBbmRyb2lkIFRhbGtiYWNr44CBaU9TIFZvaWNlT3Zlcu+8ie+8jOW5tuWQjOaXtuS9v+eUqOiFvuiuryBRUSDnp7vliqjlrqLmiLfnq68gOS4wLjg1IOWPiuS7peS4iueJiOacrOaXtu+8jOiFvuiuryBRUSDlsIblh4/lsJHmiJblgZzmraLlkJHmraTnsbsgUVEg5a6i5oi356uv5LiL5Y+R5bm/5ZGK44CC
+ 应用宣传图
+ 分享
+ 下载
+ 停止
+ 跳过
diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml
index 62a0a7cd..3c500859 100644
--- a/app/src/main/res/values-ja-rJP/strings.xml
+++ b/app/src/main/res/values-ja-rJP/strings.xml
@@ -63,10 +63,10 @@
额定大小:
源 JSON
建议的内容
- 长按版本卡片查看源 JSON 详情
+ 长按版本卡片查看源详情
使用系统下载管理器接管下载意图
解除 QQ 测试版猜版小版本号遵循 5 的倍数限制
- 未开启长按查看 JSON 详情功能,请前往设置开启
+ 未开启长按查看源详情功能,请前往设置开启
占比历史最大包(
):
扩展测试版猜版直链后缀
@@ -116,4 +116,16 @@
跟随系统
返回
使用进阶配置
+ 本机 QQ:
+ (
+ )
+ 本机 TIM:
+ 本机 QQ 版本详情
+ 本机 TIM 版本详情
+ 6IW+6K6vIFFRIOW3suS4iue6v+S4gOmhueaXoOmanOeijeeUqOaIt+S4k+WxnuS8mOWMluaOquaWveabtOaWsOOAguenu+WKqOe7iOerr+iuvuWkh+W8gOWQr+ezu+e7n+aXoOmanOeijeivu+Wxj+acjeWKoe+8iOWmgiBBbmRyb2lkIFRhbGtiYWNr44CBaU9TIFZvaWNlT3Zlcu+8ie+8jOW5tuWQjOaXtuS9v+eUqOiFvuiuryBRUSDnp7vliqjlrqLmiLfnq68gOS4wLjg1IOWPiuS7peS4iueJiOacrOaXtu+8jOiFvuiuryBRUSDlsIblh4/lsJHmiJblgZzmraLlkJHmraTnsbsgUVEg5a6i5oi356uv5LiL5Y+R5bm/5ZGK44CC
+ 应用宣传图
+ 分享
+ 下载
+ 停止
+ 跳过
diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml
index 62a0a7cd..3c500859 100644
--- a/app/src/main/res/values-ko-rKR/strings.xml
+++ b/app/src/main/res/values-ko-rKR/strings.xml
@@ -63,10 +63,10 @@
额定大小:
源 JSON
建议的内容
- 长按版本卡片查看源 JSON 详情
+ 长按版本卡片查看源详情
使用系统下载管理器接管下载意图
解除 QQ 测试版猜版小版本号遵循 5 的倍数限制
- 未开启长按查看 JSON 详情功能,请前往设置开启
+ 未开启长按查看源详情功能,请前往设置开启
占比历史最大包(
):
扩展测试版猜版直链后缀
@@ -116,4 +116,16 @@
跟随系统
返回
使用进阶配置
+ 本机 QQ:
+ (
+ )
+ 本机 TIM:
+ 本机 QQ 版本详情
+ 本机 TIM 版本详情
+ 6IW+6K6vIFFRIOW3suS4iue6v+S4gOmhueaXoOmanOeijeeUqOaIt+S4k+WxnuS8mOWMluaOquaWveabtOaWsOOAguenu+WKqOe7iOerr+iuvuWkh+W8gOWQr+ezu+e7n+aXoOmanOeijeivu+Wxj+acjeWKoe+8iOWmgiBBbmRyb2lkIFRhbGtiYWNr44CBaU9TIFZvaWNlT3Zlcu+8ie+8jOW5tuWQjOaXtuS9v+eUqOiFvuiuryBRUSDnp7vliqjlrqLmiLfnq68gOS4wLjg1IOWPiuS7peS4iueJiOacrOaXtu+8jOiFvuiuryBRUSDlsIblh4/lsJHmiJblgZzmraLlkJHmraTnsbsgUVEg5a6i5oi356uv5LiL5Y+R5bm/5ZGK44CC
+ 应用宣传图
+ 分享
+ 下载
+ 停止
+ 跳过
diff --git a/app/src/main/res/values-night-v27/themes.xml b/app/src/main/res/values-night-v27/themes.xml
new file mode 100644
index 00000000..16e0e6b5
--- /dev/null
+++ b/app/src/main/res/values-night-v27/themes.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-night-v31/themes.xml b/app/src/main/res/values-night-v31/themes.xml
index 9c0ca1fd..e0ae213d 100644
--- a/app/src/main/res/values-night-v31/themes.xml
+++ b/app/src/main/res/values-night-v31/themes.xml
@@ -28,6 +28,8 @@
- ?attr/colorPrimaryContainer
+ - true
+ - shortEdges
- @style/ThemeOverlay.App.BottomSheetDialog
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
index a009b05c..908c9da9 100644
--- a/app/src/main/res/values-night/themes.xml
+++ b/app/src/main/res/values-night/themes.xml
@@ -22,6 +22,7 @@
- false
+ - true
- @style/ThemeOverlay.App.BottomSheetDialog
diff --git a/app/src/main/res/values-ru-rRU/strings.xml b/app/src/main/res/values-ru-rRU/strings.xml
index 62a0a7cd..3c500859 100644
--- a/app/src/main/res/values-ru-rRU/strings.xml
+++ b/app/src/main/res/values-ru-rRU/strings.xml
@@ -63,10 +63,10 @@
额定大小:
源 JSON
建议的内容
- 长按版本卡片查看源 JSON 详情
+ 长按版本卡片查看源详情
使用系统下载管理器接管下载意图
解除 QQ 测试版猜版小版本号遵循 5 的倍数限制
- 未开启长按查看 JSON 详情功能,请前往设置开启
+ 未开启长按查看源详情功能,请前往设置开启
占比历史最大包(
):
扩展测试版猜版直链后缀
@@ -116,4 +116,16 @@
跟随系统
返回
使用进阶配置
+ 本机 QQ:
+ (
+ )
+ 本机 TIM:
+ 本机 QQ 版本详情
+ 本机 TIM 版本详情
+ 6IW+6K6vIFFRIOW3suS4iue6v+S4gOmhueaXoOmanOeijeeUqOaIt+S4k+WxnuS8mOWMluaOquaWveabtOaWsOOAguenu+WKqOe7iOerr+iuvuWkh+W8gOWQr+ezu+e7n+aXoOmanOeijeivu+Wxj+acjeWKoe+8iOWmgiBBbmRyb2lkIFRhbGtiYWNr44CBaU9TIFZvaWNlT3Zlcu+8ie+8jOW5tuWQjOaXtuS9v+eUqOiFvuiuryBRUSDnp7vliqjlrqLmiLfnq68gOS4wLjg1IOWPiuS7peS4iueJiOacrOaXtu+8jOiFvuiuryBRUSDlsIblh4/lsJHmiJblgZzmraLlkJHmraTnsbsgUVEg5a6i5oi356uv5LiL5Y+R5bm/5ZGK44CC
+ 应用宣传图
+ 分享
+ 下载
+ 停止
+ 跳过
diff --git a/app/src/main/res/values-v27/themes.xml b/app/src/main/res/values-v27/themes.xml
new file mode 100644
index 00000000..5c91279d
--- /dev/null
+++ b/app/src/main/res/values-v27/themes.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-v31/themes.xml b/app/src/main/res/values-v31/themes.xml
index 44ec50b4..033ae2f5 100644
--- a/app/src/main/res/values-v31/themes.xml
+++ b/app/src/main/res/values-v31/themes.xml
@@ -26,6 +26,8 @@
-
@drawable/ic_launcher_foreground_splash
+ - true
+ - shortEdges
- ?attr/colorPrimaryContainer
- @style/ThemeOverlay.App.BottomSheetDialog
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 62a0a7cd..3c500859 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -63,10 +63,10 @@
额定大小:
源 JSON
建议的内容
- 长按版本卡片查看源 JSON 详情
+ 长按版本卡片查看源详情
使用系统下载管理器接管下载意图
解除 QQ 测试版猜版小版本号遵循 5 的倍数限制
- 未开启长按查看 JSON 详情功能,请前往设置开启
+ 未开启长按查看源详情功能,请前往设置开启
占比历史最大包(
):
扩展测试版猜版直链后缀
@@ -116,4 +116,16 @@
跟随系统
返回
使用进阶配置
+ 本机 QQ:
+ (
+ )
+ 本机 TIM:
+ 本机 QQ 版本详情
+ 本机 TIM 版本详情
+ 6IW+6K6vIFFRIOW3suS4iue6v+S4gOmhueaXoOmanOeijeeUqOaIt+S4k+WxnuS8mOWMluaOquaWveabtOaWsOOAguenu+WKqOe7iOerr+iuvuWkh+W8gOWQr+ezu+e7n+aXoOmanOeijeivu+Wxj+acjeWKoe+8iOWmgiBBbmRyb2lkIFRhbGtiYWNr44CBaU9TIFZvaWNlT3Zlcu+8ie+8jOW5tuWQjOaXtuS9v+eUqOiFvuiuryBRUSDnp7vliqjlrqLmiLfnq68gOS4wLjg1IOWPiuS7peS4iueJiOacrOaXtu+8jOiFvuiuryBRUSDlsIblh4/lsJHmiJblgZzmraLlkJHmraTnsbsgUVEg5a6i5oi356uv5LiL5Y+R5bm/5ZGK44CC
+ 应用宣传图
+ 分享
+ 下载
+ 停止
+ 跳过
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index 7144cf53..3e83a8f7 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -63,10 +63,10 @@
額定大小:
源 JSON
建議的內容
- 長按版本卡片查看源 JSON 詳情
+ 長按版本卡片查看源詳情
使用系統下載管理器接管下載意圖
解除 QQ 測試版猜版小版本號遵循 5 的倍數限制
- 未開啟長按查看 JSON 詳情功能,請前往設定開啟
+ 未開啟長按查看源詳情功能,請前往設定開啟
占比歷史最大包(
):
擴展測試版猜版直鏈後綴
@@ -116,4 +116,16 @@
跟隨系統
返回
使用進階配置
+ 本機 QQ:
+ (
+ )
+ 本機 TIM:
+ 本機 QQ 版本詳情
+ 本機 TIM 版本詳情
+ 6aiw6KiKIFFRIOW3suS4iue3muS4gOmgheeEoemanOekmeeUqOaItuWwiOWxrOWEquWMluaOquaWveabtOaWsOOAgueVtuenu+WLlee1guerr+ioreWCmeWVn+eUqOezu+e1seeEoemanOekmeiugOWxj+acjeWLme+8iOWmgiBBbmRyb2lkIFRhbGtiYWNr44CBaU9TIFZvaWNlT3Zlcu+8ie+8jOS4puS4lOWQjOaZguS9v+eUqOmosOioiiBRUSDnp7vli5XlrqLmiLbnq68gOS4wLjg1IOWPiuS7peS4iueJiOacrOaZgu+8jOmosOioiiBRUSDlsIfmnIPmuJvlsJHmiJblgZzmraLlkJHmraTpoZ4gUVEg5a6i5oi256uv55m86YCB5buj5ZGK44CC
+ 應用宣傳圖
+ 分享
+ 下載
+ 停止
+ 跳過
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4e74fbce..77f77a17 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -62,10 +62,10 @@
额定大小:
源 JSON
建议的内容
- 长按版本卡片查看源 JSON 详情
+ 长按版本卡片查看源详情
使用系统下载管理器接管下载意图
解除 QQ 测试版猜版小版本号遵循 5 的倍数限制
- 未开启长按查看 JSON 详情功能,请前往设置开启
+ 未开启长按查看源详情功能,请前往设置开启
占比历史最大包(
):
扩展测试版猜版直链后缀
@@ -115,4 +115,16 @@
跟随系统
返回
使用进阶配置
+ 本机 QQ:
+ (
+ )
+ 本机 TIM:
+ 本机 QQ 版本详情
+ 本机 TIM 版本详情
+ 6IW+6K6vIFFRIOW3suS4iue6v+S4gOmhueaXoOmanOeijeeUqOaIt+S4k+WxnuS8mOWMluaOquaWveabtOaWsOOAguenu+WKqOe7iOerr+iuvuWkh+W8gOWQr+ezu+e7n+aXoOmanOeijeivu+Wxj+acjeWKoe+8iOWmgiBBbmRyb2lkIFRhbGtiYWNr44CBaU9TIFZvaWNlT3Zlcu+8ie+8jOW5tuWQjOaXtuS9v+eUqOiFvuiuryBRUSDnp7vliqjlrqLmiLfnq68gOS4wLjg1IOWPiuS7peS4iueJiOacrOaXtu+8jOiFvuiuryBRUSDlsIblh4/lsJHmiJblgZzmraLlkJHmraTnsbsgUVEg5a6i5oi356uv5LiL5Y+R5bm/5ZGK44CC
+ 应用宣传图
+ 分享
+ 下载
+ 停止
+ 跳过
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index 549a6295..8f66c59b 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -21,6 +21,7 @@
- true
+ - true
- @style/ThemeOverlay.App.BottomSheetDialog