Skip to content

Commit

Permalink
Merge pull request #193 from GuoXiCheng/dev-c
Browse files Browse the repository at this point in the history
add MyForeground Service
  • Loading branch information
GuoXiCheng authored Aug 12, 2024
2 parents e3c3a60 + 6a7f22e commit c14f157
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 60 deletions.
5 changes: 5 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@
android:enabled="true"
android:foregroundServiceType="mediaProjection"
/>

<service
android:name=".service.MyForegroundService"
android:enabled="true"
/>
</application>

</manifest>
145 changes: 86 additions & 59 deletions app/src/main/java/com/android/skip/KeepAliveActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ 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 com.android.skip.service.MyAccessibilityService
import com.android.skip.utils.Constants
import com.android.skip.utils.DataStoreUtils
import com.blankj.utilcode.util.ServiceUtils.startService
import java.net.URLEncoder

class KeepAliveActivity : BaseActivity() {
Expand All @@ -26,68 +30,91 @@ class KeepAliveActivity : BaseActivity() {
finish()
}
}
}

@Composable
fun KeepAliveInterface(onBackClick: () -> Unit) {
val context = LocalContext.current
val showPicDialog = remember { mutableStateOf(false) }
val showBrowserDialog = remember { mutableStateOf(false) }
ScaffoldPage(stringResource(id = R.string.alive), onBackClick = onBackClick, content = {
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) }
)
}) {
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
intent.data = Uri.parse("package:${context.packageName}")
context.startActivity(intent)
}
FlatButton(content = {
RowContent(
stringResource(id = R.string.alive_self_start_title),
stringResource(id = R.string.alive_self_start_subtitle),
{ ResourceIcon(iconResource = R.drawable.counter_2) }
)
}) {
val intent = Intent()
intent.component = ComponentName(
"com.miui.securitycenter",
"com.miui.permcenter.autostart.AutoStartManagementActivity"
)
context.startActivity(intent)
}
FlatButton(content = {
RowContent(
stringResource(id = R.string.alive_backstage_title),
stringResource(id = R.string.alive_backstage_subtitle),
{ ResourceIcon(iconResource = R.drawable.counter_3) }
)
}) {
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) }
@Composable
fun KeepAliveInterface(onBackClick: () -> Unit) {
val context = LocalContext.current
val showPicDialog = remember { mutableStateOf(false) }
val showBrowserDialog = remember { mutableStateOf(false) }
val checkForegroundAccessibility = remember {
mutableStateOf(
DataStoreUtils.getSyncData(Constants.SKIP_FOREGROUND_ACCESSIBILITY, false),
)
}) {
showBrowserDialog.value = true
}
})
ScaffoldPage(stringResource(id = R.string.alive), onBackClick = onBackClick, content = {
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) }
)
}) {
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
intent.data = Uri.parse("package:${context.packageName}")
context.startActivity(intent)
}
FlatButton(content = {
RowContent(
stringResource(id = R.string.alive_self_start_title),
stringResource(id = R.string.alive_self_start_subtitle),
{ ResourceIcon(iconResource = R.drawable.counter_2) }
)
}) {
val intent = Intent()
intent.component = ComponentName(
"com.miui.securitycenter",
"com.miui.permcenter.autostart.AutoStartManagementActivity"
)
context.startActivity(intent)
}
FlatButton(content = {
RowContent(
stringResource(id = R.string.alive_backstage_title),
stringResource(id = R.string.alive_backstage_subtitle),
{ ResourceIcon(iconResource = R.drawable.counter_3) }
)
}) {
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) }
)
}) {
showBrowserDialog.value = true
}
FlatButton(content = {
RowContent(
stringResource(id = R.string.alive_foreground_service_title),
stringResource(id = R.string.alive_foreground_service_subtitle),
{ ResourceIcon(iconResource = R.drawable.counter_4) },
checkForegroundAccessibility.value,
{
checkForegroundAccessibility.value = it
DataStoreUtils.putSyncData(Constants.SKIP_FOREGROUND_ACCESSIBILITY, it)

val intent = Intent(Constants.FOREGROUND_ACCESSIBILITY_RECEIVER_ACTION)
intent.putExtra(Constants.FOREGROUND_ACCESSIBILITY_RECEIVER_ENABLED, it)
intent.setPackage(packageName)
sendBroadcast(intent)
}
)
})
})

val searchContent = Build.MANUFACTURER + stringResource(id = R.string.alive_warn_search_content)
OpenBrowserDialog(
openName = searchContent,
openUrl = createBaiduSearchUrl(searchContent),
showDialog = showBrowserDialog
)
val searchContent = Build.MANUFACTURER + stringResource(id = R.string.alive_warn_search_content)
OpenBrowserDialog(
openName = searchContent,
openUrl = createBaiduSearchUrl(searchContent),
showDialog = showBrowserDialog
)
}

private fun createBaiduSearchUrl(query: String): String {
return "https://www.baidu.com/s?wd=${URLEncoder.encode(query, "UTF-8")}"
}
}

fun createBaiduSearchUrl(query: String): String {
return "https://www.baidu.com/s?wd=${URLEncoder.encode(query, "UTF-8")}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ package com.android.skip.service

import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.GestureDescription
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Path
import android.graphics.Rect
import android.os.Build
import android.view.KeyEvent
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import androidx.annotation.RequiresApi
import com.android.skip.SKIP_LAYOUT_INSPECT
import com.android.skip.SKIP_PERMIT_NOTICE
import com.android.skip.handler.BoundsHandler
Expand All @@ -16,8 +21,10 @@ import com.android.skip.handler.TextNodeHandler
import com.android.skip.manager.AnalyticsManager
import com.android.skip.manager.ToastManager
import com.android.skip.manager.WhitelistManager
import com.android.skip.utils.Constants
import com.android.skip.utils.DataStoreUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ServiceUtils

data class MyNode(val node: AccessibilityNodeInfo, val depth: Int)

Expand All @@ -27,6 +34,7 @@ class MyAccessibilityService : AccessibilityService() {
private val boundsHandler = BoundsHandler()
private var isLayoutInspect = false
private var layoutInspectClassName: String? = null
private lateinit var foregroundAccessibilityReceiver: ForegroundAccessibilityChangeReceiver

init {
textNodeHandler.setNextHandler(idNodeHandler).setNextHandler(boundsHandler)
Expand Down Expand Up @@ -59,7 +67,7 @@ class MyAccessibilityService : AccessibilityService() {
click(this, rect)
}
} catch (e: Exception) {
LogUtils.e(e)
// LogUtils.e(e)
} finally {
AnalyticsManager.increaseScanCount()
}
Expand Down Expand Up @@ -155,4 +163,45 @@ class MyAccessibilityService : AccessibilityService() {
false
}
}

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
override fun onServiceConnected() {
super.onServiceConnected()

val intentFilter = IntentFilter(Constants.FOREGROUND_ACCESSIBILITY_RECEIVER_ACTION)
foregroundAccessibilityReceiver = ForegroundAccessibilityChangeReceiver()
registerReceiver(foregroundAccessibilityReceiver, intentFilter, RECEIVER_NOT_EXPORTED)

if (DataStoreUtils.getSyncData(Constants.SKIP_FOREGROUND_ACCESSIBILITY, false)) {
val intent = Intent(this, MyForegroundService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent);
} else {
startService(intent);
}
}
}

override fun onDestroy() {
super.onDestroy()
unregisterReceiver(foregroundAccessibilityReceiver)
}

inner class ForegroundAccessibilityChangeReceiver: BroadcastReceiver() {
override fun onReceive(p0: Context?, p1: Intent?) {
if (p1 != null && p1.action.equals(Constants.FOREGROUND_ACCESSIBILITY_RECEIVER_ACTION)) {
val enabled = p1.getBooleanExtra(Constants.FOREGROUND_ACCESSIBILITY_RECEIVER_ENABLED, false)
val intent = Intent(this@MyAccessibilityService, MyForegroundService::class.java)
if (enabled) { // start foreground service
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(intent);
} else {
startService(intent);
}
} else { // stop foreground service
stopService(intent)
}
}
}
}
}
40 changes: 40 additions & 0 deletions app/src/main/java/com/android/skip/service/MyForegroundService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.android.skip.service

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import com.android.skip.NewMainActivity
import com.android.skip.R

class MyForegroundService: Service() {
override fun onBind(p0: Intent?): IBinder? {
TODO("Not yet implemented")
}

override fun onCreate() {
super.onCreate()

val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel("skip_foreground_service", "SKIP 前台服务", NotificationManager.IMPORTANCE_DEFAULT)
manager.createNotificationChannel(channel)
}
val it = Intent(this, NewMainActivity::class.java)
val pi = PendingIntent.getActivity(this, 0, it, PendingIntent.FLAG_IMMUTABLE)
val notification = NotificationCompat.Builder(this, "skip_foreground_service")
.setContentTitle("SKIP 前台服务")
.setContentText("SKIP 前台服务运行中")
.setSmallIcon(R.drawable.warning)
.setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.warning))
.setContentIntent(pi)
.build()
startForeground(1, notification)
}
}
9 changes: 9 additions & 0 deletions app/src/main/java/com/android/skip/utils/Constants.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.android.skip.utils

object Constants {
const val FOREGROUND_ACCESSIBILITY_RECEIVER_ACTION = "SKIP_FOREGROUND_ACCESSIBILITY_RECEIVER_ACTION"

const val FOREGROUND_ACCESSIBILITY_RECEIVER_ENABLED = "SKIP_FOREGROUND_ACCESSIBILITY_RECEIVER_ENABLED"

const val SKIP_FOREGROUND_ACCESSIBILITY = "SKIP_FOREGROUND_ACCESSIBILITY"
}
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/counter_4.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:pathData="M480,880q-83,0 -156,-31.5T197,763q-54,-54 -85.5,-127T80,480q0,-83 31.5,-156T197,197q54,-54 127,-85.5T480,80q83,0 156,31.5T763,197q54,54 85.5,127T880,480q0,83 -31.5,156T763,763q-54,54 -127,85.5T480,880ZM480,800q134,0 227,-93t93,-227q0,-134 -93,-227t-227,-93q-134,0 -227,93t-93,227q0,134 93,227t227,93ZM480,480ZM520,680h80v-400h-80v160h-80v-160h-80v240h160v160Z"
android:fillColor="#000000"/>
</vector>
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
<string name="alive_warn_title">请注意</string>
<string name="alive_warn_subtitle">以上操作方法可能仅适用于MIUI或HyperOS,其他系统手机请自行查询相应的应用保活方法</string>
<string name="alive_warn_search_content">如何实现应用后台保活</string>
<string name="alive_foreground_service_title">前台服务</string>
<string name="alive_foreground_service_subtitle">是否允许以前台服务方式运行无障碍服务</string>

<string name="whitelist">应用白名单</string>

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit c14f157

Please sign in to comment.