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 @@ + + + + + + + +