diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index d2ed45e4..14fc5264 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,7 +5,7 @@ on:
branches:
- release
env:
- LATEST_VERSION: "1.5"
+ LATEST_VERSION: "2.0.0"
jobs:
build-and-deploy:
diff --git a/README.md b/README.md
index 9ed4e382..b4c279d8 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ SKIP 是一款免费开源的安卓应用,旨在利用 Android 无障碍服务
## 主界面预览
-
+
## 使用说明
@@ -18,7 +18,7 @@ SKIP 是一款免费开源的安卓应用,旨在利用 Android 无障碍服务
## 如何贡献
- 应用市场APP种类繁多,情况各异,无法保证完全适配
-- 如有问题可以提交issue,或者参考 👉 [贡献指南](https://guoxicheng.top/projects/SKIP-Docs/003-contribute.html)
+- 如有问题可以提交issue,或者参考 👉 [贡献指南](https://guoxicheng.top/projects/SKIP-Docs/contribute.html)
## 许可证
diff --git a/apk/SKIP-v2.0.0.apk b/apk/SKIP-v2.0.0.apk
new file mode 100644
index 00000000..4507ea6b
Binary files /dev/null and b/apk/SKIP-v2.0.0.apk differ
diff --git a/app/build.gradle b/app/build.gradle
index 4faecac7..f3cffb53 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -11,7 +11,7 @@ android {
minSdk 24
targetSdk 32
versionCode 1
- versionName "1.5"
+ versionName "2.0.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
diff --git a/app/src/main/java/com/android/skip/AboutActivity.kt b/app/src/main/java/com/android/skip/AboutActivity.kt
index 6fef33f9..9d1ccd94 100644
--- a/app/src/main/java/com/android/skip/AboutActivity.kt
+++ b/app/src/main/java/com/android/skip/AboutActivity.kt
@@ -1,15 +1,11 @@
package com.android.skip
-import android.content.Intent
-import android.net.Uri
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
-import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
-import com.android.skip.compose.ConfirmDialog
import com.android.skip.compose.FlatButton
+import com.android.skip.compose.OpenBrowserDialog
import com.android.skip.compose.RowContent
import com.android.skip.compose.ScaffoldPage
import com.android.skip.manager.RectManager
@@ -54,31 +50,14 @@ fun AboutActivityInterface(onBackClick: () -> Unit) {
}
FlatButton(content = {
- RowContent("当前版本:${BuildConfig.VERSION_NAME}")
+ RowContent(stringResource(id = R.string.about_current_version) + BuildConfig.VERSION_NAME)
})
FlatButton(content = {
- RowContent("当前分辨率:${RectManager.getMaxRect()}")
+ RowContent(stringResource(id = R.string.about_current_resolution) + RectManager.getMaxRect())
})
})
- OpenApplicationDialog(openName = openName.value, openUrl = openUrl.value, showDialog)
-}
-
-@Composable
-fun OpenApplicationDialog(openName: String, openUrl: String, showDialog: MutableState) {
- val context = LocalContext.current
-
- if (showDialog.value) {
- ConfirmDialog(
- title = "启动应用",
- content = "是否通过浏览器访问 $openName?",
- onDismiss = { showDialog.value = false },
- onAllow = {
- val intent = Intent(Intent.ACTION_VIEW, Uri.parse(openUrl))
- context.startActivity(intent)
- showDialog.value = false
- })
- }
+ OpenBrowserDialog(openName = openName.value, openUrl = openUrl.value, showDialog)
}
diff --git a/app/src/main/java/com/android/skip/BaseActivity.kt b/app/src/main/java/com/android/skip/BaseActivity.kt
index 4cfae732..3d8bec49 100644
--- a/app/src/main/java/com/android/skip/BaseActivity.kt
+++ b/app/src/main/java/com/android/skip/BaseActivity.kt
@@ -39,7 +39,16 @@ abstract class BaseActivity : AppCompatActivity() {
ProvideContent()
}
}
+
RectManager.setMaxRect(this)
+
+ // 清理临时文件
+ val directory = this.getExternalFilesDir(null)
+ directory?.let {
+ it.listFiles()?.forEach { file ->
+ file.delete()
+ }
+ }
}
@Composable
diff --git a/app/src/main/java/com/android/skip/KeepAliveActivity.kt b/app/src/main/java/com/android/skip/KeepAliveActivity.kt
index ed32dde7..7dd11144 100644
--- a/app/src/main/java/com/android/skip/KeepAliveActivity.kt
+++ b/app/src/main/java/com/android/skip/KeepAliveActivity.kt
@@ -3,6 +3,7 @@ package com.android.skip
import android.content.ComponentName
import android.content.Intent
import android.net.Uri
+import android.os.Build
import android.provider.Settings
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
@@ -10,10 +11,12 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import com.android.skip.compose.FlatButton
+import com.android.skip.compose.OpenBrowserDialog
import com.android.skip.compose.PictureDialog
import com.android.skip.compose.ResourceIcon
import com.android.skip.compose.RowContent
import com.android.skip.compose.ScaffoldPage
+import java.net.URLEncoder
class KeepAliveActivity : BaseActivity() {
@@ -28,14 +31,15 @@ class KeepAliveActivity : BaseActivity() {
@Composable
fun KeepAliveInterface(onBackClick: () -> Unit) {
val context = LocalContext.current
- val showDialog = remember { mutableStateOf(false) }
+ val showPicDialog = remember { mutableStateOf(false) }
+ val showBrowserDialog = remember { mutableStateOf(false) }
ScaffoldPage(stringResource(id = R.string.alive), onBackClick = onBackClick, content = {
- PictureDialog(showDialog)
+ PictureDialog(showPicDialog)
FlatButton(content = {
RowContent(
stringResource(id = R.string.alive_power_saving_title),
stringResource(id = R.string.alive_power_saving_subtitle),
- { ResourceIcon(iconResource = R.drawable.counter_1)}
+ { ResourceIcon(iconResource = R.drawable.counter_1) }
)
}) {
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
@@ -46,7 +50,7 @@ fun KeepAliveInterface(onBackClick: () -> Unit) {
RowContent(
stringResource(id = R.string.alive_self_start_title),
stringResource(id = R.string.alive_self_start_subtitle),
- { ResourceIcon(iconResource = R.drawable.counter_2)}
+ { ResourceIcon(iconResource = R.drawable.counter_2) }
)
}) {
val intent = Intent()
@@ -60,17 +64,30 @@ fun KeepAliveInterface(onBackClick: () -> Unit) {
RowContent(
stringResource(id = R.string.alive_backstage_title),
stringResource(id = R.string.alive_backstage_subtitle),
- { ResourceIcon(iconResource = R.drawable.counter_3)}
+ { ResourceIcon(iconResource = R.drawable.counter_3) }
)
}) {
- showDialog.value = true
+ showPicDialog.value = true
}
FlatButton(content = {
RowContent(
stringResource(id = R.string.alive_warn_title),
stringResource(id = R.string.alive_warn_subtitle),
- { ResourceIcon(iconResource = R.drawable.warning)}
+ { ResourceIcon(iconResource = R.drawable.warning) }
)
- })
+ }) {
+ showBrowserDialog.value = true
+ }
})
+
+ val searchContent = Build.MANUFACTURER + stringResource(id = R.string.alive_warn_search_content)
+ OpenBrowserDialog(
+ openName = searchContent,
+ openUrl = createBaiduSearchUrl(searchContent),
+ showDialog = showBrowserDialog
+ )
+}
+
+fun createBaiduSearchUrl(query: String): String {
+ return "https://www.baidu.com/s?wd=${URLEncoder.encode(query, "UTF-8")}"
}
\ No newline at end of file
diff --git a/app/src/main/java/com/android/skip/MainActivity.kt b/app/src/main/java/com/android/skip/MainActivity.kt
index 546830ad..ee7baab7 100644
--- a/app/src/main/java/com/android/skip/MainActivity.kt
+++ b/app/src/main/java/com/android/skip/MainActivity.kt
@@ -1,638 +1,638 @@
package com.android.skip
-
-import android.content.ComponentName
-import android.content.Context
-import android.content.Intent
-import android.net.Uri
-import android.os.Build
-import android.os.Bundle
-import android.provider.Settings
-import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.offset
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.text.ClickableText
-import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.Button
-import androidx.compose.material3.ButtonDefaults
-import androidx.compose.material3.LinearProgressIndicator
-import androidx.compose.material3.Text
-import androidx.compose.material3.TextButton
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.rememberCoroutineScope
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.SpanStyle
-import androidx.compose.ui.text.buildAnnotatedString
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.text.withStyle
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.Density
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import androidx.core.content.FileProvider
-import com.android.skip.dataclass.PackageInfo
-import com.android.skip.manager.HttpManager
-import com.android.skip.manager.RectManager
-import com.android.skip.manager.SkipConfigManager
-import com.android.skip.manager.ToastManager
-import com.android.skip.ui.theme.AppTheme
-import com.android.skip.ui.theme.green
-import com.google.android.material.dialog.MaterialAlertDialogBuilder
-import kotlinx.coroutines.launch
-import org.yaml.snakeyaml.Yaml
-import java.io.File
-import java.util.Locale
-import kotlin.concurrent.thread
-import kotlin.math.roundToInt
-
-
-var accessibilityState by mutableStateOf(false)
-
-var alertDialogPositiveButtonClickState by mutableStateOf(false)
-
-// 无障碍服务启用停用按钮
-var isAccessibilityBtnClicked by mutableStateOf(false)
-
-// 后台任务管理
-var isBackendTaskBtnClicked by mutableStateOf(false)
-
-// 自启动管理
-var isAutoStartBtnClicked by mutableStateOf(false)
-
-// 省电策略按钮
-var isPowerSavingBtnClicked by mutableStateOf(false)
-
-// 检查更新按钮
-var isCheckUpdateBtnClicked by mutableStateOf(false)
-
-// 是否需要更新
-var isNeedUpdateAPK by mutableStateOf(false)
-
-// 最新版本号
-var latestVersionText by mutableStateOf("")
-
-// 立即更新
-var isUpdateAPKClicked by mutableStateOf(false)
-
-// 更新进度对话框
-var isProcessDialogVisible by mutableStateOf(false)
-
-var downloadProgress by mutableStateOf(0f)
-
-
-class MainActivity : ComponentActivity() {
-
- private fun openAppInfo() {
- val packageName = packageName
- val intent = Intent(
- Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
- Uri.parse("package:$packageName")
- )
- startActivity(intent)
- }
-
- private fun openAutoStartSettings(context: Context) {
- try {
- val intent = Intent()
-
- val manufacturer = Build.MANUFACTURER.lowercase(Locale.ENGLISH)
- when {
- manufacturer.contains("xiaomi") -> {
- intent.component = ComponentName(
- "com.miui.securitycenter",
- "com.miui.permcenter.autostart.AutoStartManagementActivity"
- )
- }
- manufacturer.contains("oppo") -> {
- intent.component = ComponentName(
- "com.coloros.safecenter",
- "com.coloros.safecenter.permission.startup.StartupAppListActivity"
- )
- }
- manufacturer.contains("vivo") -> {
- intent.component = ComponentName(
- "com.vivo.permissionmanager",
- "com.vivo.permissionmanager.activity.BgStartUpManagerActivity"
- )
- }
- manufacturer.contains("oneplus") -> {
- intent.component = ComponentName(
- "com.oneplus.security",
- "com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity"
- )
- }
- manufacturer.contains("huawei") -> {
- intent.component = ComponentName(
- "com.huawei.systemmanager",
- "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity"
- )
- }
- else -> {
- openAppInfo()
- }
- }
-
- context.startActivity(intent)
- } catch (e: Exception) {
- openAppInfo()
- }
- }
-
- private fun openBatteryOptimizationSettings(context: Context) {
- try {
- val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
- intent.data = Uri.parse("package:${context.packageName}")
- context.startActivity(intent)
- } catch (e: Exception) {
- openAppInfo()
- }
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
-
- super.onCreate(savedInstanceState)
-
- setContent {
-
- val displayMetrics = LocalContext.current.resources.displayMetrics
- val widthPixels = displayMetrics.widthPixels
- val fontScale = LocalDensity.current.fontScale
-
- CompositionLocalProvider(
- LocalDensity provides Density(
- density = widthPixels / 360.0f,
- fontScale = fontScale
- )
- ) {
- MainSurface()
- ProcessDialog()
- }
-
-
- if (isAccessibilityBtnClicked) {
- if (!accessibilityState) {
- AlertDialog(
- context = this,
- title = "启用无障碍服务",
- message = "已下载的应用 > SKIP > 打开「使用SKIP」",
- negativeText = "再想想",
- positiveText = "去开启"
- ) {
- alertDialogPositiveButtonClickState = true
- }
- } else {
- AlertDialog(
- context = this,
- title = "停用无障碍服务",
- message = "已下载的应用 > SKIP > 关闭「使用SKIP」",
- negativeText = "再想想",
- positiveText = "去停用"
- ) {
- alertDialogPositiveButtonClickState = true
- }
- }
- isAccessibilityBtnClicked = false
- }
-
- if (isNeedUpdateAPK) {
- AlertDialog(
- context = this,
- title = "发现新版本",
- message = "${BuildConfig.VERSION_NAME} -> $latestVersionText",
- negativeText = "暂不更新",
- positiveText = "立即更新"
- ) {
- isUpdateAPKClicked = true
- }
- isNeedUpdateAPK = false
- }
-
- when {
- alertDialogPositiveButtonClickState -> {
- val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
- this.startActivity(intent)
- alertDialogPositiveButtonClickState = false
- }
- isAutoStartBtnClicked -> {
- openAutoStartSettings(this)
- isAutoStartBtnClicked = false
- }
- isPowerSavingBtnClicked -> {
- openBatteryOptimizationSettings(this)
- isPowerSavingBtnClicked = false
- }
- isBackendTaskBtnClicked -> {
- ImageDialog()
- }
- isCheckUpdateBtnClicked -> {
- thread {
- ToastManager.showToast(this, "开始检查更新")
- val updateSkipConfigResult =
- if (HttpManager.updateSkipConfig()) "配置更新成功" else "配置更新失败"
- ToastManager.showToast(this, updateSkipConfigResult)
-
- val latestVersion = HttpManager.getLatestVersion()
- if (latestVersion != BuildConfig.VERSION_NAME.trim()) {
- isNeedUpdateAPK = true
- latestVersionText = latestVersion
- } else {
- ToastManager.showToast(this, "当前版本已是最新版")
- }
-
- isCheckUpdateBtnClicked = false
- }
- }
- isUpdateAPKClicked -> {
- thread {
- isProcessDialogVisible = true
- HttpManager.downloadNewAPK(latestVersionText, this) { it ->
- downloadProgress = it * 0.01f
- if (it == 100) isProcessDialogVisible = false
- }
- val latestVersionAPK = "SKIP-v$latestVersionText.apk"
- val apkFile = File(this.getExternalFilesDir(null), latestVersionAPK)
-
- val apkUri = FileProvider.getUriForFile(
- this,
- this.applicationContext.packageName + ".provider",
- apkFile
- )
-
- val intent = Intent(Intent.ACTION_VIEW)
- intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
- intent.flags =
- Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
- this.startActivity(intent)
-
- isUpdateAPKClicked = false
- }
- }
- }
-
- }
-
- RectManager.setMaxRect(this)
-
- val yaml = Yaml().load>(assets.open("skip_config.yaml"))
- SkipConfigManager.setConfig(yaml)
-
- // 清理临时文件
- val directory = this.getExternalFilesDir(null)
- directory?.let {
- it.listFiles()?.forEach { file ->
- file.delete()
- }
- }
- }
-
- override fun onResume() {
- super.onResume()
- accessibilityState = MyUtils.isAccessibilitySettingsOn(this)
- }
-}
-
-
-@Composable
-@Preview(showBackground = true)
-fun MainSurface() {
- AppTheme {
-
- val res = LocalContext.current.resources
-
- PageHeader(res.getString(R.string.app_name), "是一款免费开源的自动跳过开屏广告的工具")
-
-
- Box(
- modifier = Modifier.fillMaxSize(),
- contentAlignment = Alignment.Center
- ) {
- Box(modifier = Modifier.offset(y = (-50).dp)) {
- AccessibilityControlBtn()
- }
- }
-
- Box(
- modifier = Modifier.fillMaxSize(),
- contentAlignment = Alignment.Center
- ) {
- Box(modifier = Modifier.offset(y = (90).dp)) {
- AccessibilityTextBox()
- }
- }
-
- Box(
- modifier = Modifier.fillMaxSize(),
- contentAlignment = Alignment.BottomCenter
- ) {
- TipBox()
- PageFooter()
- }
-
- }
-}
-
-@Composable
-fun PageHeader(title: String, subtitle: String) {
- Column(
- modifier = Modifier
- .fillMaxWidth()
- .padding(top = 60.dp, start = 20.dp)
- ) {
- Text(
- text = title,
- color = Color.White,
- fontSize = 36.sp,
- fontWeight = FontWeight.Bold,
- modifier = Modifier.padding(bottom = 8.dp)
- )
- Text(
- text = subtitle,
- color = Color.White,
- fontSize = 16.sp,
- )
- }
-}
-
-@Composable
-fun AccessibilityTextBox() {
- Row {
- if (accessibilityState) {
- Text(text = "无障碍服务功能: 启用中", color = Color.White)
- } else {
- Text(text = "无障碍服务功能: 未启用", color = Color.White)
- }
-
- }
-}
-
-@Composable
-fun TipBox() {
-
- Column(
- modifier = Modifier
- .background(color = Color.White)
- .height(240.dp)
- .fillMaxWidth()
- .padding(start = 15.dp, top = 10.dp)
- ) {
- Text(
- "操作方式",
- fontWeight = FontWeight.Bold,
- fontSize = 18.sp,
- modifier = Modifier.padding(0.dp, 5.dp, 0.dp, 5.dp)
- )
-
- Row {
- TipText("第一步:进入「")
- ClickableText("后台任务管理", onClick = { clicked -> isBackendTaskBtnClicked = clicked })
- TipText("」,长按「SKIP」,锁定")
- }
-
- Row {
- TipText("第二步:进入「")
- ClickableText("省电策略", onClick = { clicked -> isPowerSavingBtnClicked = clicked })
- TipText("」,无限制")
- }
-
- Row {
- TipText("第三步:进入「")
- ClickableText("自启动管理", onClick = { clicked -> isAutoStartBtnClicked = clicked })
- TipText("」,找到「SKIP」,允许")
- }
-
- Text(
- "注意事项",
- fontWeight = FontWeight.Bold,
- fontSize = 18.sp,
- modifier = Modifier.padding(0.dp, 5.dp, 0.dp, 5.dp)
- )
-
- TipText("由于无障碍服务会在应用进程结束后自动关闭,因此需要完成上述操作开启应用后台运行权限")
-
-
- }
-}
-
-@Composable
-fun TipText(text: String) {
- Text(
- text,
- fontSize = 14.sp,
- color = Color.Gray,
- modifier = Modifier.padding(0.dp, 2.5.dp, 0.dp, 2.5.dp)
- )
-}
-
-
-@Composable
-fun ClickableText(text: String, onClick: (Boolean) -> Unit) {
- val annotatedString = buildAnnotatedString {
- append(text)
- addStyle(
- style = SpanStyle(textDecoration = androidx.compose.ui.text.style.TextDecoration.Underline),
- start = 0,
- end = length
- )
- addStringAnnotation(
- tag = "Clickable",
- annotation = "Details",
- start = 0,
- end = length
- )
- }
-
- ClickableText(
- text = annotatedString,
- modifier = Modifier.padding(0.dp, 2.5.dp, 0.dp, 2.5.dp),
- onClick = { offset ->
- annotatedString.getStringAnnotations("Clickable", offset, offset)
- .firstOrNull()?.let { _ ->
- onClick(true)
- }
- }
- )
-}
-
-
-@Composable
-fun AccessibilityControlBtn() {
- Button(
- onClick = {
- isAccessibilityBtnClicked = true
- },
- contentPadding = PaddingValues(0.dp),
- colors = ButtonDefaults.textButtonColors()
- ) {
- if (accessibilityState) {
- Image(
- modifier = Modifier.size(140.dp, 140.dp),
- painter = painterResource(id = R.drawable.disabled),
- contentDescription = "disabled",
- )
- } else {
- Image(
- modifier = Modifier.size(140.dp, 140.dp),
- painter = painterResource(id = R.drawable.enabled),
- contentDescription = "enabled",
- )
- }
- }
-}
-
-@Composable
-fun PageFooter() {
- val context = LocalContext.current
- val coroutineScope = rememberCoroutineScope()
-
- Row(
- modifier = Modifier
- .fillMaxWidth()
- .height(45.dp)
- .background(color = Color.White),
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.Center
- ) {
- val annotatedString = buildAnnotatedString {
- withStyle(style = SpanStyle(color = Color.Black, fontSize = 12.sp)) {
- append("Github")
- addStringAnnotation(
- tag = "URL",
- annotation = "https://github.com/GuoXiCheng/SKIP",
- start = 0,
- end = 6
- )
- append(" | ")
- append(RectManager.getMaxRect())
- append(" | version " + BuildConfig.VERSION_NAME)
- append(" | ")
- append("检查更新")
- addStringAnnotation(
- tag = "CHECK_UPDATE",
- annotation = "",
- start = length - 4,
- end = length
- )
- }
- }
- ClickableText(
- text = annotatedString,
- onClick = { offset ->
- annotatedString.getStringAnnotations(start = offset, end = offset).firstOrNull()
- ?.let { annotation ->
- when (annotation.tag) {
- "URL" -> {
- val url = annotation.item
- coroutineScope.launch {
- val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
- context.startActivity(intent)
- }
- }
- "CHECK_UPDATE" -> {
- isCheckUpdateBtnClicked = true
- }
- }
- }
- }
- )
- }
-}
-
-
-@Composable
-fun AlertDialog(
- context: Context, title: CharSequence,
- message: CharSequence?, negativeText: CharSequence,
- positiveText: CharSequence, onPositiveButtonClick: () -> Unit
-) {
- MaterialAlertDialogBuilder(context)
- .setTitle(title)
- .setMessage(message)
- .setNegativeButton(negativeText, null)
- .setPositiveButton(positiveText) { _, _ ->
- onPositiveButtonClick()
- }
- .show()
-}
-
-@Composable
-fun ImageDialog() {
- AlertDialog(
- onDismissRequest = { isBackendTaskBtnClicked = false },
- containerColor = Color.White,
- text = {
- Box(modifier = Modifier.fillMaxWidth()) {
- Image(
- painter = painterResource(R.drawable.backend_lock), // 设置要显示的图片
- contentDescription = "Image",
- modifier = Modifier.fillMaxWidth()
- )
- }
- },
- confirmButton = {
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.Center
- ) {
- TextButton(
- onClick = { isBackendTaskBtnClicked = false },
- colors = ButtonDefaults.textButtonColors(contentColor = green)
- ) {
- Text(text = "我知道了")
- }
- }
-
- }
- )
-}
-
-@Composable
-fun ProcessDialog() {
- if (isProcessDialogVisible) {
- AlertDialog(
- onDismissRequest = {
- isProcessDialogVisible = false
- },
- title = {
- Text(text = "正在下载")
- },
- text = {
- Column(
- horizontalAlignment = Alignment.CenterHorizontally,
- verticalArrangement = Arrangement.Center,
- modifier = Modifier.padding(16.dp)
- ) {
- LinearProgressIndicator(progress = downloadProgress)
- Spacer(modifier = Modifier.height(16.dp))
- Text(text = "下载进度:${(downloadProgress * 100).roundToInt()}%")
- }
- },
- confirmButton = {
- },
- dismissButton = {
- }
- )
- }
-}
-
-
+//
+//import android.content.ComponentName
+//import android.content.Context
+//import android.content.Intent
+//import android.net.Uri
+//import android.os.Build
+//import android.os.Bundle
+//import android.provider.Settings
+//import androidx.activity.ComponentActivity
+//import androidx.activity.compose.setContent
+//import androidx.compose.foundation.Image
+//import androidx.compose.foundation.background
+//import androidx.compose.foundation.layout.Arrangement
+//import androidx.compose.foundation.layout.Box
+//import androidx.compose.foundation.layout.Column
+//import androidx.compose.foundation.layout.PaddingValues
+//import androidx.compose.foundation.layout.Row
+//import androidx.compose.foundation.layout.Spacer
+//import androidx.compose.foundation.layout.fillMaxSize
+//import androidx.compose.foundation.layout.fillMaxWidth
+//import androidx.compose.foundation.layout.height
+//import androidx.compose.foundation.layout.offset
+//import androidx.compose.foundation.layout.padding
+//import androidx.compose.foundation.layout.size
+//import androidx.compose.foundation.text.ClickableText
+//import androidx.compose.material3.AlertDialog
+//import androidx.compose.material3.Button
+//import androidx.compose.material3.ButtonDefaults
+//import androidx.compose.material3.LinearProgressIndicator
+//import androidx.compose.material3.Text
+//import androidx.compose.material3.TextButton
+//import androidx.compose.runtime.Composable
+//import androidx.compose.runtime.CompositionLocalProvider
+//import androidx.compose.runtime.getValue
+//import androidx.compose.runtime.mutableStateOf
+//import androidx.compose.runtime.rememberCoroutineScope
+//import androidx.compose.runtime.setValue
+//import androidx.compose.ui.Alignment
+//import androidx.compose.ui.Modifier
+//import androidx.compose.ui.graphics.Color
+//import androidx.compose.ui.platform.LocalContext
+//import androidx.compose.ui.platform.LocalDensity
+//import androidx.compose.ui.res.painterResource
+//import androidx.compose.ui.text.SpanStyle
+//import androidx.compose.ui.text.buildAnnotatedString
+//import androidx.compose.ui.text.font.FontWeight
+//import androidx.compose.ui.text.withStyle
+//import androidx.compose.ui.tooling.preview.Preview
+//import androidx.compose.ui.unit.Density
+//import androidx.compose.ui.unit.dp
+//import androidx.compose.ui.unit.sp
+//import androidx.core.content.FileProvider
+//import com.android.skip.dataclass.PackageInfo
+//import com.android.skip.manager.HttpManager
+//import com.android.skip.manager.RectManager
+//import com.android.skip.manager.SkipConfigManager
+//import com.android.skip.manager.ToastManager
+//import com.android.skip.ui.theme.AppTheme
+//import com.android.skip.ui.theme.green
+//import com.google.android.material.dialog.MaterialAlertDialogBuilder
+//import kotlinx.coroutines.launch
+//import org.yaml.snakeyaml.Yaml
+//import java.io.File
+//import java.util.Locale
+//import kotlin.concurrent.thread
+//import kotlin.math.roundToInt
+//
+//
+//var accessibilityState by mutableStateOf(false)
+//
+//var alertDialogPositiveButtonClickState by mutableStateOf(false)
+//
+//// 无障碍服务启用停用按钮
+//var isAccessibilityBtnClicked by mutableStateOf(false)
+//
+//// 后台任务管理
+//var isBackendTaskBtnClicked by mutableStateOf(false)
+//
+//// 自启动管理
+//var isAutoStartBtnClicked by mutableStateOf(false)
+//
+//// 省电策略按钮
+//var isPowerSavingBtnClicked by mutableStateOf(false)
+//
+//// 检查更新按钮
+//var isCheckUpdateBtnClicked by mutableStateOf(false)
+//
+//// 是否需要更新
+//var isNeedUpdateAPK by mutableStateOf(false)
+//
+//// 最新版本号
+//var latestVersionText by mutableStateOf("")
+//
+//// 立即更新
+//var isUpdateAPKClicked by mutableStateOf(false)
+//
+//// 更新进度对话框
+//var isProcessDialogVisible by mutableStateOf(false)
+//
+//var downloadProgress by mutableStateOf(0f)
+//
+//
+//class MainActivity : ComponentActivity() {
+//
+// private fun openAppInfo() {
+// val packageName = packageName
+// val intent = Intent(
+// Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
+// Uri.parse("package:$packageName")
+// )
+// startActivity(intent)
+// }
+//
+// private fun openAutoStartSettings(context: Context) {
+// try {
+// val intent = Intent()
+//
+// val manufacturer = Build.MANUFACTURER.lowercase(Locale.ENGLISH)
+// when {
+// manufacturer.contains("xiaomi") -> {
+// intent.component = ComponentName(
+// "com.miui.securitycenter",
+// "com.miui.permcenter.autostart.AutoStartManagementActivity"
+// )
+// }
+// manufacturer.contains("oppo") -> {
+// intent.component = ComponentName(
+// "com.coloros.safecenter",
+// "com.coloros.safecenter.permission.startup.StartupAppListActivity"
+// )
+// }
+// manufacturer.contains("vivo") -> {
+// intent.component = ComponentName(
+// "com.vivo.permissionmanager",
+// "com.vivo.permissionmanager.activity.BgStartUpManagerActivity"
+// )
+// }
+// manufacturer.contains("oneplus") -> {
+// intent.component = ComponentName(
+// "com.oneplus.security",
+// "com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity"
+// )
+// }
+// manufacturer.contains("huawei") -> {
+// intent.component = ComponentName(
+// "com.huawei.systemmanager",
+// "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity"
+// )
+// }
+// else -> {
+// openAppInfo()
+// }
+// }
+//
+// context.startActivity(intent)
+// } catch (e: Exception) {
+// openAppInfo()
+// }
+// }
+//
+// private fun openBatteryOptimizationSettings(context: Context) {
+// try {
+// val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
+// intent.data = Uri.parse("package:${context.packageName}")
+// context.startActivity(intent)
+// } catch (e: Exception) {
+// openAppInfo()
+// }
+// }
+//
+// override fun onCreate(savedInstanceState: Bundle?) {
+//
+// super.onCreate(savedInstanceState)
+//
+// setContent {
+//
+// val displayMetrics = LocalContext.current.resources.displayMetrics
+// val widthPixels = displayMetrics.widthPixels
+// val fontScale = LocalDensity.current.fontScale
+//
+// CompositionLocalProvider(
+// LocalDensity provides Density(
+// density = widthPixels / 360.0f,
+// fontScale = fontScale
+// )
+// ) {
+// MainSurface()
+// ProcessDialog()
+// }
+//
+//
+// if (isAccessibilityBtnClicked) {
+// if (!accessibilityState) {
+// AlertDialog(
+// context = this,
+// title = "启用无障碍服务",
+// message = "已下载的应用 > SKIP > 打开「使用SKIP」",
+// negativeText = "再想想",
+// positiveText = "去开启"
+// ) {
+// alertDialogPositiveButtonClickState = true
+// }
+// } else {
+// AlertDialog(
+// context = this,
+// title = "停用无障碍服务",
+// message = "已下载的应用 > SKIP > 关闭「使用SKIP」",
+// negativeText = "再想想",
+// positiveText = "去停用"
+// ) {
+// alertDialogPositiveButtonClickState = true
+// }
+// }
+// isAccessibilityBtnClicked = false
+// }
+//
+// if (isNeedUpdateAPK) {
+// AlertDialog(
+// context = this,
+// title = "发现新版本",
+// message = "${BuildConfig.VERSION_NAME} -> $latestVersionText",
+// negativeText = "暂不更新",
+// positiveText = "立即更新"
+// ) {
+// isUpdateAPKClicked = true
+// }
+// isNeedUpdateAPK = false
+// }
+//
+// when {
+// alertDialogPositiveButtonClickState -> {
+// val intent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS)
+// this.startActivity(intent)
+// alertDialogPositiveButtonClickState = false
+// }
+// isAutoStartBtnClicked -> {
+// openAutoStartSettings(this)
+// isAutoStartBtnClicked = false
+// }
+// isPowerSavingBtnClicked -> {
+// openBatteryOptimizationSettings(this)
+// isPowerSavingBtnClicked = false
+// }
+// isBackendTaskBtnClicked -> {
+// ImageDialog()
+// }
+// isCheckUpdateBtnClicked -> {
+// thread {
+// ToastManager.showToast(this, "开始检查更新")
+// val updateSkipConfigResult =
+// if (HttpManager.updateSkipConfig()) "配置更新成功" else "配置更新失败"
+// ToastManager.showToast(this, updateSkipConfigResult)
+//
+// val latestVersion = HttpManager.getLatestVersion()
+// if (latestVersion != BuildConfig.VERSION_NAME.trim()) {
+// isNeedUpdateAPK = true
+// latestVersionText = latestVersion
+// } else {
+// ToastManager.showToast(this, "当前版本已是最新版")
+// }
+//
+// isCheckUpdateBtnClicked = false
+// }
+// }
+// isUpdateAPKClicked -> {
+// thread {
+// isProcessDialogVisible = true
+// HttpManager.downloadNewAPK(latestVersionText, this) { it ->
+// downloadProgress = it * 0.01f
+// if (it == 100) isProcessDialogVisible = false
+// }
+// val latestVersionAPK = "SKIP-v$latestVersionText.apk"
+// val apkFile = File(this.getExternalFilesDir(null), latestVersionAPK)
+//
+// val apkUri = FileProvider.getUriForFile(
+// this,
+// this.applicationContext.packageName + ".provider",
+// apkFile
+// )
+//
+// val intent = Intent(Intent.ACTION_VIEW)
+// intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
+// intent.flags =
+// Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
+// this.startActivity(intent)
+//
+// isUpdateAPKClicked = false
+// }
+// }
+// }
+//
+// }
+//
+// RectManager.setMaxRect(this)
+//
+// val yaml = Yaml().load>(assets.open("skip_config.yaml"))
+// SkipConfigManager.setConfig(yaml)
+//
+// // 清理临时文件
+// val directory = this.getExternalFilesDir(null)
+// directory?.let {
+// it.listFiles()?.forEach { file ->
+// file.delete()
+// }
+// }
+// }
+//
+// override fun onResume() {
+// super.onResume()
+// accessibilityState = MyUtils.isAccessibilitySettingsOn(this)
+// }
+//}
+//
+//
+//@Composable
+//@Preview(showBackground = true)
+//fun MainSurface() {
+// AppTheme {
+//
+// val res = LocalContext.current.resources
+//
+// PageHeader(res.getString(R.string.app_name), "是一款免费开源的自动跳过开屏广告的工具")
+//
+//
+// Box(
+// modifier = Modifier.fillMaxSize(),
+// contentAlignment = Alignment.Center
+// ) {
+// Box(modifier = Modifier.offset(y = (-50).dp)) {
+// AccessibilityControlBtn()
+// }
+// }
+//
+// Box(
+// modifier = Modifier.fillMaxSize(),
+// contentAlignment = Alignment.Center
+// ) {
+// Box(modifier = Modifier.offset(y = (90).dp)) {
+// AccessibilityTextBox()
+// }
+// }
+//
+// Box(
+// modifier = Modifier.fillMaxSize(),
+// contentAlignment = Alignment.BottomCenter
+// ) {
+// TipBox()
+// PageFooter()
+// }
+//
+// }
+//}
+//
+//@Composable
+//fun PageHeader(title: String, subtitle: String) {
+// Column(
+// modifier = Modifier
+// .fillMaxWidth()
+// .padding(top = 60.dp, start = 20.dp)
+// ) {
+// Text(
+// text = title,
+// color = Color.White,
+// fontSize = 36.sp,
+// fontWeight = FontWeight.Bold,
+// modifier = Modifier.padding(bottom = 8.dp)
+// )
+// Text(
+// text = subtitle,
+// color = Color.White,
+// fontSize = 16.sp,
+// )
+// }
+//}
+//
+//@Composable
+//fun AccessibilityTextBox() {
+// Row {
+// if (accessibilityState) {
+// Text(text = "无障碍服务功能: 启用中", color = Color.White)
+// } else {
+// Text(text = "无障碍服务功能: 未启用", color = Color.White)
+// }
+//
+// }
+//}
+//
+//@Composable
+//fun TipBox() {
+//
+// Column(
+// modifier = Modifier
+// .background(color = Color.White)
+// .height(240.dp)
+// .fillMaxWidth()
+// .padding(start = 15.dp, top = 10.dp)
+// ) {
+// Text(
+// "操作方式",
+// fontWeight = FontWeight.Bold,
+// fontSize = 18.sp,
+// modifier = Modifier.padding(0.dp, 5.dp, 0.dp, 5.dp)
+// )
+//
+// Row {
+// TipText("第一步:进入「")
+// ClickableText("后台任务管理", onClick = { clicked -> isBackendTaskBtnClicked = clicked })
+// TipText("」,长按「SKIP」,锁定")
+// }
+//
+// Row {
+// TipText("第二步:进入「")
+// ClickableText("省电策略", onClick = { clicked -> isPowerSavingBtnClicked = clicked })
+// TipText("」,无限制")
+// }
+//
+// Row {
+// TipText("第三步:进入「")
+// ClickableText("自启动管理", onClick = { clicked -> isAutoStartBtnClicked = clicked })
+// TipText("」,找到「SKIP」,允许")
+// }
+//
+// Text(
+// "注意事项",
+// fontWeight = FontWeight.Bold,
+// fontSize = 18.sp,
+// modifier = Modifier.padding(0.dp, 5.dp, 0.dp, 5.dp)
+// )
+//
+// TipText("由于无障碍服务会在应用进程结束后自动关闭,因此需要完成上述操作开启应用后台运行权限")
+//
+//
+// }
+//}
+//
+//@Composable
+//fun TipText(text: String) {
+// Text(
+// text,
+// fontSize = 14.sp,
+// color = Color.Gray,
+// modifier = Modifier.padding(0.dp, 2.5.dp, 0.dp, 2.5.dp)
+// )
+//}
+//
+//
+//@Composable
+//fun ClickableText(text: String, onClick: (Boolean) -> Unit) {
+// val annotatedString = buildAnnotatedString {
+// append(text)
+// addStyle(
+// style = SpanStyle(textDecoration = androidx.compose.ui.text.style.TextDecoration.Underline),
+// start = 0,
+// end = length
+// )
+// addStringAnnotation(
+// tag = "Clickable",
+// annotation = "Details",
+// start = 0,
+// end = length
+// )
+// }
+//
+// ClickableText(
+// text = annotatedString,
+// modifier = Modifier.padding(0.dp, 2.5.dp, 0.dp, 2.5.dp),
+// onClick = { offset ->
+// annotatedString.getStringAnnotations("Clickable", offset, offset)
+// .firstOrNull()?.let { _ ->
+// onClick(true)
+// }
+// }
+// )
+//}
+//
+//
+//@Composable
+//fun AccessibilityControlBtn() {
+// Button(
+// onClick = {
+// isAccessibilityBtnClicked = true
+// },
+// contentPadding = PaddingValues(0.dp),
+// colors = ButtonDefaults.textButtonColors()
+// ) {
+// if (accessibilityState) {
+// Image(
+// modifier = Modifier.size(140.dp, 140.dp),
+// painter = painterResource(id = R.drawable.disabled),
+// contentDescription = "disabled",
+// )
+// } else {
+// Image(
+// modifier = Modifier.size(140.dp, 140.dp),
+// painter = painterResource(id = R.drawable.enabled),
+// contentDescription = "enabled",
+// )
+// }
+// }
+//}
+//
+//@Composable
+//fun PageFooter() {
+// val context = LocalContext.current
+// val coroutineScope = rememberCoroutineScope()
+//
+// Row(
+// modifier = Modifier
+// .fillMaxWidth()
+// .height(45.dp)
+// .background(color = Color.White),
+// verticalAlignment = Alignment.CenterVertically,
+// horizontalArrangement = Arrangement.Center
+// ) {
+// val annotatedString = buildAnnotatedString {
+// withStyle(style = SpanStyle(color = Color.Black, fontSize = 12.sp)) {
+// append("Github")
+// addStringAnnotation(
+// tag = "URL",
+// annotation = "https://github.com/GuoXiCheng/SKIP",
+// start = 0,
+// end = 6
+// )
+// append(" | ")
+// append(RectManager.getMaxRect())
+// append(" | version " + BuildConfig.VERSION_NAME)
+// append(" | ")
+// append("检查更新")
+// addStringAnnotation(
+// tag = "CHECK_UPDATE",
+// annotation = "",
+// start = length - 4,
+// end = length
+// )
+// }
+// }
+// ClickableText(
+// text = annotatedString,
+// onClick = { offset ->
+// annotatedString.getStringAnnotations(start = offset, end = offset).firstOrNull()
+// ?.let { annotation ->
+// when (annotation.tag) {
+// "URL" -> {
+// val url = annotation.item
+// coroutineScope.launch {
+// val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
+// context.startActivity(intent)
+// }
+// }
+// "CHECK_UPDATE" -> {
+// isCheckUpdateBtnClicked = true
+// }
+// }
+// }
+// }
+// )
+// }
+//}
+//
+//
+//@Composable
+//fun AlertDialog(
+// context: Context, title: CharSequence,
+// message: CharSequence?, negativeText: CharSequence,
+// positiveText: CharSequence, onPositiveButtonClick: () -> Unit
+//) {
+// MaterialAlertDialogBuilder(context)
+// .setTitle(title)
+// .setMessage(message)
+// .setNegativeButton(negativeText, null)
+// .setPositiveButton(positiveText) { _, _ ->
+// onPositiveButtonClick()
+// }
+// .show()
+//}
+//
+//@Composable
+//fun ImageDialog() {
+// AlertDialog(
+// onDismissRequest = { isBackendTaskBtnClicked = false },
+// containerColor = Color.White,
+// text = {
+// Box(modifier = Modifier.fillMaxWidth()) {
+// Image(
+// painter = painterResource(R.drawable.backend_lock), // 设置要显示的图片
+// contentDescription = "Image",
+// modifier = Modifier.fillMaxWidth()
+// )
+// }
+// },
+// confirmButton = {
+// Row(
+// modifier = Modifier.fillMaxWidth(),
+// horizontalArrangement = Arrangement.Center
+// ) {
+// TextButton(
+// onClick = { isBackendTaskBtnClicked = false },
+// colors = ButtonDefaults.textButtonColors(contentColor = green)
+// ) {
+// Text(text = "我知道了")
+// }
+// }
+//
+// }
+// )
+//}
+//
+//@Composable
+//fun ProcessDialog() {
+// if (isProcessDialogVisible) {
+// AlertDialog(
+// onDismissRequest = {
+// isProcessDialogVisible = false
+// },
+// title = {
+// Text(text = "正在下载")
+// },
+// text = {
+// Column(
+// horizontalAlignment = Alignment.CenterHorizontally,
+// verticalArrangement = Arrangement.Center,
+// modifier = Modifier.padding(16.dp)
+// ) {
+// LinearProgressIndicator(progress = downloadProgress)
+// Spacer(modifier = Modifier.height(16.dp))
+// Text(text = "下载进度:${(downloadProgress * 100).roundToInt()}%")
+// }
+// },
+// confirmButton = {
+// },
+// dismissButton = {
+// }
+// )
+// }
+//}
+//
+//
diff --git a/app/src/main/java/com/android/skip/MyUtils.kt b/app/src/main/java/com/android/skip/MyUtils.kt
deleted file mode 100644
index 20013cdb..00000000
--- a/app/src/main/java/com/android/skip/MyUtils.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.android.skip
-import android.content.Context
-import android.provider.Settings
-import android.text.TextUtils
-import com.android.skip.service.MyAccessibilityService
-
-object MyUtils {
- /**
- * 判断无障碍服务是否已经启用
- */
- fun isAccessibilitySettingsOn(mContext: Context): Boolean {
- var accessibilityEnabled = 0
- val service = mContext.packageName + "/" + MyAccessibilityService::class.java.canonicalName
- try {
- accessibilityEnabled = Settings.Secure.getInt(
- mContext.applicationContext.contentResolver,
- android.provider.Settings.Secure.ACCESSIBILITY_ENABLED
- )
- } catch (e: Settings.SettingNotFoundException) {
- }
- val mStringColonSplitter = TextUtils.SimpleStringSplitter(':')
- if (accessibilityEnabled == 1) {
- val settingValue = Settings.Secure.getString(
- mContext.applicationContext.contentResolver,
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
- )
- if (settingValue != null) {
- mStringColonSplitter.setString(settingValue)
- while (mStringColonSplitter.hasNext()) {
- val accessibilityService = mStringColonSplitter.next()
- if (accessibilityService.equals(service, ignoreCase = true)) {
- return true
- }
- }
- }
- }
- return false
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/android/skip/NewMainActivity.kt b/app/src/main/java/com/android/skip/NewMainActivity.kt
index 77261c1b..a802ef3a 100644
--- a/app/src/main/java/com/android/skip/NewMainActivity.kt
+++ b/app/src/main/java/com/android/skip/NewMainActivity.kt
@@ -1,6 +1,10 @@
package com.android.skip
+import android.content.Context
+import android.content.Intent
import android.os.Bundle
+import android.provider.Settings
+import android.text.TextUtils
import androidx.activity.viewModels
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -11,22 +15,44 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import androidx.core.content.FileProvider
import androidx.lifecycle.lifecycleScope
import com.android.skip.compose.AboutButton
+import com.android.skip.compose.ConfirmDialog
+import com.android.skip.compose.DownloadProcessDialog
import com.android.skip.compose.KeepAliveButton
import com.android.skip.compose.SettingsButton
import com.android.skip.compose.StartButton
import com.android.skip.compose.WhitelistButton
import com.android.skip.dataclass.PackageInfoV2
+import com.android.skip.manager.HttpManager
import com.android.skip.manager.SkipConfigManagerV2
import com.android.skip.manager.WhitelistManager
+import com.android.skip.service.MyAccessibilityService
+import com.android.skip.utils.DataStoreUtils
import com.android.skip.viewmodel.StartButtonViewModel
import org.yaml.snakeyaml.Yaml
+import java.io.File
+import kotlin.concurrent.thread
+var showUpdateDialog by mutableStateOf(false)
+
+var showDownloadDialog by mutableStateOf(false)
+
+var showApkInstallDialog by mutableStateOf(false)
+
+var apkDownloadProgress by mutableStateOf(0f)
+
+var apkLatestVersionText by mutableStateOf(BuildConfig.VERSION_NAME.trim())
class NewMainActivity : BaseActivity() {
private val startButtonViewModel: StartButtonViewModel by viewModels()
@@ -44,6 +70,7 @@ class NewMainActivity : BaseActivity() {
@Composable
override fun ProvideContent() {
+ val context = LocalContext.current
Column(
modifier = Modifier
.fillMaxSize()
@@ -53,7 +80,7 @@ class NewMainActivity : BaseActivity() {
) {
Row {
Text(
- text = "SKIP",
+ text = stringResource(id = R.string.app_name),
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.onBackground
@@ -64,12 +91,110 @@ class NewMainActivity : BaseActivity() {
KeepAliveButton()
SettingsButton()
AboutButton()
+
+ if (showUpdateDialog) {
+ ConfirmDialog(
+ title = "发现新版本",
+ content = "是否立即下载更新?",
+ onDismiss = { showUpdateDialog = false },
+ onAllow = {
+ showUpdateDialog = false
+ showDownloadDialog = true
+ })
+ }
+
+ if (showDownloadDialog) {
+ DownloadProcessDialog()
+
+ thread {
+ HttpManager.downloadNewAPK(apkLatestVersionText, context) { it ->
+ apkDownloadProgress = it * 0.01f
+ if (it == 100) {
+ showDownloadDialog = false
+ showApkInstallDialog = true
+ }
+ }
+ }
+ }
+
+ if (showApkInstallDialog) {
+ ConfirmDialog(
+ title = "下载完成",
+ content = "是否立即安装新版本?",
+ onDismiss = { showApkInstallDialog = false },
+ onAllow = {
+ showApkInstallDialog = false
+
+ val filename = "SKIP-v$apkLatestVersionText.apk"
+ val apkFile = File(context.getExternalFilesDir(null), filename)
+ val apkUri = FileProvider.getUriForFile(
+ context,
+ context.applicationContext.packageName + ".provider",
+ apkFile
+ )
+
+ val intent = Intent(Intent.ACTION_VIEW)
+ intent.setDataAndType(apkUri, "application/vnd.android.package-archive")
+ intent.flags =
+ Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
+ context.startActivity(intent)
+ })
+ }
}
}
override fun onResume() {
super.onResume()
- startButtonViewModel.changeButtonState(MyUtils.isAccessibilitySettingsOn(this))
+ startButtonViewModel.changeButtonState(isAccessibilitySettingsOn(this))
WhitelistManager.setWhitelist(lifecycleScope, applicationContext)
+
+ if (DataStoreUtils.getSyncData(SKIP_AUTO_SYNC_CONFIG, false)) {
+ thread {
+ HttpManager.updateSkipConfigV2()
+ }
+ }
+
+ if (DataStoreUtils.getSyncData(SKIP_AUTO_CHECK_UPDATE, false)) {
+ thread {
+ val latestVersion = HttpManager.getLatestVersion()
+ if (latestVersion != BuildConfig.VERSION_NAME.trim()) {
+ apkLatestVersionText = latestVersion
+ showUpdateDialog = true
+ }
+ }
+ }
+ }
+}
+
+/**
+ * 判断无障碍服务是否已经启用
+ */
+fun isAccessibilitySettingsOn(mContext: Context): Boolean {
+ var accessibilityEnabled = 0
+ val service = mContext.packageName + "/" + MyAccessibilityService::class.java.canonicalName
+ try {
+ accessibilityEnabled = Settings.Secure.getInt(
+ mContext.applicationContext.contentResolver,
+ android.provider.Settings.Secure.ACCESSIBILITY_ENABLED
+ )
+ } catch (e: Settings.SettingNotFoundException) {
+ e.printStackTrace()
+ }
+ val mStringColonSplitter = TextUtils.SimpleStringSplitter(':')
+ if (accessibilityEnabled == 1) {
+ val settingValue = Settings.Secure.getString(
+ mContext.applicationContext.contentResolver,
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES
+ )
+ if (settingValue != null) {
+ mStringColonSplitter.setString(settingValue)
+ while (mStringColonSplitter.hasNext()) {
+ val accessibilityService = mStringColonSplitter.next()
+ if (accessibilityService.equals(service, ignoreCase = true)) {
+ return true
+ }
+ }
+ }
}
+ return false
}
\ No newline at end of file
diff --git a/app/src/main/java/com/android/skip/SettingsActivity.kt b/app/src/main/java/com/android/skip/SettingsActivity.kt
index dcfe9b39..22b11404 100644
--- a/app/src/main/java/com/android/skip/SettingsActivity.kt
+++ b/app/src/main/java/com/android/skip/SettingsActivity.kt
@@ -57,14 +57,14 @@ fun SettingsActivityInterface(onBackClick: () -> Unit) {
val checkUpdateVersion = remember {
mutableStateOf(
DataStoreUtils.getSyncData(
- SKIP_AUTO_CHECK_UPDATE, true
+ SKIP_AUTO_CHECK_UPDATE, false
)
)
}
val checkUpdateConfig = remember {
mutableStateOf(
DataStoreUtils.getSyncData(
- SKIP_AUTO_SYNC_CONFIG, true
+ SKIP_AUTO_SYNC_CONFIG, false
)
)
}
diff --git a/app/src/main/java/com/android/skip/compose/CheckNewVersionButton.kt b/app/src/main/java/com/android/skip/compose/CheckNewVersionButton.kt
deleted file mode 100644
index f4b6eccd..00000000
--- a/app/src/main/java/com/android/skip/compose/CheckNewVersionButton.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.android.skip.compose
-
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.ui.res.stringResource
-import com.android.skip.R
-
-@Composable
-fun CheckNewVersionButton() {
- val showDialog = remember { mutableStateOf(false) }
-
- FlatButton(
- content = {
- RowContent(stringResource(id = R.string.main_check_new_version), null, {
- ResourceIcon(
- iconResource = R.drawable.sync
- )
- })
- }
- ) {
- showDialog.value = true
- }
-
- if (showDialog.value) {
- ConfirmDialog(
- title = "发现新版本",
- content = "是否立即下载更新?",
- onDismiss = { showDialog.value = false },
- onAllow = {
- showDialog.value = false
- })
- }
-}
diff --git a/app/src/main/java/com/android/skip/compose/ConfigUpdateButton.kt b/app/src/main/java/com/android/skip/compose/ConfigUpdateButton.kt
deleted file mode 100644
index b7a2b7ae..00000000
--- a/app/src/main/java/com/android/skip/compose/ConfigUpdateButton.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.android.skip.compose
-
-import androidx.compose.runtime.Composable
-import com.android.skip.R
-
-@Composable
-fun ConfigUpdateButton() {
- FlatButton(
- content = {
- RowContent("点此同步配置", null, { ResourceIcon(iconResource = R.drawable.lists) })
- }) {
-
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/android/skip/compose/ConfirmDialog.kt b/app/src/main/java/com/android/skip/compose/ConfirmDialog.kt
index b754f5a9..0206038f 100644
--- a/app/src/main/java/com/android/skip/compose/ConfirmDialog.kt
+++ b/app/src/main/java/com/android/skip/compose/ConfirmDialog.kt
@@ -1,5 +1,7 @@
package com.android.skip.compose
+import android.content.res.Configuration
+import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -10,6 +12,7 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonColors
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
@@ -20,9 +23,13 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.window.Dialog
+import com.android.skip.R
+import com.android.skip.themeTypeState
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -32,6 +39,7 @@ fun ConfirmDialog(
onDismiss: () -> Unit,
onAllow: () -> Unit
) {
+ val darkTheme = isSystemInDarkTheme()
Dialog(onDismissRequest = { /* 点击外部不关闭对话框 */ }) {
Card(
modifier = Modifier.height(200.dp),
@@ -65,10 +73,12 @@ fun ConfirmDialog(
Button(
onClick = onDismiss,
modifier = Modifier.weight(1f),
- colors = ButtonDefaults.buttonColors(Color(0xFFE0E0E0))
+ colors = if (darkTheme || themeTypeState.value == Configuration.UI_MODE_NIGHT_YES) ButtonDefaults.buttonColors(
+ Color(0xFF454545)
+ ) else ButtonDefaults.buttonColors(Color(0xFFF0F0F0))
) {
Text(
- text = "拒绝",
+ text = stringResource(id = R.string.dialog_confirm_dismiss),
color = Color(0xFFc3c3c3),
fontSize = 16.sp
)
@@ -82,7 +92,7 @@ fun ConfirmDialog(
)
) {
Text(
- text = "允许",
+ text = stringResource(id = R.string.dialog_confirm_allow),
color = Color.White,
fontSize = 16.sp
)
diff --git a/app/src/main/java/com/android/skip/compose/DownloadProcessDialog.kt b/app/src/main/java/com/android/skip/compose/DownloadProcessDialog.kt
new file mode 100644
index 00000000..7312404c
--- /dev/null
+++ b/app/src/main/java/com/android/skip/compose/DownloadProcessDialog.kt
@@ -0,0 +1,48 @@
+package com.android.skip.compose
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.AlertDialog
+import androidx.compose.material3.LinearProgressIndicator
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import com.android.skip.apkDownloadProgress
+import kotlin.math.roundToInt
+
+@Composable
+fun DownloadProcessDialog() {
+ AlertDialog(
+ onDismissRequest = {},
+ title = {
+ Box(
+ contentAlignment = Alignment.Center,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(horizontal = 16.dp)
+ ) {
+ Text(text = "正在下载")
+ }
+ },
+ text = {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center,
+ modifier = Modifier.padding(16.dp)
+ ) {
+ LinearProgressIndicator(progress = apkDownloadProgress)
+ Spacer(modifier = Modifier.height(16.dp))
+ Text(text = "下载进度:${(apkDownloadProgress * 100).roundToInt()}%")
+ }
+ },
+ confirmButton = {},
+ dismissButton = {}
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/android/skip/compose/OpenBrowserDialog.kt b/app/src/main/java/com/android/skip/compose/OpenBrowserDialog.kt
new file mode 100644
index 00000000..43225477
--- /dev/null
+++ b/app/src/main/java/com/android/skip/compose/OpenBrowserDialog.kt
@@ -0,0 +1,26 @@
+package com.android.skip.compose
+
+import android.content.Intent
+import android.net.Uri
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.MutableState
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
+import com.android.skip.R
+
+@Composable
+fun OpenBrowserDialog(openName: String, openUrl: String, showDialog: MutableState) {
+ val context = LocalContext.current
+
+ if (showDialog.value) {
+ ConfirmDialog(
+ title = stringResource(id = R.string.dialog_open_browser_title),
+ content = stringResource(id = R.string.dialog_open_browser_content) + openName,
+ onDismiss = { showDialog.value = false },
+ onAllow = {
+ val intent = Intent(Intent.ACTION_VIEW, Uri.parse(openUrl))
+ context.startActivity(intent)
+ showDialog.value = false
+ })
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/android/skip/manager/HttpManager.kt b/app/src/main/java/com/android/skip/manager/HttpManager.kt
index e219fcef..6c21c6fa 100644
--- a/app/src/main/java/com/android/skip/manager/HttpManager.kt
+++ b/app/src/main/java/com/android/skip/manager/HttpManager.kt
@@ -26,6 +26,19 @@ object HttpManager {
}
}
+ fun updateSkipConfigV2() {
+ try {
+ val request = Request.Builder().url("$BASE_URL/skip_config_v2.yaml").build()
+ client.newCall(request).execute().use {response ->
+ val bodyContent = response.body()?.string()
+ val yaml = Yaml().load(bodyContent)
+ SkipConfigManagerV2.setConfig(yaml)
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
fun getLatestVersion(): String {
return try {
val request = Request.Builder().url("$BASE_URL/latest_version.txt").build()
@@ -62,7 +75,7 @@ object HttpManager {
}
}
} catch (e: Exception) {
- LogManager.i(e.toString())
+ e.printStackTrace()
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/android/skip/manager/LogManager.kt b/app/src/main/java/com/android/skip/manager/LogManager.kt
deleted file mode 100644
index d2bc96dc..00000000
--- a/app/src/main/java/com/android/skip/manager/LogManager.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.android.skip.manager
-
-import android.util.Log
-
-object LogManager {
- private const val TAG = "SKIPS"
-
- private const val DEBUG = false
-
- fun i(message: String) {
- if (DEBUG) {
- Log.i(TAG, message)
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/android/skip/ui/theme/Theme.kt b/app/src/main/java/com/android/skip/ui/theme/Theme.kt
index 2e761302..c418c3c7 100644
--- a/app/src/main/java/com/android/skip/ui/theme/Theme.kt
+++ b/app/src/main/java/com/android/skip/ui/theme/Theme.kt
@@ -10,15 +10,12 @@ import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.MutableState
import androidx.compose.runtime.SideEffect
-import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.core.view.ViewCompat
-import com.android.skip.SKIP_APP_THEME
-import com.android.skip.utils.DataStoreUtils
+import com.android.skip.themeTypeState
private val darkColorScheme = darkColorScheme(
primary = Purple80,
@@ -37,7 +34,6 @@ private val lightColorScheme = lightColorScheme(
)
-
@Composable
fun AppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
@@ -50,6 +46,7 @@ fun AppTheme(
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
+
darkTheme -> darkColorScheme
else -> lightColorScheme
}
@@ -58,6 +55,9 @@ fun AppTheme(
SideEffect {
(view.context as Activity).window.statusBarColor = colorScheme.background.toArgb()
ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme
+ // 根据主题设置状态栏图标和文字颜色
+ ViewCompat.getWindowInsetsController((view.context as Activity).window.decorView)?.isAppearanceLightStatusBars =
+ !darkTheme || themeTypeState.value != Configuration.UI_MODE_NIGHT_YES
}
}
diff --git a/app/src/main/res/drawable-v24/backend_lock.jpg b/app/src/main/res/drawable-v24/backend_lock.jpg
index 23392b6c..0aa9f653 100644
Binary files a/app/src/main/res/drawable-v24/backend_lock.jpg and b/app/src/main/res/drawable-v24/backend_lock.jpg differ
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 4b854c5b..39655cb8 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -5,10 +5,12 @@
检查更新
关于
- SKIP 源代码地址
+ 源代码
https://github.com/GuoXiCheng/SKIP
- SKIP Docs文档地址
+ 文档
https://guoxicheng.top/projects/SKIP-Docs
+ 当前版本号:
+ 当前分辨率:
设置
浅色模式
@@ -32,7 +34,13 @@
后台任务管理
进入最近打开程序页面,长按「SKIP」卡片,锁定
请注意
- 以上操作方法可能仅适用于MIUI手机,其他品牌手机请自行查询相应的应用保活方法
+ 以上操作方法可能仅适用于MIUI或HyperOS,其他系统手机请自行查询相应的应用保活方法
+ 如何实现应用后台保活
应用白名单
+
+ 允许
+ 拒绝
+ 启动浏览器
+ 是否要通过浏览器访问
\ No newline at end of file