feat: http tile

This commit is contained in:
lisonge 2024-09-28 15:35:26 +08:00
parent 1dbb993efc
commit 0decf9a854
11 changed files with 106 additions and 29 deletions

View File

@ -114,9 +114,16 @@ android {
debug {
versionNameSuffix = vnSuffix
applicationIdSuffix = ".debug"
resValue("string", "app_name", "GKD-debug")
resValue("string", "capture_label", "捕获快照-debug")
resValue("string", "import_desc", "GKD-debug-导入数据")
// add "debug" suffix
listOf(
"app_name" to "GKD",
"capture_snapshot" to "捕获快照",
"import_data" to "导入数据",
"http_server" to "HTTP服务",
).forEach {
resValue("string", it.first, it.second + "-debug")
}
}
}
productFlavors {

View File

@ -6,7 +6,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<!-- 低版本Android截屏, Android 11 上可以使用无障碍 takeScreenshot 截屏 -->
<!-- snapshot screenshot -->
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION"
android:maxSdkVersion="29" />
@ -83,7 +83,7 @@
android:name=".OpenFileActivity"
android:exported="true"
android:theme="@style/TransparentTheme">
<intent-filter android:label="@string/import_desc">
<intent-filter android:label="@string/import_data">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
@ -126,6 +126,7 @@
android:name="android.accessibilityservice"
android:resource="@xml/ab_desc" />
</service>
<service
android:name=".debug.ScreenshotService"
android:exported="false"
@ -155,10 +156,10 @@
android:value="Display a screenshot button for users to actively save screen information." />
</service>
<service
android:name=".debug.SnapshotTileService"
android:name=".service.GkdTileService"
android:exported="true"
android:icon="@drawable/ic_capture"
android:label="@string/capture_label"
android:icon="@drawable/ic_status"
android:label="@string/app_name"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
@ -166,12 +167,21 @@
</intent-filter>
</service>
<service
android:name=".service.GkdTileService"
android:name=".debug.SnapshotTileService"
android:exported="true"
android:icon="@drawable/ic_status"
android:label="@string/app_name"
android:icon="@drawable/ic_capture"
android:label="@string/capture_snapshot"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
<service
android:name=".debug.HttpTileService"
android:exported="true"
android:icon="@drawable/ic_http"
android:label="@string/http_server"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>

View File

@ -1,7 +1,6 @@
package li.songe.gkd.debug
import android.app.Service
import android.content.Context
import android.content.Intent
import com.blankj.utilcode.util.LogUtils
import io.ktor.http.ContentType
@ -83,7 +82,7 @@ class HttpService : Service() {
createNotif(
this@HttpService,
httpChannel.id,
httpNotif.copy(text = "HTTP服务-端口$port")
httpNotif.copy(text = "HTTP服务-$port")
)
}
}
@ -107,12 +106,12 @@ class HttpService : Service() {
companion object {
val isRunning = MutableStateFlow(false)
val localNetworkIpsFlow = MutableStateFlow(emptyList<String>())
fun stop(context: Context = app) {
context.stopService(Intent(context, HttpService::class.java))
fun stop() {
app.stopService(Intent(app, HttpService::class.java))
}
fun start(context: Context = app) {
context.startForegroundService(Intent(context, HttpService::class.java))
fun start() {
app.startForegroundService(Intent(app, HttpService::class.java))
}
}

View File

@ -0,0 +1,52 @@
package li.songe.gkd.debug
import android.service.quicksettings.Tile
import android.service.quicksettings.TileService
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
class HttpTileService : TileService() {
val scope = MainScope()
private val listeningFlow = MutableStateFlow(false)
override fun onCreate() {
super.onCreate()
scope.launch {
combine(
HttpService.isRunning,
listeningFlow
) { v1, v2 -> v1 to v2 }.collect { (httpRunning, listening) ->
if (listening) {
qsTile.state = if (httpRunning) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
qsTile.updateTile()
}
}
}
}
override fun onStartListening() {
super.onStartListening()
listeningFlow.value = true
}
override fun onStopListening() {
super.onStopListening()
listeningFlow.value = false
}
override fun onClick() {
super.onClick()
if (HttpService.isRunning.value) {
HttpService.stop()
} else {
HttpService.start()
}
}
override fun onDestroy() {
super.onDestroy()
scope.cancel()
}
}

View File

@ -5,6 +5,6 @@
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#FF000000"
android:fillColor="#FFF"
android:pathData="M128,384a42.7,42.7 0,0 0,42.7 -42.7L170.7,213.3a42.7,42.7 0,0 1,42.7 -42.7h128a42.7,42.7 0,0 0,0 -85.3L213.3,85.3a128,128 0,0 0,-128 128v128a42.7,42.7 0,0 0,42.7 42.7zM341.3,853.3L213.3,853.3a42.7,42.7 0,0 1,-42.7 -42.7v-128a42.7,42.7 0,0 0,-85.3 0v128a128,128 0,0 0,128 128h128a42.7,42.7 0,0 0,0 -85.3zM512,341.3a170.7,170.7 0,1 0,170.7 170.7,170.7 170.7,0 0,0 -170.7,-170.7zM512,597.3a85.3,85.3 0,1 1,85.3 -85.3,85.3 85.3,0 0,1 -85.3,85.3zM810.7,85.3h-128a42.7,42.7 0,0 0,0 85.3h128a42.7,42.7 0,0 1,42.7 42.7v128a42.7,42.7 0,0 0,85.3 0L938.7,213.3a128,128 0,0 0,-128 -128zM896,640a42.7,42.7 0,0 0,-42.7 42.7v128a42.7,42.7 0,0 1,-42.7 42.7h-128a42.7,42.7 0,0 0,0 85.3h128a128,128 0,0 0,128 -128v-128a42.7,42.7 0,0 0,-42.7 -42.7z" />
</vector>

View File

@ -5,5 +5,5 @@
android:viewportHeight="960">
<path
android:pathData="M280,80h400l-80,280h160L643,529l-57,-57 22,-32h-54l-47,-47 67,-233L360,160v86l-80,-80v-86ZM400,880v-320L280,560v-166L55,169l57,-57 736,736 -57,57 -241,-241L400,880ZM473,359Z"
android:fillColor="#5f6368" />
android:fillColor="#FFF" />
</vector>

View File

@ -5,5 +5,5 @@
android:viewportHeight="960">
<path
android:pathData="m480,624 l128,-184L494,440l80,-280L360,160v320h120v144ZM400,880v-320L280,560v-480h400l-80,280h160L400,880ZM480,480L360,480h120Z"
android:fillColor="#5f6368" />
android:fillColor="#FFF" />
</vector>

View File

@ -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:fillColor="#FFF"
android:pathData="M40,600v-240h60v80h80v-80h60v240h-60v-100h-80v100L40,600ZM340,600v-180h-60v-60h180v60h-60v180h-60ZM560,600v-180h-60v-60h180v60h-60v180h-60ZM720,600v-240h140q24,0 42,18t18,42v40q0,24 -18,42t-42,18h-80v80h-60ZM780,460h80v-40h-80v40Z" />
</vector>

View File

@ -2,9 +2,8 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
android:viewportHeight="960">
<path
android:fillColor="@android:color/white"
android:fillColor="#FFF"
android:pathData="M710,810Q647,810 603.5,766.5Q560,723 560,660Q560,597 603.5,553.5Q647,510 710,510Q773,510 816.5,553.5Q860,597 860,660Q860,723 816.5,766.5Q773,810 710,810ZM710,730Q739,730 759.5,709.5Q780,689 780,660Q780,631 759.5,610.5Q739,590 710,590Q681,590 660.5,610.5Q640,631 640,660Q640,689 660.5,709.5Q681,730 710,730ZM160,700L160,620L480,620L480,700L160,700ZM250,450Q187,450 143.5,406.5Q100,363 100,300Q100,237 143.5,193.5Q187,150 250,150Q313,150 356.5,193.5Q400,237 400,300Q400,363 356.5,406.5Q313,450 250,450ZM250,370Q279,370 299.5,349.5Q320,329 320,300Q320,271 299.5,250.5Q279,230 250,230Q221,230 200.5,250.5Q180,271 180,300Q180,329 200.5,349.5Q221,370 250,370ZM480,340L480,260L800,260L800,340L480,340ZM710,660Q710,660 710,660Q710,660 710,660Q710,660 710,660Q710,660 710,660Q710,660 710,660Q710,660 710,660Q710,660 710,660Q710,660 710,660ZM250,300Q250,300 250,300Q250,300 250,300Q250,300 250,300Q250,300 250,300Q250,300 250,300Q250,300 250,300Q250,300 250,300Q250,300 250,300Z"/>
</vector>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">GKD</string>
<string name="ab_desc">基于高级选择器+订阅规则的屏幕自定义点击服务\n\n通过自定义选择器和订阅规则,能帮助你实现点击任意位置控件,自定义快捷操作等高级功能</string>
<string name="capture_label">捕获快照</string>
<string name="import_desc">GKD-导入数据</string>
</resources>
<string name="a11y_desc">基于高级选择器+订阅规则的屏幕自定义点击服务\n\n通过自定义选择器和订阅规则,能帮助你实现点击任意位置控件,自定义快捷操作等高级功能</string>
<string name="import_data">导入数据</string>
<string name="capture_snapshot">捕获快照</string>
<string name="http_server">HTTP服务</string>
</resources>

View File

@ -7,7 +7,7 @@
android:canPerformGestures="true"
android:canRetrieveWindowContent="true"
android:canTakeScreenshot="true"
android:description="@string/ab_desc"
android:description="@string/a11y_desc"
android:notificationTimeout="100"
android:settingsActivity="li.songe.gkd.MainActivity"
tools:ignore="UnusedAttribute" />